diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/js/highcharts/highcharts-more.src.js b/NMP 3.0 Moodle Pluggin/fliplearning/js/highcharts/highcharts-more.src.js
index 675702c12a0ae4e7bd3532a9da5657aaf93f685f..7d4adcefd8bb2dd1ca1eac55c8ad6bf3aca62d81 100644
--- a/NMP 3.0 Moodle Pluggin/fliplearning/js/highcharts/highcharts-more.src.js	
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/js/highcharts/highcharts-more.src.js	
@@ -10569,4 +10569,4 @@
 
 
     });
-}));
+}));
\ No newline at end of file
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/composer.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/composer.json
new file mode 100644
index 0000000000000000000000000000000000000000..774a9e33dc9e1801245296fda32882acd72b2d14
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/composer.json	
@@ -0,0 +1,5 @@
+{
+    "require": {
+        "mongodb/mongodb": "^1.0.0"
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/composer.lock b/NMP 3.0 Moodle Pluggin/fliplearning/server/composer.lock
new file mode 100644
index 0000000000000000000000000000000000000000..8b6302f4ccf3c9d0652260c1160728ab03585222
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/composer.lock	
@@ -0,0 +1,298 @@
+{
+    "_readme": [
+        "This file locks the dependencies of your project to a known state",
+        "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
+        "This file is @generated automatically"
+    ],
+    "content-hash": "71f0e32689e000c75f7b268c243e7ee5",
+    "packages": [
+        {
+            "name": "composer/package-versions-deprecated",
+            "version": "1.11.99.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/composer/package-versions-deprecated.git",
+                "reference": "7413f0b55a051e89485c5cb9f765fe24bb02a7b6"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/composer/package-versions-deprecated/zipball/7413f0b55a051e89485c5cb9f765fe24bb02a7b6",
+                "reference": "7413f0b55a051e89485c5cb9f765fe24bb02a7b6",
+                "shasum": ""
+            },
+            "require": {
+                "composer-plugin-api": "^1.1.0 || ^2.0",
+                "php": "^7 || ^8"
+            },
+            "replace": {
+                "ocramius/package-versions": "1.11.99"
+            },
+            "require-dev": {
+                "composer/composer": "^1.9.3 || ^2.0@dev",
+                "ext-zip": "^1.13",
+                "phpunit/phpunit": "^6.5 || ^7"
+            },
+            "type": "composer-plugin",
+            "extra": {
+                "class": "PackageVersions\\Installer",
+                "branch-alias": {
+                    "dev-master": "1.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "PackageVersions\\": "src/PackageVersions"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Marco Pivetta",
+                    "email": "ocramius@gmail.com"
+                },
+                {
+                    "name": "Jordi Boggiano",
+                    "email": "j.boggiano@seld.be"
+                }
+            ],
+            "description": "Composer plugin that provides efficient querying for installed package versions (no runtime IO)",
+            "support": {
+                "issues": "https://github.com/composer/package-versions-deprecated/issues",
+                "source": "https://github.com/composer/package-versions-deprecated/tree/1.11.99.1"
+            },
+            "funding": [
+                {
+                    "url": "https://packagist.com",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/composer",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/composer/composer",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2020-11-11T10:22:58+00:00"
+        },
+        {
+            "name": "jean85/pretty-package-versions",
+            "version": "1.6.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/Jean85/pretty-package-versions.git",
+                "reference": "1e0104b46f045868f11942aea058cd7186d6c303"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/Jean85/pretty-package-versions/zipball/1e0104b46f045868f11942aea058cd7186d6c303",
+                "reference": "1e0104b46f045868f11942aea058cd7186d6c303",
+                "shasum": ""
+            },
+            "require": {
+                "composer/package-versions-deprecated": "^1.8.0",
+                "php": "^7.0|^8.0"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^6.0|^8.5|^9.2"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Jean85\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Alessandro Lai",
+                    "email": "alessandro.lai85@gmail.com"
+                }
+            ],
+            "description": "A wrapper for ocramius/package-versions to get pretty versions strings",
+            "keywords": [
+                "composer",
+                "package",
+                "release",
+                "versions"
+            ],
+            "support": {
+                "issues": "https://github.com/Jean85/pretty-package-versions/issues",
+                "source": "https://github.com/Jean85/pretty-package-versions/tree/1.6.0"
+            },
+            "time": "2021-02-04T16:20:16+00:00"
+        },
+        {
+            "name": "mongodb/mongodb",
+            "version": "1.8.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/mongodb/mongo-php-library.git",
+                "reference": "953dbc19443aa9314c44b7217a16873347e6840d"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/mongodb/mongo-php-library/zipball/953dbc19443aa9314c44b7217a16873347e6840d",
+                "reference": "953dbc19443aa9314c44b7217a16873347e6840d",
+                "shasum": ""
+            },
+            "require": {
+                "ext-hash": "*",
+                "ext-json": "*",
+                "ext-mongodb": "^1.8.1",
+                "jean85/pretty-package-versions": "^1.2",
+                "php": "^7.0 || ^8.0",
+                "symfony/polyfill-php80": "^1.19"
+            },
+            "require-dev": {
+                "squizlabs/php_codesniffer": "^3.5, <3.5.5",
+                "symfony/phpunit-bridge": "5.x-dev"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.8.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "MongoDB\\": "src/"
+                },
+                "files": [
+                    "src/functions.php"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "Apache-2.0"
+            ],
+            "authors": [
+                {
+                    "name": "Andreas Braun",
+                    "email": "andreas.braun@mongodb.com"
+                },
+                {
+                    "name": "Jeremy Mikola",
+                    "email": "jmikola@gmail.com"
+                }
+            ],
+            "description": "MongoDB driver library",
+            "homepage": "https://jira.mongodb.org/browse/PHPLIB",
+            "keywords": [
+                "database",
+                "driver",
+                "mongodb",
+                "persistence"
+            ],
+            "support": {
+                "issues": "https://github.com/mongodb/mongo-php-library/issues",
+                "source": "https://github.com/mongodb/mongo-php-library/tree/1.8.0"
+            },
+            "time": "2020-11-25T12:26:02+00:00"
+        },
+        {
+            "name": "symfony/polyfill-php80",
+            "version": "v1.22.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/polyfill-php80.git",
+                "reference": "dc3063ba22c2a1fd2f45ed856374d79114998f91"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/dc3063ba22c2a1fd2f45ed856374d79114998f91",
+                "reference": "dc3063ba22c2a1fd2f45ed856374d79114998f91",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.1"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-main": "1.22-dev"
+                },
+                "thanks": {
+                    "name": "symfony/polyfill",
+                    "url": "https://github.com/symfony/polyfill"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Symfony\\Polyfill\\Php80\\": ""
+                },
+                "files": [
+                    "bootstrap.php"
+                ],
+                "classmap": [
+                    "Resources/stubs"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Ion Bazan",
+                    "email": "ion.bazan@gmail.com"
+                },
+                {
+                    "name": "Nicolas Grekas",
+                    "email": "p@tchwork.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions",
+            "homepage": "https://symfony.com",
+            "keywords": [
+                "compatibility",
+                "polyfill",
+                "portable",
+                "shim"
+            ],
+            "support": {
+                "source": "https://github.com/symfony/polyfill-php80/tree/v1.22.1"
+            },
+            "funding": [
+                {
+                    "url": "https://symfony.com/sponsor",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/fabpot",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2021-01-07T16:49:33+00:00"
+        }
+    ],
+    "packages-dev": [],
+    "aliases": [],
+    "minimum-stability": "stable",
+    "stability-flags": [],
+    "prefer-stable": false,
+    "prefer-lowest": false,
+    "platform": [],
+    "platform-dev": [],
+    "plugin-api-version": "2.0.0"
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/autoload.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/autoload.php
new file mode 100644
index 0000000000000000000000000000000000000000..0f7c2427a294d9f87497197a36315bf076106461
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/autoload.php	
@@ -0,0 +1,7 @@
+<?php
+
+// autoload.php @generated by Composer
+
+require_once __DIR__ . '/composer/autoload_real.php';
+
+return ComposerAutoloaderInit84516537bcbae867938a4438c520c836::getLoader();
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/composer/ClassLoader.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/composer/ClassLoader.php
new file mode 100644
index 0000000000000000000000000000000000000000..247294d66ee04633486c9da28b94241e1f7c4c31
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/composer/ClassLoader.php	
@@ -0,0 +1,479 @@
+<?php
+
+/*
+ * This file is part of Composer.
+ *
+ * (c) Nils Adermann <naderman@naderman.de>
+ *     Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Composer\Autoload;
+
+/**
+ * ClassLoader implements a PSR-0, PSR-4 and classmap class loader.
+ *
+ *     $loader = new \Composer\Autoload\ClassLoader();
+ *
+ *     // register classes with namespaces
+ *     $loader->add('Symfony\Component', __DIR__.'/component');
+ *     $loader->add('Symfony',           __DIR__.'/framework');
+ *
+ *     // activate the autoloader
+ *     $loader->register();
+ *
+ *     // to enable searching the include path (eg. for PEAR packages)
+ *     $loader->setUseIncludePath(true);
+ *
+ * In this example, if you try to use a class in the Symfony\Component
+ * namespace or one of its children (Symfony\Component\Console for instance),
+ * the autoloader will first look for the class under the component/
+ * directory, and it will then fallback to the framework/ directory if not
+ * found before giving up.
+ *
+ * This class is loosely based on the Symfony UniversalClassLoader.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ * @author Jordi Boggiano <j.boggiano@seld.be>
+ * @see    https://www.php-fig.org/psr/psr-0/
+ * @see    https://www.php-fig.org/psr/psr-4/
+ */
+class ClassLoader
+{
+    private $vendorDir;
+
+    // PSR-4
+    private $prefixLengthsPsr4 = array();
+    private $prefixDirsPsr4 = array();
+    private $fallbackDirsPsr4 = array();
+
+    // PSR-0
+    private $prefixesPsr0 = array();
+    private $fallbackDirsPsr0 = array();
+
+    private $useIncludePath = false;
+    private $classMap = array();
+    private $classMapAuthoritative = false;
+    private $missingClasses = array();
+    private $apcuPrefix;
+
+    private static $registeredLoaders = array();
+
+    public function __construct($vendorDir = null)
+    {
+        $this->vendorDir = $vendorDir;
+    }
+
+    public function getPrefixes()
+    {
+        if (!empty($this->prefixesPsr0)) {
+            return call_user_func_array('array_merge', array_values($this->prefixesPsr0));
+        }
+
+        return array();
+    }
+
+    public function getPrefixesPsr4()
+    {
+        return $this->prefixDirsPsr4;
+    }
+
+    public function getFallbackDirs()
+    {
+        return $this->fallbackDirsPsr0;
+    }
+
+    public function getFallbackDirsPsr4()
+    {
+        return $this->fallbackDirsPsr4;
+    }
+
+    public function getClassMap()
+    {
+        return $this->classMap;
+    }
+
+    /**
+     * @param array $classMap Class to filename map
+     */
+    public function addClassMap(array $classMap)
+    {
+        if ($this->classMap) {
+            $this->classMap = array_merge($this->classMap, $classMap);
+        } else {
+            $this->classMap = $classMap;
+        }
+    }
+
+    /**
+     * Registers a set of PSR-0 directories for a given prefix, either
+     * appending or prepending to the ones previously set for this prefix.
+     *
+     * @param string       $prefix  The prefix
+     * @param array|string $paths   The PSR-0 root directories
+     * @param bool         $prepend Whether to prepend the directories
+     */
+    public function add($prefix, $paths, $prepend = false)
+    {
+        if (!$prefix) {
+            if ($prepend) {
+                $this->fallbackDirsPsr0 = array_merge(
+                    (array) $paths,
+                    $this->fallbackDirsPsr0
+                );
+            } else {
+                $this->fallbackDirsPsr0 = array_merge(
+                    $this->fallbackDirsPsr0,
+                    (array) $paths
+                );
+            }
+
+            return;
+        }
+
+        $first = $prefix[0];
+        if (!isset($this->prefixesPsr0[$first][$prefix])) {
+            $this->prefixesPsr0[$first][$prefix] = (array) $paths;
+
+            return;
+        }
+        if ($prepend) {
+            $this->prefixesPsr0[$first][$prefix] = array_merge(
+                (array) $paths,
+                $this->prefixesPsr0[$first][$prefix]
+            );
+        } else {
+            $this->prefixesPsr0[$first][$prefix] = array_merge(
+                $this->prefixesPsr0[$first][$prefix],
+                (array) $paths
+            );
+        }
+    }
+
+    /**
+     * Registers a set of PSR-4 directories for a given namespace, either
+     * appending or prepending to the ones previously set for this namespace.
+     *
+     * @param string       $prefix  The prefix/namespace, with trailing '\\'
+     * @param array|string $paths   The PSR-4 base directories
+     * @param bool         $prepend Whether to prepend the directories
+     *
+     * @throws \InvalidArgumentException
+     */
+    public function addPsr4($prefix, $paths, $prepend = false)
+    {
+        if (!$prefix) {
+            // Register directories for the root namespace.
+            if ($prepend) {
+                $this->fallbackDirsPsr4 = array_merge(
+                    (array) $paths,
+                    $this->fallbackDirsPsr4
+                );
+            } else {
+                $this->fallbackDirsPsr4 = array_merge(
+                    $this->fallbackDirsPsr4,
+                    (array) $paths
+                );
+            }
+        } elseif (!isset($this->prefixDirsPsr4[$prefix])) {
+            // Register directories for a new namespace.
+            $length = strlen($prefix);
+            if ('\\' !== $prefix[$length - 1]) {
+                throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
+            }
+            $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
+            $this->prefixDirsPsr4[$prefix] = (array) $paths;
+        } elseif ($prepend) {
+            // Prepend directories for an already registered namespace.
+            $this->prefixDirsPsr4[$prefix] = array_merge(
+                (array) $paths,
+                $this->prefixDirsPsr4[$prefix]
+            );
+        } else {
+            // Append directories for an already registered namespace.
+            $this->prefixDirsPsr4[$prefix] = array_merge(
+                $this->prefixDirsPsr4[$prefix],
+                (array) $paths
+            );
+        }
+    }
+
+    /**
+     * Registers a set of PSR-0 directories for a given prefix,
+     * replacing any others previously set for this prefix.
+     *
+     * @param string       $prefix The prefix
+     * @param array|string $paths  The PSR-0 base directories
+     */
+    public function set($prefix, $paths)
+    {
+        if (!$prefix) {
+            $this->fallbackDirsPsr0 = (array) $paths;
+        } else {
+            $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
+        }
+    }
+
+    /**
+     * Registers a set of PSR-4 directories for a given namespace,
+     * replacing any others previously set for this namespace.
+     *
+     * @param string       $prefix The prefix/namespace, with trailing '\\'
+     * @param array|string $paths  The PSR-4 base directories
+     *
+     * @throws \InvalidArgumentException
+     */
+    public function setPsr4($prefix, $paths)
+    {
+        if (!$prefix) {
+            $this->fallbackDirsPsr4 = (array) $paths;
+        } else {
+            $length = strlen($prefix);
+            if ('\\' !== $prefix[$length - 1]) {
+                throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
+            }
+            $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
+            $this->prefixDirsPsr4[$prefix] = (array) $paths;
+        }
+    }
+
+    /**
+     * Turns on searching the include path for class files.
+     *
+     * @param bool $useIncludePath
+     */
+    public function setUseIncludePath($useIncludePath)
+    {
+        $this->useIncludePath = $useIncludePath;
+    }
+
+    /**
+     * Can be used to check if the autoloader uses the include path to check
+     * for classes.
+     *
+     * @return bool
+     */
+    public function getUseIncludePath()
+    {
+        return $this->useIncludePath;
+    }
+
+    /**
+     * Turns off searching the prefix and fallback directories for classes
+     * that have not been registered with the class map.
+     *
+     * @param bool $classMapAuthoritative
+     */
+    public function setClassMapAuthoritative($classMapAuthoritative)
+    {
+        $this->classMapAuthoritative = $classMapAuthoritative;
+    }
+
+    /**
+     * Should class lookup fail if not found in the current class map?
+     *
+     * @return bool
+     */
+    public function isClassMapAuthoritative()
+    {
+        return $this->classMapAuthoritative;
+    }
+
+    /**
+     * APCu prefix to use to cache found/not-found classes, if the extension is enabled.
+     *
+     * @param string|null $apcuPrefix
+     */
+    public function setApcuPrefix($apcuPrefix)
+    {
+        $this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null;
+    }
+
+    /**
+     * The APCu prefix in use, or null if APCu caching is not enabled.
+     *
+     * @return string|null
+     */
+    public function getApcuPrefix()
+    {
+        return $this->apcuPrefix;
+    }
+
+    /**
+     * Registers this instance as an autoloader.
+     *
+     * @param bool $prepend Whether to prepend the autoloader or not
+     */
+    public function register($prepend = false)
+    {
+        spl_autoload_register(array($this, 'loadClass'), true, $prepend);
+
+        if (null === $this->vendorDir) {
+            return;
+        }
+
+        if ($prepend) {
+            self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders;
+        } else {
+            unset(self::$registeredLoaders[$this->vendorDir]);
+            self::$registeredLoaders[$this->vendorDir] = $this;
+        }
+    }
+
+    /**
+     * Unregisters this instance as an autoloader.
+     */
+    public function unregister()
+    {
+        spl_autoload_unregister(array($this, 'loadClass'));
+
+        if (null !== $this->vendorDir) {
+            unset(self::$registeredLoaders[$this->vendorDir]);
+        }
+    }
+
+    /**
+     * Loads the given class or interface.
+     *
+     * @param  string    $class The name of the class
+     * @return bool|null True if loaded, null otherwise
+     */
+    public function loadClass($class)
+    {
+        if ($file = $this->findFile($class)) {
+            includeFile($file);
+
+            return true;
+        }
+    }
+
+    /**
+     * Finds the path to the file where the class is defined.
+     *
+     * @param string $class The name of the class
+     *
+     * @return string|false The path if found, false otherwise
+     */
+    public function findFile($class)
+    {
+        // class map lookup
+        if (isset($this->classMap[$class])) {
+            return $this->classMap[$class];
+        }
+        if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) {
+            return false;
+        }
+        if (null !== $this->apcuPrefix) {
+            $file = apcu_fetch($this->apcuPrefix.$class, $hit);
+            if ($hit) {
+                return $file;
+            }
+        }
+
+        $file = $this->findFileWithExtension($class, '.php');
+
+        // Search for Hack files if we are running on HHVM
+        if (false === $file && defined('HHVM_VERSION')) {
+            $file = $this->findFileWithExtension($class, '.hh');
+        }
+
+        if (null !== $this->apcuPrefix) {
+            apcu_add($this->apcuPrefix.$class, $file);
+        }
+
+        if (false === $file) {
+            // Remember that this class does not exist.
+            $this->missingClasses[$class] = true;
+        }
+
+        return $file;
+    }
+
+    /**
+     * Returns the currently registered loaders indexed by their corresponding vendor directories.
+     *
+     * @return self[]
+     */
+    public static function getRegisteredLoaders()
+    {
+        return self::$registeredLoaders;
+    }
+
+    private function findFileWithExtension($class, $ext)
+    {
+        // PSR-4 lookup
+        $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
+
+        $first = $class[0];
+        if (isset($this->prefixLengthsPsr4[$first])) {
+            $subPath = $class;
+            while (false !== $lastPos = strrpos($subPath, '\\')) {
+                $subPath = substr($subPath, 0, $lastPos);
+                $search = $subPath . '\\';
+                if (isset($this->prefixDirsPsr4[$search])) {
+                    $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
+                    foreach ($this->prefixDirsPsr4[$search] as $dir) {
+                        if (file_exists($file = $dir . $pathEnd)) {
+                            return $file;
+                        }
+                    }
+                }
+            }
+        }
+
+        // PSR-4 fallback dirs
+        foreach ($this->fallbackDirsPsr4 as $dir) {
+            if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
+                return $file;
+            }
+        }
+
+        // PSR-0 lookup
+        if (false !== $pos = strrpos($class, '\\')) {
+            // namespaced class name
+            $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
+                . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
+        } else {
+            // PEAR-like class name
+            $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
+        }
+
+        if (isset($this->prefixesPsr0[$first])) {
+            foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
+                if (0 === strpos($class, $prefix)) {
+                    foreach ($dirs as $dir) {
+                        if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
+                            return $file;
+                        }
+                    }
+                }
+            }
+        }
+
+        // PSR-0 fallback dirs
+        foreach ($this->fallbackDirsPsr0 as $dir) {
+            if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
+                return $file;
+            }
+        }
+
+        // PSR-0 include paths.
+        if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
+            return $file;
+        }
+
+        return false;
+    }
+}
+
+/**
+ * Scope isolated include.
+ *
+ * Prevents access to $this/self from included files.
+ */
+function includeFile($file)
+{
+    include $file;
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/composer/InstalledVersions.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/composer/InstalledVersions.php
new file mode 100644
index 0000000000000000000000000000000000000000..00ca7ad3585f14593619fe18ff9b1ea6a9269524
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/composer/InstalledVersions.php	
@@ -0,0 +1,326 @@
+<?php
+
+
+
+
+
+
+
+
+
+
+
+namespace Composer;
+
+use Composer\Autoload\ClassLoader;
+use Composer\Semver\VersionParser;
+
+
+
+
+
+
+class InstalledVersions
+{
+private static $installed = array (
+  'root' => 
+  array (
+    'pretty_version' => '1.0.0+no-version-set',
+    'version' => '1.0.0.0',
+    'aliases' => 
+    array (
+    ),
+    'reference' => NULL,
+    'name' => '__root__',
+  ),
+  'versions' => 
+  array (
+    '__root__' => 
+    array (
+      'pretty_version' => '1.0.0+no-version-set',
+      'version' => '1.0.0.0',
+      'aliases' => 
+      array (
+      ),
+      'reference' => NULL,
+    ),
+    'composer/package-versions-deprecated' => 
+    array (
+      'pretty_version' => '1.11.99.1',
+      'version' => '1.11.99.1',
+      'aliases' => 
+      array (
+      ),
+      'reference' => '7413f0b55a051e89485c5cb9f765fe24bb02a7b6',
+    ),
+    'jean85/pretty-package-versions' => 
+    array (
+      'pretty_version' => '1.6.0',
+      'version' => '1.6.0.0',
+      'aliases' => 
+      array (
+      ),
+      'reference' => '1e0104b46f045868f11942aea058cd7186d6c303',
+    ),
+    'mongodb/mongodb' => 
+    array (
+      'pretty_version' => '1.8.0',
+      'version' => '1.8.0.0',
+      'aliases' => 
+      array (
+      ),
+      'reference' => '953dbc19443aa9314c44b7217a16873347e6840d',
+    ),
+    'ocramius/package-versions' => 
+    array (
+      'replaced' => 
+      array (
+        0 => '1.11.99',
+      ),
+    ),
+    'symfony/polyfill-php80' => 
+    array (
+      'pretty_version' => 'v1.22.1',
+      'version' => '1.22.1.0',
+      'aliases' => 
+      array (
+      ),
+      'reference' => 'dc3063ba22c2a1fd2f45ed856374d79114998f91',
+    ),
+  ),
+);
+private static $canGetVendors;
+private static $installedByVendor = array();
+
+
+
+
+
+
+
+public static function getInstalledPackages()
+{
+$packages = array();
+foreach (self::getInstalled() as $installed) {
+$packages[] = array_keys($installed['versions']);
+}
+
+
+if (1 === \count($packages)) {
+return $packages[0];
+}
+
+return array_keys(array_flip(\call_user_func_array('array_merge', $packages)));
+}
+
+
+
+
+
+
+
+
+
+public static function isInstalled($packageName)
+{
+foreach (self::getInstalled() as $installed) {
+if (isset($installed['versions'][$packageName])) {
+return true;
+}
+}
+
+return false;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+public static function satisfies(VersionParser $parser, $packageName, $constraint)
+{
+$constraint = $parser->parseConstraints($constraint);
+$provided = $parser->parseConstraints(self::getVersionRanges($packageName));
+
+return $provided->matches($constraint);
+}
+
+
+
+
+
+
+
+
+
+
+public static function getVersionRanges($packageName)
+{
+foreach (self::getInstalled() as $installed) {
+if (!isset($installed['versions'][$packageName])) {
+continue;
+}
+
+$ranges = array();
+if (isset($installed['versions'][$packageName]['pretty_version'])) {
+$ranges[] = $installed['versions'][$packageName]['pretty_version'];
+}
+if (array_key_exists('aliases', $installed['versions'][$packageName])) {
+$ranges = array_merge($ranges, $installed['versions'][$packageName]['aliases']);
+}
+if (array_key_exists('replaced', $installed['versions'][$packageName])) {
+$ranges = array_merge($ranges, $installed['versions'][$packageName]['replaced']);
+}
+if (array_key_exists('provided', $installed['versions'][$packageName])) {
+$ranges = array_merge($ranges, $installed['versions'][$packageName]['provided']);
+}
+
+return implode(' || ', $ranges);
+}
+
+throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
+}
+
+
+
+
+
+public static function getVersion($packageName)
+{
+foreach (self::getInstalled() as $installed) {
+if (!isset($installed['versions'][$packageName])) {
+continue;
+}
+
+if (!isset($installed['versions'][$packageName]['version'])) {
+return null;
+}
+
+return $installed['versions'][$packageName]['version'];
+}
+
+throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
+}
+
+
+
+
+
+public static function getPrettyVersion($packageName)
+{
+foreach (self::getInstalled() as $installed) {
+if (!isset($installed['versions'][$packageName])) {
+continue;
+}
+
+if (!isset($installed['versions'][$packageName]['pretty_version'])) {
+return null;
+}
+
+return $installed['versions'][$packageName]['pretty_version'];
+}
+
+throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
+}
+
+
+
+
+
+public static function getReference($packageName)
+{
+foreach (self::getInstalled() as $installed) {
+if (!isset($installed['versions'][$packageName])) {
+continue;
+}
+
+if (!isset($installed['versions'][$packageName]['reference'])) {
+return null;
+}
+
+return $installed['versions'][$packageName]['reference'];
+}
+
+throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
+}
+
+
+
+
+
+public static function getRootPackage()
+{
+$installed = self::getInstalled();
+
+return $installed[0]['root'];
+}
+
+
+
+
+
+
+
+public static function getRawData()
+{
+return self::$installed;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+public static function reload($data)
+{
+self::$installed = $data;
+self::$installedByVendor = array();
+}
+
+
+
+
+private static function getInstalled()
+{
+if (null === self::$canGetVendors) {
+self::$canGetVendors = method_exists('Composer\Autoload\ClassLoader', 'getRegisteredLoaders');
+}
+
+$installed = array();
+
+if (self::$canGetVendors) {
+foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) {
+if (isset(self::$installedByVendor[$vendorDir])) {
+$installed[] = self::$installedByVendor[$vendorDir];
+} elseif (is_file($vendorDir.'/composer/installed.php')) {
+$installed[] = self::$installedByVendor[$vendorDir] = require $vendorDir.'/composer/installed.php';
+}
+}
+}
+
+$installed[] = self::$installed;
+
+return $installed;
+}
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/composer/LICENSE b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/composer/LICENSE
new file mode 100644
index 0000000000000000000000000000000000000000..f27399a042d95c4708af3a8c74d35d338763cf8f
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/composer/LICENSE	
@@ -0,0 +1,21 @@
+
+Copyright (c) Nils Adermann, Jordi Boggiano
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/composer/autoload_classmap.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/composer/autoload_classmap.php
new file mode 100644
index 0000000000000000000000000000000000000000..4ebd53fca8e5cbe0b1b7fb9c1d4ba75aebb3c7b3
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/composer/autoload_classmap.php	
@@ -0,0 +1,14 @@
+<?php
+
+// autoload_classmap.php @generated by Composer
+
+$vendorDir = dirname(dirname(__FILE__));
+$baseDir = dirname($vendorDir);
+
+return array(
+    'Attribute' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/Attribute.php',
+    'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
+    'Stringable' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/Stringable.php',
+    'UnhandledMatchError' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php',
+    'ValueError' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/ValueError.php',
+);
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/composer/autoload_files.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/composer/autoload_files.php
new file mode 100644
index 0000000000000000000000000000000000000000..12afa3f62cdb9dcd711974d90cb5874d6e148770
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/composer/autoload_files.php	
@@ -0,0 +1,11 @@
+<?php
+
+// autoload_files.php @generated by Composer
+
+$vendorDir = dirname(dirname(__FILE__));
+$baseDir = dirname($vendorDir);
+
+return array(
+    'a4a119a56e50fbb293281d9a48007e0e' => $vendorDir . '/symfony/polyfill-php80/bootstrap.php',
+    '3a37ebac017bc098e9a86b35401e7a68' => $vendorDir . '/mongodb/mongodb/src/functions.php',
+);
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/composer/autoload_namespaces.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/composer/autoload_namespaces.php
new file mode 100644
index 0000000000000000000000000000000000000000..b7fc0125dbca56fd7565ad62097672a59473e64e
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/composer/autoload_namespaces.php	
@@ -0,0 +1,9 @@
+<?php
+
+// autoload_namespaces.php @generated by Composer
+
+$vendorDir = dirname(dirname(__FILE__));
+$baseDir = dirname($vendorDir);
+
+return array(
+);
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/composer/autoload_psr4.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/composer/autoload_psr4.php
new file mode 100644
index 0000000000000000000000000000000000000000..1267baae31987a1c4be0d57d7f3f8b8c508e146a
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/composer/autoload_psr4.php	
@@ -0,0 +1,13 @@
+<?php
+
+// autoload_psr4.php @generated by Composer
+
+$vendorDir = dirname(dirname(__FILE__));
+$baseDir = dirname($vendorDir);
+
+return array(
+    'Symfony\\Polyfill\\Php80\\' => array($vendorDir . '/symfony/polyfill-php80'),
+    'PackageVersions\\' => array($vendorDir . '/composer/package-versions-deprecated/src/PackageVersions'),
+    'MongoDB\\' => array($vendorDir . '/mongodb/mongodb/src'),
+    'Jean85\\' => array($vendorDir . '/jean85/pretty-package-versions/src'),
+);
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/composer/autoload_real.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/composer/autoload_real.php
new file mode 100644
index 0000000000000000000000000000000000000000..aafb55c899b58e4782848196e9274de58ce9cc76
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/composer/autoload_real.php	
@@ -0,0 +1,75 @@
+<?php
+
+// autoload_real.php @generated by Composer
+
+class ComposerAutoloaderInit84516537bcbae867938a4438c520c836
+{
+    private static $loader;
+
+    public static function loadClassLoader($class)
+    {
+        if ('Composer\Autoload\ClassLoader' === $class) {
+            require __DIR__ . '/ClassLoader.php';
+        }
+    }
+
+    /**
+     * @return \Composer\Autoload\ClassLoader
+     */
+    public static function getLoader()
+    {
+        if (null !== self::$loader) {
+            return self::$loader;
+        }
+
+        require __DIR__ . '/platform_check.php';
+
+        spl_autoload_register(array('ComposerAutoloaderInit84516537bcbae867938a4438c520c836', 'loadClassLoader'), true, true);
+        self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(\dirname(__FILE__)));
+        spl_autoload_unregister(array('ComposerAutoloaderInit84516537bcbae867938a4438c520c836', 'loadClassLoader'));
+
+        $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
+        if ($useStaticLoader) {
+            require __DIR__ . '/autoload_static.php';
+
+            call_user_func(\Composer\Autoload\ComposerStaticInit84516537bcbae867938a4438c520c836::getInitializer($loader));
+        } else {
+            $map = require __DIR__ . '/autoload_namespaces.php';
+            foreach ($map as $namespace => $path) {
+                $loader->set($namespace, $path);
+            }
+
+            $map = require __DIR__ . '/autoload_psr4.php';
+            foreach ($map as $namespace => $path) {
+                $loader->setPsr4($namespace, $path);
+            }
+
+            $classMap = require __DIR__ . '/autoload_classmap.php';
+            if ($classMap) {
+                $loader->addClassMap($classMap);
+            }
+        }
+
+        $loader->register(true);
+
+        if ($useStaticLoader) {
+            $includeFiles = Composer\Autoload\ComposerStaticInit84516537bcbae867938a4438c520c836::$files;
+        } else {
+            $includeFiles = require __DIR__ . '/autoload_files.php';
+        }
+        foreach ($includeFiles as $fileIdentifier => $file) {
+            composerRequire84516537bcbae867938a4438c520c836($fileIdentifier, $file);
+        }
+
+        return $loader;
+    }
+}
+
+function composerRequire84516537bcbae867938a4438c520c836($fileIdentifier, $file)
+{
+    if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
+        require $file;
+
+        $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/composer/autoload_static.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/composer/autoload_static.php
new file mode 100644
index 0000000000000000000000000000000000000000..d8f5dbb4c0b45f1de9f3be8d8bed162b6207b747
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/composer/autoload_static.php	
@@ -0,0 +1,69 @@
+<?php
+
+// autoload_static.php @generated by Composer
+
+namespace Composer\Autoload;
+
+class ComposerStaticInit84516537bcbae867938a4438c520c836
+{
+    public static $files = array (
+        'a4a119a56e50fbb293281d9a48007e0e' => __DIR__ . '/..' . '/symfony/polyfill-php80/bootstrap.php',
+        '3a37ebac017bc098e9a86b35401e7a68' => __DIR__ . '/..' . '/mongodb/mongodb/src/functions.php',
+    );
+
+    public static $prefixLengthsPsr4 = array (
+        'S' => 
+        array (
+            'Symfony\\Polyfill\\Php80\\' => 23,
+        ),
+        'P' => 
+        array (
+            'PackageVersions\\' => 16,
+        ),
+        'M' => 
+        array (
+            'MongoDB\\' => 8,
+        ),
+        'J' => 
+        array (
+            'Jean85\\' => 7,
+        ),
+    );
+
+    public static $prefixDirsPsr4 = array (
+        'Symfony\\Polyfill\\Php80\\' => 
+        array (
+            0 => __DIR__ . '/..' . '/symfony/polyfill-php80',
+        ),
+        'PackageVersions\\' => 
+        array (
+            0 => __DIR__ . '/..' . '/composer/package-versions-deprecated/src/PackageVersions',
+        ),
+        'MongoDB\\' => 
+        array (
+            0 => __DIR__ . '/..' . '/mongodb/mongodb/src',
+        ),
+        'Jean85\\' => 
+        array (
+            0 => __DIR__ . '/..' . '/jean85/pretty-package-versions/src',
+        ),
+    );
+
+    public static $classMap = array (
+        'Attribute' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/Attribute.php',
+        'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
+        'Stringable' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/Stringable.php',
+        'UnhandledMatchError' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php',
+        'ValueError' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/ValueError.php',
+    );
+
+    public static function getInitializer(ClassLoader $loader)
+    {
+        return \Closure::bind(function () use ($loader) {
+            $loader->prefixLengthsPsr4 = ComposerStaticInit84516537bcbae867938a4438c520c836::$prefixLengthsPsr4;
+            $loader->prefixDirsPsr4 = ComposerStaticInit84516537bcbae867938a4438c520c836::$prefixDirsPsr4;
+            $loader->classMap = ComposerStaticInit84516537bcbae867938a4438c520c836::$classMap;
+
+        }, null, ClassLoader::class);
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/composer/installed.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/composer/installed.json
new file mode 100644
index 0000000000000000000000000000000000000000..997aaf256e9b6331abb87baa332db9c21f0bf929
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/composer/installed.json	
@@ -0,0 +1,297 @@
+{
+    "packages": [
+        {
+            "name": "composer/package-versions-deprecated",
+            "version": "1.11.99.1",
+            "version_normalized": "1.11.99.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/composer/package-versions-deprecated.git",
+                "reference": "7413f0b55a051e89485c5cb9f765fe24bb02a7b6"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/composer/package-versions-deprecated/zipball/7413f0b55a051e89485c5cb9f765fe24bb02a7b6",
+                "reference": "7413f0b55a051e89485c5cb9f765fe24bb02a7b6",
+                "shasum": ""
+            },
+            "require": {
+                "composer-plugin-api": "^1.1.0 || ^2.0",
+                "php": "^7 || ^8"
+            },
+            "replace": {
+                "ocramius/package-versions": "1.11.99"
+            },
+            "require-dev": {
+                "composer/composer": "^1.9.3 || ^2.0@dev",
+                "ext-zip": "^1.13",
+                "phpunit/phpunit": "^6.5 || ^7"
+            },
+            "time": "2020-11-11T10:22:58+00:00",
+            "type": "composer-plugin",
+            "extra": {
+                "class": "PackageVersions\\Installer",
+                "branch-alias": {
+                    "dev-master": "1.x-dev"
+                }
+            },
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "PackageVersions\\": "src/PackageVersions"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Marco Pivetta",
+                    "email": "ocramius@gmail.com"
+                },
+                {
+                    "name": "Jordi Boggiano",
+                    "email": "j.boggiano@seld.be"
+                }
+            ],
+            "description": "Composer plugin that provides efficient querying for installed package versions (no runtime IO)",
+            "support": {
+                "issues": "https://github.com/composer/package-versions-deprecated/issues",
+                "source": "https://github.com/composer/package-versions-deprecated/tree/1.11.99.1"
+            },
+            "funding": [
+                {
+                    "url": "https://packagist.com",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/composer",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/composer/composer",
+                    "type": "tidelift"
+                }
+            ],
+            "install-path": "./package-versions-deprecated"
+        },
+        {
+            "name": "jean85/pretty-package-versions",
+            "version": "1.6.0",
+            "version_normalized": "1.6.0.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/Jean85/pretty-package-versions.git",
+                "reference": "1e0104b46f045868f11942aea058cd7186d6c303"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/Jean85/pretty-package-versions/zipball/1e0104b46f045868f11942aea058cd7186d6c303",
+                "reference": "1e0104b46f045868f11942aea058cd7186d6c303",
+                "shasum": ""
+            },
+            "require": {
+                "composer/package-versions-deprecated": "^1.8.0",
+                "php": "^7.0|^8.0"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^6.0|^8.5|^9.2"
+            },
+            "time": "2021-02-04T16:20:16+00:00",
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.x-dev"
+                }
+            },
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "Jean85\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Alessandro Lai",
+                    "email": "alessandro.lai85@gmail.com"
+                }
+            ],
+            "description": "A wrapper for ocramius/package-versions to get pretty versions strings",
+            "keywords": [
+                "composer",
+                "package",
+                "release",
+                "versions"
+            ],
+            "support": {
+                "issues": "https://github.com/Jean85/pretty-package-versions/issues",
+                "source": "https://github.com/Jean85/pretty-package-versions/tree/1.6.0"
+            },
+            "install-path": "../jean85/pretty-package-versions"
+        },
+        {
+            "name": "mongodb/mongodb",
+            "version": "1.8.0",
+            "version_normalized": "1.8.0.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/mongodb/mongo-php-library.git",
+                "reference": "953dbc19443aa9314c44b7217a16873347e6840d"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/mongodb/mongo-php-library/zipball/953dbc19443aa9314c44b7217a16873347e6840d",
+                "reference": "953dbc19443aa9314c44b7217a16873347e6840d",
+                "shasum": ""
+            },
+            "require": {
+                "ext-hash": "*",
+                "ext-json": "*",
+                "ext-mongodb": "^1.8.1",
+                "jean85/pretty-package-versions": "^1.2",
+                "php": "^7.0 || ^8.0",
+                "symfony/polyfill-php80": "^1.19"
+            },
+            "require-dev": {
+                "squizlabs/php_codesniffer": "^3.5, <3.5.5",
+                "symfony/phpunit-bridge": "5.x-dev"
+            },
+            "time": "2020-11-25T12:26:02+00:00",
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.8.x-dev"
+                }
+            },
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "MongoDB\\": "src/"
+                },
+                "files": [
+                    "src/functions.php"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "Apache-2.0"
+            ],
+            "authors": [
+                {
+                    "name": "Andreas Braun",
+                    "email": "andreas.braun@mongodb.com"
+                },
+                {
+                    "name": "Jeremy Mikola",
+                    "email": "jmikola@gmail.com"
+                }
+            ],
+            "description": "MongoDB driver library",
+            "homepage": "https://jira.mongodb.org/browse/PHPLIB",
+            "keywords": [
+                "database",
+                "driver",
+                "mongodb",
+                "persistence"
+            ],
+            "support": {
+                "issues": "https://github.com/mongodb/mongo-php-library/issues",
+                "source": "https://github.com/mongodb/mongo-php-library/tree/1.8.0"
+            },
+            "install-path": "../mongodb/mongodb"
+        },
+        {
+            "name": "symfony/polyfill-php80",
+            "version": "v1.22.1",
+            "version_normalized": "1.22.1.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/polyfill-php80.git",
+                "reference": "dc3063ba22c2a1fd2f45ed856374d79114998f91"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/dc3063ba22c2a1fd2f45ed856374d79114998f91",
+                "reference": "dc3063ba22c2a1fd2f45ed856374d79114998f91",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.1"
+            },
+            "time": "2021-01-07T16:49:33+00:00",
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-main": "1.22-dev"
+                },
+                "thanks": {
+                    "name": "symfony/polyfill",
+                    "url": "https://github.com/symfony/polyfill"
+                }
+            },
+            "installation-source": "dist",
+            "autoload": {
+                "psr-4": {
+                    "Symfony\\Polyfill\\Php80\\": ""
+                },
+                "files": [
+                    "bootstrap.php"
+                ],
+                "classmap": [
+                    "Resources/stubs"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Ion Bazan",
+                    "email": "ion.bazan@gmail.com"
+                },
+                {
+                    "name": "Nicolas Grekas",
+                    "email": "p@tchwork.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions",
+            "homepage": "https://symfony.com",
+            "keywords": [
+                "compatibility",
+                "polyfill",
+                "portable",
+                "shim"
+            ],
+            "support": {
+                "source": "https://github.com/symfony/polyfill-php80/tree/v1.22.1"
+            },
+            "funding": [
+                {
+                    "url": "https://symfony.com/sponsor",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/fabpot",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+                    "type": "tidelift"
+                }
+            ],
+            "install-path": "../symfony/polyfill-php80"
+        }
+    ],
+    "dev": true,
+    "dev-package-names": []
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/composer/installed.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/composer/installed.php
new file mode 100644
index 0000000000000000000000000000000000000000..e5aa3bf7779f88b534261c1da9f3ea1cecb97325
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/composer/installed.php	
@@ -0,0 +1,67 @@
+<?php return array (
+  'root' => 
+  array (
+    'pretty_version' => '1.0.0+no-version-set',
+    'version' => '1.0.0.0',
+    'aliases' => 
+    array (
+    ),
+    'reference' => NULL,
+    'name' => '__root__',
+  ),
+  'versions' => 
+  array (
+    '__root__' => 
+    array (
+      'pretty_version' => '1.0.0+no-version-set',
+      'version' => '1.0.0.0',
+      'aliases' => 
+      array (
+      ),
+      'reference' => NULL,
+    ),
+    'composer/package-versions-deprecated' => 
+    array (
+      'pretty_version' => '1.11.99.1',
+      'version' => '1.11.99.1',
+      'aliases' => 
+      array (
+      ),
+      'reference' => '7413f0b55a051e89485c5cb9f765fe24bb02a7b6',
+    ),
+    'jean85/pretty-package-versions' => 
+    array (
+      'pretty_version' => '1.6.0',
+      'version' => '1.6.0.0',
+      'aliases' => 
+      array (
+      ),
+      'reference' => '1e0104b46f045868f11942aea058cd7186d6c303',
+    ),
+    'mongodb/mongodb' => 
+    array (
+      'pretty_version' => '1.8.0',
+      'version' => '1.8.0.0',
+      'aliases' => 
+      array (
+      ),
+      'reference' => '953dbc19443aa9314c44b7217a16873347e6840d',
+    ),
+    'ocramius/package-versions' => 
+    array (
+      'replaced' => 
+      array (
+        0 => '1.11.99',
+      ),
+    ),
+    'symfony/polyfill-php80' => 
+    array (
+      'pretty_version' => 'v1.22.1',
+      'version' => '1.22.1.0',
+      'aliases' => 
+      array (
+      ),
+      'reference' => 'dc3063ba22c2a1fd2f45ed856374d79114998f91',
+    ),
+  ),
+);
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/composer/package-versions-deprecated/CHANGELOG.md b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/composer/package-versions-deprecated/CHANGELOG.md
new file mode 100644
index 0000000000000000000000000000000000000000..a838c56ad346fd2cc433f0a73ab178975f74d796
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/composer/package-versions-deprecated/CHANGELOG.md	
@@ -0,0 +1,120 @@
+# CHANGELOG
+
+## 1.1.3 - 2017-09-06
+
+This release fixes a bug that caused PackageVersions to prevent
+the `composer remove` and `composer update` commands to fail when
+this package is removed.
+
+In addition to that, mutation testing has been added to the suite,
+ensuring that the package is accurately and extensively tested.
+
+Total issues resolved: **3**
+
+- [40: Mutation testing, PHP 7.1 testing](https://github.com/Ocramius/PackageVersions/pull/40) thanks to @Ocramius
+- [41: Removing this package on install results in file access error](https://github.com/Ocramius/PackageVersions/issues/41) thanks to @Xerkus
+- [46: #41 Avoid issues when the package is scheduled for removal](https://github.com/Ocramius/PackageVersions/pull/46) thanks to @Jean85
+
+## 1.1.2 - 2016-12-30
+
+This release fixes a bug that caused PackageVersions to be enabled
+even when it was part of a globally installed package.
+
+Total issues resolved: **3**
+
+- [35: remove all temp directories](https://github.com/Ocramius/PackageVersions/pull/35)
+- [38: Interferes with other projects when installed globally](https://github.com/Ocramius/PackageVersions/issues/38)
+- [39: Ignore the global plugin when updating local projects](https://github.com/Ocramius/PackageVersions/pull/39)
+
+## 1.1.1 - 2016-07-25
+
+This release removes the [`"files"`](https://getcomposer.org/doc/04-schema.md#files) directive from
+[`composer.json`](https://github.com/Ocramius/PackageVersions/commit/86f2636f7c5e7b56fa035fa3826d5fcf80b6dc72),
+as it is no longer needed for `composer install --classmap-authoritative`.
+Also, that directive was causing issues with HHVM installations, since
+PackageVersions is not compatible with it.
+
+Total issues resolved: **1**
+
+- [34: Fatal error during travis build after update to 1.1.0](https://github.com/Ocramius/PackageVersions/issues/34)
+
+## 1.1.0 - 2016-07-22
+
+This release introduces support for running `composer install --classmap-authoritative`
+and `composer install --no-scripts`. Please note that performance
+while using these modes may be degraded, but the package will
+still work.
+
+Additionally, the package was tuned to prevent the plugin from
+running twice at installation.
+
+Total issues resolved: **10**
+
+- [18: Fails when using composer install --no-scripts](https://github.com/Ocramius/PackageVersions/issues/18)
+- [20: CS (spacing)](https://github.com/Ocramius/PackageVersions/pull/20)
+- [22: Document the way the require-dev section is treated](https://github.com/Ocramius/PackageVersions/issues/22)
+- [23: Underline that composer.lock is used as source of information](https://github.com/Ocramius/PackageVersions/pull/23)
+- [27: Fix incompatibility with --classmap-authoritative](https://github.com/Ocramius/PackageVersions/pull/27)
+- [29: mention optimize-autoloader composer.json config option in README](https://github.com/Ocramius/PackageVersions/pull/29)
+- [30: The version class is generated twice during composer update](https://github.com/Ocramius/PackageVersions/issues/30)
+- [31: Remove double registration of the event listeners](https://github.com/Ocramius/PackageVersions/pull/31)
+- [32: Update the usage of mock APIs to use the new API](https://github.com/Ocramius/PackageVersions/pull/32)
+- [33: Fix for #18 -  support running with --no-scripts flag](https://github.com/Ocramius/PackageVersions/pull/33)
+
+## 1.0.4 - 2016-04-23
+
+This release includes a fix/workaround for composer/composer#5237,
+which causes `ocramius/package-versions` to sometimes generate a
+`Versions` class with malformed name (something like
+`Versions_composer_tmp0`) when running `composer require <package-name>`.
+
+Total issues resolved: **2**
+
+- [16: Workaround for composer/composer#5237 - class parsing](https://github.com/Ocramius/PackageVersions/pull/16)
+- [17: Weird Class name being generated](https://github.com/Ocramius/PackageVersions/issues/17)
+
+## 1.0.3 - 2016-02-26
+
+This release fixes an issue related to concurrent autoloader
+re-generation caused by multiple composer plugins being installed.
+The issue was solved by removing autoloader re-generation from this
+package, but it may still affect other packages.
+
+It is now recommended that you run `composer dump-autoload --optimize`
+after installation when using this particular package.
+Please note that `composer (install|update) -o` is not sufficient
+to avoid autoload overhead when using this particular package.
+
+Total issues resolved: **1**
+
+- [15: Remove autoload re-dump optimization](https://github.com/Ocramius/PackageVersions/pull/15)
+
+## 1.0.2 - 2016-02-24
+
+This release fixes issues related to installing the component without
+any dev dependencies or with packages that don't have a source or dist
+reference, which is usual with packages defined directly in the
+`composer.json`.
+
+Total issues resolved: **3**
+
+- [11: fix composer install --no-dev PHP7](https://github.com/Ocramius/PackageVersions/pull/11)
+- [12: Packages don't always have a source/reference](https://github.com/Ocramius/PackageVersions/issues/12)
+- [13: Fix #12 - support dist and missing package version references](https://github.com/Ocramius/PackageVersions/pull/13)
+
+## 1.0.1 - 2016-02-01
+
+This release fixes an issue related with composer updates to
+already installed versions.
+Using `composer require` within a package that already used
+`ocramius/package-versions` caused the installation to be unable
+to write the `PackageVersions\Versions` class to a file.
+
+Total issues resolved: **6**
+
+- [2: remove unused use statement](https://github.com/Ocramius/PackageVersions/pull/2)
+- [3: Remove useless files from dist package](https://github.com/Ocramius/PackageVersions/pull/3)
+- [5: failed to open stream: phar error: write operations disabled by the php.ini setting phar.readonly](https://github.com/Ocramius/PackageVersions/issues/5)
+- [6: Fix/#5 use composer vendor dir](https://github.com/Ocramius/PackageVersions/pull/6)
+- [7: Hotfix - #5 generate package versions also when in phar context](https://github.com/Ocramius/PackageVersions/pull/7)
+- [8: Versions class should be ignored by VCS, as it is an install-time artifact](https://github.com/Ocramius/PackageVersions/pull/8)
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/composer/package-versions-deprecated/CONTRIBUTING.md b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/composer/package-versions-deprecated/CONTRIBUTING.md
new file mode 100644
index 0000000000000000000000000000000000000000..71806175833b052ebb4bb2ee35bb1e3ae74b0877
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/composer/package-versions-deprecated/CONTRIBUTING.md	
@@ -0,0 +1,39 @@
+---
+title: Contributing
+---
+
+# Contributing
+
+ * Coding standard for the project is [PSR-2](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md)
+ * The project will follow strict [object calisthenics](http://www.slideshare.net/guilhermeblanco/object-calisthenics-applied-to-php)
+ * Any contribution must provide tests for additional introduced conditions
+ * Any un-confirmed issue needs a failing test case before being accepted
+ * Pull requests must be sent from a new hotfix/feature branch, not from `master`.
+
+## Installation
+
+To install the project and run the tests, you need to clone it first:
+
+```sh
+$ git clone git://github.com/Ocramius/PackageVersions.git
+```
+
+You will then need to run a composer installation:
+
+```sh
+$ cd PackageVersions
+$ curl -s https://getcomposer.org/installer | php
+$ php composer.phar update
+```
+
+## Testing
+
+The PHPUnit version to be used is the one installed as a dev- dependency via composer:
+
+```sh
+$ ./vendor/bin/phpunit
+```
+
+Accepted coverage for new contributions is 80%. Any contribution not satisfying this requirement 
+won't be merged.
+
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/composer/package-versions-deprecated/LICENSE b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/composer/package-versions-deprecated/LICENSE
new file mode 100644
index 0000000000000000000000000000000000000000..a90b0792cc78b1eb3746f93f9266a5842b7b8f3d
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/composer/package-versions-deprecated/LICENSE	
@@ -0,0 +1,19 @@
+Copyright (c) 2016 Marco Pivetta
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/composer/package-versions-deprecated/README.md b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/composer/package-versions-deprecated/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..c5f5bba103f1d0e6423fe7629bbfc0040a5d8ea4
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/composer/package-versions-deprecated/README.md	
@@ -0,0 +1,5 @@
+# Package Versions
+
+**`composer/package-versions-deprecated` is a fully-compatible fork of [`ocramius/package-versions`](https://github.com/Ocramius/PackageVersions)** which provides compatibility with Composer 1 and 2 on PHP 7+. It replaces ocramius/package-versions so if you have a dependency requiring it and you want to use Composer v2 but can not upgrade to PHP 7.4 just yet, you can require this package instead.
+
+If you have a direct dependency on ocramius/package-versions, we recommend instead that once you migrated to Composer 2 you also migrate to use the `Composer\Versions` class which offers the functionality present here out of the box.
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/composer/package-versions-deprecated/SECURITY.md b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/composer/package-versions-deprecated/SECURITY.md
new file mode 100644
index 0000000000000000000000000000000000000000..da9c516dd744b6c88dd8c91f58f7bcf8f7e8341b
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/composer/package-versions-deprecated/SECURITY.md	
@@ -0,0 +1,5 @@
+## Security contact information
+
+To report a security vulnerability, please use the
+[Tidelift security contact](https://tidelift.com/security).
+Tidelift will coordinate the fix and disclosure.
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/composer/package-versions-deprecated/composer.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/composer/package-versions-deprecated/composer.json
new file mode 100644
index 0000000000000000000000000000000000000000..d5a40daacf364f07910fd903f1fa0edc98be6992
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/composer/package-versions-deprecated/composer.json	
@@ -0,0 +1,48 @@
+{
+    "name": "composer/package-versions-deprecated",
+    "description": "Composer plugin that provides efficient querying for installed package versions (no runtime IO)",
+    "type": "composer-plugin",
+    "license": "MIT",
+    "authors": [
+        {
+            "name": "Marco Pivetta",
+            "email": "ocramius@gmail.com"
+        },
+        {
+            "name": "Jordi Boggiano",
+            "email": "j.boggiano@seld.be"
+        }
+    ],
+    "require": {
+        "php":                 "^7 || ^8",
+        "composer-plugin-api": "^1.1.0 || ^2.0"
+    },
+    "replace": {
+        "ocramius/package-versions": "1.11.99"
+    },
+    "require-dev": {
+        "phpunit/phpunit":          "^6.5 || ^7",
+        "composer/composer":        "^1.9.3 || ^2.0@dev",
+        "ext-zip":                  "^1.13"
+    },
+    "autoload": {
+        "psr-4": {
+            "PackageVersions\\": "src/PackageVersions"
+        }
+    },
+    "autoload-dev": {
+        "psr-4": {
+            "PackageVersionsTest\\": "test/PackageVersionsTest"
+        }
+    },
+    "extra": {
+        "class": "PackageVersions\\Installer",
+        "branch-alias": {
+            "dev-master": "1.x-dev"
+        }
+    },
+    "scripts": {
+        "post-update-cmd":  "PackageVersions\\Installer::dumpVersionsClass",
+        "post-install-cmd": "PackageVersions\\Installer::dumpVersionsClass"
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/composer/package-versions-deprecated/composer.lock b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/composer/package-versions-deprecated/composer.lock
new file mode 100644
index 0000000000000000000000000000000000000000..b711f6b13841bfe8b87ad0ce4103e2da44ed5e1b
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/composer/package-versions-deprecated/composer.lock	
@@ -0,0 +1,2603 @@
+{
+    "_readme": [
+        "This file locks the dependencies of your project to a known state",
+        "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
+        "This file is @generated automatically"
+    ],
+    "content-hash": "6bfe0a7d7a51c4bdf14a2d7ea1d22d11",
+    "packages": [],
+    "packages-dev": [
+        {
+            "name": "composer/ca-bundle",
+            "version": "1.2.7",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/composer/ca-bundle.git",
+                "reference": "95c63ab2117a72f48f5a55da9740a3273d45b7fd"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/composer/ca-bundle/zipball/95c63ab2117a72f48f5a55da9740a3273d45b7fd",
+                "reference": "95c63ab2117a72f48f5a55da9740a3273d45b7fd",
+                "shasum": ""
+            },
+            "require": {
+                "ext-openssl": "*",
+                "ext-pcre": "*",
+                "php": "^5.3.2 || ^7.0 || ^8.0"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^4.8.35 || ^5.7 || 6.5 - 8",
+                "psr/log": "^1.0",
+                "symfony/process": "^2.5 || ^3.0 || ^4.0 || ^5.0"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Composer\\CaBundle\\": "src"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Jordi Boggiano",
+                    "email": "j.boggiano@seld.be",
+                    "homepage": "http://seld.be"
+                }
+            ],
+            "description": "Lets you find a path to the system CA bundle, and includes a fallback to the Mozilla CA bundle.",
+            "keywords": [
+                "cabundle",
+                "cacert",
+                "certificate",
+                "ssl",
+                "tls"
+            ],
+            "funding": [
+                {
+                    "url": "https://packagist.com",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/composer/composer",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2020-04-08T08:27:21+00:00"
+        },
+        {
+            "name": "composer/composer",
+            "version": "dev-master",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/composer/composer.git",
+                "reference": "a8c105da344dd84ebd5d11be7943a45b09dc076f"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/composer/composer/zipball/a8c105da344dd84ebd5d11be7943a45b09dc076f",
+                "reference": "a8c105da344dd84ebd5d11be7943a45b09dc076f",
+                "shasum": ""
+            },
+            "require": {
+                "composer/ca-bundle": "^1.0",
+                "composer/semver": "^1.0",
+                "composer/spdx-licenses": "^1.2",
+                "composer/xdebug-handler": "^1.1",
+                "justinrainbow/json-schema": "^3.0 || ^4.0 || ^5.0",
+                "php": "^5.3.2 || ^7.0",
+                "psr/log": "^1.0",
+                "seld/jsonlint": "^1.4",
+                "seld/phar-utils": "^1.0",
+                "symfony/console": "^2.7 || ^3.0 || ^4.0 || ^5.0",
+                "symfony/filesystem": "^2.7 || ^3.0 || ^4.0 || ^5.0",
+                "symfony/finder": "^2.7 || ^3.0 || ^4.0 || ^5.0",
+                "symfony/process": "^2.7 || ^3.0 || ^4.0 || ^5.0"
+            },
+            "conflict": {
+                "symfony/console": "2.8.38"
+            },
+            "require-dev": {
+                "phpspec/prophecy": "^1.10",
+                "symfony/phpunit-bridge": "^3.4"
+            },
+            "suggest": {
+                "ext-openssl": "Enabling the openssl extension allows you to access https URLs for repositories and packages",
+                "ext-zip": "Enabling the zip extension allows you to unzip archives",
+                "ext-zlib": "Allow gzip compression of HTTP requests"
+            },
+            "bin": [
+                "bin/composer"
+            ],
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.10-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Composer\\": "src/Composer"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Nils Adermann",
+                    "email": "naderman@naderman.de",
+                    "homepage": "http://www.naderman.de"
+                },
+                {
+                    "name": "Jordi Boggiano",
+                    "email": "j.boggiano@seld.be",
+                    "homepage": "http://seld.be"
+                }
+            ],
+            "description": "Composer helps you declare, manage and install dependencies of PHP projects. It ensures you have the right stack everywhere.",
+            "homepage": "https://getcomposer.org/",
+            "keywords": [
+                "autoload",
+                "dependency",
+                "package"
+            ],
+            "support": {
+                "irc": "irc://irc.freenode.org/composer",
+                "issues": "https://github.com/composer/composer/issues",
+                "source": "https://github.com/composer/composer/tree/master"
+            },
+            "funding": [
+                {
+                    "url": "https://packagist.com",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/composer/composer",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2020-03-29T14:59:26+00:00"
+        },
+        {
+            "name": "composer/semver",
+            "version": "1.5.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/composer/semver.git",
+                "reference": "c6bea70230ef4dd483e6bbcab6005f682ed3a8de"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/composer/semver/zipball/c6bea70230ef4dd483e6bbcab6005f682ed3a8de",
+                "reference": "c6bea70230ef4dd483e6bbcab6005f682ed3a8de",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^5.3.2 || ^7.0"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^4.5 || ^5.0.5"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Composer\\Semver\\": "src"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Nils Adermann",
+                    "email": "naderman@naderman.de",
+                    "homepage": "http://www.naderman.de"
+                },
+                {
+                    "name": "Jordi Boggiano",
+                    "email": "j.boggiano@seld.be",
+                    "homepage": "http://seld.be"
+                },
+                {
+                    "name": "Rob Bast",
+                    "email": "rob.bast@gmail.com",
+                    "homepage": "http://robbast.nl"
+                }
+            ],
+            "description": "Semver library that offers utilities, version constraint parsing and validation.",
+            "keywords": [
+                "semantic",
+                "semver",
+                "validation",
+                "versioning"
+            ],
+            "support": {
+                "irc": "irc://irc.freenode.org/composer",
+                "issues": "https://github.com/composer/semver/issues",
+                "source": "https://github.com/composer/semver/tree/1.5.1"
+            },
+            "time": "2020-01-13T12:06:48+00:00"
+        },
+        {
+            "name": "composer/spdx-licenses",
+            "version": "1.5.3",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/composer/spdx-licenses.git",
+                "reference": "0c3e51e1880ca149682332770e25977c70cf9dae"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/composer/spdx-licenses/zipball/0c3e51e1880ca149682332770e25977c70cf9dae",
+                "reference": "0c3e51e1880ca149682332770e25977c70cf9dae",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^5.3.2 || ^7.0 || ^8.0"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^4.8.35 || ^5.7 || 6.5 - 7"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Composer\\Spdx\\": "src"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Nils Adermann",
+                    "email": "naderman@naderman.de",
+                    "homepage": "http://www.naderman.de"
+                },
+                {
+                    "name": "Jordi Boggiano",
+                    "email": "j.boggiano@seld.be",
+                    "homepage": "http://seld.be"
+                },
+                {
+                    "name": "Rob Bast",
+                    "email": "rob.bast@gmail.com",
+                    "homepage": "http://robbast.nl"
+                }
+            ],
+            "description": "SPDX licenses list and validation library.",
+            "keywords": [
+                "license",
+                "spdx",
+                "validator"
+            ],
+            "time": "2020-02-14T07:44:31+00:00"
+        },
+        {
+            "name": "composer/xdebug-handler",
+            "version": "1.4.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/composer/xdebug-handler.git",
+                "reference": "1ab9842d69e64fb3a01be6b656501032d1b78cb7"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/1ab9842d69e64fb3a01be6b656501032d1b78cb7",
+                "reference": "1ab9842d69e64fb3a01be6b656501032d1b78cb7",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^5.3.2 || ^7.0 || ^8.0",
+                "psr/log": "^1.0"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^4.8.35 || ^5.7 || 6.5 - 8"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "Composer\\XdebugHandler\\": "src"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "John Stevenson",
+                    "email": "john-stevenson@blueyonder.co.uk"
+                }
+            ],
+            "description": "Restarts a process without Xdebug.",
+            "keywords": [
+                "Xdebug",
+                "performance"
+            ],
+            "support": {
+                "irc": "irc://irc.freenode.org/composer",
+                "issues": "https://github.com/composer/xdebug-handler/issues",
+                "source": "https://github.com/composer/xdebug-handler/tree/master"
+            },
+            "funding": [
+                {
+                    "url": "https://packagist.com",
+                    "type": "custom"
+                }
+            ],
+            "time": "2020-03-01T12:26:26+00:00"
+        },
+        {
+            "name": "doctrine/instantiator",
+            "version": "1.3.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/doctrine/instantiator.git",
+                "reference": "ae466f726242e637cebdd526a7d991b9433bacf1"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/doctrine/instantiator/zipball/ae466f726242e637cebdd526a7d991b9433bacf1",
+                "reference": "ae466f726242e637cebdd526a7d991b9433bacf1",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^7.1"
+            },
+            "require-dev": {
+                "doctrine/coding-standard": "^6.0",
+                "ext-pdo": "*",
+                "ext-phar": "*",
+                "phpbench/phpbench": "^0.13",
+                "phpstan/phpstan-phpunit": "^0.11",
+                "phpstan/phpstan-shim": "^0.11",
+                "phpunit/phpunit": "^7.0"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.2.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Marco Pivetta",
+                    "email": "ocramius@gmail.com",
+                    "homepage": "http://ocramius.github.com/"
+                }
+            ],
+            "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors",
+            "homepage": "https://www.doctrine-project.org/projects/instantiator.html",
+            "keywords": [
+                "constructor",
+                "instantiate"
+            ],
+            "support": {
+                "issues": "https://github.com/doctrine/instantiator/issues",
+                "source": "https://github.com/doctrine/instantiator/tree/master"
+            },
+            "time": "2019-10-21T16:45:58+00:00"
+        },
+        {
+            "name": "justinrainbow/json-schema",
+            "version": "5.2.9",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/justinrainbow/json-schema.git",
+                "reference": "44c6787311242a979fa15c704327c20e7221a0e4"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/justinrainbow/json-schema/zipball/44c6787311242a979fa15c704327c20e7221a0e4",
+                "reference": "44c6787311242a979fa15c704327c20e7221a0e4",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.3.3"
+            },
+            "require-dev": {
+                "friendsofphp/php-cs-fixer": "~2.2.20||~2.15.1",
+                "json-schema/json-schema-test-suite": "1.2.0",
+                "phpunit/phpunit": "^4.8.35"
+            },
+            "bin": [
+                "bin/validate-json"
+            ],
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "5.0.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "JsonSchema\\": "src/JsonSchema/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Bruno Prieto Reis",
+                    "email": "bruno.p.reis@gmail.com"
+                },
+                {
+                    "name": "Justin Rainbow",
+                    "email": "justin.rainbow@gmail.com"
+                },
+                {
+                    "name": "Igor Wiedler",
+                    "email": "igor@wiedler.ch"
+                },
+                {
+                    "name": "Robert Schönthal",
+                    "email": "seroscho@googlemail.com"
+                }
+            ],
+            "description": "A library to validate a json schema.",
+            "homepage": "https://github.com/justinrainbow/json-schema",
+            "keywords": [
+                "json",
+                "schema"
+            ],
+            "support": {
+                "issues": "https://github.com/justinrainbow/json-schema/issues",
+                "source": "https://github.com/justinrainbow/json-schema/tree/5.2.9"
+            },
+            "time": "2019-09-25T14:49:45+00:00"
+        },
+        {
+            "name": "myclabs/deep-copy",
+            "version": "1.9.5",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/myclabs/DeepCopy.git",
+                "reference": "b2c28789e80a97badd14145fda39b545d83ca3ef"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/b2c28789e80a97badd14145fda39b545d83ca3ef",
+                "reference": "b2c28789e80a97badd14145fda39b545d83ca3ef",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^7.1"
+            },
+            "replace": {
+                "myclabs/deep-copy": "self.version"
+            },
+            "require-dev": {
+                "doctrine/collections": "^1.0",
+                "doctrine/common": "^2.6",
+                "phpunit/phpunit": "^7.1"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "DeepCopy\\": "src/DeepCopy/"
+                },
+                "files": [
+                    "src/DeepCopy/deep_copy.php"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "description": "Create deep copies (clones) of your objects",
+            "keywords": [
+                "clone",
+                "copy",
+                "duplicate",
+                "object",
+                "object graph"
+            ],
+            "support": {
+                "issues": "https://github.com/myclabs/DeepCopy/issues",
+                "source": "https://github.com/myclabs/DeepCopy/tree/1.9.5"
+            },
+            "time": "2020-01-17T21:11:47+00:00"
+        },
+        {
+            "name": "phar-io/manifest",
+            "version": "1.0.3",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/phar-io/manifest.git",
+                "reference": "7761fcacf03b4d4f16e7ccb606d4879ca431fcf4"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/phar-io/manifest/zipball/7761fcacf03b4d4f16e7ccb606d4879ca431fcf4",
+                "reference": "7761fcacf03b4d4f16e7ccb606d4879ca431fcf4",
+                "shasum": ""
+            },
+            "require": {
+                "ext-dom": "*",
+                "ext-phar": "*",
+                "phar-io/version": "^2.0",
+                "php": "^5.6 || ^7.0"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.0.x-dev"
+                }
+            },
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Arne Blankerts",
+                    "email": "arne@blankerts.de",
+                    "role": "Developer"
+                },
+                {
+                    "name": "Sebastian Heuer",
+                    "email": "sebastian@phpeople.de",
+                    "role": "Developer"
+                },
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de",
+                    "role": "Developer"
+                }
+            ],
+            "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)",
+            "time": "2018-07-08T19:23:20+00:00"
+        },
+        {
+            "name": "phar-io/version",
+            "version": "2.0.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/phar-io/version.git",
+                "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/phar-io/version/zipball/45a2ec53a73c70ce41d55cedef9063630abaf1b6",
+                "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^5.6 || ^7.0"
+            },
+            "type": "library",
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Arne Blankerts",
+                    "email": "arne@blankerts.de",
+                    "role": "Developer"
+                },
+                {
+                    "name": "Sebastian Heuer",
+                    "email": "sebastian@phpeople.de",
+                    "role": "Developer"
+                },
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de",
+                    "role": "Developer"
+                }
+            ],
+            "description": "Library for handling version information and constraints",
+            "time": "2018-07-08T19:19:57+00:00"
+        },
+        {
+            "name": "phpdocumentor/reflection-common",
+            "version": "2.0.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/phpDocumentor/ReflectionCommon.git",
+                "reference": "63a995caa1ca9e5590304cd845c15ad6d482a62a"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/63a995caa1ca9e5590304cd845c15ad6d482a62a",
+                "reference": "63a995caa1ca9e5590304cd845c15ad6d482a62a",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.1"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "~6"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "2.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "phpDocumentor\\Reflection\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "description": "Common reflection classes used by phpdocumentor to reflect the code structure",
+            "homepage": "http://www.phpdoc.org",
+            "time": "2018-08-07T13:53:10+00:00"
+        },
+        {
+            "name": "phpdocumentor/reflection-docblock",
+            "version": "5.1.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
+                "reference": "cd72d394ca794d3466a3b2fc09d5a6c1dc86b47e"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/cd72d394ca794d3466a3b2fc09d5a6c1dc86b47e",
+                "reference": "cd72d394ca794d3466a3b2fc09d5a6c1dc86b47e",
+                "shasum": ""
+            },
+            "require": {
+                "ext-filter": "^7.1",
+                "php": "^7.2",
+                "phpdocumentor/reflection-common": "^2.0",
+                "phpdocumentor/type-resolver": "^1.0",
+                "webmozart/assert": "^1"
+            },
+            "require-dev": {
+                "doctrine/instantiator": "^1",
+                "mockery/mockery": "^1"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "5.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "phpDocumentor\\Reflection\\": "src"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Mike van Riel",
+                    "email": "me@mikevanriel.com"
+                },
+                {
+                    "name": "Jaap van Otterdijk",
+                    "email": "account@ijaap.nl"
+                }
+            ],
+            "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.",
+            "time": "2020-02-22T12:28:44+00:00"
+        },
+        {
+            "name": "phpdocumentor/type-resolver",
+            "version": "1.1.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/phpDocumentor/TypeResolver.git",
+                "reference": "7462d5f123dfc080dfdf26897032a6513644fc95"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/7462d5f123dfc080dfdf26897032a6513644fc95",
+                "reference": "7462d5f123dfc080dfdf26897032a6513644fc95",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^7.2",
+                "phpdocumentor/reflection-common": "^2.0"
+            },
+            "require-dev": {
+                "ext-tokenizer": "^7.2",
+                "mockery/mockery": "~1"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "phpDocumentor\\Reflection\\": "src"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Mike van Riel",
+                    "email": "me@mikevanriel.com"
+                }
+            ],
+            "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names",
+            "support": {
+                "issues": "https://github.com/phpDocumentor/TypeResolver/issues",
+                "source": "https://github.com/phpDocumentor/TypeResolver/tree/master"
+            },
+            "time": "2020-02-18T18:59:58+00:00"
+        },
+        {
+            "name": "phpspec/prophecy",
+            "version": "v1.10.3",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/phpspec/prophecy.git",
+                "reference": "451c3cd1418cf640de218914901e51b064abb093"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/phpspec/prophecy/zipball/451c3cd1418cf640de218914901e51b064abb093",
+                "reference": "451c3cd1418cf640de218914901e51b064abb093",
+                "shasum": ""
+            },
+            "require": {
+                "doctrine/instantiator": "^1.0.2",
+                "php": "^5.3|^7.0",
+                "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0|^5.0",
+                "sebastian/comparator": "^1.2.3|^2.0|^3.0|^4.0",
+                "sebastian/recursion-context": "^1.0|^2.0|^3.0|^4.0"
+            },
+            "require-dev": {
+                "phpspec/phpspec": "^2.5 || ^3.2",
+                "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5 || ^7.1"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.10.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Prophecy\\": "src/Prophecy"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Konstantin Kudryashov",
+                    "email": "ever.zet@gmail.com",
+                    "homepage": "http://everzet.com"
+                },
+                {
+                    "name": "Marcello Duarte",
+                    "email": "marcello.duarte@gmail.com"
+                }
+            ],
+            "description": "Highly opinionated mocking framework for PHP 5.3+",
+            "homepage": "https://github.com/phpspec/prophecy",
+            "keywords": [
+                "Double",
+                "Dummy",
+                "fake",
+                "mock",
+                "spy",
+                "stub"
+            ],
+            "support": {
+                "issues": "https://github.com/phpspec/prophecy/issues",
+                "source": "https://github.com/phpspec/prophecy/tree/v1.10.3"
+            },
+            "time": "2020-03-05T15:02:03+00:00"
+        },
+        {
+            "name": "phpunit/php-code-coverage",
+            "version": "6.1.4",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
+                "reference": "807e6013b00af69b6c5d9ceb4282d0393dbb9d8d"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/807e6013b00af69b6c5d9ceb4282d0393dbb9d8d",
+                "reference": "807e6013b00af69b6c5d9ceb4282d0393dbb9d8d",
+                "shasum": ""
+            },
+            "require": {
+                "ext-dom": "*",
+                "ext-xmlwriter": "*",
+                "php": "^7.1",
+                "phpunit/php-file-iterator": "^2.0",
+                "phpunit/php-text-template": "^1.2.1",
+                "phpunit/php-token-stream": "^3.0",
+                "sebastian/code-unit-reverse-lookup": "^1.0.1",
+                "sebastian/environment": "^3.1 || ^4.0",
+                "sebastian/version": "^2.0.1",
+                "theseer/tokenizer": "^1.1"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^7.0"
+            },
+            "suggest": {
+                "ext-xdebug": "^2.6.0"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "6.1-dev"
+                }
+            },
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de",
+                    "role": "lead"
+                }
+            ],
+            "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.",
+            "homepage": "https://github.com/sebastianbergmann/php-code-coverage",
+            "keywords": [
+                "coverage",
+                "testing",
+                "xunit"
+            ],
+            "time": "2018-10-31T16:06:48+00:00"
+        },
+        {
+            "name": "phpunit/php-file-iterator",
+            "version": "2.0.2",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/php-file-iterator.git",
+                "reference": "050bedf145a257b1ff02746c31894800e5122946"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/050bedf145a257b1ff02746c31894800e5122946",
+                "reference": "050bedf145a257b1ff02746c31894800e5122946",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^7.1"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^7.1"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "2.0.x-dev"
+                }
+            },
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de",
+                    "role": "lead"
+                }
+            ],
+            "description": "FilterIterator implementation that filters files based on a list of suffixes.",
+            "homepage": "https://github.com/sebastianbergmann/php-file-iterator/",
+            "keywords": [
+                "filesystem",
+                "iterator"
+            ],
+            "time": "2018-09-13T20:33:42+00:00"
+        },
+        {
+            "name": "phpunit/php-text-template",
+            "version": "1.2.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/php-text-template.git",
+                "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686",
+                "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.3.3"
+            },
+            "type": "library",
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de",
+                    "role": "lead"
+                }
+            ],
+            "description": "Simple template engine.",
+            "homepage": "https://github.com/sebastianbergmann/php-text-template/",
+            "keywords": [
+                "template"
+            ],
+            "time": "2015-06-21T13:50:34+00:00"
+        },
+        {
+            "name": "phpunit/php-timer",
+            "version": "2.1.2",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/php-timer.git",
+                "reference": "1038454804406b0b5f5f520358e78c1c2f71501e"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/1038454804406b0b5f5f520358e78c1c2f71501e",
+                "reference": "1038454804406b0b5f5f520358e78c1c2f71501e",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^7.1"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^7.0"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "2.1-dev"
+                }
+            },
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de",
+                    "role": "lead"
+                }
+            ],
+            "description": "Utility class for timing",
+            "homepage": "https://github.com/sebastianbergmann/php-timer/",
+            "keywords": [
+                "timer"
+            ],
+            "time": "2019-06-07T04:22:29+00:00"
+        },
+        {
+            "name": "phpunit/php-token-stream",
+            "version": "3.1.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/php-token-stream.git",
+                "reference": "995192df77f63a59e47f025390d2d1fdf8f425ff"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/995192df77f63a59e47f025390d2d1fdf8f425ff",
+                "reference": "995192df77f63a59e47f025390d2d1fdf8f425ff",
+                "shasum": ""
+            },
+            "require": {
+                "ext-tokenizer": "*",
+                "php": "^7.1"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^7.0"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "3.1-dev"
+                }
+            },
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de"
+                }
+            ],
+            "description": "Wrapper around PHP's tokenizer extension.",
+            "homepage": "https://github.com/sebastianbergmann/php-token-stream/",
+            "keywords": [
+                "tokenizer"
+            ],
+            "time": "2019-09-17T06:23:10+00:00"
+        },
+        {
+            "name": "phpunit/phpunit",
+            "version": "7.5.20",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/phpunit.git",
+                "reference": "9467db479d1b0487c99733bb1e7944d32deded2c"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/9467db479d1b0487c99733bb1e7944d32deded2c",
+                "reference": "9467db479d1b0487c99733bb1e7944d32deded2c",
+                "shasum": ""
+            },
+            "require": {
+                "doctrine/instantiator": "^1.1",
+                "ext-dom": "*",
+                "ext-json": "*",
+                "ext-libxml": "*",
+                "ext-mbstring": "*",
+                "ext-xml": "*",
+                "myclabs/deep-copy": "^1.7",
+                "phar-io/manifest": "^1.0.2",
+                "phar-io/version": "^2.0",
+                "php": "^7.1",
+                "phpspec/prophecy": "^1.7",
+                "phpunit/php-code-coverage": "^6.0.7",
+                "phpunit/php-file-iterator": "^2.0.1",
+                "phpunit/php-text-template": "^1.2.1",
+                "phpunit/php-timer": "^2.1",
+                "sebastian/comparator": "^3.0",
+                "sebastian/diff": "^3.0",
+                "sebastian/environment": "^4.0",
+                "sebastian/exporter": "^3.1",
+                "sebastian/global-state": "^2.0",
+                "sebastian/object-enumerator": "^3.0.3",
+                "sebastian/resource-operations": "^2.0",
+                "sebastian/version": "^2.0.1"
+            },
+            "conflict": {
+                "phpunit/phpunit-mock-objects": "*"
+            },
+            "require-dev": {
+                "ext-pdo": "*"
+            },
+            "suggest": {
+                "ext-soap": "*",
+                "ext-xdebug": "*",
+                "phpunit/php-invoker": "^2.0"
+            },
+            "bin": [
+                "phpunit"
+            ],
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "7.5-dev"
+                }
+            },
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de",
+                    "role": "lead"
+                }
+            ],
+            "description": "The PHP Unit Testing framework.",
+            "homepage": "https://phpunit.de/",
+            "keywords": [
+                "phpunit",
+                "testing",
+                "xunit"
+            ],
+            "time": "2020-01-08T08:45:45+00:00"
+        },
+        {
+            "name": "psr/container",
+            "version": "1.0.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/php-fig/container.git",
+                "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f",
+                "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.3.0"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.0.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Psr\\Container\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "PHP-FIG",
+                    "homepage": "http://www.php-fig.org/"
+                }
+            ],
+            "description": "Common Container Interface (PHP FIG PSR-11)",
+            "homepage": "https://github.com/php-fig/container",
+            "keywords": [
+                "PSR-11",
+                "container",
+                "container-interface",
+                "container-interop",
+                "psr"
+            ],
+            "time": "2017-02-14T16:28:37+00:00"
+        },
+        {
+            "name": "psr/log",
+            "version": "1.1.3",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/php-fig/log.git",
+                "reference": "0f73288fd15629204f9d42b7055f72dacbe811fc"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/php-fig/log/zipball/0f73288fd15629204f9d42b7055f72dacbe811fc",
+                "reference": "0f73288fd15629204f9d42b7055f72dacbe811fc",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.3.0"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.1.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Psr\\Log\\": "Psr/Log/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "PHP-FIG",
+                    "homepage": "http://www.php-fig.org/"
+                }
+            ],
+            "description": "Common interface for logging libraries",
+            "homepage": "https://github.com/php-fig/log",
+            "keywords": [
+                "log",
+                "psr",
+                "psr-3"
+            ],
+            "time": "2020-03-23T09:12:05+00:00"
+        },
+        {
+            "name": "sebastian/code-unit-reverse-lookup",
+            "version": "1.0.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git",
+                "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/4419fcdb5eabb9caa61a27c7a1db532a6b55dd18",
+                "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^5.6 || ^7.0"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^5.7 || ^6.0"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.0.x-dev"
+                }
+            },
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de"
+                }
+            ],
+            "description": "Looks up which function or method a line of code belongs to",
+            "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/",
+            "time": "2017-03-04T06:30:41+00:00"
+        },
+        {
+            "name": "sebastian/comparator",
+            "version": "3.0.2",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/comparator.git",
+                "reference": "5de4fc177adf9bce8df98d8d141a7559d7ccf6da"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/5de4fc177adf9bce8df98d8d141a7559d7ccf6da",
+                "reference": "5de4fc177adf9bce8df98d8d141a7559d7ccf6da",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^7.1",
+                "sebastian/diff": "^3.0",
+                "sebastian/exporter": "^3.1"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^7.1"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "3.0-dev"
+                }
+            },
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Jeff Welch",
+                    "email": "whatthejeff@gmail.com"
+                },
+                {
+                    "name": "Volker Dusch",
+                    "email": "github@wallbash.com"
+                },
+                {
+                    "name": "Bernhard Schussek",
+                    "email": "bschussek@2bepublished.at"
+                },
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de"
+                }
+            ],
+            "description": "Provides the functionality to compare PHP values for equality",
+            "homepage": "https://github.com/sebastianbergmann/comparator",
+            "keywords": [
+                "comparator",
+                "compare",
+                "equality"
+            ],
+            "time": "2018-07-12T15:12:46+00:00"
+        },
+        {
+            "name": "sebastian/diff",
+            "version": "3.0.2",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/diff.git",
+                "reference": "720fcc7e9b5cf384ea68d9d930d480907a0c1a29"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/720fcc7e9b5cf384ea68d9d930d480907a0c1a29",
+                "reference": "720fcc7e9b5cf384ea68d9d930d480907a0c1a29",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^7.1"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^7.5 || ^8.0",
+                "symfony/process": "^2 || ^3.3 || ^4"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "3.0-dev"
+                }
+            },
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Kore Nordmann",
+                    "email": "mail@kore-nordmann.de"
+                },
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de"
+                }
+            ],
+            "description": "Diff implementation",
+            "homepage": "https://github.com/sebastianbergmann/diff",
+            "keywords": [
+                "diff",
+                "udiff",
+                "unidiff",
+                "unified diff"
+            ],
+            "time": "2019-02-04T06:01:07+00:00"
+        },
+        {
+            "name": "sebastian/environment",
+            "version": "4.2.3",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/environment.git",
+                "reference": "464c90d7bdf5ad4e8a6aea15c091fec0603d4368"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/464c90d7bdf5ad4e8a6aea15c091fec0603d4368",
+                "reference": "464c90d7bdf5ad4e8a6aea15c091fec0603d4368",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^7.1"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^7.5"
+            },
+            "suggest": {
+                "ext-posix": "*"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "4.2-dev"
+                }
+            },
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de"
+                }
+            ],
+            "description": "Provides functionality to handle HHVM/PHP environments",
+            "homepage": "http://www.github.com/sebastianbergmann/environment",
+            "keywords": [
+                "Xdebug",
+                "environment",
+                "hhvm"
+            ],
+            "time": "2019-11-20T08:46:58+00:00"
+        },
+        {
+            "name": "sebastian/exporter",
+            "version": "3.1.2",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/exporter.git",
+                "reference": "68609e1261d215ea5b21b7987539cbfbe156ec3e"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/68609e1261d215ea5b21b7987539cbfbe156ec3e",
+                "reference": "68609e1261d215ea5b21b7987539cbfbe156ec3e",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^7.0",
+                "sebastian/recursion-context": "^3.0"
+            },
+            "require-dev": {
+                "ext-mbstring": "*",
+                "phpunit/phpunit": "^6.0"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "3.1.x-dev"
+                }
+            },
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de"
+                },
+                {
+                    "name": "Jeff Welch",
+                    "email": "whatthejeff@gmail.com"
+                },
+                {
+                    "name": "Volker Dusch",
+                    "email": "github@wallbash.com"
+                },
+                {
+                    "name": "Adam Harvey",
+                    "email": "aharvey@php.net"
+                },
+                {
+                    "name": "Bernhard Schussek",
+                    "email": "bschussek@gmail.com"
+                }
+            ],
+            "description": "Provides the functionality to export PHP variables for visualization",
+            "homepage": "http://www.github.com/sebastianbergmann/exporter",
+            "keywords": [
+                "export",
+                "exporter"
+            ],
+            "time": "2019-09-14T09:02:43+00:00"
+        },
+        {
+            "name": "sebastian/global-state",
+            "version": "2.0.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/global-state.git",
+                "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4",
+                "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^7.0"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^6.0"
+            },
+            "suggest": {
+                "ext-uopz": "*"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "2.0-dev"
+                }
+            },
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de"
+                }
+            ],
+            "description": "Snapshotting of global state",
+            "homepage": "http://www.github.com/sebastianbergmann/global-state",
+            "keywords": [
+                "global state"
+            ],
+            "time": "2017-04-27T15:39:26+00:00"
+        },
+        {
+            "name": "sebastian/object-enumerator",
+            "version": "3.0.3",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/object-enumerator.git",
+                "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/7cfd9e65d11ffb5af41198476395774d4c8a84c5",
+                "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^7.0",
+                "sebastian/object-reflector": "^1.1.1",
+                "sebastian/recursion-context": "^3.0"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^6.0"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "3.0.x-dev"
+                }
+            },
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de"
+                }
+            ],
+            "description": "Traverses array structures and object graphs to enumerate all referenced objects",
+            "homepage": "https://github.com/sebastianbergmann/object-enumerator/",
+            "time": "2017-08-03T12:35:26+00:00"
+        },
+        {
+            "name": "sebastian/object-reflector",
+            "version": "1.1.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/object-reflector.git",
+                "reference": "773f97c67f28de00d397be301821b06708fca0be"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/773f97c67f28de00d397be301821b06708fca0be",
+                "reference": "773f97c67f28de00d397be301821b06708fca0be",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^7.0"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^6.0"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.1-dev"
+                }
+            },
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de"
+                }
+            ],
+            "description": "Allows reflection of object attributes, including inherited and non-public ones",
+            "homepage": "https://github.com/sebastianbergmann/object-reflector/",
+            "time": "2017-03-29T09:07:27+00:00"
+        },
+        {
+            "name": "sebastian/recursion-context",
+            "version": "3.0.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/recursion-context.git",
+                "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8",
+                "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^7.0"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^6.0"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "3.0.x-dev"
+                }
+            },
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Jeff Welch",
+                    "email": "whatthejeff@gmail.com"
+                },
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de"
+                },
+                {
+                    "name": "Adam Harvey",
+                    "email": "aharvey@php.net"
+                }
+            ],
+            "description": "Provides functionality to recursively process PHP variables",
+            "homepage": "http://www.github.com/sebastianbergmann/recursion-context",
+            "time": "2017-03-03T06:23:57+00:00"
+        },
+        {
+            "name": "sebastian/resource-operations",
+            "version": "2.0.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/resource-operations.git",
+                "reference": "4d7a795d35b889bf80a0cc04e08d77cedfa917a9"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/4d7a795d35b889bf80a0cc04e08d77cedfa917a9",
+                "reference": "4d7a795d35b889bf80a0cc04e08d77cedfa917a9",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^7.1"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "2.0-dev"
+                }
+            },
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de"
+                }
+            ],
+            "description": "Provides a list of PHP built-in functions that operate on resources",
+            "homepage": "https://www.github.com/sebastianbergmann/resource-operations",
+            "time": "2018-10-04T04:07:39+00:00"
+        },
+        {
+            "name": "sebastian/version",
+            "version": "2.0.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/version.git",
+                "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019",
+                "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.6"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "2.0.x-dev"
+                }
+            },
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de",
+                    "role": "lead"
+                }
+            ],
+            "description": "Library that helps with managing the version number of Git-hosted PHP projects",
+            "homepage": "https://github.com/sebastianbergmann/version",
+            "time": "2016-10-03T07:35:21+00:00"
+        },
+        {
+            "name": "seld/jsonlint",
+            "version": "1.7.2",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/Seldaek/jsonlint.git",
+                "reference": "e2e5d290e4d2a4f0eb449f510071392e00e10d19"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/Seldaek/jsonlint/zipball/e2e5d290e4d2a4f0eb449f510071392e00e10d19",
+                "reference": "e2e5d290e4d2a4f0eb449f510071392e00e10d19",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^5.3 || ^7.0"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0"
+            },
+            "bin": [
+                "bin/jsonlint"
+            ],
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "Seld\\JsonLint\\": "src/Seld/JsonLint/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Jordi Boggiano",
+                    "email": "j.boggiano@seld.be",
+                    "homepage": "http://seld.be"
+                }
+            ],
+            "description": "JSON Linter",
+            "keywords": [
+                "json",
+                "linter",
+                "parser",
+                "validator"
+            ],
+            "support": {
+                "issues": "https://github.com/Seldaek/jsonlint/issues",
+                "source": "https://github.com/Seldaek/jsonlint/tree/1.7.2"
+            },
+            "time": "2019-10-24T14:27:39+00:00"
+        },
+        {
+            "name": "seld/phar-utils",
+            "version": "1.1.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/Seldaek/phar-utils.git",
+                "reference": "8800503d56b9867d43d9c303b9cbcc26016e82f0"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/Seldaek/phar-utils/zipball/8800503d56b9867d43d9c303b9cbcc26016e82f0",
+                "reference": "8800503d56b9867d43d9c303b9cbcc26016e82f0",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.3"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Seld\\PharUtils\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Jordi Boggiano",
+                    "email": "j.boggiano@seld.be"
+                }
+            ],
+            "description": "PHAR file format utilities, for when PHP phars you up",
+            "keywords": [
+                "phar"
+            ],
+            "support": {
+                "issues": "https://github.com/Seldaek/phar-utils/issues",
+                "source": "https://github.com/Seldaek/phar-utils/tree/1.1.0"
+            },
+            "time": "2020-02-14T15:25:33+00:00"
+        },
+        {
+            "name": "symfony/console",
+            "version": "v5.0.7",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/console.git",
+                "reference": "5fa1caadc8cdaa17bcfb25219f3b53fe294a9935"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/console/zipball/5fa1caadc8cdaa17bcfb25219f3b53fe294a9935",
+                "reference": "5fa1caadc8cdaa17bcfb25219f3b53fe294a9935",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^7.2.5",
+                "symfony/polyfill-mbstring": "~1.0",
+                "symfony/polyfill-php73": "^1.8",
+                "symfony/service-contracts": "^1.1|^2"
+            },
+            "conflict": {
+                "symfony/dependency-injection": "<4.4",
+                "symfony/event-dispatcher": "<4.4",
+                "symfony/lock": "<4.4",
+                "symfony/process": "<4.4"
+            },
+            "provide": {
+                "psr/log-implementation": "1.0"
+            },
+            "require-dev": {
+                "psr/log": "~1.0",
+                "symfony/config": "^4.4|^5.0",
+                "symfony/dependency-injection": "^4.4|^5.0",
+                "symfony/event-dispatcher": "^4.4|^5.0",
+                "symfony/lock": "^4.4|^5.0",
+                "symfony/process": "^4.4|^5.0",
+                "symfony/var-dumper": "^4.4|^5.0"
+            },
+            "suggest": {
+                "psr/log": "For using the console logger",
+                "symfony/event-dispatcher": "",
+                "symfony/lock": "",
+                "symfony/process": ""
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "5.0-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Symfony\\Component\\Console\\": ""
+                },
+                "exclude-from-classmap": [
+                    "/Tests/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Fabien Potencier",
+                    "email": "fabien@symfony.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Symfony Console Component",
+            "homepage": "https://symfony.com",
+            "support": {
+                "source": "https://github.com/symfony/console/tree/v5.0.7"
+            },
+            "time": "2020-03-30T11:42:42+00:00"
+        },
+        {
+            "name": "symfony/filesystem",
+            "version": "v5.0.7",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/filesystem.git",
+                "reference": "ca3b87dd09fff9b771731637f5379965fbfab420"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/filesystem/zipball/ca3b87dd09fff9b771731637f5379965fbfab420",
+                "reference": "ca3b87dd09fff9b771731637f5379965fbfab420",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^7.2.5",
+                "symfony/polyfill-ctype": "~1.8"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "5.0-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Symfony\\Component\\Filesystem\\": ""
+                },
+                "exclude-from-classmap": [
+                    "/Tests/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Fabien Potencier",
+                    "email": "fabien@symfony.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Symfony Filesystem Component",
+            "homepage": "https://symfony.com",
+            "support": {
+                "source": "https://github.com/symfony/filesystem/tree/v5.0.7"
+            },
+            "funding": [
+                {
+                    "url": "https://symfony.com/sponsor",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/fabpot",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2020-03-27T16:56:45+00:00"
+        },
+        {
+            "name": "symfony/finder",
+            "version": "v5.0.7",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/finder.git",
+                "reference": "600a52c29afc0d1caa74acbec8d3095ca7e9910d"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/finder/zipball/600a52c29afc0d1caa74acbec8d3095ca7e9910d",
+                "reference": "600a52c29afc0d1caa74acbec8d3095ca7e9910d",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^7.2.5"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "5.0-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Symfony\\Component\\Finder\\": ""
+                },
+                "exclude-from-classmap": [
+                    "/Tests/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Fabien Potencier",
+                    "email": "fabien@symfony.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Symfony Finder Component",
+            "homepage": "https://symfony.com",
+            "support": {
+                "source": "https://github.com/symfony/finder/tree/5.0"
+            },
+            "funding": [
+                {
+                    "url": "https://symfony.com/sponsor",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/fabpot",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2020-03-27T16:56:45+00:00"
+        },
+        {
+            "name": "symfony/polyfill-ctype",
+            "version": "v1.15.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/polyfill-ctype.git",
+                "reference": "4719fa9c18b0464d399f1a63bf624b42b6fa8d14"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/4719fa9c18b0464d399f1a63bf624b42b6fa8d14",
+                "reference": "4719fa9c18b0464d399f1a63bf624b42b6fa8d14",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.3.3"
+            },
+            "suggest": {
+                "ext-ctype": "For best performance"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.15-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Symfony\\Polyfill\\Ctype\\": ""
+                },
+                "files": [
+                    "bootstrap.php"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Gert de Pagter",
+                    "email": "BackEndTea@gmail.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Symfony polyfill for ctype functions",
+            "homepage": "https://symfony.com",
+            "keywords": [
+                "compatibility",
+                "ctype",
+                "polyfill",
+                "portable"
+            ],
+            "support": {
+                "source": "https://github.com/symfony/polyfill-ctype/tree/v1.15.0"
+            },
+            "funding": [
+                {
+                    "url": "https://symfony.com/sponsor",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/fabpot",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2020-02-27T09:26:54+00:00"
+        },
+        {
+            "name": "symfony/polyfill-mbstring",
+            "version": "v1.15.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/polyfill-mbstring.git",
+                "reference": "81ffd3a9c6d707be22e3012b827de1c9775fc5ac"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/81ffd3a9c6d707be22e3012b827de1c9775fc5ac",
+                "reference": "81ffd3a9c6d707be22e3012b827de1c9775fc5ac",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.3.3"
+            },
+            "suggest": {
+                "ext-mbstring": "For best performance"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.15-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Symfony\\Polyfill\\Mbstring\\": ""
+                },
+                "files": [
+                    "bootstrap.php"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Nicolas Grekas",
+                    "email": "p@tchwork.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Symfony polyfill for the Mbstring extension",
+            "homepage": "https://symfony.com",
+            "keywords": [
+                "compatibility",
+                "mbstring",
+                "polyfill",
+                "portable",
+                "shim"
+            ],
+            "support": {
+                "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.15.0"
+            },
+            "funding": [
+                {
+                    "url": "https://symfony.com/sponsor",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/fabpot",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2020-03-09T19:04:49+00:00"
+        },
+        {
+            "name": "symfony/polyfill-php73",
+            "version": "v1.15.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/polyfill-php73.git",
+                "reference": "0f27e9f464ea3da33cbe7ca3bdf4eb66def9d0f7"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/0f27e9f464ea3da33cbe7ca3bdf4eb66def9d0f7",
+                "reference": "0f27e9f464ea3da33cbe7ca3bdf4eb66def9d0f7",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.3.3"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.15-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Symfony\\Polyfill\\Php73\\": ""
+                },
+                "files": [
+                    "bootstrap.php"
+                ],
+                "classmap": [
+                    "Resources/stubs"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Nicolas Grekas",
+                    "email": "p@tchwork.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions",
+            "homepage": "https://symfony.com",
+            "keywords": [
+                "compatibility",
+                "polyfill",
+                "portable",
+                "shim"
+            ],
+            "support": {
+                "source": "https://github.com/symfony/polyfill-php73/tree/v1.15.0"
+            },
+            "funding": [
+                {
+                    "url": "https://symfony.com/sponsor",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/fabpot",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2020-02-27T09:26:54+00:00"
+        },
+        {
+            "name": "symfony/process",
+            "version": "v5.0.7",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/process.git",
+                "reference": "c5ca4a0fc16a0c888067d43fbcfe1f8a53d8e70e"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/process/zipball/c5ca4a0fc16a0c888067d43fbcfe1f8a53d8e70e",
+                "reference": "c5ca4a0fc16a0c888067d43fbcfe1f8a53d8e70e",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^7.2.5"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "5.0-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Symfony\\Component\\Process\\": ""
+                },
+                "exclude-from-classmap": [
+                    "/Tests/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Fabien Potencier",
+                    "email": "fabien@symfony.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Symfony Process Component",
+            "homepage": "https://symfony.com",
+            "support": {
+                "source": "https://github.com/symfony/process/tree/v5.0.7"
+            },
+            "time": "2020-03-27T16:56:45+00:00"
+        },
+        {
+            "name": "symfony/service-contracts",
+            "version": "v2.0.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/service-contracts.git",
+                "reference": "144c5e51266b281231e947b51223ba14acf1a749"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/service-contracts/zipball/144c5e51266b281231e947b51223ba14acf1a749",
+                "reference": "144c5e51266b281231e947b51223ba14acf1a749",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^7.2.5",
+                "psr/container": "^1.0"
+            },
+            "suggest": {
+                "symfony/service-implementation": ""
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "2.0-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Symfony\\Contracts\\Service\\": ""
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Nicolas Grekas",
+                    "email": "p@tchwork.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Generic abstractions related to writing services",
+            "homepage": "https://symfony.com",
+            "keywords": [
+                "abstractions",
+                "contracts",
+                "decoupling",
+                "interfaces",
+                "interoperability",
+                "standards"
+            ],
+            "support": {
+                "source": "https://github.com/symfony/service-contracts/tree/v2.0.1"
+            },
+            "time": "2019-11-18T17:27:11+00:00"
+        },
+        {
+            "name": "theseer/tokenizer",
+            "version": "1.1.3",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/theseer/tokenizer.git",
+                "reference": "11336f6f84e16a720dae9d8e6ed5019efa85a0f9"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/theseer/tokenizer/zipball/11336f6f84e16a720dae9d8e6ed5019efa85a0f9",
+                "reference": "11336f6f84e16a720dae9d8e6ed5019efa85a0f9",
+                "shasum": ""
+            },
+            "require": {
+                "ext-dom": "*",
+                "ext-tokenizer": "*",
+                "ext-xmlwriter": "*",
+                "php": "^7.0"
+            },
+            "type": "library",
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Arne Blankerts",
+                    "email": "arne@blankerts.de",
+                    "role": "Developer"
+                }
+            ],
+            "description": "A small library for converting tokenized PHP source code into XML and potentially other formats",
+            "time": "2019-06-13T22:48:21+00:00"
+        },
+        {
+            "name": "webmozart/assert",
+            "version": "1.8.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/webmozart/assert.git",
+                "reference": "ab2cb0b3b559010b75981b1bdce728da3ee90ad6"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/webmozart/assert/zipball/ab2cb0b3b559010b75981b1bdce728da3ee90ad6",
+                "reference": "ab2cb0b3b559010b75981b1bdce728da3ee90ad6",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^5.3.3 || ^7.0",
+                "symfony/polyfill-ctype": "^1.8"
+            },
+            "conflict": {
+                "vimeo/psalm": "<3.9.1"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^4.8.36 || ^7.5.13"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "Webmozart\\Assert\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Bernhard Schussek",
+                    "email": "bschussek@gmail.com"
+                }
+            ],
+            "description": "Assertions to validate method input/output with nice error messages.",
+            "keywords": [
+                "assert",
+                "check",
+                "validate"
+            ],
+            "support": {
+                "issues": "https://github.com/webmozart/assert/issues",
+                "source": "https://github.com/webmozart/assert/tree/master"
+            },
+            "time": "2020-04-18T12:12:48+00:00"
+        }
+    ],
+    "aliases": [],
+    "minimum-stability": "stable",
+    "stability-flags": {
+        "composer/composer": 20
+    },
+    "prefer-stable": false,
+    "prefer-lowest": false,
+    "platform": {
+        "php": "^7",
+        "composer-plugin-api": "^1.1.0 || ^2.0"
+    },
+    "platform-dev": {
+        "ext-zip": "^1.13"
+    },
+    "plugin-api-version": "1.1.0"
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/composer/package-versions-deprecated/phpcs.xml.dist b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/composer/package-versions-deprecated/phpcs.xml.dist
new file mode 100644
index 0000000000000000000000000000000000000000..e169c61679d95b61b80c65f8d2670515d5b15201
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/composer/package-versions-deprecated/phpcs.xml.dist	
@@ -0,0 +1,21 @@
+<?xml version="1.0"?>
+<ruleset>
+    <arg name="basepath" value="."/>
+    <arg name="extensions" value="php"/>
+    <arg name="parallel" value="80"/>
+    <arg name="cache" value=".phpcs-cache"/>
+    <arg name="colors"/>
+
+    <arg value="nps"/>
+
+    <file>src</file>
+    <file>test</file>
+
+    <rule ref="Doctrine">
+        <exclude-pattern>src/PackageVersions/Versions.php</exclude-pattern>
+    </rule>
+
+    <rule ref="Generic.Strings.UnnecessaryStringConcat.Found">
+        <exclude-pattern>src/PackageVersions/Installer.php</exclude-pattern>
+    </rule>
+</ruleset>
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/composer/package-versions-deprecated/src/PackageVersions/FallbackVersions.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/composer/package-versions-deprecated/src/PackageVersions/FallbackVersions.php
new file mode 100644
index 0000000000000000000000000000000000000000..18e5fe64f627d1506b69904a01443ce3116354ae
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/composer/package-versions-deprecated/src/PackageVersions/FallbackVersions.php	
@@ -0,0 +1,128 @@
+<?php
+
+declare(strict_types=1);
+
+namespace PackageVersions;
+
+use Generator;
+use OutOfBoundsException;
+use UnexpectedValueException;
+use function array_key_exists;
+use function array_merge;
+use function basename;
+use function file_exists;
+use function file_get_contents;
+use function getcwd;
+use function iterator_to_array;
+use function json_decode;
+use function json_encode;
+use function sprintf;
+
+/**
+ * @internal
+ *
+ * This is a fallback for {@see \PackageVersions\Versions::getVersion()}
+ * Do not use this class directly: it is intended to be only used when
+ * {@see \PackageVersions\Versions} fails to be generated, which typically
+ * happens when running composer with `--no-scripts` flag)
+ */
+final class FallbackVersions
+{
+    const ROOT_PACKAGE_NAME = 'unknown/root-package@UNKNOWN';
+
+    private function __construct()
+    {
+    }
+
+    /**
+     * @throws OutOfBoundsException If a version cannot be located.
+     * @throws UnexpectedValueException If the composer.lock file could not be located.
+     */
+    public static function getVersion(string $packageName): string
+    {
+        $versions = iterator_to_array(self::getVersions(self::getPackageData()));
+
+        if (! array_key_exists($packageName, $versions)) {
+            throw new OutOfBoundsException(
+                'Required package "' . $packageName . '" is not installed: check your ./vendor/composer/installed.json and/or ./composer.lock files'
+            );
+        }
+
+        return $versions[$packageName];
+    }
+
+    /**
+     * @return mixed[]
+     *
+     * @throws UnexpectedValueException
+     */
+    private static function getPackageData(): array
+    {
+        $checkedPaths = [
+            // The top-level project's ./vendor/composer/installed.json
+            getcwd() . '/vendor/composer/installed.json',
+            __DIR__ . '/../../../../composer/installed.json',
+            // The top-level project's ./composer.lock
+            getcwd() . '/composer.lock',
+            __DIR__ . '/../../../../../composer.lock',
+            // This package's composer.lock
+            __DIR__ . '/../../composer.lock',
+        ];
+
+        $packageData = [];
+        foreach ($checkedPaths as $path) {
+            if (! file_exists($path)) {
+                continue;
+            }
+
+            $data = json_decode(file_get_contents($path), true);
+            switch (basename($path)) {
+                case 'installed.json':
+                    // composer 2.x installed.json format
+                    if (isset($data['packages'])) {
+                        $packageData[] = $data['packages'];
+                    } else {
+                        // composer 1.x installed.json format
+                        $packageData[] = $data;
+                    }
+
+                    break;
+                case 'composer.lock':
+                    $packageData[] = $data['packages'] + ($data['packages-dev'] ?? []);
+                    break;
+                default:
+                    // intentionally left blank
+            }
+        }
+
+        if ($packageData !== []) {
+            return array_merge(...$packageData);
+        }
+
+        throw new UnexpectedValueException(sprintf(
+            'PackageVersions could not locate the `vendor/composer/installed.json` or your `composer.lock` '
+            . 'location. This is assumed to be in %s. If you customized your composer vendor directory and ran composer '
+            . 'installation with --no-scripts, or if you deployed without the required composer files, PackageVersions '
+            . 'can\'t detect installed versions.',
+            json_encode($checkedPaths)
+        ));
+    }
+
+    /**
+     * @param mixed[] $packageData
+     *
+     * @return Generator&string[]
+     *
+     * @psalm-return Generator<string, string>
+     */
+    private static function getVersions(array $packageData): Generator
+    {
+        foreach ($packageData as $package) {
+            yield $package['name'] => $package['version'] . '@' . (
+                $package['source']['reference'] ?? $package['dist']['reference'] ?? ''
+            );
+        }
+
+        yield self::ROOT_PACKAGE_NAME => self::ROOT_PACKAGE_NAME;
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/composer/package-versions-deprecated/src/PackageVersions/Installer.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/composer/package-versions-deprecated/src/PackageVersions/Installer.php
new file mode 100644
index 0000000000000000000000000000000000000000..c0853c1614c21128154c5db7b6446cbe2aa0ebe2
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/composer/package-versions-deprecated/src/PackageVersions/Installer.php	
@@ -0,0 +1,269 @@
+<?php
+
+declare(strict_types=1);
+
+namespace PackageVersions;
+
+use Composer\Composer;
+use Composer\Config;
+use Composer\EventDispatcher\EventSubscriberInterface;
+use Composer\IO\IOInterface;
+use Composer\Package\AliasPackage;
+use Composer\Package\Locker;
+use Composer\Package\PackageInterface;
+use Composer\Package\RootPackageInterface;
+use Composer\Plugin\PluginInterface;
+use Composer\Script\Event;
+use Composer\Script\ScriptEvents;
+use Generator;
+use RuntimeException;
+
+use function array_key_exists;
+use function array_merge;
+use function chmod;
+use function dirname;
+use function file_exists;
+use function file_put_contents;
+use function is_writable;
+use function iterator_to_array;
+use function rename;
+use function sprintf;
+use function uniqid;
+use function var_export;
+
+final class Installer implements PluginInterface, EventSubscriberInterface
+{
+    private static $generatedClassTemplate = <<<'PHP'
+<?php
+
+declare(strict_types=1);
+
+namespace PackageVersions;
+
+use Composer\InstalledVersions;
+use OutOfBoundsException;
+
+class_exists(InstalledVersions::class);
+
+/**
+ * This class is generated by composer/package-versions-deprecated, specifically by
+ * @see \PackageVersions\Installer
+ *
+ * This file is overwritten at every run of `composer install` or `composer update`.
+ *
+ * @deprecated in favor of the Composer\InstalledVersions class provided by Composer 2. Require composer-runtime-api:^2 to ensure it is present.
+ */
+%s
+{
+    /**
+     * @deprecated please use {@see self::rootPackageName()} instead.
+     *             This constant will be removed in version 2.0.0.
+     */
+    const ROOT_PACKAGE_NAME = '%s';
+
+    /**
+     * Array of all available composer packages.
+     * Dont read this array from your calling code, but use the \PackageVersions\Versions::getVersion() method instead.
+     *
+     * @var array<string, string>
+     * @internal
+     */
+    const VERSIONS          = %s;
+
+    private function __construct()
+    {
+    }
+
+    /**
+     * @psalm-pure
+     *
+     * @psalm-suppress ImpureMethodCall we know that {@see InstalledVersions} interaction does not
+     *                                  cause any side effects here.
+     */
+    public static function rootPackageName() : string
+    {
+        if (!class_exists(InstalledVersions::class, false) || !InstalledVersions::getRawData()) {
+            return self::ROOT_PACKAGE_NAME;
+        }
+
+        return InstalledVersions::getRootPackage()['name'];
+    }
+
+    /**
+     * @throws OutOfBoundsException If a version cannot be located.
+     *
+     * @psalm-param key-of<self::VERSIONS> $packageName
+     * @psalm-pure
+     *
+     * @psalm-suppress ImpureMethodCall we know that {@see InstalledVersions} interaction does not
+     *                                  cause any side effects here.
+     */
+    public static function getVersion(string $packageName): string
+    {
+        if (class_exists(InstalledVersions::class, false) && InstalledVersions::getRawData()) {
+            return InstalledVersions::getPrettyVersion($packageName)
+                . '@' . InstalledVersions::getReference($packageName);
+        }
+
+        if (isset(self::VERSIONS[$packageName])) {
+            return self::VERSIONS[$packageName];
+        }
+
+        throw new OutOfBoundsException(
+            'Required package "' . $packageName . '" is not installed: check your ./vendor/composer/installed.json and/or ./composer.lock files'
+        );
+    }
+}
+
+PHP;
+
+    public function activate(Composer $composer, IOInterface $io)
+    {
+        // Nothing to do here, as all features are provided through event listeners
+    }
+
+    public function deactivate(Composer $composer, IOInterface $io)
+    {
+        // Nothing to do here, as all features are provided through event listeners
+    }
+
+    public function uninstall(Composer $composer, IOInterface $io)
+    {
+        // Nothing to do here, as all features are provided through event listeners
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public static function getSubscribedEvents(): array
+    {
+        return [ScriptEvents::POST_AUTOLOAD_DUMP => 'dumpVersionsClass'];
+    }
+
+    /**
+     * @throws RuntimeException
+     */
+    public static function dumpVersionsClass(Event $composerEvent)
+    {
+        $composer    = $composerEvent->getComposer();
+        $rootPackage = $composer->getPackage();
+        $versions    = iterator_to_array(self::getVersions($composer->getLocker(), $rootPackage));
+
+        if (! array_key_exists('composer/package-versions-deprecated', $versions)) {
+            //plugin must be globally installed - we only want to generate versions for projects which specifically
+            //require composer/package-versions-deprecated
+            return;
+        }
+
+        $versionClass = self::generateVersionsClass($rootPackage->getName(), $versions);
+
+        self::writeVersionClassToFile($versionClass, $composer, $composerEvent->getIO());
+    }
+
+    /**
+     * @param string[] $versions
+     */
+    private static function generateVersionsClass(string $rootPackageName, array $versions): string
+    {
+        return sprintf(
+            self::$generatedClassTemplate,
+            'fin' . 'al ' . 'cla' . 'ss ' . 'Versions', // note: workaround for regex-based code parsers :-(
+            $rootPackageName,
+            var_export($versions, true)
+        );
+    }
+
+    /**
+     * @throws RuntimeException
+     */
+    private static function writeVersionClassToFile(string $versionClassSource, Composer $composer, IOInterface $io)
+    {
+        $installPath = self::locateRootPackageInstallPath($composer->getConfig(), $composer->getPackage())
+            . '/src/PackageVersions/Versions.php';
+
+        $installDir = dirname($installPath);
+        if (! file_exists($installDir)) {
+            $io->write('<info>composer/package-versions-deprecated:</info> Package not found (probably scheduled for removal); generation of version class skipped.');
+
+            return;
+        }
+
+        if (! is_writable($installDir)) {
+            $io->write(
+                sprintf(
+                    '<info>composer/package-versions-deprecated:</info> %s is not writable; generation of version class skipped.',
+                    $installDir
+                )
+            );
+
+            return;
+        }
+
+        $io->write('<info>composer/package-versions-deprecated:</info> Generating version class...');
+
+        $installPathTmp = $installPath . '_' . uniqid('tmp', true);
+        file_put_contents($installPathTmp, $versionClassSource);
+        chmod($installPathTmp, 0664);
+        rename($installPathTmp, $installPath);
+
+        $io->write('<info>composer/package-versions-deprecated:</info> ...done generating version class');
+    }
+
+    /**
+     * @throws RuntimeException
+     */
+    private static function locateRootPackageInstallPath(
+        Config $composerConfig,
+        RootPackageInterface $rootPackage
+    ): string {
+        if (self::getRootPackageAlias($rootPackage)->getName() === 'composer/package-versions-deprecated') {
+            return dirname($composerConfig->get('vendor-dir'));
+        }
+
+        return $composerConfig->get('vendor-dir') . '/composer/package-versions-deprecated';
+    }
+
+    private static function getRootPackageAlias(RootPackageInterface $rootPackage): PackageInterface
+    {
+        $package = $rootPackage;
+
+        while ($package instanceof AliasPackage) {
+            $package = $package->getAliasOf();
+        }
+
+        return $package;
+    }
+
+    /**
+     * @return Generator&string[]
+     *
+     * @psalm-return Generator<string, string>
+     */
+    private static function getVersions(Locker $locker, RootPackageInterface $rootPackage): Generator
+    {
+        $lockData = $locker->getLockData();
+
+        $lockData['packages-dev'] = $lockData['packages-dev'] ?? [];
+
+        $packages = $lockData['packages'];
+        if (getenv('COMPOSER_DEV_MODE') !== '0') {
+            $packages = array_merge($packages, $lockData['packages-dev']);
+        }
+        foreach ($packages as $package) {
+            yield $package['name'] => $package['version'] . '@' . (
+                $package['source']['reference'] ?? $package['dist']['reference'] ?? ''
+            );
+        }
+
+        foreach ($rootPackage->getReplaces() as $replace) {
+            $version = $replace->getPrettyConstraint();
+            if ($version === 'self.version') {
+                $version = $rootPackage->getPrettyVersion();
+            }
+
+            yield $replace->getTarget() => $version . '@' . $rootPackage->getSourceReference();
+        }
+
+        yield $rootPackage->getName() => $rootPackage->getPrettyVersion() . '@' . $rootPackage->getSourceReference();
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/composer/package-versions-deprecated/src/PackageVersions/Versions.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/composer/package-versions-deprecated/src/PackageVersions/Versions.php
new file mode 100644
index 0000000000000000000000000000000000000000..6fb2b449b500452c5deef750bcdc91721d5eb14c
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/composer/package-versions-deprecated/src/PackageVersions/Versions.php	
@@ -0,0 +1,86 @@
+<?php
+
+declare(strict_types=1);
+
+namespace PackageVersions;
+
+use Composer\InstalledVersions;
+use OutOfBoundsException;
+
+class_exists(InstalledVersions::class);
+
+/**
+ * This class is generated by composer/package-versions-deprecated, specifically by
+ * @see \PackageVersions\Installer
+ *
+ * This file is overwritten at every run of `composer install` or `composer update`.
+ *
+ * @deprecated in favor of the Composer\InstalledVersions class provided by Composer 2. Require composer-runtime-api:^2 to ensure it is present.
+ */
+final class Versions
+{
+    /**
+     * @deprecated please use {@see self::rootPackageName()} instead.
+     *             This constant will be removed in version 2.0.0.
+     */
+    const ROOT_PACKAGE_NAME = '__root__';
+
+    /**
+     * Array of all available composer packages.
+     * Dont read this array from your calling code, but use the \PackageVersions\Versions::getVersion() method instead.
+     *
+     * @var array<string, string>
+     * @internal
+     */
+    const VERSIONS          = array (
+  'composer/package-versions-deprecated' => '1.11.99.1@7413f0b55a051e89485c5cb9f765fe24bb02a7b6',
+  'jean85/pretty-package-versions' => '1.6.0@1e0104b46f045868f11942aea058cd7186d6c303',
+  'mongodb/mongodb' => '1.8.0@953dbc19443aa9314c44b7217a16873347e6840d',
+  'symfony/polyfill-php80' => 'v1.22.1@dc3063ba22c2a1fd2f45ed856374d79114998f91',
+  '__root__' => '1.0.0+no-version-set@',
+);
+
+    private function __construct()
+    {
+    }
+
+    /**
+     * @psalm-pure
+     *
+     * @psalm-suppress ImpureMethodCall we know that {@see InstalledVersions} interaction does not
+     *                                  cause any side effects here.
+     */
+    public static function rootPackageName() : string
+    {
+        if (!class_exists(InstalledVersions::class, false) || !InstalledVersions::getRawData()) {
+            return self::ROOT_PACKAGE_NAME;
+        }
+
+        return InstalledVersions::getRootPackage()['name'];
+    }
+
+    /**
+     * @throws OutOfBoundsException If a version cannot be located.
+     *
+     * @psalm-param key-of<self::VERSIONS> $packageName
+     * @psalm-pure
+     *
+     * @psalm-suppress ImpureMethodCall we know that {@see InstalledVersions} interaction does not
+     *                                  cause any side effects here.
+     */
+    public static function getVersion(string $packageName): string
+    {
+        if (class_exists(InstalledVersions::class, false) && InstalledVersions::getRawData()) {
+            return InstalledVersions::getPrettyVersion($packageName)
+                . '@' . InstalledVersions::getReference($packageName);
+        }
+
+        if (isset(self::VERSIONS[$packageName])) {
+            return self::VERSIONS[$packageName];
+        }
+
+        throw new OutOfBoundsException(
+            'Required package "' . $packageName . '" is not installed: check your ./vendor/composer/installed.json and/or ./composer.lock files'
+        );
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/composer/platform_check.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/composer/platform_check.php
new file mode 100644
index 0000000000000000000000000000000000000000..6d3407dbb68517a03ccf2557f8fbad1c023af549
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/composer/platform_check.php	
@@ -0,0 +1,26 @@
+<?php
+
+// platform_check.php @generated by Composer
+
+$issues = array();
+
+if (!(PHP_VERSION_ID >= 70100)) {
+    $issues[] = 'Your Composer dependencies require a PHP version ">= 7.1.0". You are running ' . PHP_VERSION . '.';
+}
+
+if ($issues) {
+    if (!headers_sent()) {
+        header('HTTP/1.1 500 Internal Server Error');
+    }
+    if (!ini_get('display_errors')) {
+        if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
+            fwrite(STDERR, 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . implode(PHP_EOL, $issues) . PHP_EOL.PHP_EOL);
+        } elseif (!headers_sent()) {
+            echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL;
+        }
+    }
+    trigger_error(
+        'Composer detected issues in your platform: ' . implode(' ', $issues),
+        E_USER_ERROR
+    );
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/jean85/pretty-package-versions/.github/workflows/tests.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/jean85/pretty-package-versions/.github/workflows/tests.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..f25a092714c7f69e6dd8e93f9d9baffa6dd33c5e
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/jean85/pretty-package-versions/.github/workflows/tests.yaml	
@@ -0,0 +1,48 @@
+name: Tests
+
+on:
+  pull_request: null
+  push:
+    branches:
+      - 1.x
+
+jobs:
+  tests:
+    runs-on: ubuntu-latest
+    strategy:
+      matrix:
+        php:
+          - '7.0'
+          - '7.1'
+          - '7.2'
+          - '7.3'
+          - '7.4'
+          - '8.0'
+
+    name: PHP ${{ matrix.php }} tests
+    steps:
+      # checkout git
+      - uses: actions/checkout@v2
+      # cache
+      - uses: actions/cache@v2
+        with:
+          path: ~/.composer/cache/files
+          key: ${{ matrix.php }}
+      # setup PHP
+      - uses: shivammathur/setup-php@v2
+        with:
+          php-version: ${{ matrix.php }}
+          coverage: xdebug
+      - run: composer install --no-progress --ansi
+        if: matrix.php != '8.0'
+      - run: composer install --no-progress --ansi --ignore-platform-reqs
+        if: matrix.php == '8.0'
+      - run: vendor/bin/phpunit --coverage-clover=coverage.xml
+        if: matrix.php != '8.0'
+      - run: vendor/bin/phpunit
+        if: matrix.php == '8.0'
+      - uses: codecov/codecov-action@v1
+        if: matrix.php != '8.0'
+        with:
+          file: './coverage.xml'
+          fail_ci_if_error: true
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/jean85/pretty-package-versions/LICENSE b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/jean85/pretty-package-versions/LICENSE
new file mode 100644
index 0000000000000000000000000000000000000000..07c8ecbbd96f0333663fbe0af0210c37d7315a6b
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/jean85/pretty-package-versions/LICENSE	
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2017 Alessandro Lai
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/jean85/pretty-package-versions/codecov.yml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/jean85/pretty-package-versions/codecov.yml
new file mode 100644
index 0000000000000000000000000000000000000000..69cb76019a474330e99666f147ecb85e44de1ce6
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/jean85/pretty-package-versions/codecov.yml	
@@ -0,0 +1 @@
+comment: false
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/jean85/pretty-package-versions/composer.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/jean85/pretty-package-versions/composer.json
new file mode 100644
index 0000000000000000000000000000000000000000..084310038437b2be9865f87e96c10674a48cf76e
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/jean85/pretty-package-versions/composer.json	
@@ -0,0 +1,43 @@
+{
+    "name": "jean85/pretty-package-versions",
+    "description": "A wrapper for ocramius/package-versions to get pretty versions strings",
+    "type": "library",
+    "require": {
+        "php": "^7.0|^8.0",
+        "composer/package-versions-deprecated": "^1.8.0"
+    },
+    "require-dev": {
+        "phpunit/phpunit": "^6.0|^8.5|^9.2"
+    },
+    "license": "MIT",
+    "authors": [
+        {
+            "name": "Alessandro Lai",
+            "email": "alessandro.lai85@gmail.com"
+        }
+    ],
+    "support": {
+        "issues": "https://github.com/Jean85/pretty-package-versions/issues"
+    },
+    "keywords": [
+        "package",
+        "versions",
+        "composer",
+        "release"
+    ],
+    "extra": {
+        "branch-alias": {
+            "dev-master": "1.x-dev"
+        }
+    },
+    "autoload": {
+        "psr-4": {
+            "Jean85\\": "src/"
+        }
+    },
+    "autoload-dev": {
+        "psr-4": {
+            "Tests\\": "tests"
+        }
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/jean85/pretty-package-versions/src/PrettyVersions.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/jean85/pretty-package-versions/src/PrettyVersions.php
new file mode 100644
index 0000000000000000000000000000000000000000..6bd4ff8b449a1522d62f0b91eaba438b56c9c439
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/jean85/pretty-package-versions/src/PrettyVersions.php	
@@ -0,0 +1,25 @@
+<?php
+
+namespace Jean85;
+
+use PackageVersions\Versions;
+
+class PrettyVersions
+{
+    const SHORT_COMMIT_LENGTH = 7;
+
+    public static function getVersion(string $packageName): Version
+    {
+        return new Version($packageName, Versions::getVersion($packageName));
+    }
+
+    public static function getRootPackageName(): string
+    {
+        return Versions::ROOT_PACKAGE_NAME;
+    }
+
+    public static function getRootPackageVersion(): Version
+    {
+        return self::getVersion(Versions::ROOT_PACKAGE_NAME);
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/jean85/pretty-package-versions/src/Version.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/jean85/pretty-package-versions/src/Version.php
new file mode 100644
index 0000000000000000000000000000000000000000..8f1401f9c408081ff3398cc6ada74b6534368460
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/jean85/pretty-package-versions/src/Version.php	
@@ -0,0 +1,97 @@
+<?php
+
+namespace Jean85;
+
+class Version
+{
+    const SHORT_COMMIT_LENGTH = PrettyVersions::SHORT_COMMIT_LENGTH;
+
+    /** @var string */
+    private $packageName;
+
+    /** @var string */
+    private $shortVersion;
+
+    /** @var string */
+    private $commitHash;
+
+    /** @var bool */
+    private $versionIsTagged;
+
+    public function __construct(string $packageName, string $version)
+    {
+        $this->packageName = $packageName;
+        $splittedVersion = explode('@', $version);
+        $this->shortVersion = $splittedVersion[0];
+        $this->commitHash = $splittedVersion[1];
+        $this->versionIsTagged = preg_match('/[^v\d\.]/', $this->getShortVersion()) === 0;
+    }
+
+    public function getPrettyVersion(): string
+    {
+        if ($this->versionIsTagged) {
+            return $this->getShortVersion();
+        }
+
+        return $this->getVersionWithShortCommit();
+    }
+
+    public function getFullVersion(): string
+    {
+        return $this->getShortVersion() . '@' . $this->getCommitHash();
+    }
+
+    public function getVersionWithShortReference(): string
+    {
+        return $this->getShortVersion() . '@' . $this->getShortCommitHash();
+    }
+
+    /**
+     * @deprecated since 1.6, use getVersionWithShortReference instead
+     */
+    public function getVersionWithShortCommit(): string
+    {
+        return $this->getVersionWithShortReference();
+    }
+
+    public function getPackageName(): string
+    {
+        return $this->packageName;
+    }
+
+    public function getShortVersion(): string
+    {
+        return $this->shortVersion;
+    }
+
+    public function getReference(): string
+    {
+        return $this->commitHash;
+    }
+
+    /**
+     * @deprecated since 1.6, use getReference instead
+     */
+    public function getCommitHash(): string
+    {
+        return $this->getReference();
+    }
+
+    public function getShortReference(): string
+    {
+        return substr($this->commitHash, 0, self::SHORT_COMMIT_LENGTH);
+    }
+
+    /**
+     * @deprecated since 1.6, use getShortReference instead
+     */
+    public function getShortCommitHash(): string
+    {
+        return $this->getShortReference();
+    }
+
+    public function __toString(): string
+    {
+        return $this->getPrettyVersion();
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/auth_aws/README.md b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/auth_aws/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..028e3d0f2cb9a309812066e5ed60b19bd27745a8
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/auth_aws/README.md	
@@ -0,0 +1,4 @@
+# Configuration Scripts for End-to-end Testing
+
+These scripts were taken from [mongo-enterprise-modules](https://github.com/10gen/mongo-enterprise-modules/tree/master/jstests/external_auth_aws) 
+and intended to simplify creating users, attaching roles to existing EC2 instances, launching an Amazon ECS container instance, etc.
\ No newline at end of file
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/auth_aws/aws_e2e_assume_role.js b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/auth_aws/aws_e2e_assume_role.js
new file mode 100644
index 0000000000000000000000000000000000000000..ae5169667d424068ba56307b0a7ef6849d844f23
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/auth_aws/aws_e2e_assume_role.js	
@@ -0,0 +1,49 @@
+/**
+ * Verify the AWS IAM Auth works with temporary credentials from sts:AssumeRole
+ */
+
+load("lib/aws_e2e_lib.js");
+
+(function() {
+"use strict";
+
+const ASSUMED_ROLE = "arn:aws:sts::557821124784:assumed-role/authtest_user_assume_role/*";
+
+function getAssumeCredentials() {
+    const config = readSetupJson();
+
+    const env = {
+        AWS_ACCESS_KEY_ID: config["iam_auth_assume_aws_account"],
+        AWS_SECRET_ACCESS_KEY: config["iam_auth_assume_aws_secret_access_key"],
+    };
+
+    const role_name = config["iam_auth_assume_role_name"];
+
+    const python_command = getPython3Binary() +
+        ` -u lib/aws_assume_role.py --role_name=${role_name} > creds.json`;
+
+    const ret = runShellCmdWithEnv(python_command, env);
+    assert.eq(ret, 0, "Failed to assume role on the current machine");
+
+    const result = cat("creds.json");
+    try {
+        return JSON.parse(result);
+    } catch (e) {
+        jsTestLog("Failed to parse: " + result);
+        throw e;
+    }
+}
+
+const credentials = getAssumeCredentials();
+const admin = Mongo().getDB("admin");
+const external = admin.getMongo().getDB("$external");
+
+assert(admin.auth("bob", "pwd123"));
+assert.commandWorked(external.runCommand({createUser: ASSUMED_ROLE, roles:[{role: 'read', db: "aws"}]}));
+assert(external.auth({
+    user: credentials["AccessKeyId"],
+    pwd: credentials["SecretAccessKey"],
+    awsIamSessionToken: credentials["SessionToken"],
+    mechanism: 'MONGODB-AWS'
+}));
+}());
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/auth_aws/aws_e2e_ec2.js b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/auth_aws/aws_e2e_ec2.js
new file mode 100644
index 0000000000000000000000000000000000000000..a492db86d3106b0de4c3602df9d758c981b93446
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/auth_aws/aws_e2e_ec2.js	
@@ -0,0 +1,58 @@
+/**
+ * Verify the AWS IAM EC2 hosted auth works
+ */
+load("lib/aws_e2e_lib.js");
+
+(function() {
+"use strict";
+
+// This varies based on hosting EC2 as the account id and role name can vary
+const AWS_ACCOUNT_ARN = "arn:aws:sts::557821124784:assumed-role/authtest_instance_profile_role/*";
+
+function assignInstanceProfile() {
+    const config = readSetupJson();
+
+    const env = {
+        AWS_ACCESS_KEY_ID: config["iam_auth_ec2_instance_account"],
+        AWS_SECRET_ACCESS_KEY: config["iam_auth_ec2_instance_secret_access_key"],
+    };
+
+    const instanceProfileName = config["iam_auth_ec2_instance_profile"];
+    const python_command = getPython3Binary() +
+        ` -u lib/aws_assign_instance_profile.py --instance_profile_arn=${instanceProfileName}`;
+
+    const ret = runShellCmdWithEnv(python_command, env);
+    if (ret == 2) {
+        print("WARNING: Request limit exceeded for AWS API");
+        return false;
+    }
+
+    assert.eq(ret, 0, "Failed to assign an instance profile to the current machine");
+    return true;
+}
+
+if (!assignInstanceProfile()) {
+    return;
+}
+
+const admin = Mongo().getDB("admin");
+const external = admin.getMongo().getDB("$external");
+
+assert(admin.auth("bob", "pwd123"));
+assert.commandWorked(external.runCommand({createUser: AWS_ACCOUNT_ARN, roles:[{role: 'read', db: "aws"}]}));
+
+// Try the command line
+const smoke = runMongoProgram("mongo",
+                              "--host",
+                              "localhost",
+                              '--authenticationMechanism',
+                              'MONGODB-AWS',
+                              '--authenticationDatabase',
+                              '$external',
+                              "--eval",
+                              "1");
+assert.eq(smoke, 0, "Could not auth with smoke user");
+
+// Try the auth function
+assert(external.auth({mechanism: 'MONGODB-AWS'}));
+}());
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/auth_aws/aws_e2e_ecs.js b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/auth_aws/aws_e2e_ecs.js
new file mode 100644
index 0000000000000000000000000000000000000000..8efd8cb43ab37b61964752a0b35091747188b34c
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/auth_aws/aws_e2e_ecs.js	
@@ -0,0 +1,44 @@
+/**
+ * Validate that MONGODB-AWS auth works from ECS temporary credentials.
+ */
+load("lib/aws_e2e_lib.js");
+
+(function() {
+   'use strict';
+
+   assert.eq(typeof mongo_binaries != 'undefined', true, "mongo_binaries must be set");
+   assert.eq(typeof project_dir != 'undefined', true, "project_dir must be set");
+
+   const config = readSetupJson();
+
+   const base_command = getPython3Binary() + " -u  lib/container_tester.py";
+   const run_prune_command = base_command + ' -v remote_gc_services ' +
+       ' --cluster ' + config['iam_auth_ecs_cluster'];
+
+   const run_test_command = base_command + ' -d -v run_e2e_test' +
+       ' --cluster ' + config['iam_auth_ecs_cluster'] + ' --task_definition ' +
+       config['iam_auth_ecs_task_definition'] + ' --subnets ' +
+       config['iam_auth_ecs_subnet_a'] + ' --subnets ' +
+       config['iam_auth_ecs_subnet_b'] + ' --security_group ' +
+       config['iam_auth_ecs_security_group'] +
+       ` --files ${mongo_binaries}/mongod:/root/mongod ${mongo_binaries}/mongo:/root/mongo ` +
+       " lib/ecs_hosted_test.js:/root/ecs_hosted_test.js " +
+       `${project_dir}:/root` +
+       " --script lib/ecs_hosted_test.sh";
+
+   // Pass in the AWS credentials as environment variables
+   // AWS_SHARED_CREDENTIALS_FILE does not work in evergreen for an unknown
+   // reason
+   const env = {
+      AWS_ACCESS_KEY_ID: config['iam_auth_ecs_account'],
+      AWS_SECRET_ACCESS_KEY: config['iam_auth_ecs_secret_access_key'],
+   };
+
+   // Prune other containers
+   let ret = runWithEnv(['/bin/sh', '-c', run_prune_command], env);
+   assert.eq(ret, 0, 'Prune Container failed');
+
+   // Run the test in a container
+   ret = runWithEnv(['/bin/sh', '-c', run_test_command], env);
+   assert.eq(ret, 0, 'Container Test failed');
+}());
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/auth_aws/aws_e2e_regular_aws.js b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/auth_aws/aws_e2e_regular_aws.js
new file mode 100644
index 0000000000000000000000000000000000000000..1c4f2d0329b22d1909bf7a67ece354a7f275be02
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/auth_aws/aws_e2e_regular_aws.js	
@@ -0,0 +1,23 @@
+/**
+ * Validate that the server supports real credentials from AWS and can talk to a real AWS STS
+ * service
+ */
+load("lib/aws_e2e_lib.js");
+
+(function() {
+"use strict";
+
+const admin = Mongo().getDB("admin");
+const external = admin.getMongo().getDB("$external");
+assert(admin.auth("bob", "pwd123"));
+
+const config = readSetupJson();
+assert.commandWorked(
+    external.runCommand({createUser: config["iam_auth_ecs_account_arn"], roles:[{role: 'read', db: "aws"}]}));
+
+assert(external.auth({
+    user: config["iam_auth_ecs_account"],
+    pwd: config["iam_auth_ecs_secret_access_key"],
+    mechanism: 'MONGODB-AWS'
+}));
+}());
\ No newline at end of file
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/auth_aws/lib/aws_assign_instance_profile.py b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/auth_aws/lib/aws_assign_instance_profile.py
new file mode 100644
index 0000000000000000000000000000000000000000..cb3ad154dc5cca85f6fa12a8f245cb322732065f
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/auth_aws/lib/aws_assign_instance_profile.py	
@@ -0,0 +1,102 @@
+#!/usr/bin/env python3
+"""
+Script for assign an instance policy to the current machine.
+"""
+
+import argparse
+import urllib.request
+import logging
+import sys
+import time
+
+import boto3
+import botocore
+
+LOGGER = logging.getLogger(__name__)
+
+def _get_local_instance_id():
+    return urllib.request.urlopen('http://169.254.169.254/latest/meta-data/instance-id').read().decode()
+
+def _has_instance_profile():
+    base_url = "http://169.254.169.254/latest/meta-data/iam/security-credentials/"
+    try:
+        print("Reading: " + base_url)
+        iam_role = urllib.request.urlopen(base_url).read().decode()
+    except urllib.error.HTTPError as e:
+        print(e)
+        if e.code == 404:
+            return False
+        raise e
+
+    try:
+        url = base_url + iam_role
+        print("Reading: " + url)
+        req = urllib.request.urlopen(url)
+    except urllib.error.HTTPError as e:
+        print(e)
+        if e.code == 404:
+            return False
+        raise e
+
+    return True
+
+def _wait_instance_profile():
+    retry = 60
+    while not _has_instance_profile() and retry:
+        time.sleep(5)
+        retry -= 1
+
+    if retry == 0:
+        raise ValueError("Timeout on waiting for instance profile")
+
+def _assign_instance_policy(iam_instance_arn):
+
+    if _has_instance_profile():
+        print("IMPORTANT: Found machine already has instance profile, skipping the assignment")
+        return
+
+    instance_id = _get_local_instance_id()
+
+    ec2_client = boto3.client("ec2", 'us-east-1')
+
+    #https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/ec2.html#EC2.Client.associate_iam_instance_profile
+    try:
+        response = ec2_client.associate_iam_instance_profile(
+            IamInstanceProfile={
+                'Arn' : iam_instance_arn,
+            },
+            InstanceId = instance_id)
+
+        print(response)
+
+        # Wait for the instance profile to be assigned by polling the local instance metadata service
+        _wait_instance_profile()
+
+    except botocore.exceptions.ClientError as ce:
+        if ce.response["Error"]["Code"] == "RequestLimitExceeded":
+            print("WARNING: RequestLimitExceeded, exiting with error code 2")
+            sys.exit(2)
+        raise
+
+def main() -> None:
+    """Execute Main entry point."""
+
+    parser = argparse.ArgumentParser(description='IAM Assign Instance frontend.')
+
+    parser.add_argument('-v', "--verbose", action='store_true', help="Enable verbose logging")
+    parser.add_argument('-d', "--debug", action='store_true', help="Enable debug logging")
+
+    parser.add_argument('--instance_profile_arn', type=str, help="Name of instance profile")
+
+    args = parser.parse_args()
+
+    if args.debug:
+        logging.basicConfig(level=logging.DEBUG)
+    elif args.verbose:
+        logging.basicConfig(level=logging.INFO)
+
+    _assign_instance_policy(args.instance_profile_arn)
+
+
+if __name__ == "__main__":
+    main()
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/auth_aws/lib/aws_assume_role.py b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/auth_aws/lib/aws_assume_role.py
new file mode 100644
index 0000000000000000000000000000000000000000..6df1fc7ef5dddbfa9b7835dbd1cd7427bd123b9d
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/auth_aws/lib/aws_assume_role.py	
@@ -0,0 +1,53 @@
+#!/usr/bin/env python3
+"""
+Script for assuming an aws role.
+"""
+
+import argparse
+import uuid
+import logging
+
+import boto3
+
+LOGGER = logging.getLogger(__name__)
+
+STS_DEFAULT_ROLE_NAME = "arn:aws:iam::579766882180:role/mark.benvenuto"
+
+def _assume_role(role_name):
+    sts_client = boto3.client("sts")
+
+    response = sts_client.assume_role(RoleArn=role_name, RoleSessionName=str(uuid.uuid4()), DurationSeconds=900)
+
+    creds = response["Credentials"]
+
+
+    print(f"""{{
+  "AccessKeyId" : "{creds["AccessKeyId"]}",
+  "SecretAccessKey" : "{creds["SecretAccessKey"]}",
+  "SessionToken" : "{creds["SessionToken"]}",
+  "Expiration" : "{str(creds["Expiration"])}"
+}}""")
+
+
+def main() -> None:
+    """Execute Main entry point."""
+
+    parser = argparse.ArgumentParser(description='Assume Role frontend.')
+
+    parser.add_argument('-v', "--verbose", action='store_true', help="Enable verbose logging")
+    parser.add_argument('-d', "--debug", action='store_true', help="Enable debug logging")
+
+    parser.add_argument('--role_name', type=str, default=STS_DEFAULT_ROLE_NAME, help="Role to assume")
+
+    args = parser.parse_args()
+
+    if args.debug:
+        logging.basicConfig(level=logging.DEBUG)
+    elif args.verbose:
+        logging.basicConfig(level=logging.INFO)
+
+    _assume_role(args.role_name)
+
+
+if __name__ == "__main__":
+    main()
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/auth_aws/lib/aws_e2e_lib.js b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/auth_aws/lib/aws_e2e_lib.js
new file mode 100644
index 0000000000000000000000000000000000000000..d38471ac8ac46d55769a2af53d46867caf9a84d3
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/auth_aws/lib/aws_e2e_lib.js	
@@ -0,0 +1,39 @@
+
+function readSetupJson() {
+    let result;
+    try {
+        result = cat("aws_e2e_setup.json");
+    } catch (e) {
+        jsTestLog(
+            "Failed to parse read aws_e2e_setup.json. See evergreen.yml for how to generate this file which contains evergreen secrets.");
+        throw e;
+    }
+
+    try {
+        return JSON.parse(result);
+    } catch (e) {
+        jsTestLog("Failed to parse: aws_e2e_setup.json");
+        throw e;
+    }
+}
+
+function runWithEnv(args, env) {
+    const pid = _startMongoProgram({args: args, env: env});
+    return waitProgram(pid);
+}
+
+function runShellCmdWithEnv(argStr, env) {
+    if (_isWindows()) {
+        return runWithEnv(['cmd.exe', '/c', argStr], env);
+    } else {
+        return runWithEnv(['/bin/sh', '-c', argStr], env);
+    }
+}
+
+function getPython3Binary() {
+    if (_isWindows()) {
+        return "python.exe";
+    }
+
+    return "python3";
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/auth_aws/lib/container_tester.py b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/auth_aws/lib/container_tester.py
new file mode 100644
index 0000000000000000000000000000000000000000..eb3703c8fa6d6c5640fc401b0f70c78589412159
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/auth_aws/lib/container_tester.py	
@@ -0,0 +1,385 @@
+#!/usr/bin/env python3
+"""
+Script for testing mongodb in containers.
+
+Requires ssh, scp, and sh on local and remote hosts.
+Assumes remote host is Linux
+"""
+
+import argparse
+import datetime
+import logging
+import os
+import pprint
+import subprocess
+import uuid
+
+import boto3
+
+LOGGER = logging.getLogger(__name__)
+
+
+############################################################################
+# Default configuration settings for working with a ECS cluster in a region
+#
+
+# These settings depend on a cluster, task subnets, and security group already setup
+ECS_DEFAULT_CLUSTER = "arn:aws:ecs:us-east-2:579766882180:cluster/tf-mcb-ecs-cluster"
+ECS_DEFAULT_TASK_DEFINITION = "arn:aws:ecs:us-east-2:579766882180:task-definition/tf-app:2"
+ECS_DEFAULT_SUBNETS = ['subnet-a5e114cc']
+# Must allow ssh from 0.0.0.0
+ECS_DEFAULT_SECURITY_GROUP = 'sg-051a91d96332f8f3a'
+
+# This is just a string local to this file
+DEFAULT_SERVICE_NAME = 'script-test'
+
+# Garbage collection threshold for old/stale services
+DEFAULT_GARBAGE_COLLECTION_THRESHOLD = datetime.timedelta(hours=1)
+
+############################################################################
+
+
+def _run_process(params, cwd=None):
+    LOGGER.info("RUNNING COMMAND: %s", params)
+    ret = subprocess.run(params, cwd=cwd)
+    return ret.returncode
+
+def _userandhostandport(endpoint):
+    user_and_host = endpoint.find("@")
+    if user_and_host == -1:
+        raise ValueError("Invalid endpoint, Endpoint must be user@host:port")
+    (user, host) = (endpoint[:user_and_host], endpoint[user_and_host + 1:])
+
+    colon = host.find(":")
+    if colon == -1:
+        return (user, host, "22")
+    return (user, host[:colon], host[colon + 1:])
+
+def _scp(endpoint, src, dest):
+    (user, host, port) = _userandhostandport(endpoint)
+    cmd = ["scp", "-o", "StrictHostKeyChecking=no", "-P", port, src, "%s@%s:%s" % (user, host, dest)]
+    if os.path.isdir(src):
+       cmd.insert(5, "-r")
+    _run_process(cmd)
+
+def _ssh(endpoint, cmd):
+    (user, host, port) = _userandhostandport(endpoint)
+    cmd = ["ssh", "-o", "StrictHostKeyChecking=no", "-p", port, "%s@%s" % (user, host), cmd ]
+    ret = _run_process(cmd)
+    LOGGER.info("RETURN CODE: %s", ret)
+    return ret
+
+def _run_test_args(args):
+    run_test(args.endpoint, args.script, args.files)
+
+def run_test(endpoint, script, files):
+    """
+    Run a test on a machine
+
+    Steps
+    1. Copy over a files which are tuples of (src, dest)
+    2. Copy over the test script to "/tmp/test.sh"
+    3. Run the test script and return the results
+    """
+    LOGGER.info("Copying files to %s", endpoint)
+
+    for file in files:
+        colon = file.find(":")
+        (src, dest) = (file[:colon], file[colon + 1:])
+        _scp(endpoint, src, dest)
+
+    LOGGER.info("Copying script to %s", endpoint)
+    _scp(endpoint, script, "/tmp/test.sh")
+    return_code = _ssh(endpoint, "/bin/bash -x /tmp/test.sh")
+    if return_code != 0:
+        LOGGER.error("FAILED: %s", return_code)
+        raise ValueError(f"test failed with {return_code}")
+
+def _get_region(arn):
+    return arn.split(':')[3]
+
+
+def _remote_ps_container_args(args):
+    remote_ps_container(args.cluster)
+
+def remote_ps_container(cluster):
+    """
+    Get a list of task running in the cluster with their network addresses.
+
+    Emulates the docker ps and ecs-cli ps commands.
+    """
+    ecs_client = boto3.client('ecs', region_name=_get_region(cluster))
+    ec2_client = boto3.client('ec2', region_name=_get_region(cluster))
+
+    tasks = ecs_client.list_tasks(cluster=cluster)
+
+    task_list = ecs_client.describe_tasks(cluster=cluster, tasks=tasks['taskArns'])
+
+    #Example from ecs-cli tool
+    #Name                                       State    Ports                    TaskDefinition  Health
+    #aa2c2642-3013-4370-885e-8b8d956e753d/sshd  RUNNING  3.15.149.114:22->22/tcp  sshd:1          UNKNOWN
+
+    print("Name                                       State    Public IP                Private IP               TaskDefinition  Health")
+    for task in task_list['tasks']:
+
+        taskDefinition = task['taskDefinitionArn']
+        taskDefinition_short = taskDefinition[taskDefinition.rfind('/') + 1:]
+
+        private_ip_address = None
+        enis = []
+        for b in [ a['details'] for a in task["attachments"] if a['type'] == 'ElasticNetworkInterface']:
+            for c in b:
+                if c['name'] == 'networkInterfaceId':
+                    enis.append(c['value'])
+                elif c['name'] == 'privateIPv4Address':
+                    private_ip_address = c['value']
+        assert enis
+        assert private_ip_address
+
+        eni = ec2_client.describe_network_interfaces(NetworkInterfaceIds=enis)
+        public_ip = [n["Association"]["PublicIp"] for n in eni["NetworkInterfaces"]][0]
+
+        for container in task['containers']:
+            taskArn = container['taskArn']
+            task_id = taskArn[taskArn.rfind('/')+ 1:]
+            name = container['name']
+            task_id = task_id + "/" + name
+            lastStatus = container['lastStatus']
+
+        print("{:<43}{:<9}{:<25}{:<25}{:<16}".format(task_id, lastStatus, public_ip, private_ip_address, taskDefinition_short ))
+
+def _remote_create_container_args(args):
+    remote_create_container(args.cluster, args.task_definition, args.service, args.subnets, args.security_group)
+
+def remote_create_container(cluster, task_definition, service_name, subnets, security_group):
+    """
+    Create a task in ECS
+    """
+    ecs_client = boto3.client('ecs', region_name=_get_region(cluster))
+
+    resp = ecs_client.create_service(cluster=cluster, serviceName=service_name,
+        taskDefinition = task_definition,
+        desiredCount = 1,
+        launchType='FARGATE',
+        networkConfiguration={
+            'awsvpcConfiguration': {
+                'subnets': subnets,
+                'securityGroups': [
+                    security_group,
+                ],
+                'assignPublicIp': "ENABLED"
+            }
+        }
+        )
+
+    pprint.pprint(resp)
+
+    service_arn = resp["service"]["serviceArn"]
+    print(f"Waiting for Service {service_arn} to become active...")
+
+    waiter = ecs_client.get_waiter('services_stable')
+
+    waiter.wait(cluster=cluster, services=[service_arn])
+
+def _remote_stop_container_args(args):
+    remote_stop_container(args.cluster, args.service)
+
+def remote_stop_container(cluster, service_name):
+    """
+    Stop a ECS task
+    """
+    ecs_client = boto3.client('ecs', region_name=_get_region(cluster))
+
+    resp = ecs_client.delete_service(cluster=cluster, service=service_name, force=True)
+    pprint.pprint(resp)
+
+    service_arn = resp["service"]["serviceArn"]
+
+    print(f"Waiting for Service {service_arn} to become inactive...")
+    waiter = ecs_client.get_waiter('services_inactive')
+
+    waiter.wait(cluster=cluster, services=[service_arn])
+
+def _remote_gc_services_container_args(args):
+    remote_gc_services_container(args.cluster)
+
+def remote_gc_services_container(cluster):
+    """
+    Delete all ECS services over then a given treshold.
+    """
+    ecs_client = boto3.client('ecs', region_name=_get_region(cluster))
+
+    services = ecs_client.list_services(cluster=cluster)
+    if not services["serviceArns"]:
+        return
+
+    services_details = ecs_client.describe_services(cluster=cluster, services=services["serviceArns"])
+
+    not_expired_now = datetime.datetime.now().astimezone() - DEFAULT_GARBAGE_COLLECTION_THRESHOLD
+
+    for service in services_details["services"]:
+        created_at = service["createdAt"]
+
+        # Find the services that we created "too" long ago
+        if created_at < not_expired_now:
+            print("DELETING expired service %s which was created at %s." % (service["serviceName"], created_at))
+
+            remote_stop_container(cluster, service["serviceName"])
+
+def remote_get_public_endpoint_str(cluster, service_name):
+    """
+    Get an SSH connection string for the remote service via the public ip address
+    """
+    ecs_client = boto3.client('ecs', region_name=_get_region(cluster))
+    ec2_client = boto3.client('ec2', region_name=_get_region(cluster))
+
+    tasks = ecs_client.list_tasks(cluster=cluster, serviceName=service_name)
+
+    task_list = ecs_client.describe_tasks(cluster=cluster, tasks=tasks['taskArns'])
+
+    for task in task_list['tasks']:
+
+        enis = []
+        for b in [ a['details'] for a in task["attachments"] if a['type'] == 'ElasticNetworkInterface']:
+            for c in b:
+                if c['name'] == 'networkInterfaceId':
+                    enis.append(c['value'])
+        assert enis
+
+        eni = ec2_client.describe_network_interfaces(NetworkInterfaceIds=enis)
+        public_ip = [n["Association"]["PublicIp"] for n in eni["NetworkInterfaces"]][0]
+        break
+
+    return f"root@{public_ip}:22"
+
+def remote_get_endpoint_str(cluster, service_name):
+    """
+    Get an SSH connection string for the remote service via the private ip address
+    """
+    ecs_client = boto3.client('ecs', region_name=_get_region(cluster))
+
+    tasks = ecs_client.list_tasks(cluster=cluster, serviceName=service_name)
+
+    task_list = ecs_client.describe_tasks(cluster=cluster, tasks=tasks['taskArns'])
+
+    for task in task_list['tasks']:
+
+        private_ip_address = None
+        for b in [ a['details'] for a in task["attachments"] if a['type'] == 'ElasticNetworkInterface']:
+            for c in b:
+                if c['name'] == 'privateIPv4Address':
+                    private_ip_address = c['value']
+        assert private_ip_address
+        break
+
+    return f"root@{private_ip_address}:22"
+
+def _remote_get_endpoint_args(args):
+    _remote_get_endpoint(args.cluster, args.service)
+
+def _remote_get_endpoint(cluster, service_name):
+    endpoint = remote_get_endpoint_str(cluster, service_name)
+    print(endpoint)
+
+def _get_caller_identity(args):
+    sts_client = boto3.client('sts')
+
+    pprint.pprint(sts_client.get_caller_identity())
+
+
+def _run_e2e_test_args(args):
+    _run_e2e_test(args.script, args.files, args.cluster, args.task_definition, args.subnets, args.security_group)
+
+def _run_e2e_test(script, files, cluster, task_definition, subnets, security_group):
+    """
+    Run a test end-to-end
+
+    1. Start an ECS service
+    2. Copy the files over and run the test
+    3. Stop the ECS service
+    """
+    service_name = str(uuid.uuid4())
+
+    remote_create_container(cluster, task_definition, service_name, subnets, security_group)
+
+    # The build account hosted ECS tasks are only available via the private ip address
+    endpoint = remote_get_endpoint_str(cluster, service_name)
+    if cluster == ECS_DEFAULT_CLUSTER:
+        # The test account hosted ECS tasks are the opposite, only public ip address access
+        endpoint = remote_get_public_endpoint_str(cluster, service_name)
+
+    try:
+        run_test(endpoint, script, files)
+    finally:
+        remote_stop_container(cluster, service_name)
+
+
+def main() -> None:
+    """Execute Main entry point."""
+
+    parser = argparse.ArgumentParser(description='ECS container tester.')
+
+    parser.add_argument('-v', "--verbose", action='store_true', help="Enable verbose logging")
+    parser.add_argument('-d', "--debug", action='store_true', help="Enable debug logging")
+
+    sub = parser.add_subparsers(title="Container Tester subcommands", help="sub-command help")
+
+    run_test_cmd = sub.add_parser('run_test', help='Run Test')
+    run_test_cmd.add_argument("--endpoint", required=True, type=str, help="User and Host and port, ie user@host:port")
+    run_test_cmd.add_argument("--script", required=True, type=str, help="script to run")
+    run_test_cmd.add_argument("--files", type=str, nargs="*", help="Files to copy, each string must be a pair of src:dest joined by a colon")
+    run_test_cmd.set_defaults(func=_run_test_args)
+
+    remote_ps_cmd = sub.add_parser('remote_ps', help='Stop Local Container')
+    remote_ps_cmd.add_argument("--cluster", type=str, default=ECS_DEFAULT_CLUSTER, help="ECS Cluster to target")
+    remote_ps_cmd.set_defaults(func=_remote_ps_container_args)
+
+    remote_create_cmd = sub.add_parser('remote_create', help='Create Remote Container')
+    remote_create_cmd.add_argument("--cluster", type=str, default=ECS_DEFAULT_CLUSTER, help="ECS Cluster to target")
+    remote_create_cmd.add_argument("--service", type=str, default=DEFAULT_SERVICE_NAME, help="ECS Service to create")
+    remote_create_cmd.add_argument("--task_definition", type=str, default=ECS_DEFAULT_TASK_DEFINITION, help="ECS Task Definition to use to create service")
+    remote_create_cmd.add_argument("--subnets", type=str, nargs="*", default=ECS_DEFAULT_SUBNETS, help="EC2 subnets to use")
+    remote_create_cmd.add_argument("--security_group", type=str, default=ECS_DEFAULT_SECURITY_GROUP, help="EC2 security group use")
+    remote_create_cmd.set_defaults(func=_remote_create_container_args)
+
+    remote_stop_cmd = sub.add_parser('remote_stop', help='Stop Remote Container')
+    remote_stop_cmd.add_argument("--cluster", type=str, default=ECS_DEFAULT_CLUSTER, help="ECS Cluster to target")
+    remote_stop_cmd.add_argument("--service", type=str, default=DEFAULT_SERVICE_NAME, help="ECS Service to stop")
+    remote_stop_cmd.set_defaults(func=_remote_stop_container_args)
+
+    remote_gc_services_cmd = sub.add_parser('remote_gc_services', help='GC Remote Container')
+    remote_gc_services_cmd.add_argument("--cluster", type=str, default=ECS_DEFAULT_CLUSTER, help="ECS Cluster to target")
+    remote_gc_services_cmd.set_defaults(func=_remote_gc_services_container_args)
+
+    get_caller_identity_cmd = sub.add_parser('get_caller_identity', help='Get the AWS IAM caller identity')
+    get_caller_identity_cmd.set_defaults(func=_get_caller_identity)
+
+    remote_get_endpoint_cmd = sub.add_parser('remote_get_endpoint', help='Get SSH remote endpoint')
+    remote_get_endpoint_cmd.add_argument("--cluster", type=str, default=ECS_DEFAULT_CLUSTER, help="ECS Cluster to target")
+    remote_get_endpoint_cmd.add_argument("--service", type=str, default=DEFAULT_SERVICE_NAME, help="ECS Service to stop")
+    remote_get_endpoint_cmd.set_defaults(func=_remote_get_endpoint_args)
+
+    run_e2e_test_cmd = sub.add_parser('run_e2e_test', help='Run Test')
+    run_e2e_test_cmd.add_argument("--script", required=True, type=str, help="script to run")
+    run_e2e_test_cmd.add_argument("--files", type=str, nargs="*", help="Files to copy, each string must be a pair of src:dest joined by a colon")
+    run_e2e_test_cmd.add_argument("--cluster", type=str, default=ECS_DEFAULT_CLUSTER, help="ECS Cluster to target")
+    run_e2e_test_cmd.add_argument("--task_definition", type=str, default=ECS_DEFAULT_TASK_DEFINITION, help="ECS Task Definition to use to create service")
+    run_e2e_test_cmd.add_argument("--subnets", type=str, nargs="*", default=ECS_DEFAULT_SUBNETS, help="EC2 subnets to use")
+    run_e2e_test_cmd.add_argument("--security_group", type=str, default=ECS_DEFAULT_SECURITY_GROUP, help="EC2 security group use")
+    run_e2e_test_cmd.set_defaults(func=_run_e2e_test_args)
+
+    args = parser.parse_args()
+
+    print("AWS_SHARED_CREDENTIALS_FILE: %s" % (os.getenv("AWS_SHARED_CREDENTIALS_FILE")))
+
+    if args.debug:
+        logging.basicConfig(level=logging.DEBUG)
+    elif args.verbose:
+        logging.basicConfig(level=logging.INFO)
+
+
+    args.func(args)
+
+
+if __name__ == "__main__":
+    main()
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/auth_aws/lib/ecs_hosted_test.js b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/auth_aws/lib/ecs_hosted_test.js
new file mode 100644
index 0000000000000000000000000000000000000000..17d4b3703b86470dab61438f70cb8c6ffd8202f1
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/auth_aws/lib/ecs_hosted_test.js	
@@ -0,0 +1,37 @@
+/**
+ * Verify the AWS IAM ECS hosted auth works
+ */
+
+(function() {
+"use strict";
+
+// This varies based on hosting ECS task as the account id and role name can vary
+const AWS_ACCOUNT_ARN = "arn:aws:sts::557821124784:assumed-role/ecsTaskExecutionRole/*";
+
+const conn = MongoRunner.runMongod({
+    setParameter: {
+        "authenticationMechanisms": "MONGODB-AWS,SCRAM-SHA-256",
+    },
+    auth: "",
+});
+
+const external = conn.getDB("$external");
+const admin = conn.getDB("admin");
+
+assert.commandWorked(admin.runCommand({createUser: "admin", pwd: "pwd", roles: ['root']}));
+assert(admin.auth("admin", "pwd"));
+
+assert.commandWorked(external.runCommand({createUser: AWS_ACCOUNT_ARN, roles:[{role: 'read', db: "aws"}]}));
+
+const uri = "mongodb://127.0.0.1:20000/aws?authMechanism=MONGODB-AWS";
+const program = "/root/src/.evergreen/run-mongodb-aws-ecs-test.sh";
+
+// Try the command line
+const smoke = runMongoProgram(program, uri);
+assert.eq(smoke, 0, "Could not auth with smoke user");
+
+// Try the auth function
+assert(external.auth({mechanism: 'MONGODB-AWS'}));
+
+MongoRunner.stopMongod(conn);
+}());
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/auth_aws/lib/ecs_hosted_test.sh b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/auth_aws/lib/ecs_hosted_test.sh
new file mode 100644
index 0000000000000000000000000000000000000000..7dddbc80b19ad9f3bfe9520236fb26da3106b19e
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/auth_aws/lib/ecs_hosted_test.sh	
@@ -0,0 +1,16 @@
+#!/bin/bash
+# A shell script to run in an ECS hosted task
+
+# The environment variable is always set during interactive logins
+# But for non-interactive logs, ~/.bashrc does not appear to be read on Ubuntu but it works on Fedora
+[[ -z "${AWS_CONTAINER_CREDENTIALS_RELATIVE_URI}" ]] && export $(strings /proc/1/environ | grep AWS_CONTAINER_CREDENTIALS_RELATIVE_URI)
+
+env
+
+mkdir -p /data/db || true
+
+/root/mongo  --verbose --nodb ecs_hosted_test.js
+
+RET_CODE=$?
+echo RETURN CODE: $RET_CODE
+exit $RET_CODE
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/compile-unix.sh b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/compile-unix.sh
new file mode 100644
index 0000000000000000000000000000000000000000..7591c3241a74fad3cf8a5e4e0a092508a6db2523
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/compile-unix.sh	
@@ -0,0 +1,67 @@
+#!/bin/sh
+set -o xtrace   # Write all commands first to stderr
+set -o errexit  # Exit the script with error if any of the commands fail
+
+# Supported/used environment variables:
+#       MARCH                   Machine Architecture. Defaults to lowercase uname -m
+#       RELEASE                 Use the fully qualified release archive
+
+RELEASE=${RELEASE:-no}
+
+
+# Automatically retrieve the machine architecture, lowercase, unless provided
+# as an environment variable (e.g. to force 32bit)
+[ -z "$MARCH" ] && MARCH=$(uname -m | tr '[:upper:]' '[:lower:]')
+
+# Get the kernel name, lowercased
+OS=$(uname -s | tr '[:upper:]' '[:lower:]')
+echo "OS: $OS"
+
+# --strip-components is an GNU tar extension. Check if the platform
+# (e.g. Solaris) has GNU tar installed as `gtar`, otherwise we assume to be on
+# platform that supports it
+# command -v returns success error code if found and prints the path to it
+if command -v gtar 2>/dev/null; then
+   TAR=gtar
+else
+   TAR=tar
+fi
+
+# Any architecture specific configuration here
+case "$MARCH" in
+   i386)
+      CFLAGS="$CFLAGS -m32 -march=i386"
+   ;;
+   x86_64)
+      CFLAGS="$CFLAGS -m64 -march=x86-64"
+   ;;
+   ppc64le)
+      CFLAGS="$CFLAGS -mcpu=power8 -mtune=power8 -mcmodel=medium"
+   ;;
+esac
+
+
+# Operating system specific tweaks
+case "$OS" in
+   darwin)
+   ;;
+
+   linux)
+      # Make linux builds a tad faster by parallelise the build
+      cpus=$(grep -c '^processor' /proc/cpuinfo)
+      MAKEFLAGS="-j${cpus}"
+   ;;
+
+   sunos)
+      # Most normal build tools on the Solaris servers lives here
+      PATH="/opt/mongodbtoolchain/bin:$PATH"
+   ;;
+esac
+
+echo "MARCH: $MARCH"
+echo "RELEASE: $RELEASE"
+echo "OS: $OS"
+
+
+#./configure
+make
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/compile-windows.sh b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/compile-windows.sh
new file mode 100644
index 0000000000000000000000000000000000000000..33349bb34bba6c7bb12ea12d78eb6d70fcf2d2af
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/compile-windows.sh	
@@ -0,0 +1,49 @@
+#!/bin/sh
+set -o igncr    # Ignore CR in this script
+set -o xtrace   # Write all commands first to stderr
+set -o errexit  # Exit the script with error if any of the commands fail
+
+# Supported/used environment variables:
+#       CC            Which compiler to use
+
+
+case "$CC" in
+   # 64bit specific configuration
+   *Win64)
+   ;;
+   # 32bit specific configuration
+   *)
+   ;;
+esac
+
+# Resolve the compiler name to correct MSBuild location
+case "$CC" in
+   "Visual Studio 10 2010")
+      BUILD="/cygdrive/c/Windows/Microsoft.NET/Framework/v4.0.30319/MSBuild.exe"
+   ;;
+   "Visual Studio 10 2010 Win64")
+      BUILD="/cygdrive/c/Windows/Microsoft.NET/Framework64/v4.0.30319/MSBuild.exe"
+   ;;
+   "Visual Studio 12 2013")
+      BUILD="/cygdrive/c/Program Files (x86)/MSBuild/12.0/Bin/MSBuild.exe"
+   ;;
+   "Visual Studio 12 2013 Win64")
+      BUILD="/cygdrive/c/Program Files (x86)/MSBuild/12.0/Bin/MSBuild.exe"
+   ;;
+   "Visual Studio 14 2015")
+      BUILD="/cygdrive/c/Program Files (x86)/MSBuild/14.0/Bin/MSBuild.exe"
+   ;;
+   "Visual Studio 14 2015 Win64")
+      BUILD="/cygdrive/c/Program Files (x86)/MSBuild/14.0/Bin/MSBuild.exe"
+   ;;
+esac
+
+export PATH=$PATH:`pwd`/tests:`pwd`/Debug:`pwd`/src/libbson/Debug
+CMAKE="/cygdrive/c/cmake/bin/cmake"
+INSTALL_DIR="C:/install-dir"
+
+
+"$CMAKE" -G "$CC" "-DCMAKE_INSTALL_PREFIX=${INSTALL_DIR}" "-DBSON_ROOT_DIR=${INSTALL_DIR}" $CONFIGURE_FLAGS
+"$BUILD" /m ALL_BUILD.vcxproj
+"$BUILD" /m INSTALL.vcxproj
+
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/compile.sh b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/compile.sh
new file mode 100644
index 0000000000000000000000000000000000000000..8b7820e9989c4fd2d340f45d800935b9bdb2c2aa
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/compile.sh	
@@ -0,0 +1,30 @@
+#!/bin/sh
+set -o xtrace   # Write all commands first to stderr
+set -o errexit  # Exit the script with error if any of the commands fail
+
+
+DIR=$(dirname $0)
+
+OS=$(uname -s | tr '[:upper:]' '[:lower:]')
+BUILDTOOL=${BUILDTOOL:-autotools}
+
+case "$OS" in
+   cygwin*)
+      sh $DIR/compile-windows.sh
+   ;;
+
+   *)
+      # If compiling using multiple different build tools or variants
+      # that require wildly different scripting,
+      # this would be a good place to call the different scripts
+      case "$BUILDTOOL" in
+         cmake)
+            sh $DIR/compile-unix-cmake.sh
+         ;;
+         autotools)
+            sh $DIR/compile-unix.sh
+         ;;
+      esac
+   ;;
+esac
+
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/config.yml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/config.yml
new file mode 100644
index 0000000000000000000000000000000000000000..2755f9966493bd322c207b89f02864cf4a03d15e
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/config.yml	
@@ -0,0 +1,594 @@
+########################################
+# Evergreen Template for MongoDB Drivers
+########################################
+
+# When a task that used to pass starts to fail
+# Go through all versions that may have been skipped to detect
+# when the task started failing
+stepback: true
+
+# Mark a failure as a system/bootstrap failure (purple box) rather then a task
+# failure by default.
+# Actual testing tasks are marked with `type: test`
+command_type: system
+
+# Protect ourself against rogue test case, or curl gone wild, that runs forever
+# Good rule of thumb: the averageish length a task takes, times 5
+# That roughly accounts for variable system performance for various buildvariants
+exec_timeout_secs: 1800 # 6 minutes is the longest we'll ever run
+
+# What to do when evergreen hits the timeout (`post:` tasks are run automatically)
+timeout:
+  - command: shell.exec
+    params:
+      script: |
+        ls -la
+
+functions:
+  "fetch source":
+    # Executes git clone and applies the submitted patch, if any
+    - command: git.get_project
+      params:
+        directory: "src"
+    # Make an evergreen exapanstion file with dynamic values
+    - command: shell.exec
+      params:
+        working_dir: "src"
+        script: |
+           # Get the current unique version of this checkout
+           if [ "${is_patch}" = "true" ]; then
+              CURRENT_VERSION=$(git describe)-patch-${version_id}
+           else
+              CURRENT_VERSION=latest
+           fi
+
+           export DRIVERS_TOOLS="$(pwd)/../drivers-tools"
+           export PROJECT_DIRECTORY="$(pwd)"
+
+           # Python has cygwin path problems on Windows. Detect prospective mongo-orchestration home directory
+           if [ "Windows_NT" = "$OS" ]; then # Magic variable in cygwin
+              export DRIVERS_TOOLS=$(cygpath -m $DRIVERS_TOOLS)
+              export PROJECT_DIRECTORY=$(cygpath -m $PROJECT_DIRECTORY)
+           fi
+
+           export MONGO_ORCHESTRATION_HOME="$DRIVERS_TOOLS/.evergreen/orchestration"
+           export MONGODB_BINARIES="$DRIVERS_TOOLS/mongodb/bin"
+           export UPLOAD_BUCKET="${project}"
+
+           cat <<EOT > expansion.yml
+           CURRENT_VERSION: "$CURRENT_VERSION"
+           DRIVERS_TOOLS: "$DRIVERS_TOOLS"
+           MONGO_ORCHESTRATION_HOME: "$MONGO_ORCHESTRATION_HOME"
+           MONGODB_BINARIES: "$MONGODB_BINARIES"
+           UPLOAD_BUCKET: "$UPLOAD_BUCKET"
+           PROJECT_DIRECTORY: "$PROJECT_DIRECTORY"
+           PREPARE_SHELL: |
+              set -o errexit
+              set -o xtrace
+              export DRIVERS_TOOLS="$DRIVERS_TOOLS"
+              export MONGO_ORCHESTRATION_HOME="$MONGO_ORCHESTRATION_HOME"
+              export MONGODB_BINARIES="$MONGODB_BINARIES"
+              export UPLOAD_BUCKET="$UPLOAD_BUCKET"
+              export PROJECT_DIRECTORY="$PROJECT_DIRECTORY"
+
+              export TMPDIR="$MONGO_ORCHESTRATION_HOME/db"
+              export PATH="$MONGODB_BINARIES:$PATH"
+              export PROJECT="${project}"
+           EOT
+           # See what we've done
+           cat expansion.yml
+
+    # Load the expansion file to make an evergreen variable with the current unique version
+    - command: expansions.update
+      params:
+        file: src/expansion.yml
+
+  "prepare resources":
+    - command: shell.exec
+      params:
+        script: |
+          ${PREPARE_SHELL}
+          rm -rf $DRIVERS_TOOLS
+          if [ "${project}" = "drivers-tools" ]; then
+            # If this was a patch build, doing a fresh clone would not actually test the patch
+            cp -R ${PROJECT_DIRECTORY}/ $DRIVERS_TOOLS
+          else
+            git clone git://github.com/mongodb-labs/drivers-evergreen-tools.git $DRIVERS_TOOLS
+          fi
+          echo "{ \"releases\": { \"default\": \"$MONGODB_BINARIES\" }}" > $MONGO_ORCHESTRATION_HOME/orchestration.config
+
+  "upload mo artifacts":
+    - command: shell.exec
+      params:
+        script: |
+          ${PREPARE_SHELL}
+          find $MONGO_ORCHESTRATION_HOME -name \*.log | xargs tar czf mongodb-logs.tar.gz
+    - command: s3.put
+      params:
+        aws_key: ${aws_key}
+        aws_secret: ${aws_secret}
+        local_file: mongodb-logs.tar.gz
+        remote_file: ${UPLOAD_BUCKET}/${build_variant}/${revision}/${version_id}/${build_id}/logs/${task_id}-${execution}-mongodb-logs.tar.gz
+        bucket: mciuploads
+        permissions: public-read
+        content_type: ${content_type|application/x-gzip}
+        display_name: "mongodb-logs.tar.gz"
+    - command: s3.put
+      params:
+        aws_key: ${aws_key}
+        aws_secret: ${aws_secret}
+        local_file: ${DRIVERS_TOOLS}/.evergreen/orchestration/server.log
+        remote_file: ${UPLOAD_BUCKET}/${build_variant}/${revision}/${version_id}/${build_id}/logs/${task_id}-${execution}-orchestration.log
+        bucket: mciuploads
+        permissions: public-read
+        content_type: ${content_type|text/plain}
+        display_name: "orchestration.log"
+
+  "upload working dir":
+    - command: archive.targz_pack
+      params:
+        target: "working-dir.tar.gz"
+        source_dir: ${PROJECT_DIRECTORY}/
+        include:
+          - "./**"
+    - command: s3.put
+      params:
+        aws_key: ${aws_key}
+        aws_secret: ${aws_secret}
+        local_file: working-dir.tar.gz
+        remote_file: ${UPLOAD_BUCKET}/${build_variant}/${revision}/${version_id}/${build_id}/artifacts/${task_id}-${execution}-working-dir.tar.gz
+        bucket: mciuploads
+        permissions: public-read
+        content_type: ${content_type|application/x-gzip}
+        display_name: "working-dir.tar.gz"
+    - command: archive.targz_pack
+      params:
+        target: "drivers-dir.tar.gz"
+        source_dir: ${DRIVERS_TOOLS}
+        include:
+          - "./**"
+        exclude_files:
+          # Windows cannot read the mongod *.lock files because they are locked.
+          - "*.lock"
+    - command: s3.put
+      params:
+        aws_key: ${aws_key}
+        aws_secret: ${aws_secret}
+        local_file: drivers-dir.tar.gz
+        remote_file: ${UPLOAD_BUCKET}/${build_variant}/${revision}/${version_id}/${build_id}/artifacts/${task_id}-${execution}-drivers-dir.tar.gz
+        bucket: mciuploads
+        permissions: public-read
+        content_type: ${content_type|application/x-gzip}
+        display_name: "drivers-dir.tar.gz"
+
+  "upload test results":
+    - command: attach.xunit_results
+      params:
+        file: "${PROJECT_DIRECTORY}/test-results.xml"
+    - command: attach.results
+      params:
+        file_location: "${DRIVERS_TOOLS}/results.json"
+
+  "bootstrap mongo-orchestration":
+    - command: shell.exec
+      params:
+        script: |
+          ${PREPARE_SHELL}
+          MONGODB_VERSION=${VERSION} ORCHESTRATION_FILE=${ORCHESTRATION_FILE} TOPOLOGY=${TOPOLOGY} AUTH=${AUTH} SSL=${SSL} STORAGE_ENGINE=${STORAGE_ENGINE} sh ${PROJECT_DIRECTORY}/.evergreen/run-orchestration.sh
+    # run-orchestration generates expansion file with the MONGODB_URI for the cluster
+    - command: expansions.update
+      params:
+        file: mo-expansion.yml
+
+  "stop mongo-orchestration":
+    - command: shell.exec
+      params:
+        script: |
+          ${PREPARE_SHELL}
+          sh ${DRIVERS_TOOLS}/.evergreen/stop-orchestration.sh
+
+  "bootstrap mongohoused":
+    - command: shell.exec
+      params:
+        script: |
+          DRIVERS_TOOLS="${DRIVERS_TOOLS}" sh ${DRIVERS_TOOLS}/.evergreen/atlas_data_lake/build-mongohouse-local.sh
+    - command: shell.exec
+      params:
+        background: true
+        script: |
+          DRIVERS_TOOLS="${DRIVERS_TOOLS}" sh ${DRIVERS_TOOLS}/.evergreen/atlas_data_lake/run-mongohouse-local.sh
+
+  "run tests":
+    - command: shell.exec
+      type: test
+      params:
+        working_dir: "src"
+        script: |
+          ${PREPARE_SHELL}
+          PHP_VERSION=${PHP_VERSION} AUTH=${AUTH} SSL=${SSL} MONGODB_URI="${MONGODB_URI}" sh ${PROJECT_DIRECTORY}/.evergreen/run-tests.sh
+
+  "run atlas data lake test":
+     - command: shell.exec
+       type: test
+       params:
+         working_dir: "src"
+         script: |
+           ${PREPARE_SHELL}
+           PHP_VERSION=${PHP_VERSION} TESTS="atlas-data-lake" AUTH=${AUTH} SSL=${SSL} MONGODB_URI="${MONGODB_URI}" sh ${PROJECT_DIRECTORY}/.evergreen/run-tests.sh
+
+  "cleanup":
+    - command: shell.exec
+      params:
+        script: |
+          ${PREPARE_SHELL}
+          rm -rf $DRIVERS_TOOLS || true
+
+  "fix absolute paths":
+    - command: shell.exec
+      params:
+        script: |
+          ${PREPARE_SHELL}
+          for filename in $(find ${DRIVERS_TOOLS} -name \*.json); do
+            perl -p -i -e "s|ABSOLUTE_PATH_REPLACEMENT_TOKEN|${DRIVERS_TOOLS}|g" $filename
+          done
+
+  "windows fix":
+    - command: shell.exec
+      params:
+        script: |
+          ${PREPARE_SHELL}
+          for i in $(find ${DRIVERS_TOOLS}/.evergreen ${PROJECT_DIRECTORY}/.evergreen -name \*.sh); do
+            cat $i | tr -d '\r' > $i.new
+            mv $i.new $i
+          done
+          # Copy client certificate because symlinks do not work on Windows.
+          cp ${DRIVERS_TOOLS}/.evergreen/x509gen/client.pem ${MONGO_ORCHESTRATION_HOME}/lib/client.pem
+
+  "make files executable":
+    - command: shell.exec
+      params:
+        script: |
+          ${PREPARE_SHELL}
+          for i in $(find ${DRIVERS_TOOLS}/.evergreen ${PROJECT_DIRECTORY}/.evergreen -name \*.sh); do
+            chmod +x $i
+          done
+
+  "install dependencies":
+    - command: shell.exec
+      params:
+        working_dir: "src"
+        script: |
+          ${PREPARE_SHELL}
+          file="${PROJECT_DIRECTORY}/.evergreen/install-dependencies.sh"
+          # Don't use ${file} syntax here because evergreen treats it as an empty expansion.
+          [ -f "$file" ] && PHP_VERSION=${PHP_VERSION} DRIVER_VERSION=${DRIVER_VERSION} DRIVER_REPO=${DRIVER_REPO} DRIVER_BRANCH=${DRIVER_BRANCH} DEPENDENCIES=${DEPENDENCIES} sh $file || echo "$file not available, skipping"
+
+pre:
+  - func: "fetch source"
+  - func: "prepare resources"
+  - func: "windows fix"
+  - func: "fix absolute paths"
+  - func: "make files executable"
+  - func: "install dependencies"
+
+post:
+  # Skip: uploading the full working directory is not needed by drivers-evergreen-tools.
+  # - func: "upload working dir"
+  - func: "upload mo artifacts"
+  - func: "upload test results"
+  - func: "stop mongo-orchestration"
+  - func: "cleanup"
+
+tasks:
+
+    # Wildcard task. Do you need to find out what tools are available and where?
+    # Throw it here, and execute this task on all buildvariants
+    - name: getdata
+      commands:
+        - command: shell.exec
+          type: test
+          params:
+            script: |
+               set -o xtrace
+               . ${DRIVERS_TOOLS}/.evergreen/download-mongodb.sh || true
+               get_distro || true
+               echo $DISTRO
+               echo $MARCH
+               echo $OS
+               uname -a || true
+               ls /etc/*release* || true
+               cc --version || true
+               gcc --version || true
+               clang --version || true
+               gcov --version || true
+               lcov --version || true
+               llvm-cov --version || true
+               echo $PATH
+               ls -la /usr/local/Cellar/llvm/*/bin/ || true
+               ls -la /usr/local/Cellar/ || true
+               scan-build --version || true
+               genhtml --version || true
+               valgrind --version || true
+
+
+# Standard test tasks {{{
+
+    - name: "test-standalone"
+      tags: ["standalone"]
+      commands:
+        - func: "bootstrap mongo-orchestration"
+          vars:
+            TOPOLOGY: "server"
+        - func: "run tests"
+
+    - name: "test-replica_set"
+      tags: ["replica_set"]
+      commands:
+        - func: "bootstrap mongo-orchestration"
+          vars:
+            TOPOLOGY: "replica_set"
+        - func: "run tests"
+
+    - name: "test-sharded_cluster"
+      tags: ["sharded_cluster"]
+      commands:
+        - func: "bootstrap mongo-orchestration"
+          vars:
+            TOPOLOGY: "sharded_cluster"
+        - func: "run tests"
+
+    - name: "test-atlas-data-lake"
+      commands:
+        - func: "bootstrap mongohoused"
+        - func: "run atlas data lake test"
+
+
+# }}}
+
+
+axes:
+  - id: php-versions
+    display_name: PHP Version
+    values:
+      - id: "7.4"
+        display_name: "7.4"
+        variables:
+          PHP_VERSION: "7.4.7"
+      - id: "7.3"
+        display_name: "7.3"
+        variables:
+          PHP_VERSION: "7.3.8"
+      - id: "7.2"
+        display_name: "7.2"
+        variables:
+          PHP_VERSION: "7.2.21"
+      - id: "7.1"
+        display_name: "7.1"
+        variables:
+          PHP_VERSION: "7.1.31"
+      - id: "7.0"
+        display_name: "7.0"
+        variables:
+          PHP_VERSION: "7.0.32"
+
+  - id: php-edge-versions
+    display_name: PHP Version
+    values:
+      - id: "latest-stable"
+        display_name: "7.4"
+        variables:
+          PHP_VERSION: "7.4.7"
+      - id: "oldest-supported"
+        display_name: "7.0"
+        variables:
+          PHP_VERSION: "7.0.32"
+
+  - id: versions
+    display_name: MongoDB Version
+    values:
+      - id: "latest"
+        display_name: "latest"
+        variables:
+           VERSION: "latest"
+      - id: "4.4"
+        display_name: "4.4"
+        variables:
+           VERSION: "4.4"
+      - id: "4.2"
+        display_name: "4.2"
+        variables:
+           VERSION: "4.2"
+      - id: "4.0"
+        display_name: "4.0"
+        variables:
+           VERSION: "4.0"
+      - id: "3.6"
+        display_name: "3.6"
+        variables:
+           VERSION: "3.6"
+      - id: "3.4"
+        display_name: "3.4"
+        variables:
+           VERSION: "3.4"
+      - id: "3.2"
+        display_name: "3.2"
+        variables:
+           VERSION: "3.2"
+      - id: "3.0"
+        display_name: "3.0"
+        variables:
+           VERSION: "3.0"
+
+  - id: edge-versions
+    display_name: MongoDB Version
+    values:
+      - id: "latest-stable"
+        display_name: "4.4"
+        variables:
+          VERSION: "4.4"
+      - id: "oldest-supported"
+        display_name: "3.0"
+        variables:
+          VERSION: "3.0"
+
+  - id: driver-versions
+    display_name: Driver Version
+    values:
+      - id: "lowest-supported"
+        display_name: "1.8.1"
+        variables:
+          DRIVER_VERSION: "1.8.1"
+      - id: "latest-stable"
+        display_name: "1.9-stable"
+        variables:
+          DRIVER_VERSION: "stable"
+      - id: "1.8-dev"
+        display_name: "1.8-dev"
+        variables:
+          DRIVER_BRANCH: "v1.8"
+      - id: "1.9-dev"
+        display_name: "1.9-dev"
+        variables:
+          DRIVER_BRANCH: "v1.9"
+      - id: "latest-dev"
+        display_name: "1.10-dev (master)"
+        variables:
+          DRIVER_BRANCH: "master"
+
+  - id: os-php7
+    display_name: OS
+    values:
+      - id: debian92-test
+        display_name: "Debian 9.2"
+        run_on: debian92-test
+      - id: rhel70-test
+        display_name: "RHEL 7.0"
+        run_on: rhel70
+      - id: rhel71-power8
+        display_name: "RHEL 7.1 Power 8"
+        run_on: rhel71-power8-test
+      - id: rhel74-zseries
+        display_name: "RHEL 7.4 zSeries"
+        run_on: rhel74-zseries-test
+      - id: ubuntu1804-arm64-test
+        display_name: "Ubuntu 18.04 ARM64"
+        run_on: ubuntu1804-arm64-test
+
+  - id: topology
+    display_name: Topology
+    values:
+      - id: standalone
+        display_name: Standalone
+        variables:
+           TOPOLOGY: "server"
+      - id: replicaset
+        display_name: Replica Set
+        variables:
+           TOPOLOGY: "replica_set"
+      - id: sharded-cluster
+        display_name: Sharded Cluster
+        variables:
+           TOPOLOGY: "sharded_cluster"
+
+  - id: auth
+    display_name: Authentication
+    values:
+      - id: auth
+        display_name: Auth
+        variables:
+           AUTH: "auth"
+      - id: noauth
+        display_name: NoAuth
+        variables:
+           AUTH: "noauth"
+
+  - id: ssl
+    display_name: SSL
+    values:
+      - id: ssl
+        display_name: SSL
+        variables:
+           SSL: "ssl"
+      - id: nossl
+        display_name: NoSSL
+        variables:
+           SSL: "nossl"
+
+  - id: storage-engine
+    display_name: Storage
+    values:
+      - id: mmapv1
+        display_name: MMAPv1
+        variables:
+           STORAGE_ENGINE: "mmapv1"
+      - id: wiredtiger
+        display_name: WiredTiger
+        variables:
+           STORAGE_ENGINE: "wiredtiger"
+      - id: inmemory
+        display_name: InMemory
+        variables:
+           STORAGE_ENGINE: "inmemory"
+
+  - id: dependencies
+    display_name: Dependencies
+    values:
+      - id: lowest
+        display_name: Lowest
+        variables:
+          DEPENDENCIES: "lowest"
+
+buildvariants:
+
+# Tests all PHP versions on all operating systems.
+# Only tests against latest MongoDB and ext-mongodb versions
+- matrix_name: "test-php-versions"
+  matrix_spec: {"os-php7": "*", "php-versions": "*", "edge-versions": "latest-stable", "driver-versions": "latest-stable" }
+  exclude_spec:
+    # rhel71-power8 fails due to not reaching pecl
+    - { "os-php7": "rhel71-power8", "php-versions": "*", edge-versions: "*", "driver-versions": "*" }
+    # rhel74-zseries doesn't start in a timely fashion - most likely missing executors
+    - { "os-php7": "rhel74-zseries", "php-versions": "*", edge-versions: "*", "driver-versions": "*" }
+  display_name: "* ${os-php7}, PHP ${php-versions}, MongoDB ${edge-versions}, ext-mongodb ${driver-versions}"
+  tasks:
+    - name: "test-standalone"
+    - name: "test-replica_set"
+    - name: "test-sharded_cluster"
+
+# Tests all driver versions on all PHP versions
+# Only tests on Ubuntu 18.04 and latest MongoDB
+- matrix_name: "test-driver-versions"
+  matrix_spec: {"os-php7": "ubuntu1804-arm64-test", "php-versions": "*", "edge-versions": "latest-stable", "driver-versions": "*" }
+  display_name: "ext-mongodb ${driver-versions}, PHP ${php-versions}, ${os-php7}, MongoDB ${edge-versions}"
+  tasks:
+    - name: "test-standalone"
+    - name: "test-replica_set"
+    - name: "test-sharded_cluster"
+
+# Tests all MongoDB versions
+# Only tests on Ubuntu 18.04, with latest stable PHP and driver versions
+# Tests against various topologies
+- matrix_name: "test-mongodb-versions"
+  matrix_spec: {"os-php7": "rhel70-test", "php-edge-versions": "latest-stable", "versions": "*", "driver-versions": "latest-stable" }
+  display_name: "MongoDB ${versions}, PHP ${php-edge-versions}, ${os-php7}, ext-mongodb ${driver-versions}"
+  tasks:
+    - name: "test-standalone"
+    - name: "test-replica_set"
+    - name: "test-sharded_cluster"
+
+# Tests oldest supported version
+# Enables --prefer-lowest for composer to test oldest dependencies against all server versions
+- matrix_name: "test-dependencies"
+  matrix_spec: { "dependencies": "lowest", "os-php7": "rhel70-test", "php-edge-versions": "oldest-supported", "versions": "*", "driver-versions": "lowest-supported" }
+  display_name: "Dependencies: ${dependencies}, MongoDB ${versions}, PHP ${php-edge-versions}, ${os-php7}, ext-mongodb ${driver-versions}"
+  tasks:
+    - name: "test-standalone"
+    - name: "test-replica_set"
+    - name: "test-sharded_cluster"
+
+- matrix_name: "atlas-data-lake-test"
+  matrix_spec: { "php-edge-versions": "latest-stable" }
+  display_name: "Atlas Data Lake test"
+  run_on: rhel70
+  tasks:
+    - name: "test-atlas-data-lake"
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/config/php.ini b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/config/php.ini
new file mode 100644
index 0000000000000000000000000000000000000000..45969d065b27dfe24be0eaaf27f26b5edb2edd2a
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/config/php.ini	
@@ -0,0 +1 @@
+extension=mongodb.so
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/download-mongodb.sh b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/download-mongodb.sh
new file mode 100644
index 0000000000000000000000000000000000000000..26238667d93343d646bc1847478542534abae694
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/download-mongodb.sh	
@@ -0,0 +1,391 @@
+#!/bin/sh
+
+#For future use the feed to get full list of distros : http://downloads.mongodb.org/full.json
+
+set -o xtrace   # Write all commands first to stderr
+set -o errexit  # Exit the script with error if any of the commands fail
+
+get_distro ()
+{
+   if [ -f /etc/os-release ]; then
+      . /etc/os-release
+      DISTRO="${ID}-${VERSION_ID}"
+   elif command -v lsb_release >/dev/null 2>&1; then
+      name=$(lsb_release -s -i)
+      if [ "$name" = "RedHatEnterpriseServer" ]; then # RHEL 6.2 at least
+         name="rhel"
+      fi
+      version=$(lsb_release -s -r)
+      DISTRO="${name}-${version}"
+   elif [ -f /etc/redhat-release ]; then
+      release=$(cat /etc/redhat-release)
+
+      if [[ "$release" =~ "Red Hat" ]]; then
+         name="rhel"
+      elif [[ "$release" =~ "Fedora" ]]; then
+         name="fedora"
+      fi
+      version=$(echo $release | sed 's/.*\([[:digit:]]\).*/\1/g')
+      DISTRO="${name}-${version}"
+   elif [ -f /etc/lsb-release ]; then
+      . /etc/lsb-release
+      DISTRO="${DISTRIB_ID}-${DISTRIB_RELEASE}"
+   elif grep -R "Amazon Linux" "/etc/system-release" >/dev/null 2>&1; then
+      DISTRO="amzn64"
+   fi
+
+   OS_NAME=$(uname -s)
+   MARCH=$(uname -m)
+   DISTRO=$(echo "$OS_NAME-$DISTRO-$MARCH" | tr '[:upper:]' '[:lower:]')
+
+   echo $DISTRO
+}
+
+# get_mongodb_download_url_for "linux-distro-version-architecture" "latest|40|36|34|32|30|28|26|24"
+# Sets EXTRACT to aproprate extract command
+# Sets MONGODB_DOWNLOAD_URL to the aproprate download url
+get_mongodb_download_url_for ()
+{
+   _DISTRO=$1
+   _VERSION=$2
+
+   VERSION_44="v4.4-latest"
+   VERSION_42="4.2.5"
+   VERSION_40="4.0.17"
+   VERSION_36="3.6.17"
+   VERSION_34="3.4.24"
+   VERSION_32="3.2.22"
+   VERSION_30="3.0.15"
+   VERSION_26="2.6.12"
+   VERSION_24="2.4.14"
+
+   EXTRACT="tar zxf"
+   # getdata matrix on:
+   # https://evergreen.mongodb.com/version/5797f0493ff12235e5001f05
+   case "$_DISTRO" in
+      darwin*)
+         MONGODB_LATEST="http://downloads.10gen.com/osx/mongodb-macos-x86_64-enterprise-latest.tgz"
+             MONGODB_44="http://downloads.10gen.com/osx/mongodb-macos-x86_64-enterprise-${VERSION_44}.tgz"
+             MONGODB_42="http://downloads.10gen.com/osx/mongodb-macos-x86_64-enterprise-${VERSION_42}.tgz"
+             MONGODB_40="http://downloads.10gen.com/osx/mongodb-osx-x86_64-enterprise-${VERSION_40}.tgz"
+             MONGODB_36="http://downloads.10gen.com/osx/mongodb-osx-x86_64-enterprise-${VERSION_36}.tgz"
+             MONGODB_34="http://downloads.10gen.com/osx/mongodb-osx-x86_64-enterprise-${VERSION_34}.tgz"
+             MONGODB_32="http://downloads.10gen.com/osx/mongodb-osx-x86_64-enterprise-${VERSION_32}.tgz"
+             MONGODB_30="https://fastdl.mongodb.org/osx/mongodb-osx-x86_64-${VERSION_30}.tgz"
+             MONGODB_26="https://fastdl.mongodb.org/osx/mongodb-osx-x86_64-${VERSION_26}.tgz"
+             MONGODB_24="https://fastdl.mongodb.org/osx/mongodb-osx-x86_64-${VERSION_24}.tgz"
+      ;;
+      sunos*i86pc)
+         MONGODB_LATEST="https://fastdl.mongodb.org/sunos5/mongodb-sunos5-x86_64-latest.tgz"
+             MONGODB_34="https://fastdl.mongodb.org/sunos5/mongodb-sunos5-x86_64-3.4.5.tgz"
+             MONGODB_32="https://fastdl.mongodb.org/sunos5/mongodb-sunos5-x86_64-3.2.14.tgz"
+             MONGODB_30="https://fastdl.mongodb.org/sunos5/mongodb-sunos5-x86_64-${VERSION_30}.tgz"
+             MONGODB_26="https://fastdl.mongodb.org/sunos5/mongodb-sunos5-x86_64-${VERSION_26}.tgz"
+             MONGODB_24="https://fastdl.mongodb.org/sunos5/mongodb-sunos5-x86_64-${VERSION_24}.tgz"
+      ;;
+      linux-rhel-8*)
+         MONGODB_LATEST="http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-rhel80-latest.tgz"
+             MONGODB_44="http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-rhel80-${VERSION_44}.tgz"
+      ;;
+      linux-rhel-7*-s390x)
+         MONGODB_LATEST="http://downloads.10gen.com/linux/mongodb-linux-s390x-enterprise-rhel72-latest.tgz"
+             MONGODB_44="http://downloads.10gen.com/linux/mongodb-linux-s390x-enterprise-rhel72-${VERSION_44}.tgz"
+             MONGODB_42="http://downloads.10gen.com/linux/mongodb-linux-s390x-enterprise-rhel72-${VERSION_42}.tgz"
+             MONGODB_40="http://downloads.10gen.com/linux/mongodb-linux-s390x-enterprise-rhel72-${VERSION_40}.tgz"
+             MONGODB_36="http://downloads.10gen.com/linux/mongodb-linux-s390x-enterprise-rhel72-3.6.4.tgz"
+             MONGODB_34="http://downloads.10gen.com/linux/mongodb-linux-s390x-enterprise-rhel72-3.4.14.tgz"
+      ;;
+      linux-rhel-7.1-ppc64le)
+         MONGODB_LATEST="http://downloads.10gen.com/linux/mongodb-linux-ppc64le-enterprise-rhel71-latest.tgz"
+             MONGODB_44="http://downloads.10gen.com/linux/mongodb-linux-ppc64le-enterprise-rhel71-${VERSION_44}.tgz"
+             MONGODB_42="http://downloads.10gen.com/linux/mongodb-linux-ppc64le-enterprise-rhel71-${VERSION_42}.tgz"
+             MONGODB_40="http://downloads.10gen.com/linux/mongodb-linux-ppc64le-enterprise-rhel71-${VERSION_40}.tgz"
+             MONGODB_36="http://downloads.10gen.com/linux/mongodb-linux-ppc64le-enterprise-rhel71-${VERSION_36}.tgz"
+             MONGODB_34="http://downloads.10gen.com/linux/mongodb-linux-ppc64le-enterprise-rhel71-${VERSION_34}.tgz"
+             MONGODB_32="http://downloads.10gen.com/linux/mongodb-linux-ppc64le-enterprise-rhel71-${VERSION_32}.tgz"
+      ;;
+      linux-rhel-7.0*)
+         MONGODB_LATEST="http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-rhel70-latest.tgz"
+             MONGODB_44="http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-rhel70-${VERSION_44}.tgz"
+             MONGODB_42="http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-rhel70-${VERSION_42}.tgz"
+             MONGODB_40="http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-rhel70-${VERSION_40}.tgz"
+             MONGODB_36="http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-rhel70-${VERSION_36}.tgz"
+             MONGODB_34="http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-rhel70-${VERSION_34}.tgz"
+             MONGODB_32="http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-rhel70-${VERSION_32}.tgz"
+             MONGODB_30="http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-rhel70-${VERSION_30}.tgz"
+             MONGODB_26="http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-rhel70-${VERSION_26}.tgz"
+      ;;
+      linux-rhel-6*-s390x)
+         MONGODB_LATEST="http://downloads.10gen.com/linux/mongodb-linux-s390x-enterprise-rhel67-latest.tgz"
+             MONGODB_44="http://downloads.10gen.com/linux/mongodb-linux-s390x-enterprise-rhel67-${VERSION_44}.tgz"
+             MONGODB_42="http://downloads.10gen.com/linux/mongodb-linux-s390x-enterprise-rhel67-${VERSION_42}.tgz"
+             MONGODB_40="http://downloads.10gen.com/linux/mongodb-linux-s390x-enterprise-rhel67-${VERSION_40}.tgz"
+             MONGODB_36="http://downloads.10gen.com/linux/mongodb-linux-s390x-enterprise-rhel67-${VERSION_36}.tgz"
+             MONGODB_34="http://downloads.10gen.com/linux/mongodb-linux-s390x-enterprise-rhel67-${VERSION_34}.tgz"
+      ;;
+      linux-rhel-6.2*)
+         MONGODB_LATEST="http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-rhel62-latest.tgz"
+             MONGODB_44="http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-rhel62-${VERSION_44}.tgz"
+             MONGODB_42="http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-rhel62-${VERSION_42}.tgz"
+             MONGODB_40="http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-rhel62-${VERSION_40}.tgz"
+             MONGODB_36="http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-rhel62-${VERSION_36}.tgz"
+             MONGODB_34="http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-rhel62-${VERSION_34}.tgz"
+             MONGODB_32="http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-rhel62-${VERSION_32}.tgz"
+             MONGODB_30="http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-rhel62-${VERSION_30}.tgz"
+             MONGODB_26="http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-rhel62-${VERSION_26}.tgz"
+             MONGODB_24="http://downloads.10gen.com/linux/mongodb-linux-x86_64-subscription-rhel62-${VERSION_24}.tgz"
+      ;;
+      linux-rhel-5.5*)
+         MONGODB_LATEST="http://downloads.mongodb.org/linux/mongodb-linux-x86_64-rhel55-latest.tgz"
+             MONGODB_32="http://downloads.mongodb.org/linux/mongodb-linux-x86_64-rhel55-${VERSION_32}.tgz"
+             MONGODB_30="http://downloads.mongodb.org/linux/mongodb-linux-x86_64-rhel55-${VERSION_30}.tgz"
+      ;;
+      linux-sles-11*-x86_64)
+         MONGODB_LATEST="http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-suse11-latest.tgz"
+             MONGODB_36="http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-suse11-${VERSION_36}.tgz"
+             MONGODB_34="http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-suse11-${VERSION_34}.tgz"
+             MONGODB_32="http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-suse11-${VERSION_32}.tgz"
+             MONGODB_30="http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-suse11-${VERSION_30}.tgz"
+             MONGODB_26="http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-suse11-${VERSION_26}.tgz"
+             MONGODB_24="http://downloads.10gen.com/linux/mongodb-linux-x86_64-subscription-suse11-${VERSION_24}.tgz"
+      ;;
+      linux-sles-12*-s390x)
+         MONGODB_LATEST="http://downloads.10gen.com/linux/mongodb-linux-s390x-enterprise-suse12-latest.tgz"
+             MONGODB_44="http://downloads.10gen.com/linux/mongodb-linux-s390x-enterprise-suse12-${VERSION_44}.tgz"
+             MONGODB_42="http://downloads.10gen.com/linux/mongodb-linux-s390x-enterprise-suse12-${VERSION_42}.tgz"
+             MONGODB_40="http://downloads.10gen.com/linux/mongodb-linux-s390x-enterprise-suse12-${VERSION_40}.tgz"
+             MONGODB_36="http://downloads.10gen.com/linux/mongodb-linux-s390x-enterprise-suse12-3.6.3.tgz"
+             MONGODB_34="http://downloads.10gen.com/linux/mongodb-linux-s390x-enterprise-suse12-3.4.13.tgz"
+      ;;
+      linux-sles-12*-x86_64)
+         MONGODB_LATEST="http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-suse12-latest.tgz"
+             MONGODB_44="http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-suse12-${VERSION_44}.tgz"
+             MONGODB_42="http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-suse12-${VERSION_42}.tgz"
+             MONGODB_40="http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-suse12-${VERSION_40}.tgz"
+             MONGODB_36="http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-suse12-${VERSION_36}.tgz"
+             MONGODB_34="http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-suse12-${VERSION_34}.tgz"
+             MONGODB_32="http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-suse12-${VERSION_32}.tgz"
+      ;;
+      linux-amzn-2018*-x86_64)
+         MONGODB_LATEST="http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-amzn64-latest.tgz"
+             MONGODB_44="http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-amzn64-${VERSION_44}.tgz"
+             MONGODB_42="http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-amzn64-${VERSION_42}.tgz"
+             MONGODB_40="http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-amzn64-${VERSION_40}.tgz"
+             MONGODB_36="http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-amzn64-${VERSION_36}.tgz"
+             MONGODB_34="http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-amzn64-${VERSION_34}.tgz"
+             MONGODB_32="http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-amzn64-${VERSION_32}.tgz"
+             MONGODB_30="http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-amzn64-${VERSION_30}.tgz"
+             MONGODB_26="http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-amzn64-${VERSION_26}.tgz"
+             MONGODB_24="http://downloads.10gen.com/linux/mongodb-linux-x86_64-subscription-amzn64-${VERSION_24}.tgz"
+      ;;
+      linux-amzn-2-x86_64)
+         MONGODB_LATEST="http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-amazon2-latest.tgz"
+             MONGODB_44="http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-amazon2-${VERSION_44}.tgz"
+             MONGODB_42="http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-amazon2-${VERSION_42}.tgz"
+             MONGODB_40="http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-amazon2-${VERSION_40}.tgz"
+      ;;
+      linux-debian-7*)
+         MONGODB_LATEST="http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-debian71-latest.tgz"
+             # SERVER-32999 removed support for Debian 7.
+             MONGODB_36="http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-debian71-3.6.5.tgz"
+             MONGODB_34="http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-debian71-3.4.15.tgz"
+             MONGODB_32="http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-debian71-3.2.20.tgz"
+             MONGODB_30="http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-debian71-${VERSION_30}.tgz"
+             MONGODB_26="http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-debian71-${VERSION_26}.tgz"
+      ;;
+      linux-debian-8*)
+         MONGODB_LATEST="http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-debian81-latest.tgz"
+             # SERVER-37767 Removed support for Debian 8
+             MONGODB_40="http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-debian81-${VERSION_40}.tgz"
+             MONGODB_36="http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-debian81-${VERSION_36}.tgz"
+             MONGODB_34="http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-debian81-${VERSION_34}.tgz"
+             MONGODB_32="http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-debian81-${VERSION_32}.tgz"
+      ;;
+      linux-debian-9*)
+         MONGODB_LATEST="http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-debian92-latest.tgz"
+             MONGODB_44="http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-debian92-${VERSION_44}.tgz"
+             MONGODB_42="http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-debian92-${VERSION_42}.tgz"
+             MONGODB_40="http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-debian92-${VERSION_40}.tgz"
+             MONGODB_36="http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-debian92-${VERSION_36}.tgz"
+      ;;
+      linux-debian-10*)
+         MONGODB_LATEST="http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-debian10-latest.tgz"
+             MONGODB_44="http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-debian10-${VERSION_44}.tgz"
+      ;;
+      linux-ubuntu-18.04-s390x)
+         MONGODB_LATEST="http://downloads.10gen.com/linux/mongodb-linux-s390x-enterprise-ubuntu1804-latest.tgz"
+             MONGODB_44="http://downloads.10gen.com/linux/mongodb-linux-s390x-enterprise-ubuntu1804-${VERSION_44}.tgz"
+             MONGODB_42="http://downloads.10gen.com/linux/mongodb-linux-s390x-enterprise-ubuntu1804-${VERSION_42}.tgz"
+             MONGODB_40="http://downloads.10gen.com/linux/mongodb-linux-s390x-enterprise-ubuntu1804-${VERSION_40}.tgz"
+      ;;
+      linux-ubuntu-18.04-aarch64)
+         MONGODB_LATEST="http://downloads.10gen.com/linux/mongodb-linux-aarch64-enterprise-ubuntu1804-latest.tgz"
+             MONGODB_44="http://downloads.10gen.com/linux/mongodb-linux-aarch64-enterprise-ubuntu1804-${VERSION_44}.tgz"
+             MONGODB_42="http://downloads.10gen.com/linux/mongodb-linux-aarch64-enterprise-ubuntu1804-${VERSION_42}.tgz"
+      ;;
+      linux-ubuntu-18.04-ppc64le)
+         MONGODB_LATEST="http://downloads.10gen.com/linux/mongodb-linux-ppc64le-enterprise-ubuntu1804-latest.tgz"
+             MONGODB_44="http://downloads.10gen.com/linux/mongodb-linux-ppc64le-enterprise-ubuntu1804-${VERSION_44}.tgz"
+             MONGODB_42="http://downloads.10gen.com/linux/mongodb-linux-ppc64le-enterprise-ubuntu1804-${VERSION_42}.tgz"
+      ;;
+      linux-ubuntu-18.04*)
+         MONGODB_LATEST="http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-ubuntu1804-latest.tgz"
+             MONGODB_44="http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-ubuntu1804-${VERSION_44}.tgz"
+             MONGODB_42="http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-ubuntu1804-${VERSION_42}.tgz"
+             MONGODB_40="http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-ubuntu1804-${VERSION_40}.tgz"
+      ;;
+      linux-ubuntu-16.04-s390x)
+         MONGODB_LATEST="http://downloads.10gen.com/linux/mongodb-linux-s390x-enterprise-ubuntu1604-latest.tgz"
+             MONGODB_40="http://downloads.10gen.com/linux/mongodb-linux-s390x-enterprise-ubuntu1604-v4.0-latest.tgz"
+             MONGODB_36="http://downloads.10gen.com/linux/mongodb-linux-s390x-enterprise-ubuntu1604-3.6.4.tgz"
+             MONGODB_34="http://downloads.10gen.com/linux/mongodb-linux-s390x-enterprise-ubuntu1604-3.4.14.tgz"
+      ;;
+      linux-ubuntu-16.04-ppc64le)
+         MONGODB_LATEST="http://downloads.10gen.com/linux/mongodb-linux-ppc64le-enterprise-ubuntu1604-latest.tgz"
+             # SERVER-37774 Removed support for Ubuntu 16.04 PPCLE
+             MONGODB_40="http://downloads.10gen.com/linux/mongodb-linux-ppc64le-enterprise-ubuntu1604-4.0.9.tgz"
+             MONGODB_36="http://downloads.10gen.com/linux/mongodb-linux-ppc64le-enterprise-ubuntu1604-3.6.12.tgz"
+             MONGODB_34="http://downloads.10gen.com/linux/mongodb-linux-ppc64le-enterprise-ubuntu1604-3.4.20.tgz"
+      ;;
+      linux-ubuntu-16.04-aarch64)
+         MONGODB_LATEST="http://downloads.10gen.com/linux/mongodb-linux-aarch64-enterprise-ubuntu1604-latest.tgz"
+             MONGODB_44="http://downloads.10gen.com/linux/mongodb-linux-aarch64-enterprise-ubuntu1604-${VERSION_44}.tgz"
+             MONGODB_42="http://downloads.10gen.com/linux/mongodb-linux-aarch64-enterprise-ubuntu1604-${VERSION_42}.tgz"
+             MONGODB_40="http://downloads.10gen.com/linux/mongodb-linux-arm64-enterprise-ubuntu1604-${VERSION_40}.tgz"
+             MONGODB_36="http://downloads.10gen.com/linux/mongodb-linux-arm64-enterprise-ubuntu1604-${VERSION_36}.tgz"
+             MONGODB_34="http://downloads.10gen.com/linux/mongodb-linux-arm64-enterprise-ubuntu1604-${VERSION_34}.tgz"
+      ;;
+      linux-ubuntu-16.04*)
+         MONGODB_LATEST="http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-ubuntu1604-latest.tgz"
+             MONGODB_44="http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-ubuntu1604-${VERSION_44}.tgz"
+             MONGODB_42="http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-ubuntu1604-${VERSION_42}.tgz"
+             MONGODB_40="http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-ubuntu1604-${VERSION_40}.tgz"
+             MONGODB_36="http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-ubuntu1604-${VERSION_36}.tgz"
+             MONGODB_34="http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-ubuntu1604-${VERSION_34}.tgz"
+             MONGODB_32="http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-ubuntu1604-${VERSION_32}.tgz"
+      ;;
+      linux-ubuntu-14.04*)
+         MONGODB_LATEST="http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-ubuntu1404-latest.tgz"
+             # SERVER-37765 Removed support for Ubuntu 14.04
+             MONGODB_40="http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-ubuntu1404-4.0.9.tgz"
+             MONGODB_36="http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-ubuntu1404-3.6.12.tgz"
+             MONGODB_34="http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-ubuntu1404-3.4.20.tgz"
+             MONGODB_32="http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-ubuntu1404-${VERSION_32}.tgz"
+             MONGODB_30="http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-ubuntu1404-${VERSION_30}.tgz"
+             MONGODB_26="http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-ubuntu1404-${VERSION_26}.tgz"
+      ;;
+      linux-ubuntu-12.04*)
+         MONGODB_LATEST="http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-ubuntu1204-latest.tgz"
+             # SERVER-31535 removed support for Ubuntu 12.
+             MONGODB_36="http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-ubuntu1204-3.6.3.tgz"
+             MONGODB_34="http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-ubuntu1204-3.4.14.tgz"
+             MONGODB_32="http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-ubuntu1204-3.2.19.tgz"
+             MONGODB_30="http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-ubuntu1204-${VERSION_30}.tgz"
+             MONGODB_26="http://downloads.10gen.com/linux/mongodb-linux-x86_64-enterprise-ubuntu1204-${VERSION_26}.tgz"
+             MONGODB_24="http://downloads.10gen.com/linux/mongodb-linux-x86_64-subscription-ubuntu1204-${VERSION_24}.tgz"
+      ;;
+      windows32*)
+         EXTRACT="/cygdrive/c/Progra~2/7-Zip/7z.exe x"
+             MONGODB_32="https://fastdl.mongodb.org/win32/mongodb-win32-i386-${VERSION_32}.zip"
+             MONGODB_30="https://fastdl.mongodb.org/win32/mongodb-win32-i386-${VERSION_30}.zip"
+             MONGODB_26="https://fastdl.mongodb.org/win32/mongodb-win32-i386-${VERSION_26}.zip"
+             MONGODB_24="https://fastdl.mongodb.org/win32/mongodb-win32-i386-${VERSION_24}.zip"
+      ;;
+      windows64*)
+         # same as cygwin*-86-64
+         EXTRACT="/cygdrive/c/Progra~2/7-Zip/7z.exe x"
+         MONGODB_LATEST="http://downloads.10gen.com/windows/mongodb-windows-x86_64-enterprise-latest.zip"
+             MONGODB_44="http://downloads.10gen.com/windows/mongodb-windows-x86_64-enterprise-${VERSION_44}.zip"
+             MONGODB_42="http://downloads.10gen.com/win32/mongodb-win32-x86_64-enterprise-windows-64-${VERSION_42}.zip"
+             MONGODB_40="http://downloads.10gen.com/win32/mongodb-win32-x86_64-enterprise-windows-64-${VERSION_40}.zip"
+             MONGODB_36="http://downloads.10gen.com/win32/mongodb-win32-x86_64-enterprise-windows-64-${VERSION_36}.zip"
+             MONGODB_34="http://downloads.10gen.com/win32/mongodb-win32-x86_64-enterprise-windows-64-${VERSION_34}.zip"
+             MONGODB_32="http://downloads.10gen.com/win32/mongodb-win32-x86_64-enterprise-windows-64-${VERSION_32}.zip"
+             MONGODB_30="http://downloads.10gen.com/win32/mongodb-win32-x86_64-enterprise-windows-64-${VERSION_30}.zip"
+             MONGODB_26="http://downloads.10gen.com/win32/mongodb-win32-x86_64-enterprise-windows-64-${VERSION_26}.zip"
+             MONGODB_24="https://fastdl.mongodb.org/win32/mongodb-win32-x86_64-2008plus-${VERSION_24}.zip"
+      ;;
+      cygwin*-x86_64)
+         EXTRACT="/cygdrive/c/Progra~2/7-Zip/7z.exe x"
+         MONGODB_LATEST="http://downloads.10gen.com/windows/mongodb-windows-x86_64-enterprise-latest.zip"
+             MONGODB_44="http://downloads.10gen.com/windows/mongodb-windows-x86_64-enterprise-${VERSION_44}.zip"
+             MONGODB_42="http://downloads.10gen.com/win32/mongodb-win32-x86_64-enterprise-windows-64-${VERSION_42}.zip"
+             MONGODB_40="http://downloads.10gen.com/win32/mongodb-win32-x86_64-enterprise-windows-64-${VERSION_40}.zip"
+             MONGODB_36="http://downloads.10gen.com/win32/mongodb-win32-x86_64-enterprise-windows-64-${VERSION_36}.zip"
+             MONGODB_34="http://downloads.10gen.com/win32/mongodb-win32-x86_64-enterprise-windows-64-${VERSION_34}.zip"
+             MONGODB_32="http://downloads.10gen.com/win32/mongodb-win32-x86_64-enterprise-windows-64-${VERSION_32}.zip"
+             MONGODB_30="http://downloads.10gen.com/win32/mongodb-win32-x86_64-enterprise-windows-64-${VERSION_30}.zip"
+             MONGODB_26="http://downloads.10gen.com/win32/mongodb-win32-x86_64-enterprise-windows-64-${VERSION_26}.zip"
+             MONGODB_24="https://fastdl.mongodb.org/win32/mongodb-win32-x86_64-2008plus-${VERSION_24}.zip"
+      ;;
+      cygwin*-i686)
+         EXTRACT="/cygdrive/c/Progra~1/7-Zip/7z.exe x"
+             MONGODB_32="https://fastdl.mongodb.org/win32/mongodb-win32-i386-${VERSION_32}.zip"
+             MONGODB_30="https://fastdl.mongodb.org/win32/mongodb-win32-i386-${VERSION_30}.zip"
+             MONGODB_26="https://fastdl.mongodb.org/win32/mongodb-win32-i386-${VERSION_26}.zip"
+             MONGODB_24="https://fastdl.mongodb.org/win32/mongodb-win32-i386-${VERSION_24}.zip"
+      ;;
+   esac
+
+   # Fallback to generic Linux x86_64 builds (without SSL) when no platform specific link is available.
+   case "$_DISTRO" in
+      *linux*x86_64)
+         MONGODB_LATEST=${MONGODB_LATEST:-"http://downloads.mongodb.org/linux/mongodb-linux-x86_64-latest.tgz"}
+                 # SERVER-37316 Removed support for generic linux builds.
+                 MONGODB_42=${MONGODB_42:-""}
+                 MONGODB_40=${MONGODB_40:-"http://downloads.mongodb.org/linux/mongodb-linux-x86_64-${VERSION_40}.tgz"}
+                 MONGODB_36=${MONGODB_36:-"http://downloads.mongodb.org/linux/mongodb-linux-x86_64-${VERSION_36}.tgz"}
+                 MONGODB_34=${MONGODB_34:-"http://downloads.mongodb.org/linux/mongodb-linux-x86_64-${VERSION_34}.tgz"}
+                 MONGODB_32=${MONGODB_32:-"http://downloads.mongodb.org/linux/mongodb-linux-x86_64-${VERSION_32}.tgz"}
+                 MONGODB_30=${MONGODB_30:-"http://downloads.mongodb.org/linux/mongodb-linux-x86_64-${VERSION_30}.tgz"}
+                 MONGODB_26=${MONGODB_26:-"http://downloads.mongodb.org/linux/mongodb-linux-x86_64-${VERSION_26}.tgz"}
+                 MONGODB_24=${MONGODB_24:-"http://downloads.mongodb.org/linux/mongodb-linux-x86_64-${VERSION_24}.tgz"}
+      ;;
+   esac
+
+   # PYTHON-2238 On Archlinux MongoDB <= 3.2 requires LC_ALL=C.
+   case "$_DISTRO" in
+      linux-arch-*)
+        case "$_VERSION" in
+           3.2) export LC_ALL=C ;;
+           3.0) export LC_ALL=C ;;
+           2.6) export LC_ALL=C ;;
+           2.4) export LC_ALL=C ;;
+        esac
+      ;;
+   esac
+
+   case "$_VERSION" in
+      latest) MONGODB_DOWNLOAD_URL=$MONGODB_LATEST ;;
+      4.4) MONGODB_DOWNLOAD_URL=$MONGODB_44 ;;
+      4.2) MONGODB_DOWNLOAD_URL=$MONGODB_42 ;;
+      4.0) MONGODB_DOWNLOAD_URL=$MONGODB_40 ;;
+      3.6) MONGODB_DOWNLOAD_URL=$MONGODB_36 ;;
+      3.4) MONGODB_DOWNLOAD_URL=$MONGODB_34 ;;
+      3.2) MONGODB_DOWNLOAD_URL=$MONGODB_32 ;;
+      3.0) MONGODB_DOWNLOAD_URL=$MONGODB_30 ;;
+      2.6) MONGODB_DOWNLOAD_URL=$MONGODB_26 ;;
+      2.4) MONGODB_DOWNLOAD_URL=$MONGODB_24 ;;
+   esac
+
+   [ -z "$MONGODB_DOWNLOAD_URL" ] && MONGODB_DOWNLOAD_URL="Unknown version: $_VERSION for $_DISTRO"
+
+   echo $MONGODB_DOWNLOAD_URL
+}
+
+download_and_extract ()
+{
+   MONGODB_DOWNLOAD_URL=$1
+   EXTRACT=$2
+
+   cd $DRIVERS_TOOLS
+   curl --retry 8 -sS $MONGODB_DOWNLOAD_URL --max-time 300 --output mongodb-binaries.tgz
+   $EXTRACT mongodb-binaries.tgz
+
+   rm mongodb-binaries.tgz
+   mv mongodb* mongodb
+   chmod -R +x mongodb
+   find . -name vcredist_x64.exe -exec {} /install /quiet \;
+   ./mongodb/bin/mongod --version
+   cd -
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/generate_task_config.py b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/generate_task_config.py
new file mode 100644
index 0000000000000000000000000000000000000000..3820cc4008a21f3eeadc95a9a454f108d37b4096
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/generate_task_config.py	
@@ -0,0 +1,31 @@
+import itertools
+
+
+TASK_TEMPLATE = '''
+    - name: "test-{version}-{topology}"
+      tags: ["{version}", "{topology}"]
+      commands:
+        - func: "bootstrap mongo-orchestration"
+          vars:
+            VERSION: "{version}"
+            TOPOLOGY: "{mo_topology}"
+        - func: "run tests"'''
+
+MONGODB_VERSIONS = ['2.4', '2.6', '3.0', '3.2', '3.4', 'latest']
+TOPOLOGY_OPTIONS = ['standalone', 'replica_set', 'sharded_cluster']
+
+
+def create_task(version, topology):
+    mo_topology= topology
+    # mongo-orchestration uses 'server' as the name for 'standalone'
+    if mo_topology == 'standalone':
+        mo_topology = 'server'
+    return TASK_TEMPLATE.format(**locals())
+
+
+tasks = []
+for version, topology in itertools.product(MONGODB_VERSIONS,
+                                           TOPOLOGY_OPTIONS):
+    tasks.append(create_task(version, topology))
+
+print('\n'.join(tasks))
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/install-dependencies.sh b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/install-dependencies.sh
new file mode 100644
index 0000000000000000000000000000000000000000..9ccd2dc100866585a110b2793c32e38d0c55b213
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/install-dependencies.sh	
@@ -0,0 +1,101 @@
+#!/bin/sh
+set -o xtrace   # Write all commands first to stderr
+set -o errexit  # Exit the script with error if any of the commands fail
+
+install_extension ()
+{
+   # Workaround to get PECL running on PHP 7.0
+   export PHP_PEAR_PHP_BIN=${PHP_PATH}/bin/php
+   export PHP_PEAR_INSTALL_DIR=${PHP_PATH}/lib/php
+
+   rm -f ${PHP_PATH}/lib/php.ini
+
+   if [ "x${DRIVER_BRANCH}" != "x" ] || [ "x${DRIVER_REPO}" != "x" ]; then
+      CLONE_REPO=${DRIVER_REPO:-https://github.com/mongodb/mongo-php-driver}
+      CHECKOUT_BRANCH=${DRIVER_BRANCH:-master}
+
+      echo "Compiling driver branch ${CHECKOUT_BRANCH} from repository ${CLONE_REPO}"
+
+      mkdir -p /tmp/compile
+      rm -rf /tmp/compile/mongo-php-driver
+      git clone ${CLONE_REPO} /tmp/compile/mongo-php-driver
+      cd /tmp/compile/mongo-php-driver
+
+      git checkout ${CHECKOUT_BRANCH}
+      git submodule update --init
+      phpize
+      ./configure --enable-mongodb-developer-flags
+      make all -j20 > /dev/null
+      make install
+
+      cd ${PROJECT_DIRECTORY}
+   elif [ "x${DRIVER_VERSION}" != "x" ]; then
+      echo "Installing driver version ${DRIVER_VERSION} from PECL"
+      pecl install -f mongodb-${DRIVER_VERSION}
+   else
+      echo "Installing latest driver version from PECL"
+      pecl install -f mongodb
+   fi
+
+   sudo cp ${PROJECT_DIRECTORY}/.evergreen/config/php.ini ${PHP_PATH}/lib/php.ini
+}
+
+DIR=$(dirname $0)
+# Functions to fetch MongoDB binaries
+. $DIR/download-mongodb.sh
+OS=$(uname -s | tr '[:upper:]' '[:lower:]')
+
+get_distro
+
+# See .evergreen/download-mongodb.sh for most possible values
+case "$DISTRO" in
+   cygwin*)
+      echo "Install Windows dependencies"
+      ;;
+
+   darwin*)
+      echo "Install macOS dependencies"
+      ;;
+
+   linux-rhel*)
+      echo "Install RHEL dependencies"
+      ;;
+
+   linux-ubuntu*)
+      echo "Install Ubuntu dependencies"
+      sudo apt-get install -y awscli || true
+      ;;
+
+   sunos*)
+      echo "Install Solaris dependencies"
+      sudo /opt/csw/bin/pkgutil -y -i sasl_dev || true
+      ;;
+
+   *)
+      echo "All other platforms..."
+      ;;
+esac
+
+case "$DEPENDENCIES" in
+   lowest*)
+      COMPOSER_FLAGS="${COMPOSER_FLAGS} --prefer-lowest"
+      ;;
+
+   *)
+      ;;
+esac
+
+PHP_PATH=/opt/php/${PHP_VERSION}-64bit
+OLD_PATH=$PATH
+PATH=$PHP_PATH/bin:$OLD_PATH
+
+install_extension
+
+php --ri mongodb
+
+# Install composer
+php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
+php composer-setup.php
+php -r "unlink('composer-setup.php');"
+
+php composer.phar update $COMPOSER_FLAGS
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/make-docs.sh b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/make-docs.sh
new file mode 100644
index 0000000000000000000000000000000000000000..f61da5a4be8f72d17aa0d942ea097a35cd962213
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/make-docs.sh	
@@ -0,0 +1,26 @@
+#!/bin/sh
+set -o xtrace   # Write all commands first to stderr
+set -o errexit  # Exit the script with error if any of the commands fail
+
+
+mkdir -p doc/html || true
+
+
+cat <<EOT > doc/html/index.html > doc/html/intro.html
+<html>
+<body>
+<ul>
+<li><a href="index.html">Index</a></li>
+<li><a href="intro.html">Intro</a></li>
+</ul>
+EOT
+
+cat <<EOT >> doc/html/index.html
+This is an example of a doc page automatically uploaded to evergreen so you can see your docs rendered.
+The evergreen URL differs for patch builds and normal builds
+EOT
+cat <<EOT >> doc/html/intro.html
+This page is never actually uploaded by evergreen, only the index page was uploaded.
+Thats why there is a link to the index page ("Rendered docs") while this is not an actual artifact.
+This page was uploaded seperately with the s3cmd tools
+EOT
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/make-release.sh b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/make-release.sh
new file mode 100644
index 0000000000000000000000000000000000000000..ef6e2af7e5b1d4afdcea49747a138d768415a97a
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/make-release.sh	
@@ -0,0 +1,13 @@
+#!/bin/sh
+set -o xtrace   # Write all commands first to stderr
+set -o errexit  # Exit the script with error if any of the commands fail
+
+
+echo "Creating Release Archive Bundle RPM"
+
+echo "The release archive will have the version automatically derived from the nearest git tag for patchbuilds, otherwise 'latest' is used"
+
+echo "The release file should be called $PROJECT.tar.gz"
+
+
+cd .. && tar czf $PROJECT.tar.gz src
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/README.md b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..845d649963cdb703357e51d1c75f063be8d77a80
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/README.md	
@@ -0,0 +1,34 @@
+# Generating Test Certificates
+
+The test certificates here were generating using a fork of the server
+team's 
+[`mkcert.py`](https://github.com/mongodb/mongo/blob/master/jstests/ssl/x509/mkcert.py)
+tool.
+
+In order to generate a fresh set of certificates, clone this branch of
+a fork of the 
+[`mongo` repository](https://github.com/vincentkam/mongo/tree/mkcert-ecdsa) and
+run the following command from the root of the `mongo` repository:
+
+`python3 jstests/ssl/x509/mkcert.py --config ../drivers-evergreen-tools/.evergreen/ocsp/certs.yml`
+
+Passing a certificate ID as the final parameter will limit certificate
+generation to that certificate and all its leaves. Note: if
+regenerating ECDSA leaf certificates, ``ecsda/ca.pem`` will need to be
+temporarily renamed back to ``ecdsa-ca-ocsp.pem``.
+
+The ECDSA certificates will be output into the folder specified by the
+`global.output_path` option in the `certs.yml` file, which defaults to
+`ecsda` directory contained in this directory. The RSA certificate
+definitions override this value on a per certificate basis and are
+output into the `rsa` directory. The default configuration also
+assumes that the `mongo` repository and the `driver-evergreen-tools`
+repository have the same parent directory.
+
+After generating the RSA root certificate, one must manually split the
+`rsa/ca.pem` file, which contains both the private key and the public
+certificate, into two files. `rsa/ca.crt` should contain the public
+certificate, and `ras/ca.key` should contain the private certificate.
+
+When generating ECDSA certificates, one must normalize the ECDSA
+certificate names by running `ecdsa/rename.sh`.
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/certs.yml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/certs.yml
new file mode 100644
index 0000000000000000000000000000000000000000..3fa364da3a2a6def436046bcd9fe6d7a31ab52cc
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/certs.yml	
@@ -0,0 +1,169 @@
+
+global:
+  # All subject names will have these elements automatically,
+  # unless `explicit_subject: true` is specified.
+  output_path: '../drivers-evergreen-tools/.evergreen/ocsp/ecdsa/' # See README.md if customizing this path
+  Subject:
+    C: 'US'
+    ST: 'New York'
+    L: 'New York City'
+    O: 'MongoDB'
+    OU: 'Kernel'
+
+certs:
+
+###
+# OCSP Tree
+###
+- name: 'ca.pem'
+  description: >-
+    Primary Root Certificate Authority
+    Most Certificates are issued by this CA.
+  Subject: {CN: 'Kernel Test CA'}
+  Issuer: self
+  include_header: false
+  output_path: '../drivers-evergreen-tools/.evergreen/ocsp/rsa'
+  extensions:
+    basicConstraints:
+      critical: true
+      CA: true
+
+- name: 'server.pem'
+  description: >-
+    Certificate with OCSP for the mongodb server.
+  Subject:
+    CN: 'localhost'
+    C: US
+    ST: NY
+    L: OCSP-1
+  Issuer: 'ca.pem'
+  include_header: false
+  output_path: '../drivers-evergreen-tools/.evergreen/ocsp/rsa'
+  extensions:
+    basicConstraints: {CA: false}
+    subjectAltName:
+      DNS: localhost
+      IP: 127.0.0.1
+    authorityInfoAccess: 'OCSP;URI:http://localhost:9001/power/level,OCSP;URI:http://localhost:8100/status'
+    subjectKeyIdentifier: hash
+    keyUsage: [digitalSignature, keyEncipherment]
+    extendedKeyUsage: [serverAuth, clientAuth]
+
+- name: 'server-mustStaple.pem'
+  description: >-
+    Certificate with Must Staple OCSP for the mongodb server.
+  Subject:
+    CN: 'localhost'
+    C: US
+    ST: NY
+    L: OCSP-1
+  Issuer: 'ca.pem'
+  include_header: false
+  output_path: '../drivers-evergreen-tools/.evergreen/ocsp/rsa'
+  extensions:
+    basicConstraints: {CA: false}
+    subjectAltName:
+      DNS: localhost
+      IP: 127.0.0.1
+    authorityInfoAccess: 'OCSP;URI:http://localhost:9001/power/level,OCSP;URI:http://localhost:8100/status'
+    mustStaple: true
+    subjectKeyIdentifier: hash
+    keyUsage: [digitalSignature, keyEncipherment]
+    extendedKeyUsage: [serverAuth, clientAuth]
+
+- name: 'server-singleEndpoint.pem'
+  description: >-
+    Certificate with a single OCSP endpoint for the mongodb server.
+  Subject:
+    CN: 'localhost'
+    C: US
+    ST: NY
+    L: OCSP-1
+  Issuer: 'ca.pem'
+  include_header: false
+  output_path: '../drivers-evergreen-tools/.evergreen/ocsp/rsa'
+  extensions:
+    basicConstraints: {CA: false}
+    subjectAltName:
+      DNS: localhost
+      IP: 127.0.0.1
+    authorityInfoAccess: 'OCSP;URI:http://localhost:8100/status'
+    subjectKeyIdentifier: hash
+    keyUsage: [digitalSignature, keyEncipherment]
+    extendedKeyUsage: [serverAuth, clientAuth]
+
+- name: 'server-mustStaple-singleEndpoint.pem'
+  description: >-
+    Certificate with Must Staple OCSP and one OCSP endpoint for the mongodb server.
+  Subject:
+    CN: 'localhost'
+    C: US
+    ST: NY
+    L: OCSP-1
+  Issuer: 'ca.pem'
+  include_header: false
+  output_path: '../drivers-evergreen-tools/.evergreen/ocsp/rsa'
+  extensions:
+    basicConstraints: {CA: false}
+    subjectAltName:
+      DNS: localhost
+      IP: 127.0.0.1
+    authorityInfoAccess: 'OCSP;URI:http://localhost:8100/status'
+    mustStaple: true
+    subjectKeyIdentifier: hash
+    keyUsage: [digitalSignature, keyEncipherment]
+    extendedKeyUsage: [serverAuth, clientAuth]
+
+- name: 'ocsp-responder.crt'
+  description: Certificate and key for the OCSP responder
+  Subject:
+    CN: 'localhost'
+    C: US
+    ST: NY
+    L: OCSP-3
+  Issuer: 'ca.pem'
+  include_header: false
+  keyfile: 'ocsp-responder.key'
+  output_path: '../drivers-evergreen-tools/.evergreen/ocsp/rsa'
+  extensions:
+    basicConstraints: {CA: false}
+    keyUsage: [nonRepudiation, digitalSignature, keyEncipherment]
+    extendedKeyUsage: [OCSPSigning]
+    #noCheck: true
+
+###
+# ECDSA tree
+###
+
+# These are all special cases handled internally by mkcert.py
+# Do NOT change the names
+
+- name: 'ecdsa-ca-ocsp.pem'
+  description: Root of ECDSA tree for OCSP testing
+  Issuer: self
+  tags: [ecdsa]
+
+- name: 'ecdsa-server-ocsp.pem'
+  description: ECDSA server certificate w/OCSP
+  Issuer: 'ecdsa-ca-ocsp.pem'
+  tags: [ecdsa, ocsp]
+
+- name: 'ecdsa-server-ocsp-mustStaple.pem'
+  description: ECDSA server certificate w/OCSP + must-staple
+  Issuer: 'ecdsa-ca-ocsp.pem'
+  tags: [ecdsa, ocsp, must-staple]
+
+- name: 'ecdsa-ocsp-responder.crt'
+  description: ECDSA certificate and key for OCSP responder
+  Issuer: 'ecdsa-ca-ocsp.pem'
+  tags: [ecdsa, ocsp, responder ]
+
+- name: 'ecdsa-server-ocsp-singleEndpoint.pem'
+  description: ECDSA server certificate w/OCSP + one OCSP endpoint
+  Issuer: 'ecdsa-ca-ocsp.pem'
+  tags: [ecdsa, ocsp, single-ocsp-endpoint]
+
+- name: 'ecdsa-server-ocsp-mustStaple-singleEndpoint.pem'
+  description: ECDSA server certificate w/OCSP + must-staple + one OCSP endpoint
+  Issuer: 'ecdsa-ca-ocsp.pem'
+  tags: [ecdsa, ocsp, must-staple, single-ocsp-endpoint]
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/ecdsa/ca.crt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/ecdsa/ca.crt
new file mode 100644
index 0000000000000000000000000000000000000000..623739ecbfe9cbed03ab4f73cc46edeab2f59795
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/ecdsa/ca.crt	
@@ -0,0 +1,13 @@
+-----BEGIN CERTIFICATE-----
+MIIB9jCCAZygAwIBAgIERIhZ3jAKBggqhkjOPQQDAjB6MQswCQYDVQQGEwJVUzER
+MA8GA1UECAwITmV3IFlvcmsxFjAUBgNVBAcMDU5ldyBZb3JrIENpdHkxEDAOBgNV
+BAoMB01vbmdvREIxDzANBgNVBAsMBktlcm5lbDEdMBsGA1UEAwwUS2VybmVsIFRl
+c3QgRVNDREEgQ0EwHhcNMjAwMzE3MTk0NjU5WhcNNDAwMzEyMTk0NjU5WjB6MQsw
+CQYDVQQGEwJVUzERMA8GA1UECAwITmV3IFlvcmsxFjAUBgNVBAcMDU5ldyBZb3Jr
+IENpdHkxEDAOBgNVBAoMB01vbmdvREIxDzANBgNVBAsMBktlcm5lbDEdMBsGA1UE
+AwwUS2VybmVsIFRlc3QgRVNDREEgQ0EwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNC
+AAT1rsrbhlZEQAubaPkS23tOfSEdWNd+u7N5kV4nxKQDNxPcScnSGrb41tBEINdG
+LQ/SopWZx9O8UJSrh8sqaV1AoxAwDjAMBgNVHRMEBTADAQH/MAoGCCqGSM49BAMC
+A0gAMEUCIDEvg1FnzNQNnLDxyOthbOqpX58A0YfLjgGb8xAvvdr4AiEAtvF2jMt6
+/o4HVXXKdohjBJbETbr7XILEvnZ4Zt7QNl8=
+-----END CERTIFICATE-----
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/ecdsa/ca.key b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/ecdsa/ca.key
new file mode 100644
index 0000000000000000000000000000000000000000..05935962b577757332e1a6c12f46421aed760ca4
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/ecdsa/ca.key	
@@ -0,0 +1,5 @@
+-----BEGIN PRIVATE KEY-----
+MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgMzE6ziHkSWt+sE2O
+RMFZ9wqjOg88cWTuMMYrKXXL1UWhRANCAAT1rsrbhlZEQAubaPkS23tOfSEdWNd+
+u7N5kV4nxKQDNxPcScnSGrb41tBEINdGLQ/SopWZx9O8UJSrh8sqaV1A
+-----END PRIVATE KEY-----
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/ecdsa/ca.pem b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/ecdsa/ca.pem
new file mode 100644
index 0000000000000000000000000000000000000000..b5037745c2678212608b27628eef4a93e7564576
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/ecdsa/ca.pem	
@@ -0,0 +1,18 @@
+-----BEGIN CERTIFICATE-----
+MIIB9jCCAZygAwIBAgIERIhZ3jAKBggqhkjOPQQDAjB6MQswCQYDVQQGEwJVUzER
+MA8GA1UECAwITmV3IFlvcmsxFjAUBgNVBAcMDU5ldyBZb3JrIENpdHkxEDAOBgNV
+BAoMB01vbmdvREIxDzANBgNVBAsMBktlcm5lbDEdMBsGA1UEAwwUS2VybmVsIFRl
+c3QgRVNDREEgQ0EwHhcNMjAwMzE3MTk0NjU5WhcNNDAwMzEyMTk0NjU5WjB6MQsw
+CQYDVQQGEwJVUzERMA8GA1UECAwITmV3IFlvcmsxFjAUBgNVBAcMDU5ldyBZb3Jr
+IENpdHkxEDAOBgNVBAoMB01vbmdvREIxDzANBgNVBAsMBktlcm5lbDEdMBsGA1UE
+AwwUS2VybmVsIFRlc3QgRVNDREEgQ0EwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNC
+AAT1rsrbhlZEQAubaPkS23tOfSEdWNd+u7N5kV4nxKQDNxPcScnSGrb41tBEINdG
+LQ/SopWZx9O8UJSrh8sqaV1AoxAwDjAMBgNVHRMEBTADAQH/MAoGCCqGSM49BAMC
+A0gAMEUCIDEvg1FnzNQNnLDxyOthbOqpX58A0YfLjgGb8xAvvdr4AiEAtvF2jMt6
+/o4HVXXKdohjBJbETbr7XILEvnZ4Zt7QNl8=
+-----END CERTIFICATE-----
+-----BEGIN PRIVATE KEY-----
+MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgMzE6ziHkSWt+sE2O
+RMFZ9wqjOg88cWTuMMYrKXXL1UWhRANCAAT1rsrbhlZEQAubaPkS23tOfSEdWNd+
+u7N5kV4nxKQDNxPcScnSGrb41tBEINdGLQ/SopWZx9O8UJSrh8sqaV1A
+-----END PRIVATE KEY-----
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/ecdsa/mock-delegate-revoked.sh b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/ecdsa/mock-delegate-revoked.sh
new file mode 100644
index 0000000000000000000000000000000000000000..1e40fba5a7c5cc0d46930b67d6edb5eea98ac393
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/ecdsa/mock-delegate-revoked.sh	
@@ -0,0 +1,8 @@
+#!/usr/bin/env sh
+python3 ../ocsp_mock.py \
+  --ca_file ca.pem \
+  --ocsp_responder_cert ocsp-responder.crt \
+  --ocsp_responder_key ocsp-responder.key \
+   -p 8100 \
+   -v \
+   --fault revoked
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/ecdsa/mock-delegate-valid.sh b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/ecdsa/mock-delegate-valid.sh
new file mode 100644
index 0000000000000000000000000000000000000000..5074a7ecabde4f00c9fbcd22aa0a9bca2fc62f44
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/ecdsa/mock-delegate-valid.sh	
@@ -0,0 +1,7 @@
+#!/usr/bin/env sh
+python3 ../ocsp_mock.py \
+  --ca_file ca.pem \
+  --ocsp_responder_cert ocsp-responder.crt \
+  --ocsp_responder_key ocsp-responder.key \
+   -p 8100 \
+   -v
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/ecdsa/mock-revoked.sh b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/ecdsa/mock-revoked.sh
new file mode 100644
index 0000000000000000000000000000000000000000..a6bf2ef025e5af37e90e101e4c49cb7cff522887
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/ecdsa/mock-revoked.sh	
@@ -0,0 +1,10 @@
+#!/usr/bin/env sh
+# Use the CA as the OCSP responder
+python3 ../ocsp_mock.py \
+  --ca_file ca.pem \
+  --ocsp_responder_cert ca.crt \
+  --ocsp_responder_key ca.key \
+   -p 8100 \
+   -v \
+   --fault revoked
+
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/ecdsa/mock-valid.sh b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/ecdsa/mock-valid.sh
new file mode 100644
index 0000000000000000000000000000000000000000..c89ce9e954d4b04842a768d93882dba418a0f619
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/ecdsa/mock-valid.sh	
@@ -0,0 +1,7 @@
+#!/usr/bin/env sh
+python3 ../ocsp_mock.py \
+  --ca_file ca.pem \
+  --ocsp_responder_cert ca.crt \
+  --ocsp_responder_key ca.key \
+   -p 8100 \
+   -v
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/ecdsa/ocsp-responder.crt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/ecdsa/ocsp-responder.crt
new file mode 100644
index 0000000000000000000000000000000000000000..4d3f3e9299d38f01f69746b6cdc670ea7a4277d0
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/ecdsa/ocsp-responder.crt	
@@ -0,0 +1,15 @@
+-----BEGIN CERTIFICATE-----
+MIICVTCCAfygAwIBAgIEfpRhITAKBggqhkjOPQQDAjB6MQswCQYDVQQGEwJVUzER
+MA8GA1UECAwITmV3IFlvcmsxFjAUBgNVBAcMDU5ldyBZb3JrIENpdHkxEDAOBgNV
+BAoMB01vbmdvREIxDzANBgNVBAsMBktlcm5lbDEdMBsGA1UEAwwUS2VybmVsIFRl
+c3QgRVNDREEgQ0EwHhcNMjAwMzE3MTk0NzAwWhcNNDAwMzEyMTk0NzAwWjBsMQsw
+CQYDVQQGEwJVUzERMA8GA1UECAwITmV3IFlvcmsxFjAUBgNVBAcMDU5ldyBZb3Jr
+IENpdHkxEDAOBgNVBAoMB01vbmdvREIxDzANBgNVBAsMBktlcm5lbDEPMA0GA1UE
+AwwGc2VydmVyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAERca9Bv0PDLkCULyx
+axwx8nyPqonFF88MQiZpY7wK7atBfWkpZ9B/ukq5p+xVDXxS49huEIQUWOZ5xosF
+frma96N+MHwwCQYDVR0TBAIwADAaBgNVHREEEzARgglsb2NhbGhvc3SHBH8AAAEw
+HQYDVR0OBBYEFNQUc8MKrQDR4wAFZZ2o9PNLAiUHMAsGA1UdDwQEAwIF4DAnBgNV
+HSUEIDAeBggrBgEFBQcDAQYIKwYBBQUHAwIGCCsGAQUFBwMJMAoGCCqGSM49BAMC
+A0cAMEQCIBQs56OofXC3Io6DjP4ccgpkX8cLHpMRb3jfZ6MxulniAiBVLoXo8K23
+YmpwoWKLFBKBdtGU+WDdD01Mb8X4iQ1gYg==
+-----END CERTIFICATE-----
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/ecdsa/ocsp-responder.key b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/ecdsa/ocsp-responder.key
new file mode 100644
index 0000000000000000000000000000000000000000..9e7eaa64e4eeb615bb424148cc5fa6cc76f664e1
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/ecdsa/ocsp-responder.key	
@@ -0,0 +1,5 @@
+-----BEGIN PRIVATE KEY-----
+MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgxxFxGTsPETczP0SW
+69vnqYXZIgk+qG61j6JKElHa6duhRANCAARFxr0G/Q8MuQJQvLFrHDHyfI+qicUX
+zwxCJmljvArtq0F9aSln0H+6Srmn7FUNfFLj2G4QhBRY5nnGiwV+uZr3
+-----END PRIVATE KEY-----
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/ecdsa/rename.sh b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/ecdsa/rename.sh
new file mode 100644
index 0000000000000000000000000000000000000000..cf72559c00996c671faca87792e229cc3339c758
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/ecdsa/rename.sh	
@@ -0,0 +1,10 @@
+#!/usr/bin/env bash
+[ ! -f ecdsa-ca-ocsp.pem ] || mv ecdsa-ca-ocsp.pem ca.pem
+[ ! -f ecdsa-ca-ocsp.crt ] || mv ecdsa-ca-ocsp.crt ca.crt
+[ ! -f ecdsa-ca-ocsp.key ] ||  mv ecdsa-ca-ocsp.key ca.key
+[ ! -f ecdsa-server-ocsp.pem ] || mv ecdsa-server-ocsp.pem server.pem
+[ ! -f ecdsa-server-ocsp-mustStaple.pem ] || mv ecdsa-server-ocsp-mustStaple.pem server-mustStaple.pem
+[ ! -f ecdsa-server-ocsp-singleEndpoint.pem ] || mv ecdsa-server-ocsp-singleEndpoint.pem server-singleEndpoint.pem
+[ ! -f ecdsa-server-ocsp-mustStaple-singleEndpoint.pem ] || mv ecdsa-server-ocsp-mustStaple-singleEndpoint.pem server-mustStaple-singleEndpoint.pem
+[ ! -f ecdsa-ocsp-responder.crt ] || mv ecdsa-ocsp-responder.crt ocsp-responder.crt
+[ ! -f ecdsa-ocsp-responder.key ] || mv ecdsa-ocsp-responder.key ocsp-responder.key
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/ecdsa/server-mustStaple-singleEndpoint.pem b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/ecdsa/server-mustStaple-singleEndpoint.pem
new file mode 100644
index 0000000000000000000000000000000000000000..c2d3caa3d7fc99fd942c01873cf1259876544215
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/ecdsa/server-mustStaple-singleEndpoint.pem	
@@ -0,0 +1,21 @@
+-----BEGIN CERTIFICATE-----
+MIICmzCCAkGgAwIBAgIEK6+qITAKBggqhkjOPQQDAjB6MQswCQYDVQQGEwJVUzER
+MA8GA1UECAwITmV3IFlvcmsxFjAUBgNVBAcMDU5ldyBZb3JrIENpdHkxEDAOBgNV
+BAoMB01vbmdvREIxDzANBgNVBAsMBktlcm5lbDEdMBsGA1UEAwwUS2VybmVsIFRl
+c3QgRVNDREEgQ0EwHhcNMjAwNDE3MjIwNzM4WhcNNDAwNDEyMjIwNzM4WjBsMQsw
+CQYDVQQGEwJVUzERMA8GA1UECAwITmV3IFlvcmsxFjAUBgNVBAcMDU5ldyBZb3Jr
+IENpdHkxEDAOBgNVBAoMB01vbmdvREIxDzANBgNVBAsMBktlcm5lbDEPMA0GA1UE
+AwwGc2VydmVyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEQp0AXlVttI8EFDhm
+YZZTGT0W9XZvUwk+HCVvTyRruyFI/VRW6PvLuCrMpFiXrM6kSoDQDDwcIH4jBv6u
+y5mhYaOBwjCBvzAJBgNVHRMEAjAAMBoGA1UdEQQTMBGCCWxvY2FsaG9zdIcEfwAA
+ATAdBgNVHQ4EFgQUHnyVeKPYHhZOYzAfQW+C48W+mQowCwYDVR0PBAQDAgWgMB0G
+A1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjA4BggrBgEFBQcBAQQsMCowKAYI
+KwYBBQUHMAGGHGh0dHA6Ly9sb2NhbGhvc3Q6ODEwMC9zdGF0dXMwEQYIKwYBBQUH
+ARgEBTADAgEFMAoGCCqGSM49BAMCA0gAMEUCIHiAly+9pDK3z4shFjqQZILGcvaP
+/71l3WSdKAjfKd1LAiEA9CpCiaGR1a5D8qSvr518WZtqOVB+YsEk63aJs/2PtM0=
+-----END CERTIFICATE-----
+-----BEGIN PRIVATE KEY-----
+MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgniP9x8ixUXWk16LR
+EKiL5dqh2aH/ON6EmULoaReDLTKhRANCAARCnQBeVW20jwQUOGZhllMZPRb1dm9T
+CT4cJW9PJGu7IUj9VFbo+8u4KsykWJeszqRKgNAMPBwgfiMG/q7LmaFh
+-----END PRIVATE KEY-----
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/ecdsa/server-mustStaple.pem b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/ecdsa/server-mustStaple.pem
new file mode 100644
index 0000000000000000000000000000000000000000..b539779eff5431c25f6ac6785f8c40c24dbe5bd7
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/ecdsa/server-mustStaple.pem	
@@ -0,0 +1,22 @@
+-----BEGIN CERTIFICATE-----
+MIICyjCCAnCgAwIBAgIEA54uVTAKBggqhkjOPQQDAjB6MQswCQYDVQQGEwJVUzER
+MA8GA1UECAwITmV3IFlvcmsxFjAUBgNVBAcMDU5ldyBZb3JrIENpdHkxEDAOBgNV
+BAoMB01vbmdvREIxDzANBgNVBAsMBktlcm5lbDEdMBsGA1UEAwwUS2VybmVsIFRl
+c3QgRVNDREEgQ0EwHhcNMjAwMzI2MTU1NzU1WhcNNDAwMzIxMTU1NzU1WjBsMQsw
+CQYDVQQGEwJVUzERMA8GA1UECAwITmV3IFlvcmsxFjAUBgNVBAcMDU5ldyBZb3Jr
+IENpdHkxEDAOBgNVBAoMB01vbmdvREIxDzANBgNVBAsMBktlcm5lbDEPMA0GA1UE
+AwwGc2VydmVyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEJjAN/Hd2R/RRBoAu
+YouPhTbS/y2DiD47YQaUu1TlnrvABcvIgkMKYfbeNIhBfu44KzF2sKsmKrG6T6rs
+NdJ3pqOB8TCB7jAJBgNVHRMEAjAAMBoGA1UdEQQTMBGCCWxvY2FsaG9zdIcEfwAA
+ATAdBgNVHQ4EFgQUvHVMhH4zuedQN+9sQJ8LN7jvy3owCwYDVR0PBAQDAgWgMB0G
+A1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjBnBggrBgEFBQcBAQRbMFkwLQYI
+KwYBBQUHMAGGIWh0dHA6Ly9sb2NhbGhvc3Q6OTAwMS9wb3dlci9sZXZlbDAoBggr
+BgEFBQcwAYYcaHR0cDovL2xvY2FsaG9zdDo4MTAwL3N0YXR1czARBggrBgEFBQcB
+GAQFMAMCAQUwCgYIKoZIzj0EAwIDSAAwRQIgDiL8zqWkCR5Rc/YoAgV81qryUMrK
+BQoP7fb1M0KKarECIQDPa5q1pFu+5UZ8gn7CP4/9xDcBiG6tQYK5N0FHAZXzEg==
+-----END CERTIFICATE-----
+-----BEGIN PRIVATE KEY-----
+MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg1IHezsqNUk0tfGOS
+E2RcM7R00ue1/E8/pBBUGSt7RW2hRANCAAQmMA38d3ZH9FEGgC5ii4+FNtL/LYOI
+PjthBpS7VOWeu8AFy8iCQwph9t40iEF+7jgrMXawqyYqsbpPquw10nem
+-----END PRIVATE KEY-----
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/ecdsa/server-singleEndpoint.pem b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/ecdsa/server-singleEndpoint.pem
new file mode 100644
index 0000000000000000000000000000000000000000..fb2cfc5969e2f034f8392090798a5722da93e32d
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/ecdsa/server-singleEndpoint.pem	
@@ -0,0 +1,21 @@
+-----BEGIN CERTIFICATE-----
+MIICiTCCAi6gAwIBAgIELzCNWTAKBggqhkjOPQQDAjB6MQswCQYDVQQGEwJVUzER
+MA8GA1UECAwITmV3IFlvcmsxFjAUBgNVBAcMDU5ldyBZb3JrIENpdHkxEDAOBgNV
+BAoMB01vbmdvREIxDzANBgNVBAsMBktlcm5lbDEdMBsGA1UEAwwUS2VybmVsIFRl
+c3QgRVNDREEgQ0EwHhcNMjAwNDE3MjIwNzQ0WhcNNDAwNDEyMjIwNzQ0WjBsMQsw
+CQYDVQQGEwJVUzERMA8GA1UECAwITmV3IFlvcmsxFjAUBgNVBAcMDU5ldyBZb3Jr
+IENpdHkxEDAOBgNVBAoMB01vbmdvREIxDzANBgNVBAsMBktlcm5lbDEPMA0GA1UE
+AwwGc2VydmVyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAESvwx4QUCP0f5Dr8N
+MMfO40epXIcain4+XEVy8hcAtR0nYD0QpnFJSX7E4b5eY7A/Lr7UEKx64Qg3qYEl
+FgbezaOBrzCBrDAJBgNVHRMEAjAAMBoGA1UdEQQTMBGCCWxvY2FsaG9zdIcEfwAA
+ATAdBgNVHQ4EFgQUfOg4eUnUTje/rTmAHnZ3XzdyStIwCwYDVR0PBAQDAgWgMB0G
+A1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjA4BggrBgEFBQcBAQQsMCowKAYI
+KwYBBQUHMAGGHGh0dHA6Ly9sb2NhbGhvc3Q6ODEwMC9zdGF0dXMwCgYIKoZIzj0E
+AwIDSQAwRgIhAKT+d/zTlhzZnOeU05Gi6hJAC0W9Fq4K2Sh04Cdys9kgAiEAyEla
+DrZl0P+kGIJN49CUTHBiXN1t6nSRflNrkFiPFmI=
+-----END CERTIFICATE-----
+-----BEGIN PRIVATE KEY-----
+MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgqD1jXcZlgcRjdj1l
+i2i0L0+hE4YmhdetvKwZ8REk8jqhRANCAARK/DHhBQI/R/kOvw0wx87jR6lchxqK
+fj5cRXLyFwC1HSdgPRCmcUlJfsThvl5jsD8uvtQQrHrhCDepgSUWBt7N
+-----END PRIVATE KEY-----
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/ecdsa/server.pem b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/ecdsa/server.pem
new file mode 100644
index 0000000000000000000000000000000000000000..d120e1852e0a8bdbaa038d75e2a0970b205bbe78
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/ecdsa/server.pem	
@@ -0,0 +1,22 @@
+-----BEGIN CERTIFICATE-----
+MIICtzCCAl2gAwIBAgIEP6OYOTAKBggqhkjOPQQDAjB6MQswCQYDVQQGEwJVUzER
+MA8GA1UECAwITmV3IFlvcmsxFjAUBgNVBAcMDU5ldyBZb3JrIENpdHkxEDAOBgNV
+BAoMB01vbmdvREIxDzANBgNVBAsMBktlcm5lbDEdMBsGA1UEAwwUS2VybmVsIFRl
+c3QgRVNDREEgQ0EwHhcNMjAwMzI2MTU1ODA2WhcNNDAwMzIxMTU1ODA2WjBsMQsw
+CQYDVQQGEwJVUzERMA8GA1UECAwITmV3IFlvcmsxFjAUBgNVBAcMDU5ldyBZb3Jr
+IENpdHkxEDAOBgNVBAoMB01vbmdvREIxDzANBgNVBAsMBktlcm5lbDEPMA0GA1UE
+AwwGc2VydmVyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEK4FR+soHPeGhF5c+
+bPBX9/+gm+RimTqlXQAkHQHopLETOVexyt0eAVJe/euPAdKx3JvQ2fx2YOaBZK2U
+D98UoKOB3jCB2zAJBgNVHRMEAjAAMBoGA1UdEQQTMBGCCWxvY2FsaG9zdIcEfwAA
+ATAdBgNVHQ4EFgQU2JCna5G/Yd+Hd9hkAoWXxSjQ7acwCwYDVR0PBAQDAgWgMB0G
+A1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjBnBggrBgEFBQcBAQRbMFkwLQYI
+KwYBBQUHMAGGIWh0dHA6Ly9sb2NhbGhvc3Q6OTAwMS9wb3dlci9sZXZlbDAoBggr
+BgEFBQcwAYYcaHR0cDovL2xvY2FsaG9zdDo4MTAwL3N0YXR1czAKBggqhkjOPQQD
+AgNIADBFAiEA3F6MCGLS+gBDMl3+GTAVxYYuxLbhW92CQLwh/FbDozYCIHQzJ2G/
+ht6PGW9nKueW0yDfppBVlxBmlKody9ugpcpO
+-----END CERTIFICATE-----
+-----BEGIN PRIVATE KEY-----
+MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgp33qfUjflX1C7ROa
+e5F/RNyIhLE9hnxg4eFQQTqdxUqhRANCAAQrgVH6ygc94aEXlz5s8Ff3/6Cb5GKZ
+OqVdACQdAeiksRM5V7HK3R4BUl79648B0rHcm9DZ/HZg5oFkrZQP3xSg
+-----END PRIVATE KEY-----
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/mock-ocsp-responder-requirements.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/mock-ocsp-responder-requirements.txt
new file mode 100644
index 0000000000000000000000000000000000000000..0344252b6ffe158076a5ed5b56c871d9e58fffac
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/mock-ocsp-responder-requirements.txt	
@@ -0,0 +1,3 @@
+asn1crypto==1.3.0
+flask==1.1.1
+oscrypto==1.2.0
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/mock_ocsp_responder.py b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/mock_ocsp_responder.py
new file mode 100644
index 0000000000000000000000000000000000000000..6274e97ac86841e91c2efe82613efdd40c6afc6f
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/mock_ocsp_responder.py	
@@ -0,0 +1,614 @@
+#
+# This file has been modified in 2019 by MongoDB Inc.
+#
+
+# OCSPBuilder is derived from https://github.com/wbond/ocspbuilder
+# OCSPResponder is derived from https://github.com/threema-ch/ocspresponder
+
+# Copyright (c) 2015-2018 Will Bond <will@wbond.net>
+
+# Permission is hereby granted, free of charge, to any person obtaining a copy of
+# this software and associated documentation files (the "Software"), to deal in
+# the Software without restriction, including without limitation the rights to
+# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+# of the Software, and to permit persons to whom the Software is furnished to do
+# so, subject to the following conditions:
+
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+# Copyright 2016 Threema GmbH
+
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+
+#    http://www.apache.org/licenses/LICENSE-2.0
+
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from __future__ import unicode_literals, division, absolute_import, print_function
+
+import logging
+import base64
+import inspect
+import re
+import enum
+import sys
+import textwrap
+from datetime import datetime, timezone, timedelta
+from typing import Callable, Tuple, Optional
+
+from asn1crypto import x509, keys, core, ocsp
+from asn1crypto.ocsp import OCSPRequest, OCSPResponse
+from oscrypto import asymmetric
+from flask import Flask, request, Response
+
+__version__ = '0.10.2'
+__version_info__ = (0, 10, 2)
+
+logger = logging.getLogger(__name__)
+
+if sys.version_info < (3,):
+    byte_cls = str
+else:
+    byte_cls = bytes
+
+def _pretty_message(string, *params):
+    """
+    Takes a multi-line string and does the following:
+     - dedents
+     - converts newlines with text before and after into a single line
+     - strips leading and trailing whitespace
+    :param string:
+        The string to format
+    :param *params:
+        Params to interpolate into the string
+    :return:
+        The formatted string
+    """
+
+    output = textwrap.dedent(string)
+
+    # Unwrap lines, taking into account bulleted lists, ordered lists and
+    # underlines consisting of = signs
+    if output.find('\n') != -1:
+        output = re.sub('(?<=\\S)\n(?=[^ \n\t\\d\\*\\-=])', ' ', output)
+
+    if params:
+        output = output % params
+
+    output = output.strip()
+
+    return output
+
+
+def _type_name(value):
+    """
+    :param value:
+        A value to get the object name of
+    :return:
+        A unicode string of the object name
+    """
+
+    if inspect.isclass(value):
+        cls = value
+    else:
+        cls = value.__class__
+    if cls.__module__ in set(['builtins', '__builtin__']):
+        return cls.__name__
+    return '%s.%s' % (cls.__module__, cls.__name__)
+
+def _writer(func):
+    """
+    Decorator for a custom writer, but a default reader
+    """
+
+    name = func.__name__
+    return property(fget=lambda self: getattr(self, '_%s' % name), fset=func)
+
+
+class OCSPResponseBuilder(object):
+
+    _response_status = None
+    _certificate = None
+    _certificate_status = None
+    _revocation_date = None
+    _certificate_issuer = None
+    _hash_algo = None
+    _key_hash_algo = None
+    _nonce = None
+    _this_update = None
+    _next_update = None
+    _response_data_extensions = None
+    _single_response_extensions = None
+
+    def __init__(self, response_status, certificate_status_list=[], revocation_date=None):
+        """
+        Unless changed, responses will use SHA-256 for the signature,
+        and will be valid from the moment created for one week.
+        :param response_status:
+            A unicode string of OCSP response type:
+            - "successful" - when the response includes information about the certificate
+            - "malformed_request" - when the request could not be understood
+            - "internal_error" - when an internal error occured with the OCSP responder
+            - "try_later" - when the OCSP responder is temporarily unavailable
+            - "sign_required" - when the OCSP request must be signed
+            - "unauthorized" - when the responder is not the correct responder for the certificate
+        :param certificate_list:
+            A list of tuples with certificate serial number and certificate status objects.
+            certificate_status:
+                A unicode string of the status of the certificate. Only required if
+                the response_status is "successful".
+                - "good" - when the certificate is in good standing
+                - "revoked" - when the certificate is revoked without a reason code
+                - "key_compromise" - when a private key is compromised
+                - "ca_compromise" - when the CA issuing the certificate is compromised
+                - "affiliation_changed" - when the certificate subject name changed
+                - "superseded" - when the certificate was replaced with a new one
+                - "cessation_of_operation" - when the certificate is no longer needed
+                - "certificate_hold" - when the certificate is temporarily invalid
+                - "remove_from_crl" - only delta CRLs - when temporary hold is removed
+                - "privilege_withdrawn" - one of the usages for a certificate was removed
+                - "unknown" - the responder doesn't know about the certificate being requested
+        :param revocation_date:
+            A datetime.datetime object of when the certificate was revoked, if
+            the response_status is "successful" and the certificate status is
+            not "good" or "unknown".
+        """
+        self._response_status = response_status
+        self._certificate_status_list = certificate_status_list
+        self._revocation_date = revocation_date
+
+        self._key_hash_algo = 'sha1'
+        self._hash_algo = 'sha256'
+        self._response_data_extensions = {}
+        self._single_response_extensions = {}
+
+    @_writer
+    def nonce(self, value):
+        """
+        The nonce that was provided during the request.
+        """
+
+        if not isinstance(value, byte_cls):
+            raise TypeError(_pretty_message(
+                '''
+                nonce must be a byte string, not %s
+                ''',
+                _type_name(value)
+            ))
+
+        self._nonce = value
+
+    @_writer
+    def certificate_issuer(self, value):
+        """
+        An asn1crypto.x509.Certificate object of the issuer of the certificate.
+        This should only be set if the OCSP responder is not the issuer of
+        the certificate, but instead a special certificate only for OCSP
+        responses.
+        """
+
+        if value is not None:
+            is_oscrypto = isinstance(value, asymmetric.Certificate)
+            if not is_oscrypto and not isinstance(value, x509.Certificate):
+                raise TypeError(_pretty_message(
+                    '''
+                    certificate_issuer must be an instance of
+                    asn1crypto.x509.Certificate or
+                    oscrypto.asymmetric.Certificate, not %s
+                    ''',
+                    _type_name(value)
+                ))
+
+            if is_oscrypto:
+                value = value.asn1
+
+        self._certificate_issuer = value
+
+    @_writer
+    def next_update(self, value):
+        """
+        A datetime.datetime object of when the response may next change. This
+        should only be set if responses are cached. If responses are generated
+        fresh on every request, this should not be set.
+        """
+
+        if not isinstance(value, datetime):
+            raise TypeError(_pretty_message(
+                '''
+                next_update must be an instance of datetime.datetime, not %s
+                ''',
+                _type_name(value)
+            ))
+
+        self._next_update = value
+
+    def build(self, responder_private_key=None, responder_certificate=None):
+        """
+        Validates the request information, constructs the ASN.1 structure and
+        signs it.
+        The responder_private_key and responder_certificate parameters are onlystr
+        required if the response_status is "successful".
+        :param responder_private_key:
+            An asn1crypto.keys.PrivateKeyInfo or oscrypto.asymmetric.PrivateKey
+            object for the private key to sign the response with
+        :param responder_certificate:
+            An asn1crypto.x509.Certificate or oscrypto.asymmetric.Certificate
+            object of the certificate associated with the private key
+        :return:
+            An asn1crypto.ocsp.OCSPResponse object of the response
+        """
+        if self._response_status != 'successful':
+            return ocsp.OCSPResponse({
+                'response_status': self._response_status
+            })
+
+        is_oscrypto = isinstance(responder_private_key, asymmetric.PrivateKey)
+        if not isinstance(responder_private_key, keys.PrivateKeyInfo) and not is_oscrypto:
+            raise TypeError(_pretty_message(
+                '''
+                responder_private_key must be an instance ofthe c
+                asn1crypto.keys.PrivateKeyInfo or
+                oscrypto.asymmetric.PrivateKey, not %s
+                ''',
+                _type_name(responder_private_key)
+            ))
+
+        cert_is_oscrypto = isinstance(responder_certificate, asymmetric.Certificate)
+        if not isinstance(responder_certificate, x509.Certificate) and not cert_is_oscrypto:
+            raise TypeError(_pretty_message(
+                '''
+                responder_certificate must be an instance of
+                asn1crypto.x509.Certificate or
+                oscrypto.asymmetric.Certificate, not %s
+                ''',
+                _type_name(responder_certificate)
+            ))
+
+        if cert_is_oscrypto:
+            responder_certificate = responder_certificate.asn1
+
+        if self._certificate_status_list is None:
+            raise ValueError(_pretty_message(
+                '''
+                certificate_status_list must be set if the response_status is
+                "successful"
+                '''
+            ))
+
+        def _make_extension(name, value):
+            return {
+                'extn_id': name,
+                'critical': False,
+                'extn_value': value
+            }
+
+        responses = []
+        for serial, status in self._certificate_status_list:
+            response_data_extensions = []
+            single_response_extensions = []
+            for name, value in self._response_data_extensions.items():
+                response_data_extensions.append(_make_extension(name, value))
+            if self._nonce:
+                response_data_extensions.append(
+                    _make_extension('nonce', self._nonce)
+                )
+
+            if not response_data_extensions:
+                response_data_extensions = None
+
+            for name, value in self._single_response_extensions.items():
+                single_response_extensions.append(_make_extension(name, value))
+
+            if self._certificate_issuer:
+                single_response_extensions.append(
+                    _make_extension(
+                        'certificate_issuer',
+                        [
+                            x509.GeneralName(
+                                name='directory_name',
+                                value=self._certificate_issuer.subject
+                            )
+                        ]
+                    )
+                )
+
+            if not single_response_extensions:
+                single_response_extensions = None
+
+            responder_key_hash = getattr(responder_certificate.public_key, self._key_hash_algo)
+
+            if status == 'good':
+                cert_status = ocsp.CertStatus(
+                    name='good',
+                    value=core.Null()
+                )
+            elif status == 'unknown':
+                cert_status = ocsp.CertStatus(
+                    name='unknown',
+                    value=core.Null()
+                )
+            else:
+                reason = status if status != 'revoked' else 'unspecified'
+                cert_status = ocsp.CertStatus(
+                    name='revoked',
+                    value={
+                        'revocation_time': self._revocation_date,
+                        'revocation_reason': reason,
+                    }
+                )
+
+            issuer = self._certificate_issuer if self._certificate_issuer else responder_certificate
+
+            produced_at = datetime.now(timezone.utc).replace(microsecond=0)
+
+            if self._this_update is None:
+                self._this_update = produced_at
+
+            if self._next_update is None:
+                self._next_update = (self._this_update + timedelta(days=7)).replace(microsecond=0)
+
+            response = {
+                    'cert_id': {
+                        'hash_algorithm': {
+                            'algorithm': self._key_hash_algo
+                        },
+                        'issuer_name_hash': getattr(issuer.subject, self._key_hash_algo),
+                        'issuer_key_hash': getattr(issuer.public_key, self._key_hash_algo),
+                        'serial_number': serial,
+                    },
+                    'cert_status': cert_status,
+                    'this_update': self._this_update,
+                    'next_update': self._next_update,
+                    'single_extensions': single_response_extensions
+                }
+            responses.append(response)
+
+        response_data = ocsp.ResponseData({
+            'responder_id': ocsp.ResponderId(name='by_key', value=responder_key_hash),
+            'produced_at': produced_at,
+            'responses': responses,
+            'response_extensions': response_data_extensions
+        })
+
+        signature_algo = responder_private_key.algorithm
+        if signature_algo == 'ec':
+            signature_algo = 'ecdsa'
+
+        signature_algorithm_id = '%s_%s' % (self._hash_algo, signature_algo)
+
+        if responder_private_key.algorithm == 'rsa':
+            sign_func = asymmetric.rsa_pkcs1v15_sign
+        elif responder_private_key.algorithm == 'dsa':
+            sign_func = asymmetric.dsa_sign
+        elif responder_private_key.algorithm == 'ec':
+            sign_func = asymmetric.ecdsa_sign
+
+        if not is_oscrypto:
+            responder_private_key = asymmetric.load_private_key(responder_private_key)
+        signature_bytes = sign_func(responder_private_key, response_data.dump(), self._hash_algo)
+
+        certs = None
+        if self._certificate_issuer and getattr(self._certificate_issuer.public_key, self._key_hash_algo) != responder_key_hash:
+            certs = [responder_certificate]
+
+        return ocsp.OCSPResponse({
+            'response_status': self._response_status,
+            'response_bytes': {
+                'response_type': 'basic_ocsp_response',
+                'response': {
+                    'tbs_response_data': response_data,
+                    'signature_algorithm': {'algorithm': signature_algorithm_id},
+                    'signature': signature_bytes,
+                    'certs': certs,
+                }
+            }
+        })
+
+# Enums
+
+class ResponseStatus(enum.Enum):
+    successful = 'successful'
+    malformed_request = 'malformed_request'
+    internal_error = 'internal_error'
+    try_later = 'try_later'
+    sign_required = 'sign_required'
+    unauthorized = 'unauthorized'
+
+
+class CertificateStatus(enum.Enum):
+    good = 'good'
+    revoked = 'revoked'
+    key_compromise = 'key_compromise'
+    ca_compromise = 'ca_compromise'
+    affiliation_changed = 'affiliation_changed'
+    superseded = 'superseded'
+    cessation_of_operation = 'cessation_of_operation'
+    certificate_hold = 'certificate_hold'
+    remove_from_crl = 'remove_from_crl'
+    privilege_withdrawn = 'privilege_withdrawn'
+    unknown = 'unknown'
+
+
+# API endpoints
+FAULT_REVOKED = "revoked"
+FAULT_UNKNOWN = "unknown"
+
+app = Flask(__name__)
+class OCSPResponder:
+
+    def __init__(self, issuer_cert: str, responder_cert: str, responder_key: str,
+                       fault: str, next_update_seconds: int):
+        """
+        Create a new OCSPResponder instance.
+
+        :param issuer_cert: Path to the issuer certificate.
+        :param responder_cert: Path to the certificate of the OCSP responder
+            with the `OCSP Signing` extension.
+        :param responder_key: Path to the private key belonging to the
+            responder cert.
+        :param validate_func: A function that - given a certificate serial -
+            will return the appropriate :class:`CertificateStatus` and -
+            depending on the status - a revocation datetime.
+        :param cert_retrieve_func: A function that - given a certificate serial -
+            will return the corresponding certificate as a string.
+        :param next_update_seconds: The ``nextUpdate`` value that will be written
+            into the response. Default: 9 hours.
+
+        """
+        # Certs and keys
+        self._issuer_cert = asymmetric.load_certificate(issuer_cert)
+        self._responder_cert = asymmetric.load_certificate(responder_cert)
+        self._responder_key = asymmetric.load_private_key(responder_key)
+
+        # Next update
+        self._next_update_seconds = next_update_seconds
+
+        self._fault = fault
+
+    def _fail(self, status: ResponseStatus) -> OCSPResponse:
+        builder = OCSPResponseBuilder(response_status=status.value)
+        return builder.build()
+
+    def parse_ocsp_request(self, request_der: bytes) -> OCSPRequest:
+        """
+        Parse the request bytes, return an ``OCSPRequest`` instance.
+        """
+        return OCSPRequest.load(request_der)
+
+    def validate(self):
+        time = datetime(2018, 1, 1, 1, 00, 00, 00, timezone.utc)
+        if self._fault == FAULT_REVOKED:
+            return (CertificateStatus.revoked, time)
+        elif self._fault == FAULT_UNKNOWN:
+            return (CertificateStatus.unknown, None)
+        elif self._fault != None:
+            raise NotImplemented('Fault type could not be found')
+        return (CertificateStatus.good, time)
+
+    def _build_ocsp_response(self, ocsp_request: OCSPRequest) -> OCSPResponse:
+        """
+        Create and return an OCSP response from an OCSP request.
+        """
+        # Get the certificate serial
+        tbs_request = ocsp_request['tbs_request']
+        request_list = tbs_request['request_list']
+        if len(request_list) < 1:
+            logger.warning('Received OCSP request with no requests')
+            raise NotImplemented('Empty requests not supported')
+
+        single_request = request_list[0]  # TODO: Support more than one request
+        req_cert = single_request['req_cert']
+        serial = req_cert['serial_number'].native
+
+        # Check certificate status
+        try:
+            certificate_status, revocation_date = self.validate()
+        except Exception as e:
+            logger.exception('Could not determine certificate status: %s', e)
+            return self._fail(ResponseStatus.internal_error)
+
+        certificate_status_list = [(serial, certificate_status.value)]
+
+        # Build the response
+        builder = OCSPResponseBuilder(**{
+            'response_status': ResponseStatus.successful.value,
+            'certificate_status_list': certificate_status_list,
+            'revocation_date': revocation_date,
+        })
+
+        # Parse extensions
+        for extension in tbs_request['request_extensions']:
+            extn_id = extension['extn_id'].native
+            critical = extension['critical'].native
+            value = extension['extn_value'].parsed
+
+            # This variable tracks whether any unknown extensions were encountered
+            unknown = False
+
+            # Handle nonce extension
+            if extn_id == 'nonce':
+                builder.nonce = value.native
+
+            # That's all we know
+            else:
+                unknown = True
+
+            # If an unknown critical extension is encountered (which should not
+            # usually happen, according to RFC 6960 4.1.2), we should throw our
+            # hands up in despair and run.
+            if unknown is True and critical is True:
+                logger.warning('Could not parse unknown critical extension: %r',
+                        dict(extension.native))
+                return self._fail(ResponseStatus.internal_error)
+
+            # If it's an unknown non-critical extension, we can safely ignore it.
+            elif unknown is True:
+                logger.info('Ignored unknown non-critical extension: %r', dict(extension.native))
+
+        # Set certificate issuer
+        builder.certificate_issuer = self._issuer_cert
+
+        # Set next update date
+        now = datetime.now(timezone.utc)
+        builder.next_update = (now + timedelta(seconds=self._next_update_seconds)).replace(microsecond=0)
+
+        return builder.build(self._responder_key, self._responder_cert)
+
+    def build_http_response(self, request_der: bytes) -> Response:
+        global app
+        response_der = self._build_ocsp_response(request_der).dump()
+        resp = app.make_response((response_der, 200))
+        resp.headers['content_type'] = 'application/ocsp-response'
+        return resp
+
+
+responder = None
+
+def init_responder(issuer_cert: str, responder_cert: str, responder_key: str, fault: str, next_update_seconds: int):
+    global responder
+    responder = OCSPResponder(issuer_cert=issuer_cert, responder_cert=responder_cert, responder_key=responder_key, fault=fault, next_update_seconds=next_update_seconds)
+
+def init(port=8080, debug=False):
+    logger.info('Launching %sserver on port %d', 'debug' if debug else '', port)
+    app.run(port=port, debug=debug)
+
+@app.route('/', methods=['GET'])
+def _handle_root():
+    return 'ocsp-responder'
+
+@app.route('/status/', defaults={'u_path': ''}, methods=['GET'])
+@app.route('/status/<path:u_path>', methods=['GET'])
+def _handle_get(u_path):
+    global responder
+    """
+    An OCSP GET request contains the DER-in-base64 encoded OCSP request in the
+    HTTP request URL.
+    """
+    der = base64.b64decode(u_path)
+    ocsp_request = responder.parse_ocsp_request(der)
+    return responder.build_http_response(ocsp_request)
+
+@app.route('/status', methods=['POST'])
+def _handle_post():
+    global responder
+    """
+    An OCSP POST request contains the DER encoded OCSP request in the HTTP
+    request body.
+    """
+    ocsp_request = responder.parse_ocsp_request(request.data)
+    return responder.build_http_response(ocsp_request)
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/ocsp_mock.py b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/ocsp_mock.py
new file mode 100644
index 0000000000000000000000000000000000000000..04963b38559b733f7a71a42d03f4145b8df34bce
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/ocsp_mock.py	
@@ -0,0 +1,48 @@
+#! /usr/bin/env python3
+"""
+Python script to interface as a mock OCSP responder.
+"""
+
+import argparse
+import logging
+import sys
+import os
+
+sys.path.append(os.path.join(os.getcwd() ,'src', 'third_party', 'mock_ocsp_responder'))
+
+import mock_ocsp_responder
+
+def main():
+    """Main entry point"""
+    parser = argparse.ArgumentParser(description="MongoDB Mock OCSP Responder.")
+
+    parser.add_argument('-p', '--port', type=int, default=8080, help="Port to listen on")
+
+    parser.add_argument('--ca_file', type=str, required=True, help="CA file for OCSP responder")
+
+    parser.add_argument('-v', '--verbose', action='count', help="Enable verbose tracing")
+
+    parser.add_argument('--ocsp_responder_cert', type=str, required=True, help="OCSP Responder Certificate")
+
+    parser.add_argument('--ocsp_responder_key', type=str, required=True, help="OCSP Responder Keyfile")
+
+    parser.add_argument('--fault', choices=[mock_ocsp_responder.FAULT_REVOKED, mock_ocsp_responder.FAULT_UNKNOWN, None], default=None, type=str, help="Specify a specific fault to test")
+
+    parser.add_argument('--next_update_seconds', type=int, default=32400, help="Specify how long the OCSP response should be valid for")
+
+    args = parser.parse_args()
+    if args.verbose:
+        logging.basicConfig(level=logging.DEBUG)
+
+    print('Initializing OCSP Responder')
+    mock_ocsp_responder.init_responder(issuer_cert=args.ca_file, responder_cert=args.ocsp_responder_cert, responder_key=args.ocsp_responder_key, fault=args.fault, next_update_seconds=args.next_update_seconds)
+
+    if args.verbose:
+        mock_ocsp_responder.init(args.port, debug=True)
+    else:
+        mock_ocsp_responder.init(args.port)
+
+    print('Mock OCSP Responder is running on port %s' % (str(args.port)))
+
+if __name__ == '__main__':
+    main()
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/rsa/ca.crt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/rsa/ca.crt
new file mode 100644
index 0000000000000000000000000000000000000000..ee6dc5a65f764175c99bfd0891a176fb4d372ef2
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/rsa/ca.crt	
@@ -0,0 +1,21 @@
+-----BEGIN CERTIFICATE-----
+MIIDeTCCAmGgAwIBAgIEZLtwgzANBgkqhkiG9w0BAQsFADB0MQswCQYDVQQGEwJV
+UzERMA8GA1UECAwITmV3IFlvcmsxFjAUBgNVBAcMDU5ldyBZb3JrIENpdHkxEDAO
+BgNVBAoMB01vbmdvREIxDzANBgNVBAsMBktlcm5lbDEXMBUGA1UEAwwOS2VybmVs
+IFRlc3QgQ0EwHhcNMjAwMjA2MjAxMzExWhcNNDAwMjA4MjAxMzExWjB0MQswCQYD
+VQQGEwJVUzERMA8GA1UECAwITmV3IFlvcmsxFjAUBgNVBAcMDU5ldyBZb3JrIENp
+dHkxEDAOBgNVBAoMB01vbmdvREIxDzANBgNVBAsMBktlcm5lbDEXMBUGA1UEAwwO
+S2VybmVsIFRlc3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC0
+D1mnIrh7RRrCUEocNYLMZ2azo6c6NUTqSAMQyDDvRUsezil2NCqKo0ptMRtmb8Ws
+yuaRUkjFhh9M69kiuj89GKRALXxExHjWX7e8iS1NTGL+Uakc1J23Z5FvlUyVLucC
+fcAZ6MvcC7n6qpzUxkqz1u/27Ze9nv2mleLYBVWbGpjSHAUDuZzMCBs5Q/QrUwL7
+4cIxNsS0iHpYI3aee67cmFoK4guN9LBOtviyXUTP22kJLXe41HDjdWh01+FxcuwH
+rGmeGQwiSlw48wkdoC0M51SwpHEq+K91BqGsTboC5mshqKA88OPf5JK9ied/OsNX
++K6p5v3RVHn89VaWiTorAgMBAAGjEzARMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZI
+hvcNAQELBQADggEBAAd1jj1GECUEJMH00IX3VFgb2RpJ4Qi8TKAZgMMHdE7Cyv4M
+p4w/zvQC1F6i54n+TWucq3I+c33lEj63ybFdJO5HOWoGzC/f5qO7z0gYdP2Ltdxg
+My2uVZNQS+B8hF9MhGUeFnOpzAbKW2If3KN1fn/m2NDYGEK/Z2t7ZkpOcpEW5Lib
+vX+BBG/s4DeyhRXy+grs0ASU/z8VOhZYSJpgdbvXsY4RXXloTDcWIlNqra5K6+3T
+nVEkBDm0Qw97Y6FsqBVxk4kgWC6xNxQ4Sp+Sg4wthMQ70iFGlMin0kYRo7kAIUF9
+M+v2vMwTFWkcl0BT5LobE39kWVbQKEVPH7nkItE=
+-----END CERTIFICATE-----
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/rsa/ca.key b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/rsa/ca.key
new file mode 100644
index 0000000000000000000000000000000000000000..9d10cb2db9db11fd83896b771594fdae1eb9f24a
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/rsa/ca.key	
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC0D1mnIrh7RRrC
+UEocNYLMZ2azo6c6NUTqSAMQyDDvRUsezil2NCqKo0ptMRtmb8WsyuaRUkjFhh9M
+69kiuj89GKRALXxExHjWX7e8iS1NTGL+Uakc1J23Z5FvlUyVLucCfcAZ6MvcC7n6
+qpzUxkqz1u/27Ze9nv2mleLYBVWbGpjSHAUDuZzMCBs5Q/QrUwL74cIxNsS0iHpY
+I3aee67cmFoK4guN9LBOtviyXUTP22kJLXe41HDjdWh01+FxcuwHrGmeGQwiSlw4
+8wkdoC0M51SwpHEq+K91BqGsTboC5mshqKA88OPf5JK9ied/OsNX+K6p5v3RVHn8
+9VaWiTorAgMBAAECggEBAJ7umazMGdg80/TGF9Q0a2JutplDj5zyXgUJUSNkAMWB
+/V+Qi8pZG1/J6CzfVpche3McmU2WOsOWslQcLUnY6W7NLFW1kGXGof5e+HgDASik
+jxB6FfJrvVagpR+/wZxAjQmG46Q69o4hD6SxKcMpz9BTnPXxG6n1B2EeFd+lPb2r
+zf/C4uXBczWn5rFXkj0DZGq81ZXewcnUNnxjQnccVCuYW+hqYxznSxqWTCD6hsvg
+sGceqv0Ppp6TqMSECCIIJ+kVlbiAC2i6mnoertheFVrNUdwDb8nRn6fs8T+F0ShW
+PdxIfSvAaBKqvseJqqueVpuwVcdSl+moJYlCdMb4cUECgYEA30AIHvMQq/s33ipV
+62xOKXcEZ7tKaJrAbJvG4cx934wNiQ0tLwRNlonGbuTjsUaPRvagVeJND/UPIsfH
+ZwoY1Uw25fZNaveoQtU8LQBAG53R5yaMiUH48JWVvKRdfG09zr6EFCM/k2loHS1W
+/CiDlaIl59B8REnihyn0wvkiaIsCgYEAznlZRhlruk+n2sWklierav4M8GEK22+/
+A/UP1eUnlcHgSaFZoM0sukSrisZnj6zu/BAfFEVN5czra3ARrLClLQteFREr2BMF
+9XymrjNG99QkBAall7BGpfkDW/D2DFZa4G5R6AMG+pYZHCU84U4QT5ZKyfdhTUbQ
+uTYx2F31COECgYAIUm+7D56AerXjbzqSsw/a1dfxMfcdHR+tLMVmJ2RNz/+1KyuT
+BBsMUIh4G8otEo9GuuzRJsVuodj1l/Lj8WlpkhS9z8elBCRekWpT1x2Mqf5oGnTE
+rRPli/3v8USW3c+fBFUSFxpImXZLGCSU88Gr80ZsdMYdGY/7L+Iy3myc7wKBgQC1
+uHeqCpWV1KWXFnxU63UjJZWdussjdqZXhUf6qUS9uXT9WNTZgbrr9aRE73oWKc3s
+awPvg0+cAU7xsCDeLFoz2t1jDUnZUmTcOmk4yEidtkg8gt0bNDn5ucALG3hyQ06Y
+WIAeAwwRYCmZa+y5H0ubwFryhpdMvBbX66rTE16mAQKBgC5PJd9zLEzyLj/jUfZ0
+xOwXubu9GejOuCiVwKMTn73nvdi57zFBOrDxSl9yVCRhve61L5fcJixRDiwx8qtd
+VGclRMxbVPKVfKpAyKjpsmZXk3IPHjXjJb3fYLXAnzRHk6v+yjVn4fy2Z93pW/cF
+wBgQNqXLNTGrBzrFi469oc1s
+-----END PRIVATE KEY-----
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/rsa/ca.pem b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/rsa/ca.pem
new file mode 100644
index 0000000000000000000000000000000000000000..afa468f04ba7af74cd869a5e856642d59e2f3a19
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/rsa/ca.pem	
@@ -0,0 +1,49 @@
+-----BEGIN CERTIFICATE-----
+MIIDeTCCAmGgAwIBAgIEZLtwgzANBgkqhkiG9w0BAQsFADB0MQswCQYDVQQGEwJV
+UzERMA8GA1UECAwITmV3IFlvcmsxFjAUBgNVBAcMDU5ldyBZb3JrIENpdHkxEDAO
+BgNVBAoMB01vbmdvREIxDzANBgNVBAsMBktlcm5lbDEXMBUGA1UEAwwOS2VybmVs
+IFRlc3QgQ0EwHhcNMjAwMjA2MjAxMzExWhcNNDAwMjA4MjAxMzExWjB0MQswCQYD
+VQQGEwJVUzERMA8GA1UECAwITmV3IFlvcmsxFjAUBgNVBAcMDU5ldyBZb3JrIENp
+dHkxEDAOBgNVBAoMB01vbmdvREIxDzANBgNVBAsMBktlcm5lbDEXMBUGA1UEAwwO
+S2VybmVsIFRlc3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC0
+D1mnIrh7RRrCUEocNYLMZ2azo6c6NUTqSAMQyDDvRUsezil2NCqKo0ptMRtmb8Ws
+yuaRUkjFhh9M69kiuj89GKRALXxExHjWX7e8iS1NTGL+Uakc1J23Z5FvlUyVLucC
+fcAZ6MvcC7n6qpzUxkqz1u/27Ze9nv2mleLYBVWbGpjSHAUDuZzMCBs5Q/QrUwL7
+4cIxNsS0iHpYI3aee67cmFoK4guN9LBOtviyXUTP22kJLXe41HDjdWh01+FxcuwH
+rGmeGQwiSlw48wkdoC0M51SwpHEq+K91BqGsTboC5mshqKA88OPf5JK9ied/OsNX
++K6p5v3RVHn89VaWiTorAgMBAAGjEzARMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZI
+hvcNAQELBQADggEBAAd1jj1GECUEJMH00IX3VFgb2RpJ4Qi8TKAZgMMHdE7Cyv4M
+p4w/zvQC1F6i54n+TWucq3I+c33lEj63ybFdJO5HOWoGzC/f5qO7z0gYdP2Ltdxg
+My2uVZNQS+B8hF9MhGUeFnOpzAbKW2If3KN1fn/m2NDYGEK/Z2t7ZkpOcpEW5Lib
+vX+BBG/s4DeyhRXy+grs0ASU/z8VOhZYSJpgdbvXsY4RXXloTDcWIlNqra5K6+3T
+nVEkBDm0Qw97Y6FsqBVxk4kgWC6xNxQ4Sp+Sg4wthMQ70iFGlMin0kYRo7kAIUF9
+M+v2vMwTFWkcl0BT5LobE39kWVbQKEVPH7nkItE=
+-----END CERTIFICATE-----
+-----BEGIN PRIVATE KEY-----
+MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC0D1mnIrh7RRrC
+UEocNYLMZ2azo6c6NUTqSAMQyDDvRUsezil2NCqKo0ptMRtmb8WsyuaRUkjFhh9M
+69kiuj89GKRALXxExHjWX7e8iS1NTGL+Uakc1J23Z5FvlUyVLucCfcAZ6MvcC7n6
+qpzUxkqz1u/27Ze9nv2mleLYBVWbGpjSHAUDuZzMCBs5Q/QrUwL74cIxNsS0iHpY
+I3aee67cmFoK4guN9LBOtviyXUTP22kJLXe41HDjdWh01+FxcuwHrGmeGQwiSlw4
+8wkdoC0M51SwpHEq+K91BqGsTboC5mshqKA88OPf5JK9ied/OsNX+K6p5v3RVHn8
+9VaWiTorAgMBAAECggEBAJ7umazMGdg80/TGF9Q0a2JutplDj5zyXgUJUSNkAMWB
+/V+Qi8pZG1/J6CzfVpche3McmU2WOsOWslQcLUnY6W7NLFW1kGXGof5e+HgDASik
+jxB6FfJrvVagpR+/wZxAjQmG46Q69o4hD6SxKcMpz9BTnPXxG6n1B2EeFd+lPb2r
+zf/C4uXBczWn5rFXkj0DZGq81ZXewcnUNnxjQnccVCuYW+hqYxznSxqWTCD6hsvg
+sGceqv0Ppp6TqMSECCIIJ+kVlbiAC2i6mnoertheFVrNUdwDb8nRn6fs8T+F0ShW
+PdxIfSvAaBKqvseJqqueVpuwVcdSl+moJYlCdMb4cUECgYEA30AIHvMQq/s33ipV
+62xOKXcEZ7tKaJrAbJvG4cx934wNiQ0tLwRNlonGbuTjsUaPRvagVeJND/UPIsfH
+ZwoY1Uw25fZNaveoQtU8LQBAG53R5yaMiUH48JWVvKRdfG09zr6EFCM/k2loHS1W
+/CiDlaIl59B8REnihyn0wvkiaIsCgYEAznlZRhlruk+n2sWklierav4M8GEK22+/
+A/UP1eUnlcHgSaFZoM0sukSrisZnj6zu/BAfFEVN5czra3ARrLClLQteFREr2BMF
+9XymrjNG99QkBAall7BGpfkDW/D2DFZa4G5R6AMG+pYZHCU84U4QT5ZKyfdhTUbQ
+uTYx2F31COECgYAIUm+7D56AerXjbzqSsw/a1dfxMfcdHR+tLMVmJ2RNz/+1KyuT
+BBsMUIh4G8otEo9GuuzRJsVuodj1l/Lj8WlpkhS9z8elBCRekWpT1x2Mqf5oGnTE
+rRPli/3v8USW3c+fBFUSFxpImXZLGCSU88Gr80ZsdMYdGY/7L+Iy3myc7wKBgQC1
+uHeqCpWV1KWXFnxU63UjJZWdussjdqZXhUf6qUS9uXT9WNTZgbrr9aRE73oWKc3s
+awPvg0+cAU7xsCDeLFoz2t1jDUnZUmTcOmk4yEidtkg8gt0bNDn5ucALG3hyQ06Y
+WIAeAwwRYCmZa+y5H0ubwFryhpdMvBbX66rTE16mAQKBgC5PJd9zLEzyLj/jUfZ0
+xOwXubu9GejOuCiVwKMTn73nvdi57zFBOrDxSl9yVCRhve61L5fcJixRDiwx8qtd
+VGclRMxbVPKVfKpAyKjpsmZXk3IPHjXjJb3fYLXAnzRHk6v+yjVn4fy2Z93pW/cF
+wBgQNqXLNTGrBzrFi469oc1s
+-----END PRIVATE KEY-----
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/rsa/mock-delegate-revoked.sh b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/rsa/mock-delegate-revoked.sh
new file mode 100644
index 0000000000000000000000000000000000000000..adf026ce1b327719fbea14a46f942de1f9967133
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/rsa/mock-delegate-revoked.sh	
@@ -0,0 +1,8 @@
+#!/usr/bin/env sh
+python3 ../ocsp_mock.py \
+  --ca_file ca.pem \
+  --ocsp_responder_cert ocsp_responder.crt \
+  --ocsp_responder_key ocsp_responder.key \
+   -p 8100 \
+   -v \
+   --fault revoked
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/rsa/mock-delegate-valid.sh b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/rsa/mock-delegate-valid.sh
new file mode 100644
index 0000000000000000000000000000000000000000..5074a7ecabde4f00c9fbcd22aa0a9bca2fc62f44
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/rsa/mock-delegate-valid.sh	
@@ -0,0 +1,7 @@
+#!/usr/bin/env sh
+python3 ../ocsp_mock.py \
+  --ca_file ca.pem \
+  --ocsp_responder_cert ocsp-responder.crt \
+  --ocsp_responder_key ocsp-responder.key \
+   -p 8100 \
+   -v
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/rsa/mock-revoked.sh b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/rsa/mock-revoked.sh
new file mode 100644
index 0000000000000000000000000000000000000000..4a17926b92232d57657aff818c5451c0ded4d00f
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/rsa/mock-revoked.sh	
@@ -0,0 +1,8 @@
+#!/usr/bin/env sh
+python3 ../ocsp_mock.py \
+  --ca_file ca.pem \
+  --ocsp_responder_cert ca.crt \
+  --ocsp_responder_key ca.key \
+   -p 8100 \
+   -v \
+   --fault revoked
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/rsa/mock-valid.sh b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/rsa/mock-valid.sh
new file mode 100644
index 0000000000000000000000000000000000000000..c89ce9e954d4b04842a768d93882dba418a0f619
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/rsa/mock-valid.sh	
@@ -0,0 +1,7 @@
+#!/usr/bin/env sh
+python3 ../ocsp_mock.py \
+  --ca_file ca.pem \
+  --ocsp_responder_cert ca.crt \
+  --ocsp_responder_key ca.key \
+   -p 8100 \
+   -v
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/rsa/ocsp-responder.crt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/rsa/ocsp-responder.crt
new file mode 100644
index 0000000000000000000000000000000000000000..58caba35807f46b5784fc5a509bf40fb985e4a05
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/rsa/ocsp-responder.crt	
@@ -0,0 +1,21 @@
+-----BEGIN CERTIFICATE-----
+MIIDgzCCAmugAwIBAgIEA0v5yzANBgkqhkiG9w0BAQsFADB0MQswCQYDVQQGEwJV
+UzERMA8GA1UECAwITmV3IFlvcmsxFjAUBgNVBAcMDU5ldyBZb3JrIENpdHkxEDAO
+BgNVBAoMB01vbmdvREIxDzANBgNVBAsMBktlcm5lbDEXMBUGA1UEAwwOS2VybmVs
+IFRlc3QgQ0EwHhcNMjAwMjA2MjMyMjU4WhcNNDAwMjA4MjMyMjU4WjBiMRAwDgYD
+VQQKDAdNb25nb0RCMQ8wDQYDVQQLDAZLZXJuZWwxEjAQBgNVBAMMCWxvY2FsaG9z
+dDELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAk5ZMQ8wDQYDVQQHDAZPQ1NQLTMwggEi
+MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDiHYXGCSOK3gxlEmNSLepoFJbv
+hfYxxaqAWEceiTQdRpN97YRr/ywPm0+932EsE6/gIjqVs8IOtsiFKK1lQ9sL/9f+
+ckS5gj9AR+Cta+FLDRP5plE+aao5no0kA8qMx2HHd47XFnuxKtUztRmgmTBNYbYh
+PdY1kjBSRyuXXBn1V6TRaYhk6dsK56Zvhgo6Y3YqpjpldePa4E0XpUlBhY020QXt
+K3iWFauEYKcKR2JI2oVjY0tR60zf3GHkMLCe7SdbofCdwkBHcCctLSp4xYb44JGb
+JX1npM1mhxR4pnp80tbEXNvXQ4S3kmd7/QFUYE4IdXVkXNhkK6PtIdDKbLa9AgMB
+AAGjLzAtMAkGA1UdEwQCMAAwCwYDVR0PBAQDAgXgMBMGA1UdJQQMMAoGCCsGAQUF
+BwMJMA0GCSqGSIb3DQEBCwUAA4IBAQB5igUUQSzxzWvL+28TDYFuNnTB0hvqTnd7
+ZVyk8RVBiUkudxEmt5uFRWT6GOc7Y1H6w4igtuhhqxAeG9bUob+VQkCyc4GxaHSO
+oBtl/Zu+ts+0gUUlm+Bs6wFnFsGhM0awV/vqigDADZT2jbqbHBm2lP99eq8fsi6L
+kpohhbuTVWjLuViARYIOJLoBnNRpVXqwD5A8uNqwZI2OVGh1cQYNZcmfLJ1u2j5C
+ycohoa+o8NGgkxEhG2QETdVodfHT2dUgzPDvO42CVa3MK7J0sovBU5DeuIDPV/hh
+j+v5A8L8gMiNpkLClqt2TEiFH2GItWDNQjTgrLq9iFUgJnbwuj4F
+-----END CERTIFICATE-----
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/rsa/ocsp-responder.key b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/rsa/ocsp-responder.key
new file mode 100644
index 0000000000000000000000000000000000000000..ab3001e7f2b122df5fe9b384d573ed96e5dff107
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/rsa/ocsp-responder.key	
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDiHYXGCSOK3gxl
+EmNSLepoFJbvhfYxxaqAWEceiTQdRpN97YRr/ywPm0+932EsE6/gIjqVs8IOtsiF
+KK1lQ9sL/9f+ckS5gj9AR+Cta+FLDRP5plE+aao5no0kA8qMx2HHd47XFnuxKtUz
+tRmgmTBNYbYhPdY1kjBSRyuXXBn1V6TRaYhk6dsK56Zvhgo6Y3YqpjpldePa4E0X
+pUlBhY020QXtK3iWFauEYKcKR2JI2oVjY0tR60zf3GHkMLCe7SdbofCdwkBHcCct
+LSp4xYb44JGbJX1npM1mhxR4pnp80tbEXNvXQ4S3kmd7/QFUYE4IdXVkXNhkK6Pt
+IdDKbLa9AgMBAAECggEBAMMYOe4OwI323LbwUKX9W/0Flt1/tlZneJ9Yi7R7KW4B
+EQ1cPB96gafNl9X5wLvpGJzIq8ey28MaTpUl7cYr7/nAe7rdGRL+oFh0LBU1uaOp
+2wxSRlMVlHw2owzqAH/LIECclbBbg8nvbRk6Lqx0wEpj/mNcGVELm4nCQohMPVGC
+9/8GZ63r+tS35jry9SBG0X4R5jYKsNzgNgcjR+lgMv/2FfpuZDryk9TWIP9ApQoc
+7/DpTfC6P34f/ermfo4f2GEmRJsTACphA0kkpQX/n88r35cUSGeO5M9jYICUeCFw
+IK4L6KNQcTRVOknFYeVJembVrj0RYKtWT+oU84a4XPkCgYEA+k7fcXhU2K+NX8RN
+7HUPbxBE/TfLTNHdLTuWCUI77j+J3LUPNQ4BUyue+pUaFxI7Huc6x1zvvD27EqJ8
+0ge5MkFNflTUdUotuU/FKg7GKOU7rfdEvthzU2MbAZrHc0SeF+9/YrpvWZ+ZMKQ5
+IBQhiloFLsVGpGFzzF/MjpFdYo8CgYEA50HQxDDmfzmvNnURRZZV0lQ203m9I4KF
+DbL2x59q0DaJkUpFr3uyvghAoz4y/OD5vNIwbzHWbmDQEA06v7iFoJ6BcJFG1syc
+7A7KTB3PNQK4+ASG6pC3tYJ78mWtJwK130hFpuVkS/VPhQZJ/21EcWj9V153SZpA
+RUqv/L+lx/MCgYEAs7E7p3IDNyuQClgauM2wrsK3RDFxuUxPw9Eq/KqX64mhptg0
+epn7SYHfN3Uirb1gw+arw8NsN275hX8wrHbu9Kz8vNyZSTpfaNFjcbX5fBJUrab9
+qyQoZoyXLqe214FDHVvJz06X8Xcpukmq2OSaz3+giNsGw6tSPj3n09F3gPECgYBI
+1NGK+FufdetYm0X1RIOC2kLqF00aAeElj1dpRyu8p3Br8ZhAzBRfBPpWbyBfw/rj
+HM9kNa3y1Uqxw3jdKJ/tFf5uFVLaE1bYgU/06O55I4Jdmg9jkHBLGe0vShZeUtw0
+le5ZwaT0xy1kF7b2WtNTZF1lRrsK0ymqqPsD/teXQQKBgBTyYVxPEHKr86kEQqL5
+/OKByVpqAxA7LQ1lTLNV9lXMRawp848flv/Uc8pj43MitAIiYazfXkpeeC6gGntJ
+kkRT9jraOzy51tVAIh2KXm3l6KY/gnYTO3UXrxZOZU4IA7OttP3BG7xKq/9HP+kV
+5P1bAkqo+n3XNxKoSSeJteCd
+-----END PRIVATE KEY-----
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/rsa/server-mustStaple-singleEndpoint.pem b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/rsa/server-mustStaple-singleEndpoint.pem
new file mode 100644
index 0000000000000000000000000000000000000000..47112c02b1ebd0f1a4fcea341a154af00862e0bd
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/rsa/server-mustStaple-singleEndpoint.pem	
@@ -0,0 +1,52 @@
+-----BEGIN CERTIFICATE-----
+MIIEFzCCAv+gAwIBAgIETUEXPjANBgkqhkiG9w0BAQsFADB0MQswCQYDVQQGEwJV
+UzERMA8GA1UECAwITmV3IFlvcmsxFjAUBgNVBAcMDU5ldyBZb3JrIENpdHkxEDAO
+BgNVBAoMB01vbmdvREIxDzANBgNVBAsMBktlcm5lbDEXMBUGA1UEAwwOS2VybmVs
+IFRlc3QgQ0EwHhcNMjAwNDIxMTkxNDA3WhcNNDAwNDIzMTkxNDA3WjBiMRAwDgYD
+VQQKDAdNb25nb0RCMQ8wDQYDVQQLDAZLZXJuZWwxEjAQBgNVBAMMCWxvY2FsaG9z
+dDELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAk5ZMQ8wDQYDVQQHDAZPQ1NQLTEwggEi
+MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDEWuLtsdzYxDK//wc9VXyyQPlS
+AmkRHrLrTH0OSSPBvXK0NSkHtOjh3gX4jzTN8jTpEVkbfYt1EInZnucWOcX7mRRP
+LRp0Fcq7j1pCPJ15uNSZDqDnfEA8kiY2Qg9n9oAIR2yk3FFj/8raBB13EnzOHeq4
+27BXH7oOgOgvd8PyuOB1OmNKjCLf5laaRbB+/lyrGfPFwmNcgH2lxtkfeBhTM5kS
+vDkbAFIX6KqeWtvaV+WRPcyooa0FvNXTfCiS26qtw4rMZnWNODG13pgJCPckDZt7
+kX9qM+cS4L4oj6Hm3NrWkTpJzOFOQwZMily0X6ee1IH9m0yaLS7vq3pKlr67AgMB
+AAGjgcIwgb8wCQYDVR0TBAIwADALBgNVHQ8EBAMCBaAwHQYDVR0lBBYwFAYIKwYB
+BQUHAwEGCCsGAQUFBwMCMB0GA1UdDgQWBBQX4EjmQUUFCdz2ZKGKMHEPkkGHCDA4
+BggrBgEFBQcBAQQsMCowKAYIKwYBBQUHMAGGHGh0dHA6Ly9sb2NhbGhvc3Q6ODEw
+MC9zdGF0dXMwEQYIKwYBBQUHARgEBTADAgEFMBoGA1UdEQQTMBGCCWxvY2FsaG9z
+dIcEfwAAATANBgkqhkiG9w0BAQsFAAOCAQEAkZd/uV401ejVjqMaQ5ogkdo97Isz
+Rjrx6dDY1Ll+5LzViqdRlXiAAc/bUq8NhYQkbjUC7b931meksIRRdtJUZx9zLt43
+npjjGKDdWEilLKKwT1IvKaAb2A7hmrT4WkwDtHZODvvpE+wvmEQ2LwthHDs+FwqN
+2YDTuxdhO8mMePDXfK0Ch4WJQaJV/PT0sI34sYoeF7KC0TACWKwG08+qI9vawujq
+qWw5fRwNTqxAj9X66wp6RdE6bJ3mWOrPmUppaDww3yRGVxdsWKCC8WoH3etNl8Km
+iwDcp+WF+DmoOt2VAcvzoQsvsoUGdaMHYQ1MTJb5YsURr3BuGmcEUQI/yA==
+-----END CERTIFICATE-----
+-----BEGIN PRIVATE KEY-----
+MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDEWuLtsdzYxDK/
+/wc9VXyyQPlSAmkRHrLrTH0OSSPBvXK0NSkHtOjh3gX4jzTN8jTpEVkbfYt1EInZ
+nucWOcX7mRRPLRp0Fcq7j1pCPJ15uNSZDqDnfEA8kiY2Qg9n9oAIR2yk3FFj/8ra
+BB13EnzOHeq427BXH7oOgOgvd8PyuOB1OmNKjCLf5laaRbB+/lyrGfPFwmNcgH2l
+xtkfeBhTM5kSvDkbAFIX6KqeWtvaV+WRPcyooa0FvNXTfCiS26qtw4rMZnWNODG1
+3pgJCPckDZt7kX9qM+cS4L4oj6Hm3NrWkTpJzOFOQwZMily0X6ee1IH9m0yaLS7v
+q3pKlr67AgMBAAECggEBAJqjLUafJdt9IK6+TVhLZAoKS4//n/lAoQ3YTkCa71Mc
+PSKZHzgXjLSdIzyuo5px3qOS6wdQZy0JmlbN4xZI55gO5cS5M7UqmGAANMgnbqm3
+G49yytujqf9J5lgizHlG02wxu+lWLa9AeuQaC46D+9BkFUACnCzxKplTgggoHSSg
+fTm/AKPRg/ZxejoorqveHK3IGjwVxk/2b6aqcCsr0GCuR5ons7hCQ66clvAqR/AH
+ejz77lM/Nn6jq29Dgq/KhX22uabjML1yHFxZW0gF58chpJWTP8Rn3FEDw2mgMdao
+C5C9Im9WWHquy05GQZRP/V5bhPuAgg5E4X+nCyn4eTECgYEA7eXTp+zLsGYe6l4a
+MvXohDKMCouDF8w40hyIvJ9lF5ikQEhnJRQLPzbM7qx1AeeQwZevtyNBchX0nVwJ
+VRd9c5qsSFkar489vBvhjEJ4B57B7KNoE5BHaR0+tfzWsWwK6BxHl9PmeGSn59i/
+7UwBhIzaC6dyJpTowCu/Scv8LhMCgYEA00vR/qeC0L7YPSG+VjHwerFhzUCTfnbd
+wFpJM+N6PMRZA4GRWQLLxGmzPohjSfzwWMgUCXjopWiWOnxTEUlvTQgCWLAceMlk
+rbTnHBtlXPPpSHvlmgVEG0+U/CpqONY7upEYrbt1xPMxNponS/7Yl0BXB2Qx8Je4
+pXs2H7wTIbkCgYEAgFOxUKwTVBxCIPqR91tfCbCaijWniXbIT87Ek7sHtSrJr0Nf
+IEknp/nPog+1LknTdBp21rtV2kytnxS+lAAP1ARjWsN1+a2zB32itR5F0RZ6VUPw
+KF1zp+f2pAS3aw109LAMjoHnmJnzWMU7Aq41Q2MXW6H/mYBJ7R+sGArJBbECgYBY
+Y1Qx+bLATcU5NV9gwT0+pesqqEPK2ECFEX+jxBnDR8OQsuexW3kP7cN8eiNGtRd5
+nCC9oaV4ZBrL1mwNRDHaAGqy3ODcKisCezVeTZuGWcYRezqdxmwqHI1POxL6Oav8
+rGutaUinna/Njoi3wqCqDNEbF2/InD8ygisu9UbviQKBgQCS4Mxw+uOl5WvXjrze
+z6B8L69MkT4fidgGkqimfpjk+N5Yt49otfvlvFPjkrVqR3lMqrqjV2r0W4fTeoSo
+SDE3vZFZC9mi6ptUbgrW+aYqLHYQGYsJQXmj48Nkm/9uhkN1YEE9o04uSau1yVg+
+fDqxV7pLZwfnUbvGnYGjBShkMQ==
+-----END PRIVATE KEY-----
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/rsa/server-mustStaple.pem b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/rsa/server-mustStaple.pem
new file mode 100644
index 0000000000000000000000000000000000000000..5c80602e41388e06c7586bbe007e2a7ffdae5353
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/rsa/server-mustStaple.pem	
@@ -0,0 +1,53 @@
+-----BEGIN CERTIFICATE-----
+MIIERjCCAy6gAwIBAgIEJ++lZzANBgkqhkiG9w0BAQsFADB0MQswCQYDVQQGEwJV
+UzERMA8GA1UECAwITmV3IFlvcmsxFjAUBgNVBAcMDU5ldyBZb3JrIENpdHkxEDAO
+BgNVBAoMB01vbmdvREIxDzANBgNVBAsMBktlcm5lbDEXMBUGA1UEAwwOS2VybmVs
+IFRlc3QgQ0EwHhcNMjAwMzE5MTU1NjIyWhcNNDAwMzIxMTU1NjIyWjBiMRAwDgYD
+VQQKDAdNb25nb0RCMQ8wDQYDVQQLDAZLZXJuZWwxEjAQBgNVBAMMCWxvY2FsaG9z
+dDELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAk5ZMQ8wDQYDVQQHDAZPQ1NQLTEwggEi
+MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDykV3fTFJgaqjfAgbAC7TGPk9V
+VVsRYRgLF8Zjh9GDRU/TQ6pGZG7qo64D11oQurW0WT2Zv/lqhXW4mWNFv8+qoS5L
+9z2Dtmxr8CZbb6YftA0e22KPUuDCQ5nYhOY21A6SYFwqEZ6ZsrZAMkgfhx+TY1kZ
+0jZM/jgkvRtpG9I8BbddHyF8eFATCJ41DnLOzjfNukd5zKSIdVxY6r+ZBOr29kii
+dcNHkCAck7+WXl9/KSqH7jF5asU0S3x/68G2R/qdKAxki9b2fe70N3XGZE0P2WHi
+lq2aJeE0eqjAv+hBGiEb4iJl0s8iheardrHFeL4EMbiiVfVdVCHKkp58wjB9AgMB
+AAGjgfEwge4wCQYDVR0TBAIwADALBgNVHQ8EBAMCBaAwHQYDVR0lBBYwFAYIKwYB
+BQUHAwEGCCsGAQUFBwMCMB0GA1UdDgQWBBTOLiS9HKGWpiVKx81nNuRlK+HAITBn
+BggrBgEFBQcBAQRbMFkwLQYIKwYBBQUHMAGGIWh0dHA6Ly9sb2NhbGhvc3Q6OTAw
+MS9wb3dlci9sZXZlbDAoBggrBgEFBQcwAYYcaHR0cDovL2xvY2FsaG9zdDo4MTAw
+L3N0YXR1czARBggrBgEFBQcBGAQFMAMCAQUwGgYDVR0RBBMwEYIJbG9jYWxob3N0
+hwR/AAABMA0GCSqGSIb3DQEBCwUAA4IBAQCg3NfTO8eCdhtmdDVF5WwP4/lXMYJY
+5wn7PhYKMyUQI3rjUpQRIQwCVerHAJAiiflpgefxB8PD5spHPFq6RqAvH9SKpP5x
+nyhiRdo51BmijCIl7VNdqyM5ZgDAN2fm2m56mDxpo9xqeTWg83YK8YY1xvBHl3jl
+vQC+bBJzhaTp6SYXMc/70qIPcln0IElbuLN8vL4aG6xULkivtjiv7qBSZrNrBMSf
+QJan9En4wcNGFt5ozrgJthZHTTX9pXOGVZe4LXbPCQSrBxZiBD9bITUyhtbeYhYR
+4yfXjr7IeuoX+0g6+EEtxqrbWfIkJ3D7UaxAorZEsCt18GC7fap9/fzv
+-----END CERTIFICATE-----
+-----BEGIN PRIVATE KEY-----
+MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDykV3fTFJgaqjf
+AgbAC7TGPk9VVVsRYRgLF8Zjh9GDRU/TQ6pGZG7qo64D11oQurW0WT2Zv/lqhXW4
+mWNFv8+qoS5L9z2Dtmxr8CZbb6YftA0e22KPUuDCQ5nYhOY21A6SYFwqEZ6ZsrZA
+Mkgfhx+TY1kZ0jZM/jgkvRtpG9I8BbddHyF8eFATCJ41DnLOzjfNukd5zKSIdVxY
+6r+ZBOr29kiidcNHkCAck7+WXl9/KSqH7jF5asU0S3x/68G2R/qdKAxki9b2fe70
+N3XGZE0P2WHilq2aJeE0eqjAv+hBGiEb4iJl0s8iheardrHFeL4EMbiiVfVdVCHK
+kp58wjB9AgMBAAECggEATA91Bf3insUTKspx32pMRxVmvvVC1xJA/cl4teDyu1zS
+iQZgsC3x8bVdbWrrnO9O5rxM6pcd2F786OOAE3Dv5ysfX0apjVF4cegdvvIlfy9w
+JcrY/uQYAhI8fX4+ydZ4s0Fv5OkdeEhniX26y9gM+KRgXg5iZIYaiLqbi7vjkloE
+NBIDWGj8PCNKUVc2PSbZFVMMTc+7qZeUR0WRKr9CsaXBiEkWKfuw4MH1YUL0HJOs
+uLd/oYg0l0eHPluUkKQW+KVq1GKsmr2sSc8NOcGtVTsUygSgX4hw36V7Vw3MfQRv
+sNIgKp3RDEyynoXRoG3laHrib1GdYwDKRsHB2znKQQKBgQD+NAOOqoEx0lmlg/Wf
+sNImv+3da0owE1TqTMHBWXriGo+DwqT+d9S+M5x3JMpmgH9vTEDlLOM2+qF8M3B3
+TLlu1k7F8D1G7YCdIZwMLUNCekCSHsqQcU9HMHlQqXd2cxFqWbyATk9tvJzj7xC9
+zMhaKGKvIS/EF0Ld8kIvrINmGQKBgQD0SExjk4yshv/DvWknxfJr8OupgQrriLHA
+Hrk+n84Iv/4vzupgKsXJQE6VN0xM6e/ANhGATuxiaA3UE4p6K9wJNryHrw/wdnyf
+I9AR0Cea9F4pa26BBCdLtQuyRqgl7dBZA1n3il7vKX6wB0MLoy/uYWYCedk4w+9d
+acqh7S0CBQKBgBl8x5qHV/rR13E0AO2pAfkmp0fbGQ4m8g2n8olbWmnPNfKFEpv9
+EdScQiTkCHMskRpsr9kKniGGEajtU2pyw+jsDevkwZAaAho/I3FJHIRO06iS88Z1
+xfgiUReYVkUHFojuRGss7uPW1Hg6IRiWrsPzZqmejzZ/CpJMVvyGtIoJAoGAXmo7
+LBlxO5WJ8SuaIwc85T9etkrr35EbsnetfWjihzs9kVjV+YlOnLRAKygOU4PvaEj9
+hqv6bSZugdNzqDifeOgxAfhFntkM3a1H1DqxtBBS/ItLUI48aeR1utfYUaCS8HR9
+J1HR03okPwDvhuXxtp7qgHZ74JbKQz6KVP+Ib8kCgYEA7w0NnuOoZ0la17XuyQzA
+UeTZZavgm0tNqqT4JcPiUV9zkR8WJsFQE704KQ8BjDyeYMWwe8EpfJaqsGqdJKGo
+RnnxwNuwT4uSNb78MxXXVRG0fN/2iu70lNySKOl/DmA8siRc/weQj5JPsGbyZkjZ
+IsaTqaZQUdtbZ7vRukyPo8Q=
+-----END PRIVATE KEY-----
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/rsa/server-singleEndpoint.pem b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/rsa/server-singleEndpoint.pem
new file mode 100644
index 0000000000000000000000000000000000000000..66849f535323e6d6ae1766d47d4525d9c6a85ba8
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/rsa/server-singleEndpoint.pem	
@@ -0,0 +1,52 @@
+-----BEGIN CERTIFICATE-----
+MIIEBDCCAuygAwIBAgIEZ0Q/vTANBgkqhkiG9w0BAQsFADB0MQswCQYDVQQGEwJV
+UzERMA8GA1UECAwITmV3IFlvcmsxFjAUBgNVBAcMDU5ldyBZb3JrIENpdHkxEDAO
+BgNVBAoMB01vbmdvREIxDzANBgNVBAsMBktlcm5lbDEXMBUGA1UEAwwOS2VybmVs
+IFRlc3QgQ0EwHhcNMjAwNDEwMjA1NDEzWhcNNDAwNDEyMjA1NDEzWjBiMRAwDgYD
+VQQKDAdNb25nb0RCMQ8wDQYDVQQLDAZLZXJuZWwxEjAQBgNVBAMMCWxvY2FsaG9z
+dDELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAk5ZMQ8wDQYDVQQHDAZPQ1NQLTEwggEi
+MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDH3pCRRVSRghw0+55xvfRRWQx/
+5BO/M7XGtiLwAUU+R42FyQYdu8rgZQavtDLU/KQaws6xoIBvl0YezBGRTbEa4pM/
+ATeGSTz9Xdo5Zp9oQgb41yimdjVCxTrdMUAtocHi5UurkmuBJcyZ6UHLvQ11whgL
+tZfGFO3drhLm8A/mDFr4o+9LX4q+9qh+cDFEWnTx5j16ZN2pWNR8lFF5pu/wsqPL
+CJEC/dq95EuwQJoupjF+bC/faGx+b1/CLx2HyCR0pDSvNq9AlK9W0qw5br01qIhT
++mvv6+nPs8zzdixrguNlzHsEZN/pPnFZ3xBZii88F4xfxfPoPE+rfPO5M6DfAgMB
+AAGjga8wgawwCQYDVR0TBAIwADALBgNVHQ8EBAMCBaAwHQYDVR0lBBYwFAYIKwYB
+BQUHAwEGCCsGAQUFBwMCMB0GA1UdDgQWBBRWLvOTPv7G74DYdxd+Lv/7DzLabDA4
+BggrBgEFBQcBAQQsMCowKAYIKwYBBQUHMAGGHGh0dHA6Ly9sb2NhbGhvc3Q6ODEw
+MC9zdGF0dXMwGgYDVR0RBBMwEYIJbG9jYWxob3N0hwR/AAABMA0GCSqGSIb3DQEB
+CwUAA4IBAQAJvPmDizmNplKTdBu4YsF2E7EsAfJREuN7TKAbLsiYtyAMuIu5BIv6
+Ma4pcxeJUvYML5czHoPwjXNC9+M7aTsb18q8ZRAJzY2kVhvzhT2lVH5YFC8vhJ92
+aeX8GTpoa+lslXuvVe8os+tGcQzqMtiVF2xZHbAYOiAno+fVQey9VSjU+pXIcKUT
+7nF/b0rRHHo8ziPsfI+h3kKWttywB+iQ60Zlt3ajlfWgTuL1fdbt9GEFl68Rhhsy
+6s1h8oXSSM0VIBzJKqrubJgziXH2kVN9p1XtQcCwW2lrZ3z0GQq5nLvIsgTQHwx6
+FsuONP/eS2esZIn7LwT2nSNa/Hfh9pq/
+-----END CERTIFICATE-----
+-----BEGIN PRIVATE KEY-----
+MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDH3pCRRVSRghw0
++55xvfRRWQx/5BO/M7XGtiLwAUU+R42FyQYdu8rgZQavtDLU/KQaws6xoIBvl0Ye
+zBGRTbEa4pM/ATeGSTz9Xdo5Zp9oQgb41yimdjVCxTrdMUAtocHi5UurkmuBJcyZ
+6UHLvQ11whgLtZfGFO3drhLm8A/mDFr4o+9LX4q+9qh+cDFEWnTx5j16ZN2pWNR8
+lFF5pu/wsqPLCJEC/dq95EuwQJoupjF+bC/faGx+b1/CLx2HyCR0pDSvNq9AlK9W
+0qw5br01qIhT+mvv6+nPs8zzdixrguNlzHsEZN/pPnFZ3xBZii88F4xfxfPoPE+r
+fPO5M6DfAgMBAAECggEAR6QUR64FMR7lA2zJj1WaNGpp25GiLl/XoUF55nNeIYO+
+S50Rryi4AJTVv7cknUltfRYkxnCUeOtNPA7DoUSq3csnImdKQr0PunWgmgCZ1OIN
+47YjoP8v+h3+Cnjz2ydm+vBbnkUeea1V2DlO1zuNjo8i1Vei7mJkHJift92GpVtY
+DW5GrTZfntPJXHQQjz6nGn5mQxTlEi1WafPPyDoqykwAIonehIyhYd7UCDw/e62D
+XMWk8Bo7YmX0Y3utQF2tuu1ih2zz5+NXwviycBqE9GL4eoHZgdKJrPBA/nRBsy5J
+SqorCKxLODvl77EIdqPUDZsyGzvWlmoEyDtthsvsiQKBgQDtFaIQW+DizGqibfuT
+6/z5+4G8ZAp+FVJU/0Z/SmOX/ro2LzYhlV0l71OWvMVKxCfp30zlYaYWNo+R8h40
+O6zSsKcSE7JLFNh53euPz49Ium+N5OFZ6Yez7HBD/5sjWEt+iGDUZAr9SlqMZAGN
+PhUSu51QvFj1kqqVbXxmA3TkiwKBgQDX0NOCri8J4jqBk8TuY4AZS3zq/2lVmFYh
+81itma43zXRG3z8hFFct/CBqxObGwi1MQAGZAG7EeOvnH6FPV/85Tej1Wd0VtV8f
+ryWgjSvZDt3dATZBKVcVibTfazdkfeqze2wtYRjFqNPlAitSF7HN8iOC8B02dIMq
+ec6UM9w7fQKBgA03CHqK9IUPyd3V7ZD4NXilqTycAu22OImeVQqhVd3SCAUfKpBC
+qBeGOI2NZh3dwy/JD5s1jzFrxyLmcQKOVPrFd/qM+IIw3kQkt42jjyQJqFArctg1
+KShBRJy1sasNr9+UsHkGPoqRy2xJ4sBBtqD9ri4i4X6Gt1Vu7eEtziUzAoGAafd0
+Uz8Zg53cIlGfKXobpM/m9zAP1WJmMGdfDGZgH7A2vrHROnnVUJPyitpBgihHu5/V
+6P1IZhoFosdqGh5YCBgUIZxNLOKQYWtLa2jFtd9R2rlEnXwh8UZbVDQ9z47wFc6t
+UB7T3gHGgTSudrGBsWCKRTmG7n0JBmsmnqhUI7UCgYBb4nBED+kaMGFdzRdpq8Dv
++KgShSjWa+4U2S4QZ3MYtb+rIMsAoRO4K8S3VMqIsun3S7T5szyp72jBqAQTHiHA
+eGlRTrirc9dR8x6CO66UUf5tGMG05P7qo23Qoip+t1/rcCgrBH7er68AhMIZbxfK
+2dj9RqANXyIWWI320Y+VkA==
+-----END PRIVATE KEY-----
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/rsa/server.pem b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/rsa/server.pem
new file mode 100644
index 0000000000000000000000000000000000000000..abf978ef8fb93e31618566dc25102fc43961c4ee
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/ocsp/rsa/server.pem	
@@ -0,0 +1,53 @@
+-----BEGIN CERTIFICATE-----
+MIIEMzCCAxugAwIBAgIET11AjzANBgkqhkiG9w0BAQsFADB0MQswCQYDVQQGEwJV
+UzERMA8GA1UECAwITmV3IFlvcmsxFjAUBgNVBAcMDU5ldyBZb3JrIENpdHkxEDAO
+BgNVBAoMB01vbmdvREIxDzANBgNVBAsMBktlcm5lbDEXMBUGA1UEAwwOS2VybmVs
+IFRlc3QgQ0EwHhcNMjAwMzE5MTU1NjI1WhcNNDAwMzIxMTU1NjI1WjBiMRAwDgYD
+VQQKDAdNb25nb0RCMQ8wDQYDVQQLDAZLZXJuZWwxEjAQBgNVBAMMCWxvY2FsaG9z
+dDELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAk5ZMQ8wDQYDVQQHDAZPQ1NQLTEwggEi
+MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC0usokl3+yXDtLeYquHQyAkXIw
+lY4tukv8nEgLtUlK0kt9Q7P8EdZigzFUeJtL7piFCTIaLuv6e4UqLLDXbIANxD/J
+NXXQPtBasOSzdgZ2ToUj5ANPv0QegsFubpYGq5LXsMdKTRE8uTB91PJBvRzxY2Nx
+O1kdQcIrYpSYXqKsNgq/8iAPrmAdZ3y+S7OBuNyvlQJZqWoB1Y0ZWuR1QrcLMgdm
+q2SdBzZT/3P+r/dbHMKdDZ5JdJ9Nm4ylOG7mhZkfb38JfdvWedzXDMu6TzS2W67o
+yM90Cj9Lt+UyHLJ2jlcsZSZp4km6Oj5RBNVhd95SFckvPJxLzSyFlpjOIXsNAgMB
+AAGjgd4wgdswCQYDVR0TBAIwADALBgNVHQ8EBAMCBaAwHQYDVR0lBBYwFAYIKwYB
+BQUHAwEGCCsGAQUFBwMCMB0GA1UdDgQWBBTe7IMKaO1aQILcpoj5wLFgIRuPHzBn
+BggrBgEFBQcBAQRbMFkwLQYIKwYBBQUHMAGGIWh0dHA6Ly9sb2NhbGhvc3Q6OTAw
+MS9wb3dlci9sZXZlbDAoBggrBgEFBQcwAYYcaHR0cDovL2xvY2FsaG9zdDo4MTAw
+L3N0YXR1czAaBgNVHREEEzARgglsb2NhbGhvc3SHBH8AAAEwDQYJKoZIhvcNAQEL
+BQADggEBAFMVds6y5Qy7DlFsca0u8WE+ckoONa427bWBqNx8b/Hwaj3N3C58XQx/
+EZRNt9XVy/LoEHr+NmOWsCl69fINeVpx8Ftot8XPbFG9YxL/xbJ3lvWesPR6bwpm
+PZqGiwfl1VrZvuobXADz0Rfru7B7LPkurpSxDiNBf/9JuLPYe9ffZwdFWQoehw07
+b9FKVaJ7mSHno/5f4Z/uKau91sL0kiKKG9Lo2JEIEmpp8HJ3OKCFh7DFkeDlRCDl
+WyYxF4g/PfvJQm2Hd89cu8m3RX84rLa9jn1RGL/8bmxE0dxk4Di/t9gl5KGWIH9Q
+LBeVRSQmH9GbI/WmldMLkGkvARYYTp8=
+-----END CERTIFICATE-----
+-----BEGIN PRIVATE KEY-----
+MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQC0usokl3+yXDtL
+eYquHQyAkXIwlY4tukv8nEgLtUlK0kt9Q7P8EdZigzFUeJtL7piFCTIaLuv6e4Uq
+LLDXbIANxD/JNXXQPtBasOSzdgZ2ToUj5ANPv0QegsFubpYGq5LXsMdKTRE8uTB9
+1PJBvRzxY2NxO1kdQcIrYpSYXqKsNgq/8iAPrmAdZ3y+S7OBuNyvlQJZqWoB1Y0Z
+WuR1QrcLMgdmq2SdBzZT/3P+r/dbHMKdDZ5JdJ9Nm4ylOG7mhZkfb38JfdvWedzX
+DMu6TzS2W67oyM90Cj9Lt+UyHLJ2jlcsZSZp4km6Oj5RBNVhd95SFckvPJxLzSyF
+lpjOIXsNAgMBAAECggEAIjNe4YHR5nzRs7yyY7SXkxTzGQKUP08L5ifk8mJCFmip
+ZHEVdFQjz8yn3yZbrQjfz/0ngBD1Exeg4ZRHetzLds92iqsVOm1InIDxJozlOCov
+w9T4U3UMfQGdfTpsJaL+TNblP8hJxMX+yTEtDwesnHmEbf8fJAw3pGIpYJQ4EIJv
+1uPzyB8EsrTjj23a5NPF/FGdzzO+HP5fhNNIUmP83pqonXLUSy0v5rsRFNxNMBn3
+SPRWq+Z779eLQXnRjW/6hKssSBFg6zAOi3Gc4oDbrDa2WEbZ0BEU+JW3XduN91bU
+SsO3yQ+VL+CQn5wvXGIsc4EHH6wO8Bs0vXfD7zeLgQKBgQDrHOzPymI0p0PnxL2+
+8LrSU1x0WdedPZJugwwfUYMfn7sjKx+FyVLvM+7wuJ8zsMOAab2AHv3S0Nxkovhb
+aa4lH9SUAHILcU+nb7M6E+mwSr65AemGspvGz4ZC6L52CGVzRfIcoBDD0T8OZGH0
+4IeiqOluqtvgCoW4UV1dyw0nPQKBgQDEyQwcim5ghEQ7V2eDefE5yxNlkNEnSVnG
+DNubM8KURR8jehpDWkIlxQ4p2tLBWGB0YeOCG9NmwfLnQUStvSFE6/XjP5bBJlov
+jT66T98NgFRfUeVkcCAiVT/LlDzXWXXPLyZSY+bxtn8UA1NYNu0pLCLDR9TlH1dK
+FKwiomdgEQKBgEimcHqo4/23LeGBRsyooGH7hlchp+GbtBLYBbfrvSPZfL8aRSxX
+EHx/xLa3peIYHeEhS4A6k15AUcn7HdlJZ5lrI4n0NUlZ4y4u8ufgXVavUg3jDGEl
+8cLWP3uPZcMdRxP+qhi0UVng36Y32JkNhHv7y935h+XL+pQA+GPSKadVAoGAPPvp
+SvcDmdmjo5hEthQWU8jBbBpjFv++WIgnjoON65E4QzBV70WLdlUJPKNZ6R1QVwD3
+Fp00+IVml5A8jnMsWkWd4B0WxSjzjgUByY9zGqYIf7nLk0LEUp+Es7xu1nYc8mY0
+RBg9u+7IlxUowQ/Uk4vgAhDCw3bhAE5Dwj/+NWECgYBWnBz5l+Uar9oT1ErRSbJW
+RVYx3iIsqka1lox/zw5nme1Q/dv2uTQy6uZRn9U9ikqGwePuMEexQTR1csnMqeMM
+4i3pDFpGBfTZXJAvH790ak6eZ0eBXqzJlTyEjll4r4zXHk+slm/tAgpIg0Ps3J9j
+Sd+bTtG47gpb4sRbqEtQFQ==
+-----END PRIVATE KEY-----
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/orchestration/configs/sharded_clusters/basic.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/orchestration/configs/sharded_clusters/basic.json
new file mode 100644
index 0000000000000000000000000000000000000000..fd03f56863acfe6832f66e524035b0712ebbf03c
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/orchestration/configs/sharded_clusters/basic.json	
@@ -0,0 +1,48 @@
+{
+    "id": "shard_cluster_1",
+    "shards": [
+        {
+            "id": "sh01",
+            "shardParams": {
+                "members": [
+                    {
+                        "procParams": {
+                            "ipv6": true,
+                            "bind_ip": "127.0.0.1,::1",
+                            "shardsvr": true,
+                            "port": 27217
+                        }
+                    },
+                    {
+                        "procParams": {
+                            "ipv6": true,
+                            "bind_ip": "127.0.0.1,::1",
+                            "shardsvr": true,
+                            "port": 27218
+                        }
+                    },
+                    {
+                        "procParams": {
+                            "ipv6": true,
+                            "bind_ip": "127.0.0.1,::1",
+                            "shardsvr": true,
+                            "port": 27219
+                        }
+                    }
+                ]
+            }
+        }
+    ],
+    "routers": [
+        {
+            "ipv6": true,
+            "bind_ip": "127.0.0.1,::1",
+            "port": 27017
+        },
+        {
+            "ipv6": true,
+            "bind_ip": "127.0.0.1,::1",
+            "port": 27018
+        }
+    ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/orchestration/db/.empty b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/orchestration/db/.empty
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/orchestration/lib/client.pem b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/orchestration/lib/client.pem
new file mode 100644
index 0000000000000000000000000000000000000000..5b070010920d3159a2b4eb1bed834508fb799fde
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/orchestration/lib/client.pem	
@@ -0,0 +1,48 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpAIBAAKCAQEAsNS8UEuin7/K29jXfIOLpIoh1jEyWVqxiie2Onx7uJJKcoKo
+khA3XeUnVN0k6X5MwYWcN52xcns7LYtyt06nRpTG2/emoV44w9uKTuHsvUbiOwSV
+m/ToKQQ4FUFZoqorXH+ZmJuIpJNfoW+3CkE1vEDCIecIq6BNg5ySsPtvSuSJHGjp
+mc7/5ZUDvFE2aJ8QbJU3Ws0HXiEb6ymi048LlzEL2VKX3w6mqqh+7dcZGAy7qYk2
+5FZ9ktKvCeQau7mTyU1hsPrKFiKtMN8Q2ZAItX13asw5/IeSTq2LgLFHlbj5Kpq4
+GmLdNCshzH5X7Ew3IYM8EHmsX8dmD6mhv7vpVwIDAQABAoIBABOdpb4qhcG+3twA
+c/cGCKmaASLnljQ/UU6IFTjrsjXJVKTbRaPeVKX/05sgZQXZ0t3s2mV5AsQ2U1w8
+Cd+3w+qaemzQThW8hAOGCROzEDX29QWi/o2sX0ydgTMqaq0Wv3SlWv6I0mGfT45y
+/BURIsrdTCvCmz2erLqa1dL4MWJXRFjT9UTs5twlecIOM2IHKoGGagFhymRK4kDe
+wTRC9fpfoAgyfus3pCO/wi/F8yKGPDEwY+zgkhrJQ+kSeki7oKdGD1H540vB8gRt
+EIqssE0Y6rEYf97WssQlxJgvoJBDSftOijS6mwvoasDUwfFqyyPiirawXWWhHXkc
+DjIi/XECgYEA5xfjilw9YyM2UGQNESbNNunPcj7gDZbN347xJwmYmi9AUdPLt9xN
+3XaMqqR22k1DUOxC/5hH0uiXir7mDfqmC+XS/ic/VOsa3CDWejkEnyGLiwSHY502
+wD/xWgHwUiGVAG9HY64vnDGm6L3KGXA2oqxanL4V0+0+Ht49pZ16i8sCgYEAw+Ox
+CHGtpkzjCP/z8xr+1VTSdpc/4CP2HONnYopcn48KfQnf7Nale69/1kZpypJlvQSG
+eeA3jMGigNJEkb8/kaVoRLCisXcwLc0XIfCTeiK6FS0Ka30D/84Qm8UsHxRdpGkM
+kYITAa2r64tgRL8as4/ukeXBKE+oOhX43LeEfyUCgYBkf7IX2Ndlhsm3GlvIarxy
+NipeP9PGdR/hKlPbq0OvQf9R1q7QrcE7H7Q6/b0mYNV2mtjkOQB7S2WkFDMOP0P5
+BqDEoKLdNkV/F9TOYH+PCNKbyYNrodJOt0Ap6Y/u1+Xpw3sjcXwJDFrO+sKqX2+T
+PStG4S+y84jBedsLbDoAEwKBgQCTz7/KC11o2yOFqv09N+WKvBKDgeWlD/2qFr3w
+UU9K5viXGVhqshz0k5z25vL09Drowf1nAZVpFMO2SPOMtq8VC6b+Dfr1xmYIaXVH
+Gu1tf77CM9Zk/VSDNc66e7GrUgbHBK2DLo+A+Ld9aRIfTcSsMbNnS+LQtCrQibvb
+cG7+MQKBgQCY11oMT2dUekoZEyW4no7W5D74lR8ztMjp/fWWTDo/AZGPBY6cZoZF
+IICrzYtDT/5BzB0Jh1f4O9ZQkm5+OvlFbmoZoSbMzHL3oJCBOY5K0/kdGXL46WWh
+IRJSYakNU6VIS7SjDpKgm9D8befQqZeoSggSjIIULIiAtYgS80vmGA==
+-----END RSA PRIVATE KEY-----
+-----BEGIN CERTIFICATE-----
+MIIDgzCCAmugAwIBAgIDAxOUMA0GCSqGSIb3DQEBCwUAMHkxGzAZBgNVBAMTEkRy
+aXZlcnMgVGVzdGluZyBDQTEQMA4GA1UECxMHRHJpdmVyczEQMA4GA1UEChMHTW9u
+Z29EQjEWMBQGA1UEBxMNTmV3IFlvcmsgQ2l0eTERMA8GA1UECBMITmV3IFlvcmsx
+CzAJBgNVBAYTAlVTMB4XDTE5MDUyMjIzNTU1NFoXDTM5MDUyMjIzNTU1NFowaTEP
+MA0GA1UEAxMGY2xpZW50MRAwDgYDVQQLEwdEcml2ZXJzMQwwCgYDVQQKEwNNREIx
+FjAUBgNVBAcTDU5ldyBZb3JrIENpdHkxETAPBgNVBAgTCE5ldyBZb3JrMQswCQYD
+VQQGEwJVUzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALDUvFBLop+/
+ytvY13yDi6SKIdYxMllasYontjp8e7iSSnKCqJIQN13lJ1TdJOl+TMGFnDedsXJ7
+Oy2LcrdOp0aUxtv3pqFeOMPbik7h7L1G4jsElZv06CkEOBVBWaKqK1x/mZibiKST
+X6FvtwpBNbxAwiHnCKugTYOckrD7b0rkiRxo6ZnO/+WVA7xRNmifEGyVN1rNB14h
+G+spotOPC5cxC9lSl98Opqqofu3XGRgMu6mJNuRWfZLSrwnkGru5k8lNYbD6yhYi
+rTDfENmQCLV9d2rMOfyHkk6ti4CxR5W4+SqauBpi3TQrIcx+V+xMNyGDPBB5rF/H
+Zg+pob+76VcCAwEAAaMkMCIwCwYDVR0PBAQDAgeAMBMGA1UdJQQMMAoGCCsGAQUF
+BwMCMA0GCSqGSIb3DQEBCwUAA4IBAQAqRcLAGvYMaGYOV4HJTzNotT2qE0I9THNQ
+wOV1fBg69x6SrUQTQLjJEptpOA288Wue6Jt3H+p5qAGV5GbXjzN/yjCoItggSKxG
+Xg7279nz6/C5faoIKRjpS9R+MsJGlttP9nUzdSxrHvvqm62OuSVFjjETxD39DupE
+YPFQoHOxdFTtBQlc/zIKxVdd20rs1xJeeU2/L7jtRBSPuR/Sk8zot7G2/dQHX49y
+kHrq8qz12kj1T6XDXf8KZawFywXaz0/Ur+fUYKmkVk1T0JZaNtF4sKqDeNE4zcns
+p3xLVDSl1Q5Gwj7bgph9o4Hxs9izPwiqjmNaSjPimGYZ399zcurY
+-----END CERTIFICATE-----
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/run-atlas-proxy.sh b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/run-atlas-proxy.sh
new file mode 100644
index 0000000000000000000000000000000000000000..edfdb7bc9456bc98dea8037b3171f100463f2834
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/run-atlas-proxy.sh	
@@ -0,0 +1,104 @@
+#!/bin/sh
+#
+# This script uses the Atlas proxy project's own evergreen launch script
+# to build and launch an Atlas proxy for testing.  It works directly from
+# their master branch, so may fail if they break something.
+#
+# There is no corresponding 'shutdown' script; the Atlas proxy project
+# relies on Evergreen to terminate processes and clean up when tasks end,
+# so we do the same.
+#
+# The URI is harded coded as:
+# mongodb://user:pencil@host5.local.10gen.cc:9900/admin?replicaSet=benchmark
+#
+# Connections requires SSL and the CA file is 'main/ca.pem' in the atlasproxy repo.
+#
+# If this fails, check the 'main/test.sh' file in the atlasproxy repo for
+# possible changes.
+#
+# Installation of Go dependencies appears to require a newer git.  1.7 on
+# rhel62 failed, but 2.0 on ubuntu1604 worked.  The atlasproxy project
+# itself tests on rhel70.
+#
+# This script expects the following environment variables:
+#
+# DRIVERS_TOOLS (required) - absolute path to the checked out
+# driver-evergreen-tools repository
+#
+# MONGODB_VERSION - version of MongoDB to download and use. For Atlas
+# Proxy, must be "3.4" or "latest".  Defaults to "3.4".
+
+set -o xtrace   # Write all commands first to stderr
+set -o errexit  # Exit the script with error if any of the commands fail
+
+MONGODB_VERSION=${MONGODB_VERSION:-"3.4"}
+
+ORIG_DIR="$(pwd)"
+
+#--------------------------------------------------------------------------#
+# Downlaod MongoDB Binary
+#--------------------------------------------------------------------------#
+
+DL_START=$(date +%s)
+DIR=$(dirname $0)
+
+# Load download helper functions
+. $DIR/download-mongodb.sh
+
+# set $DISTRO
+get_distro
+
+# set $MONGODB_DOWNLOAD_URL and $EXTRACT
+get_mongodb_download_url_for "$DISTRO" "$MONGODB_VERSION"
+
+# extracts to $DRIVERS_TOOLS/mongodb
+rm -rf "$DRIVERS_TOOLS/mongodb"
+download_and_extract "$MONGODB_DOWNLOAD_URL" "$EXTRACT"
+DL_END=$(date +%s)
+
+#--------------------------------------------------------------------------#
+# Clone Atlas Proxy repo and launch it
+#--------------------------------------------------------------------------#
+
+AP_START=$(date +%s)
+
+cd "$ORIG_DIR"
+rm -rf atlasproxy
+git clone git@github.com:10gen/atlasproxy.git
+cd atlasproxy
+
+# This section copied from atlasproxy's .evergreen.yml: <<<
+export PATH="/opt/golang/go1.11/bin:$PATH"
+export GOROOT="/opt/golang/go1.11"
+export GOPATH=`pwd`/.gopath
+go version
+./gpm
+export MONGO_DIR="$DRIVERS_TOOLS/mongodb/bin"
+cd main
+./start_test_proxies_and_mtms.sh
+# >>> end of copy
+
+AP_END=$(date +%s)
+
+# Write results file
+DL_ELAPSED=$(expr $DL_END - $DL_START)
+AP_ELAPSED=$(expr $AP_END - $AP_START)
+cat <<EOT >> $DRIVERS_TOOLS/results.json
+{"results": [
+  {
+    "status": "PASS",
+    "test_file": "AtlasProxy Start",
+    "start": $AP_START,
+    "end": $AP_END,
+    "elapsed": $AP_ELAPSED
+  },
+  {
+    "status": "PASS",
+    "test_file": "Download MongoDB",
+    "start": $DL_START,
+    "end": $DL_END,
+    "elapsed": $DL_ELAPSED
+  }
+]}
+
+EOT
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/run-orchestration.sh b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/run-orchestration.sh
new file mode 100644
index 0000000000000000000000000000000000000000..d969aad164cb6bd63c7559cf10a62d97a0f36afd
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/run-orchestration.sh	
@@ -0,0 +1,108 @@
+#!/bin/sh
+set -o xtrace   # Write all commands first to stderr
+set -o errexit  # Exit the script with error if any of the commands fail
+
+
+AUTH=${AUTH:-noauth}
+SSL=${SSL:-nossl}
+TOPOLOGY=${TOPOLOGY:-server}
+STORAGE_ENGINE=${STORAGE_ENGINE}
+# Set to a non-empty string to use the <topology>/disableTestCommands.json
+# cluster config, eg DISABLE_TEST_COMMANDS=1
+DISABLE_TEST_COMMANDS=${DISABLE_TEST_COMMANDS}
+MONGODB_VERSION=${MONGODB_VERSION:-latest}
+
+DL_START=$(date +%s)
+DIR=$(dirname $0)
+# Functions to fetch MongoDB binaries
+. $DIR/download-mongodb.sh
+
+get_distro
+if [ -z "$MONGODB_DOWNLOAD_URL" ]; then
+    get_mongodb_download_url_for "$DISTRO" "$MONGODB_VERSION"
+else
+  # Even though we have the MONGODB_DOWNLOAD_URL, we still call this to get the proper EXTRACT variable
+  get_mongodb_download_url_for "$DISTRO"
+fi
+download_and_extract "$MONGODB_DOWNLOAD_URL" "$EXTRACT"
+
+DL_END=$(date +%s)
+MO_START=$(date +%s)
+
+ORCHESTRATION_FILE=${ORCHESTRATION_FILE}
+# If no orchestration file was specified, build up the name based on configuration parameters.
+if [ -z "$ORCHESTRATION_FILE" ]; then
+  ORCHESTRATION_FILE="basic"
+  if [ "$AUTH" = "auth" ]; then
+    ORCHESTRATION_FILE="auth"
+  fi
+
+  if [ "$SSL" != "nossl" ]; then
+    ORCHESTRATION_FILE="${ORCHESTRATION_FILE}-ssl"
+  fi
+
+  # disableTestCommands files do not exist for different auth or ssl modes.
+  if [ ! -z "$DISABLE_TEST_COMMANDS" ]; then
+    ORCHESTRATION_FILE="disableTestCommands"
+  fi
+
+  # Storage engine config files do not exist for different auth or ssl modes.
+  if [ ! -z "$STORAGE_ENGINE" ]; then
+    ORCHESTRATION_FILE="$STORAGE_ENGINE"
+  fi
+
+  ORCHESTRATION_FILE="${ORCHESTRATION_FILE}.json"
+fi
+
+TOOLS_ORCHESTRATION_FILE="$MONGO_ORCHESTRATION_HOME/configs/${TOPOLOGY}s/${ORCHESTRATION_FILE}"
+CUSTOM_ORCHESTRATION_FILE="$DIR/orchestration/configs/${TOPOLOGY}s/${ORCHESTRATION_FILE}"
+
+if [ -f "$CUSTOM_ORCHESTRATION_FILE" ]; then
+  export ORCHESTRATION_FILE="$CUSTOM_ORCHESTRATION_FILE"
+elif [ -f "$TOOLS_ORCHESTRATION_FILE" ]; then
+  export ORCHESTRATION_FILE="$TOOLS_ORCHESTRATION_FILE"
+else
+  echo "Could not find orchestration file $ORCHESTRATION_FILE"
+  exit 1
+fi
+
+export ORCHESTRATION_URL="http://localhost:8889/v1/${TOPOLOGY}s"
+
+# Start mongo-orchestration
+sh $DIR/start-orchestration.sh "$MONGO_ORCHESTRATION_HOME"
+
+pwd
+if ! curl --silent --show-error --data @"$ORCHESTRATION_FILE" "$ORCHESTRATION_URL" --max-time 600 --fail -o tmp.json; then
+  echo Failed to start cluster, see $MONGO_ORCHESTRATION_HOME/out.log:
+  cat $MONGO_ORCHESTRATION_HOME/out.log
+  echo Failed to start cluster, see $MONGO_ORCHESTRATION_HOME/server.log:
+  cat $MONGO_ORCHESTRATION_HOME/server.log
+  exit 1
+fi
+cat tmp.json
+URI=$(python -c 'import sys, json; j=json.load(open("tmp.json")); print(j["mongodb_auth_uri" if "mongodb_auth_uri" in j else "mongodb_uri"])' | tr -d '\r')
+echo 'MONGODB_URI: "'$URI'"' > mo-expansion.yml
+echo "Cluster URI: $URI"
+
+MO_END=$(date +%s)
+MO_ELAPSED=$(expr $MO_END - $MO_START)
+DL_ELAPSED=$(expr $DL_END - $DL_START)
+cat <<EOT >> $DRIVERS_TOOLS/results.json
+{"results": [
+  {
+    "status": "PASS",
+    "test_file": "Orchestration",
+    "start": $MO_START,
+    "end": $MO_END,
+    "elapsed": $MO_ELAPSED
+  },
+  {
+    "status": "PASS",
+    "test_file": "Download MongoDB",
+    "start": $DL_START,
+    "end": $DL_END,
+    "elapsed": $DL_ELAPSED
+  }
+]}
+
+EOT
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/run-tests.sh b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/run-tests.sh
new file mode 100644
index 0000000000000000000000000000000000000000..423466503d88b9ebeeac1ef05ca33fa9d70558ff
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/run-tests.sh	
@@ -0,0 +1,35 @@
+#!/bin/sh
+set -o xtrace   # Write all commands first to stderr
+set -o errexit  # Exit the script with error if any of the commands fail
+
+# Supported/used environment variables:
+#       AUTH                    Set to enable authentication. Defaults to "noauth"
+#       SSL                     Set to enable SSL. Defaults to "nossl"
+#       MONGODB_URI             Set the suggested connection MONGODB_URI (including credentials and topology info)
+#       MARCH                   Machine Architecture. Defaults to lowercase uname -m
+
+
+AUTH=${AUTH:-noauth}
+SSL=${SSL:-nossl}
+MONGODB_URI=${MONGODB_URI:-}
+TESTS=${TESTS:-}
+
+OS=$(uname -s | tr '[:upper:]' '[:lower:]')
+[ -z "$MARCH" ] && MARCH=$(uname -m | tr '[:upper:]' '[:lower:]')
+
+echo "Running $AUTH tests over $SSL, connecting to $MONGODB_URI"
+
+OLD_PATH=$PATH
+PATH=/opt/php/${PHP_VERSION}-64bit/bin:$OLD_PATH
+
+# Run the tests, and store the results in a Evergreen compatible JSON results file
+case "$TESTS" in
+   atlas-data-lake*)
+      MONGODB_URI="mongodb://mhuser:pencil@127.0.0.1:27017"
+      php vendor/bin/simple-phpunit --configuration phpunit.evergreen.xml --testsuite "Atlas Data Lake Test Suite"
+      ;;
+
+   *)
+      php vendor/bin/simple-phpunit --configuration phpunit.evergreen.xml
+      ;;
+esac
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/start-orchestration.sh b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/start-orchestration.sh
new file mode 100644
index 0000000000000000000000000000000000000000..2197f2d40211053f6c13216ccd13da60de3500a3
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/start-orchestration.sh	
@@ -0,0 +1,78 @@
+#!/bin/sh
+
+if [ "$#" -ne 1 ]; then
+  echo "$0 requires one argument: <MONGO_ORCHESTRATION_HOME>"
+  echo "For example: $0 /tmp/mongo-orchestration-home"
+  exit 1
+fi
+
+set -o xtrace   # Write all commands first to stderr
+set -o errexit  # Exit the script with error if any of the commands fail
+
+
+MONGO_ORCHESTRATION_HOME="$1"
+
+echo From shell `date` > $MONGO_ORCHESTRATION_HOME/server.log
+
+cd "$MONGO_ORCHESTRATION_HOME"
+# Setup or use the existing virtualenv for mongo-orchestration.
+# Prefer using Python 3 from the toolchain over the default system python.
+# We may still fallback to using an old version of Python here.
+# Many of the Linux distros in Evergreen ship Python 2.6 as the
+# system Python. Core libraries installed by virtualenv (setuptools,
+# pip, wheel) have dropped, or soon will drop, support for Python
+# 2.6. Starting with version 14, virtualenv upgrades these libraries
+# to the latest available on pypi when creating the virtual environment
+# unless you pass --never-download.
+PYTHON=$(command -v /opt/mongodbtoolchain/v2/bin/python3 || command -v python3 || command -v python)
+$PYTHON -c 'import sys; print(sys.version)'
+$PYTHON -c 'import ssl; print(ssl.OPENSSL_VERSION)'
+
+if [ -f venv/bin/activate ]; then
+  . venv/bin/activate
+elif [ -f venv/Scripts/activate ]; then
+  . venv/Scripts/activate
+elif $PYTHON -m virtualenv --system-site-packages --never-download venv || virtualenv --system-site-packages --never-download venv; then
+  if [ -f venv/bin/activate ]; then
+    . venv/bin/activate
+  elif [ -f venv/Scripts/activate ]; then
+    . venv/Scripts/activate
+  fi
+  # Install from github to get the latest mongo-orchestration.
+  pip install --upgrade 'git+git://github.com/mongodb/mongo-orchestration@master'
+  pip list
+fi
+cd -
+
+ORCHESTRATION_ARGUMENTS="-e default -f $MONGO_ORCHESTRATION_HOME/orchestration.config --socket-timeout-ms=60000 --bind=127.0.0.1 --enable-majority-read-concern"
+if [ "Windows_NT" = "$OS" ]; then # Magic variable in cygwin
+  ORCHESTRATION_ARGUMENTS="$ORCHESTRATION_ARGUMENTS -s wsgiref"
+fi
+
+# Forcibly kill the process listening on port 8889, most likey a wild
+# mongo-orchestration left running from a previous task.
+if [ "Windows_NT" = "$OS" ]; then # Magic variable in cygwin
+  OLD_MO_PID=$(netstat -ano | grep ':8889 .* LISTENING' | awk '{print $5}' | tr -d '[:space:]')
+  if [ ! -z "$OLD_MO_PID" ]; then
+    taskkill /F /T /PID "$OLD_MO_PID" || true
+  fi
+else
+  OLD_MO_PID=$(lsof -t -i:8889 || true)
+  if [ ! -z "$OLD_MO_PID" ]; then
+    kill -9 "$OLD_MO_PID" || true
+  fi
+fi
+
+mongo-orchestration $ORCHESTRATION_ARGUMENTS start > $MONGO_ORCHESTRATION_HOME/out.log 2>&1 < /dev/null &
+
+ls -la $MONGO_ORCHESTRATION_HOME
+
+sleep 5
+if ! curl http://localhost:8889/ --silent --show-error --max-time 120 --fail; then
+  echo Failed to start mongo-orchestration, see $MONGO_ORCHESTRATION_HOME/out.log:
+  cat $MONGO_ORCHESTRATION_HOME/out.log
+  echo Failed to start mongo-orchestration, see $MONGO_ORCHESTRATION_HOME/server.log:
+  cat $MONGO_ORCHESTRATION_HOME/server.log
+  exit 1
+fi
+sleep 5
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/stop-orchestration.sh b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/stop-orchestration.sh
new file mode 100644
index 0000000000000000000000000000000000000000..5c01d15801405c91926fdb1131e3641853cde16d
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/stop-orchestration.sh	
@@ -0,0 +1,12 @@
+#!/bin/sh
+set -o xtrace   # Write all commands first to stderr
+set -o errexit  # Exit the script with error if any of the commands fail
+
+cd "$MONGO_ORCHESTRATION_HOME"
+# source the mongo-orchestration virtualenv if it exists
+if [ -f venv/bin/activate ]; then
+    . venv/bin/activate
+elif [ -f venv/Scripts/activate ]; then
+    . venv/Scripts/activate
+fi
+mongo-orchestration stop
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/x509gen/82e9b7a6.0 b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/x509gen/82e9b7a6.0
new file mode 100644
index 0000000000000000000000000000000000000000..6ac86cfcc1ee3129aab684f1093e204190aee7e5
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/x509gen/82e9b7a6.0	
@@ -0,0 +1,21 @@
+-----BEGIN CERTIFICATE-----
+MIIDfzCCAmegAwIBAgIDB1MGMA0GCSqGSIb3DQEBCwUAMHkxGzAZBgNVBAMTEkRy
+aXZlcnMgVGVzdGluZyBDQTEQMA4GA1UECxMHRHJpdmVyczEQMA4GA1UEChMHTW9u
+Z29EQjEWMBQGA1UEBxMNTmV3IFlvcmsgQ2l0eTERMA8GA1UECBMITmV3IFlvcmsx
+CzAJBgNVBAYTAlVTMB4XDTE5MDUyMjIwMjMxMVoXDTM5MDUyMjIwMjMxMVoweTEb
+MBkGA1UEAxMSRHJpdmVycyBUZXN0aW5nIENBMRAwDgYDVQQLEwdEcml2ZXJzMRAw
+DgYDVQQKEwdNb25nb0RCMRYwFAYDVQQHEw1OZXcgWW9yayBDaXR5MREwDwYDVQQI
+EwhOZXcgWW9yazELMAkGA1UEBhMCVVMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
+ggEKAoIBAQCl7VN+WsQfHlwapcOpTLZVoeMAl1LTbWTFuXSAavIyy0W1Ytky1UP/
+bxCSW0mSWwCgqoJ5aXbAvrNRp6ArWu3LsTQIEcD3pEdrFIVQhYzWUs9fXqPyI9k+
+QNNQ+MRFKeGteTPYwF2eVEtPzUHU5ws3+OKp1m6MCLkwAG3RBFUAfddUnLvGoZiT
+pd8/eNabhgHvdrCw+tYFCWvSjz7SluEVievpQehrSEPKe8DxJq/IM3tSl3tdylzT
+zeiKNO7c7LuQrgjAfrZl7n2SriHIlNmqiDR/kdd8+TxBuxjFlcf2WyHCO3lIcIgH
+KXTlhUCg50KfHaxHu05Qw0x8869yIzqbAgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8w
+DQYJKoZIhvcNAQELBQADggEBAEHuhTL8KQZcKCTSJbYA9MgZj7U32arMGBbc1hiq
+VBREwvdVz4+9tIyWMzN9R/YCKmUTnCq8z3wTlC8kBtxYn/l4Tj8nJYcgLJjQ0Fwe
+gT564CmvkUat8uXPz6olOCdwkMpJ9Sj62i0mpgXJdBfxKQ6TZ9yGz6m3jannjZpN
+LchB7xSAEWtqUgvNusq0dApJsf4n7jZ+oBZVaQw2+tzaMfaLqHgMwcu1FzA8UKCD
+sxCgIsZUs8DdxaD418Ot6nPfheOTqe24n+TTa+Z6O0W0QtnofJBx7tmAo1aEc57i
+77s89pfwIJetpIlhzNSMKurCAocFCJMJLAASJFuu6dyDvPo=
+-----END CERTIFICATE-----
\ No newline at end of file
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/x509gen/altname.pem b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/x509gen/altname.pem
new file mode 100644
index 0000000000000000000000000000000000000000..ff0fd61e67017ea2bdf6efe9addcde0df97bdc52
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/x509gen/altname.pem	
@@ -0,0 +1,49 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEowIBAAKCAQEAgyOELJgWP2akoidBdtchvdRF8gZrR8rwORDmST1tmH5aKiH2
+e/lkWf+pxmXnvmLXoOKk3HHGgyZ7v1sDDB0z7/rAimECqxnqJ90GFq8rGR60jCL/
+hs+30m0U9CNAvjzD5yFruaisPeCZuZXEA06QbTbTaSD4u/n7fgZVGSnj2m+DFel5
+S7dgL4Pa7Vh2nua8QPfczLLQI/uP9Ma5ZXjk2C2V+QBkmK64OanGY6yXn8+m5Lp1
+cKhhQUiXVVO1BgFHw65FapTrhG2zgyuaqvb5F062V+XGIwZhWhDz4cTgCx0dFKU+
+WQGXuEDDY3EzaOd6Ds3h6WkCRDs9cn2i0j4taQIDAQABAoIBAHeCTXkKXPQIia6Q
+0dMIuWIy6k9nVCtIIWYQJZ3HUnJva6IL84IFxFNUcBczVV+m2lVvVsjjEwMAdjPs
+MDnA/00LGp7BS9o8Mq2DeoH/vuoUlntDhdUIxcAJ0teurNjxraKcTX0T32xAnDeJ
+6ekNlwdAuKeM+cDtTykJglH9X/324eOT8sEkpohkTJaszs3PEqgN9jrHttVatmft
+KGT06aANBrEH61xr/nfBehd3R7WyVsIUmlihlIIBwbxyycdMSxHIiE1Qno252Ek7
+GJp/dPqO2pwIH47cop48SsZLFVosqaZs3jkEIDkQkyd7tvmVG69aFBPz5+PTvdRv
+fufuvXUCgYEA1gTnvln9/PmC9mKFTDGdKLhFIypyOhKl1lUoDgcmCencjwu28yTA
++A2fKZQFupiHYvSg5kbvmr7FGVtKLNPJWocvr7jqPvrVLCzvs6l94LhGCTVyOmgn
+e09xyDx3xQTuJmpg+4LD1jImL3OLO3fplbslwisip2CWzHZR6h3QRVMCgYEAnNy5
+F81xbimMVcubQve6LPzZq1pYaUM5ppkejNdBoEKR28+GP0NQ7YbN6iu2LXlbpWk/
+IrAyUmDUpnXFsiRDDWnPol6JzYTovzeZG+NCMJWkaQEOzm8BpUsC2UBvsX55ddxt
+WM4CkLOxo7KXfQwYAMKc/H8tFE7DXloH82U7jtMCgYB+PuiBFc7IYlrJgjZFSuL8
++S33X3uAHC3tL9Bv7fGXWXd8fhmOdfjKmiZwPVvfxUffrJQZInEGpE/Z9EreBJQ7
+LZGIo5iyS/5hj6RaI7oYTDssBXX7VCMuDx/8UQcJli3xRUEuO+XPvUdfKFZSXxrP
+81SDpDRN7aEmvQj3BF0t9wKBgCgX5ptl4HtG1V7MhufMB+Md0ckRc42cKC0j8AIR
+tu1udneXiHm9C/9aOGGFQLBI15rk1sVYAdS6eT/+1EQfLqBMDk0zGsfUE+VkIZdW
+NAHVDcvlAFLVXrdP/+9ln+bfK85rQ+ux5Ef2Fg6ARGYq5Cu1koibPPt20krYejXF
+Bz8PAoGBAKbCmptnjdu4QF+rGLfYyVnrtyUuRgN+Q0MCIag1dBTag6rC17xDYJ6g
+3Txzzb9xAZ35pSHroB7TSr32vRUQVrAcfldW4mousr9A0pDoc/E2axtE1YmzSYwk
+jqgu3PeWrtwBthUEoRXbQAed97bKW+gUU677u9IFRCS2YIfwDV5R
+-----END RSA PRIVATE KEY-----
+-----BEGIN CERTIFICATE-----
+MIIDnTCCAoWgAwIBAgIDCRkUMA0GCSqGSIb3DQEBCwUAMHkxGzAZBgNVBAMTEkRy
+aXZlcnMgVGVzdGluZyBDQTEQMA4GA1UECxMHRHJpdmVyczEQMA4GA1UEChMHTW9u
+Z29EQjEWMBQGA1UEBxMNTmV3IFlvcmsgQ2l0eTERMA8GA1UECBMITmV3IFlvcmsx
+CzAJBgNVBAYTAlVTMB4XDTE5MDUyMjIyMzQzNloXDTM5MDUyMjIyMzQzNlowcDES
+MBAGA1UEAxMJbG9jYWxob3N0MRAwDgYDVQQLEwdEcml2ZXJzMRAwDgYDVQQKEwdN
+b25nb0RCMRYwFAYDVQQHEw1OZXcgWW9yayBDaXR5MREwDwYDVQQIEwhOZXcgWW9y
+azELMAkGA1UEBhMCVVMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCD
+I4QsmBY/ZqSiJ0F21yG91EXyBmtHyvA5EOZJPW2YfloqIfZ7+WRZ/6nGZee+Yteg
+4qTcccaDJnu/WwMMHTPv+sCKYQKrGeon3QYWrysZHrSMIv+Gz7fSbRT0I0C+PMPn
+IWu5qKw94Jm5lcQDTpBtNtNpIPi7+ft+BlUZKePab4MV6XlLt2Avg9rtWHae5rxA
+99zMstAj+4/0xrlleOTYLZX5AGSYrrg5qcZjrJefz6bkunVwqGFBSJdVU7UGAUfD
+rkVqlOuEbbODK5qq9vkXTrZX5cYjBmFaEPPhxOALHR0UpT5ZAZe4QMNjcTNo53oO
+zeHpaQJEOz1yfaLSPi1pAgMBAAGjNzA1MDMGA1UdEQQsMCqCCWxvY2FsaG9zdIcE
+fwAAAYIXYWx0ZXJuYXRpdmUubW9uZ29kYi5jb20wDQYJKoZIhvcNAQELBQADggEB
+AADOro10g1QReF0QVX2w+yVwCWy8FUzuksX0RI0RCFRJPo79SH7o2IZFGbLlBL8K
+MMsgSrzRW/HcyE91fv0R2b7kvqfD3Eo1W1ocufjVg+3e4uuwm9k9SLjSI6mE4hEf
+H6BeFoZhUdbrq9l/ez+NK+3ToHAl1bGLkipfnB522gRO1CjkpiY2knaaNQtjd/a9
+7QXqUs+KMJx42yqjBbVE6MdA2ypNMMIc8AgI5kRKEBGHpS4Z6VNZN4Pus1atGlRW
+OwkjHK5pnT1TAKSODjfFw5VlXGztGTPKuJhM2/X7Qi0bO8b7NmH7cjDBATmZF5O8
+FAxIQ8+3qUPMXYkb1ipLOdQ=
+-----END CERTIFICATE-----
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/x509gen/ca.pem b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/x509gen/ca.pem
new file mode 100644
index 0000000000000000000000000000000000000000..6ac86cfcc1ee3129aab684f1093e204190aee7e5
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/x509gen/ca.pem	
@@ -0,0 +1,21 @@
+-----BEGIN CERTIFICATE-----
+MIIDfzCCAmegAwIBAgIDB1MGMA0GCSqGSIb3DQEBCwUAMHkxGzAZBgNVBAMTEkRy
+aXZlcnMgVGVzdGluZyBDQTEQMA4GA1UECxMHRHJpdmVyczEQMA4GA1UEChMHTW9u
+Z29EQjEWMBQGA1UEBxMNTmV3IFlvcmsgQ2l0eTERMA8GA1UECBMITmV3IFlvcmsx
+CzAJBgNVBAYTAlVTMB4XDTE5MDUyMjIwMjMxMVoXDTM5MDUyMjIwMjMxMVoweTEb
+MBkGA1UEAxMSRHJpdmVycyBUZXN0aW5nIENBMRAwDgYDVQQLEwdEcml2ZXJzMRAw
+DgYDVQQKEwdNb25nb0RCMRYwFAYDVQQHEw1OZXcgWW9yayBDaXR5MREwDwYDVQQI
+EwhOZXcgWW9yazELMAkGA1UEBhMCVVMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
+ggEKAoIBAQCl7VN+WsQfHlwapcOpTLZVoeMAl1LTbWTFuXSAavIyy0W1Ytky1UP/
+bxCSW0mSWwCgqoJ5aXbAvrNRp6ArWu3LsTQIEcD3pEdrFIVQhYzWUs9fXqPyI9k+
+QNNQ+MRFKeGteTPYwF2eVEtPzUHU5ws3+OKp1m6MCLkwAG3RBFUAfddUnLvGoZiT
+pd8/eNabhgHvdrCw+tYFCWvSjz7SluEVievpQehrSEPKe8DxJq/IM3tSl3tdylzT
+zeiKNO7c7LuQrgjAfrZl7n2SriHIlNmqiDR/kdd8+TxBuxjFlcf2WyHCO3lIcIgH
+KXTlhUCg50KfHaxHu05Qw0x8869yIzqbAgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8w
+DQYJKoZIhvcNAQELBQADggEBAEHuhTL8KQZcKCTSJbYA9MgZj7U32arMGBbc1hiq
+VBREwvdVz4+9tIyWMzN9R/YCKmUTnCq8z3wTlC8kBtxYn/l4Tj8nJYcgLJjQ0Fwe
+gT564CmvkUat8uXPz6olOCdwkMpJ9Sj62i0mpgXJdBfxKQ6TZ9yGz6m3jannjZpN
+LchB7xSAEWtqUgvNusq0dApJsf4n7jZ+oBZVaQw2+tzaMfaLqHgMwcu1FzA8UKCD
+sxCgIsZUs8DdxaD418Ot6nPfheOTqe24n+TTa+Z6O0W0QtnofJBx7tmAo1aEc57i
+77s89pfwIJetpIlhzNSMKurCAocFCJMJLAASJFuu6dyDvPo=
+-----END CERTIFICATE-----
\ No newline at end of file
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/x509gen/client-private.pem b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/x509gen/client-private.pem
new file mode 100644
index 0000000000000000000000000000000000000000..551a43a75c98c58fca4bdc28f8bddddee5969d9a
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/x509gen/client-private.pem	
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpAIBAAKCAQEAsNS8UEuin7/K29jXfIOLpIoh1jEyWVqxiie2Onx7uJJKcoKo
+khA3XeUnVN0k6X5MwYWcN52xcns7LYtyt06nRpTG2/emoV44w9uKTuHsvUbiOwSV
+m/ToKQQ4FUFZoqorXH+ZmJuIpJNfoW+3CkE1vEDCIecIq6BNg5ySsPtvSuSJHGjp
+mc7/5ZUDvFE2aJ8QbJU3Ws0HXiEb6ymi048LlzEL2VKX3w6mqqh+7dcZGAy7qYk2
+5FZ9ktKvCeQau7mTyU1hsPrKFiKtMN8Q2ZAItX13asw5/IeSTq2LgLFHlbj5Kpq4
+GmLdNCshzH5X7Ew3IYM8EHmsX8dmD6mhv7vpVwIDAQABAoIBABOdpb4qhcG+3twA
+c/cGCKmaASLnljQ/UU6IFTjrsjXJVKTbRaPeVKX/05sgZQXZ0t3s2mV5AsQ2U1w8
+Cd+3w+qaemzQThW8hAOGCROzEDX29QWi/o2sX0ydgTMqaq0Wv3SlWv6I0mGfT45y
+/BURIsrdTCvCmz2erLqa1dL4MWJXRFjT9UTs5twlecIOM2IHKoGGagFhymRK4kDe
+wTRC9fpfoAgyfus3pCO/wi/F8yKGPDEwY+zgkhrJQ+kSeki7oKdGD1H540vB8gRt
+EIqssE0Y6rEYf97WssQlxJgvoJBDSftOijS6mwvoasDUwfFqyyPiirawXWWhHXkc
+DjIi/XECgYEA5xfjilw9YyM2UGQNESbNNunPcj7gDZbN347xJwmYmi9AUdPLt9xN
+3XaMqqR22k1DUOxC/5hH0uiXir7mDfqmC+XS/ic/VOsa3CDWejkEnyGLiwSHY502
+wD/xWgHwUiGVAG9HY64vnDGm6L3KGXA2oqxanL4V0+0+Ht49pZ16i8sCgYEAw+Ox
+CHGtpkzjCP/z8xr+1VTSdpc/4CP2HONnYopcn48KfQnf7Nale69/1kZpypJlvQSG
+eeA3jMGigNJEkb8/kaVoRLCisXcwLc0XIfCTeiK6FS0Ka30D/84Qm8UsHxRdpGkM
+kYITAa2r64tgRL8as4/ukeXBKE+oOhX43LeEfyUCgYBkf7IX2Ndlhsm3GlvIarxy
+NipeP9PGdR/hKlPbq0OvQf9R1q7QrcE7H7Q6/b0mYNV2mtjkOQB7S2WkFDMOP0P5
+BqDEoKLdNkV/F9TOYH+PCNKbyYNrodJOt0Ap6Y/u1+Xpw3sjcXwJDFrO+sKqX2+T
+PStG4S+y84jBedsLbDoAEwKBgQCTz7/KC11o2yOFqv09N+WKvBKDgeWlD/2qFr3w
+UU9K5viXGVhqshz0k5z25vL09Drowf1nAZVpFMO2SPOMtq8VC6b+Dfr1xmYIaXVH
+Gu1tf77CM9Zk/VSDNc66e7GrUgbHBK2DLo+A+Ld9aRIfTcSsMbNnS+LQtCrQibvb
+cG7+MQKBgQCY11oMT2dUekoZEyW4no7W5D74lR8ztMjp/fWWTDo/AZGPBY6cZoZF
+IICrzYtDT/5BzB0Jh1f4O9ZQkm5+OvlFbmoZoSbMzHL3oJCBOY5K0/kdGXL46WWh
+IRJSYakNU6VIS7SjDpKgm9D8befQqZeoSggSjIIULIiAtYgS80vmGA==
+-----END RSA PRIVATE KEY-----
\ No newline at end of file
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/x509gen/client-public.pem b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/x509gen/client-public.pem
new file mode 100644
index 0000000000000000000000000000000000000000..53e4e034f9ee039b3e787616ddba1a79a417e752
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/x509gen/client-public.pem	
@@ -0,0 +1,21 @@
+-----BEGIN CERTIFICATE-----
+MIIDgzCCAmugAwIBAgIDAxOUMA0GCSqGSIb3DQEBCwUAMHkxGzAZBgNVBAMTEkRy
+aXZlcnMgVGVzdGluZyBDQTEQMA4GA1UECxMHRHJpdmVyczEQMA4GA1UEChMHTW9u
+Z29EQjEWMBQGA1UEBxMNTmV3IFlvcmsgQ2l0eTERMA8GA1UECBMITmV3IFlvcmsx
+CzAJBgNVBAYTAlVTMB4XDTE5MDUyMjIzNTU1NFoXDTM5MDUyMjIzNTU1NFowaTEP
+MA0GA1UEAxMGY2xpZW50MRAwDgYDVQQLEwdEcml2ZXJzMQwwCgYDVQQKEwNNREIx
+FjAUBgNVBAcTDU5ldyBZb3JrIENpdHkxETAPBgNVBAgTCE5ldyBZb3JrMQswCQYD
+VQQGEwJVUzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALDUvFBLop+/
+ytvY13yDi6SKIdYxMllasYontjp8e7iSSnKCqJIQN13lJ1TdJOl+TMGFnDedsXJ7
+Oy2LcrdOp0aUxtv3pqFeOMPbik7h7L1G4jsElZv06CkEOBVBWaKqK1x/mZibiKST
+X6FvtwpBNbxAwiHnCKugTYOckrD7b0rkiRxo6ZnO/+WVA7xRNmifEGyVN1rNB14h
+G+spotOPC5cxC9lSl98Opqqofu3XGRgMu6mJNuRWfZLSrwnkGru5k8lNYbD6yhYi
+rTDfENmQCLV9d2rMOfyHkk6ti4CxR5W4+SqauBpi3TQrIcx+V+xMNyGDPBB5rF/H
+Zg+pob+76VcCAwEAAaMkMCIwCwYDVR0PBAQDAgeAMBMGA1UdJQQMMAoGCCsGAQUF
+BwMCMA0GCSqGSIb3DQEBCwUAA4IBAQAqRcLAGvYMaGYOV4HJTzNotT2qE0I9THNQ
+wOV1fBg69x6SrUQTQLjJEptpOA288Wue6Jt3H+p5qAGV5GbXjzN/yjCoItggSKxG
+Xg7279nz6/C5faoIKRjpS9R+MsJGlttP9nUzdSxrHvvqm62OuSVFjjETxD39DupE
+YPFQoHOxdFTtBQlc/zIKxVdd20rs1xJeeU2/L7jtRBSPuR/Sk8zot7G2/dQHX49y
+kHrq8qz12kj1T6XDXf8KZawFywXaz0/Ur+fUYKmkVk1T0JZaNtF4sKqDeNE4zcns
+p3xLVDSl1Q5Gwj7bgph9o4Hxs9izPwiqjmNaSjPimGYZ399zcurY
+-----END CERTIFICATE-----
\ No newline at end of file
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/x509gen/client.pem b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/x509gen/client.pem
new file mode 100644
index 0000000000000000000000000000000000000000..5b070010920d3159a2b4eb1bed834508fb799fde
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/x509gen/client.pem	
@@ -0,0 +1,48 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpAIBAAKCAQEAsNS8UEuin7/K29jXfIOLpIoh1jEyWVqxiie2Onx7uJJKcoKo
+khA3XeUnVN0k6X5MwYWcN52xcns7LYtyt06nRpTG2/emoV44w9uKTuHsvUbiOwSV
+m/ToKQQ4FUFZoqorXH+ZmJuIpJNfoW+3CkE1vEDCIecIq6BNg5ySsPtvSuSJHGjp
+mc7/5ZUDvFE2aJ8QbJU3Ws0HXiEb6ymi048LlzEL2VKX3w6mqqh+7dcZGAy7qYk2
+5FZ9ktKvCeQau7mTyU1hsPrKFiKtMN8Q2ZAItX13asw5/IeSTq2LgLFHlbj5Kpq4
+GmLdNCshzH5X7Ew3IYM8EHmsX8dmD6mhv7vpVwIDAQABAoIBABOdpb4qhcG+3twA
+c/cGCKmaASLnljQ/UU6IFTjrsjXJVKTbRaPeVKX/05sgZQXZ0t3s2mV5AsQ2U1w8
+Cd+3w+qaemzQThW8hAOGCROzEDX29QWi/o2sX0ydgTMqaq0Wv3SlWv6I0mGfT45y
+/BURIsrdTCvCmz2erLqa1dL4MWJXRFjT9UTs5twlecIOM2IHKoGGagFhymRK4kDe
+wTRC9fpfoAgyfus3pCO/wi/F8yKGPDEwY+zgkhrJQ+kSeki7oKdGD1H540vB8gRt
+EIqssE0Y6rEYf97WssQlxJgvoJBDSftOijS6mwvoasDUwfFqyyPiirawXWWhHXkc
+DjIi/XECgYEA5xfjilw9YyM2UGQNESbNNunPcj7gDZbN347xJwmYmi9AUdPLt9xN
+3XaMqqR22k1DUOxC/5hH0uiXir7mDfqmC+XS/ic/VOsa3CDWejkEnyGLiwSHY502
+wD/xWgHwUiGVAG9HY64vnDGm6L3KGXA2oqxanL4V0+0+Ht49pZ16i8sCgYEAw+Ox
+CHGtpkzjCP/z8xr+1VTSdpc/4CP2HONnYopcn48KfQnf7Nale69/1kZpypJlvQSG
+eeA3jMGigNJEkb8/kaVoRLCisXcwLc0XIfCTeiK6FS0Ka30D/84Qm8UsHxRdpGkM
+kYITAa2r64tgRL8as4/ukeXBKE+oOhX43LeEfyUCgYBkf7IX2Ndlhsm3GlvIarxy
+NipeP9PGdR/hKlPbq0OvQf9R1q7QrcE7H7Q6/b0mYNV2mtjkOQB7S2WkFDMOP0P5
+BqDEoKLdNkV/F9TOYH+PCNKbyYNrodJOt0Ap6Y/u1+Xpw3sjcXwJDFrO+sKqX2+T
+PStG4S+y84jBedsLbDoAEwKBgQCTz7/KC11o2yOFqv09N+WKvBKDgeWlD/2qFr3w
+UU9K5viXGVhqshz0k5z25vL09Drowf1nAZVpFMO2SPOMtq8VC6b+Dfr1xmYIaXVH
+Gu1tf77CM9Zk/VSDNc66e7GrUgbHBK2DLo+A+Ld9aRIfTcSsMbNnS+LQtCrQibvb
+cG7+MQKBgQCY11oMT2dUekoZEyW4no7W5D74lR8ztMjp/fWWTDo/AZGPBY6cZoZF
+IICrzYtDT/5BzB0Jh1f4O9ZQkm5+OvlFbmoZoSbMzHL3oJCBOY5K0/kdGXL46WWh
+IRJSYakNU6VIS7SjDpKgm9D8befQqZeoSggSjIIULIiAtYgS80vmGA==
+-----END RSA PRIVATE KEY-----
+-----BEGIN CERTIFICATE-----
+MIIDgzCCAmugAwIBAgIDAxOUMA0GCSqGSIb3DQEBCwUAMHkxGzAZBgNVBAMTEkRy
+aXZlcnMgVGVzdGluZyBDQTEQMA4GA1UECxMHRHJpdmVyczEQMA4GA1UEChMHTW9u
+Z29EQjEWMBQGA1UEBxMNTmV3IFlvcmsgQ2l0eTERMA8GA1UECBMITmV3IFlvcmsx
+CzAJBgNVBAYTAlVTMB4XDTE5MDUyMjIzNTU1NFoXDTM5MDUyMjIzNTU1NFowaTEP
+MA0GA1UEAxMGY2xpZW50MRAwDgYDVQQLEwdEcml2ZXJzMQwwCgYDVQQKEwNNREIx
+FjAUBgNVBAcTDU5ldyBZb3JrIENpdHkxETAPBgNVBAgTCE5ldyBZb3JrMQswCQYD
+VQQGEwJVUzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALDUvFBLop+/
+ytvY13yDi6SKIdYxMllasYontjp8e7iSSnKCqJIQN13lJ1TdJOl+TMGFnDedsXJ7
+Oy2LcrdOp0aUxtv3pqFeOMPbik7h7L1G4jsElZv06CkEOBVBWaKqK1x/mZibiKST
+X6FvtwpBNbxAwiHnCKugTYOckrD7b0rkiRxo6ZnO/+WVA7xRNmifEGyVN1rNB14h
+G+spotOPC5cxC9lSl98Opqqofu3XGRgMu6mJNuRWfZLSrwnkGru5k8lNYbD6yhYi
+rTDfENmQCLV9d2rMOfyHkk6ti4CxR5W4+SqauBpi3TQrIcx+V+xMNyGDPBB5rF/H
+Zg+pob+76VcCAwEAAaMkMCIwCwYDVR0PBAQDAgeAMBMGA1UdJQQMMAoGCCsGAQUF
+BwMCMA0GCSqGSIb3DQEBCwUAA4IBAQAqRcLAGvYMaGYOV4HJTzNotT2qE0I9THNQ
+wOV1fBg69x6SrUQTQLjJEptpOA288Wue6Jt3H+p5qAGV5GbXjzN/yjCoItggSKxG
+Xg7279nz6/C5faoIKRjpS9R+MsJGlttP9nUzdSxrHvvqm62OuSVFjjETxD39DupE
+YPFQoHOxdFTtBQlc/zIKxVdd20rs1xJeeU2/L7jtRBSPuR/Sk8zot7G2/dQHX49y
+kHrq8qz12kj1T6XDXf8KZawFywXaz0/Ur+fUYKmkVk1T0JZaNtF4sKqDeNE4zcns
+p3xLVDSl1Q5Gwj7bgph9o4Hxs9izPwiqjmNaSjPimGYZ399zcurY
+-----END CERTIFICATE-----
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/x509gen/commonName.pem b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/x509gen/commonName.pem
new file mode 100644
index 0000000000000000000000000000000000000000..e8ebd4953f15ef8842135afa916041cdfdff2602
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/x509gen/commonName.pem	
@@ -0,0 +1,48 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEowIBAAKCAQEArS94Vnpx+C+LwiCIyfZH45uwDbiEqCKr0hfWPVlJdoOQgaDO
+av9nbxRvx+CnsiZ1yE6Kj1NYIX3FqOzO9YizwKtPaxCqFMjDzl1HZCJ8LTZZzMic
+01K38wGfacsBwno/sNZn9jgnT+9JOasD6854IAs5T7dRCFH/nxV+RuZ4ueTWIcfH
+jXzAZv9+wtu0sVmQKHV0J3S6ZdPqqDaYRdhOCyShBTO4RbUW1myIjooIqqy/xceV
+TmXGWycqZjyDDronT1kj/yx6znqudOeDzj1PaEdnsqdXxQlI7MVdRf3nXdDXTpw5
+gPhqxqYc47vL6RvMxqief0BJnlc6PoZWoyTRPwIDAQABAoIBAQCYNMYwSsDrfO35
+mRpfVYHs+iGKjYaZNo+Hv8dcd6Jm9E4Gf0urIfjH2VA8fKclnUOa3dxNBtTH6n/T
+bPyfMpu4U1cjI6w3RBNCxRw/V0eHfOMDZbTezS459k0ib3aGc2aShn0sGkICsKzM
+cA6sKfPNRdACzXv8MgTUzdEDgv7LcGwNUKYzz/XWZxOX+XpeAGNSdXxv6ASvZNJ7
+u3Ba6LbOSAjxnKK24qdBDwCfuxRvD6ovenvI3+qIDSZSrEs/ofGhEEdKlQiyUAgS
+m40kWqtoq9sC4/6cGxCLw9scuwXhwE0NNP19QRjh6Hsmr6qmu8LJAKugJi+5WyLg
+1oHLs91xAoGBAO4oy6cdc57UdL7A2UbFDWJkBlySw0ChCK4I49Sfq/IISpd3mOfH
+SxpZoh5IEnKTEYSqMi/kUUt8J/kQhjdAhqyA33GuNekfGPumUxyB8nKtowNNevyv
+Ou6Y9FmzwEektvTLoku/4GxVbrgE262YEu/U1bMA700YK88knCtRWrtFAoGBALoo
+qdUpb9s0NK0K4pGo8NYdtqVraOkXPAhKCCOY+hnl0yJERU7LLM9pYCMmR9m/TPcA
+pXZTETPWcB6SDJoH3nCmje1Bt3xTxnSvt9P8lXYfvgVpKz8zBrvvnZqUDbMUjWe+
+vz9/jRKrarKgzG6KLnLgFV9sNbuSoOER4/h7MmCzAoGARP2qaUHd4Y/4Nd4V0yt4
+Qh1pvl2BlHJR2mCW51xN6jI+sXwi3lncRsjabt1AAtLZy02mdjs01aIkzkDcMJtP
+qB85G2x1D5BDo3q+Ls7yFgh45ZcHXrXAY6gJeQbaV6a+nVF0NW9jKt7g0QwPO02H
+htRoB4/owrOS1VHsr5vEpeUCgYAsWg/MZ2js8s0yBQvh5Dws5ztiwepmzlBRMUIr
+KQE9NlJNMbLJiQKOD+8FsNMhf8BYgODrBfNtREPGJMm30PQgJq5dvnB2wIbhuhOz
+/9OkJv/gziOtlPyfvgDwmSGCbv0ZoIp0GHGF5y0ujbznASj72YN+DovmupJ1zQth
+YgionQKBgDGtSfvf3VpJxoabJ52tC0vJFDzkqdbOT0imuLjRHmUH4pSKuMvanvVk
+kYcHXeQcfLOPjH18UUqTIgK5vXXjJraduq2bGyvdLcbd3xmj5guzfim3FP83Lh/U
+OMAbRgBdq3rlylRqcZh0NqV05L0kJ0Wt1XIaV/eknpuFz5nD7O+y
+-----END RSA PRIVATE KEY-----
+-----BEGIN CERTIFICATE-----
+MIIDcTCCAlmgAwIBAgIDB5VBMA0GCSqGSIb3DQEBCwUAMHkxGzAZBgNVBAMTEkRy
+aXZlcnMgVGVzdGluZyBDQTEQMA4GA1UECxMHRHJpdmVyczEQMA4GA1UEChMHTW9u
+Z29EQjEWMBQGA1UEBxMNTmV3IFlvcmsgQ2l0eTERMA8GA1UECBMITmV3IFlvcmsx
+CzAJBgNVBAYTAlVTMB4XDTE5MDUyMjIxMDUxNVoXDTM5MDUyMjIxMDUxNVowfTEf
+MB0GA1UEAxMWY29tbW9uTmFtZS5tb25nb2RiLm9yZzEQMA4GA1UECxMHRHJpdmVy
+czEQMA4GA1UEChMHTW9uZ29EQjEWMBQGA1UEBxMNTmV3IFlvcmsgQ2l0eTERMA8G
+A1UECBMITmV3IFlvcmsxCzAJBgNVBAYTAlVTMIIBIjANBgkqhkiG9w0BAQEFAAOC
+AQ8AMIIBCgKCAQEArS94Vnpx+C+LwiCIyfZH45uwDbiEqCKr0hfWPVlJdoOQgaDO
+av9nbxRvx+CnsiZ1yE6Kj1NYIX3FqOzO9YizwKtPaxCqFMjDzl1HZCJ8LTZZzMic
+01K38wGfacsBwno/sNZn9jgnT+9JOasD6854IAs5T7dRCFH/nxV+RuZ4ueTWIcfH
+jXzAZv9+wtu0sVmQKHV0J3S6ZdPqqDaYRdhOCyShBTO4RbUW1myIjooIqqy/xceV
+TmXGWycqZjyDDronT1kj/yx6znqudOeDzj1PaEdnsqdXxQlI7MVdRf3nXdDXTpw5
+gPhqxqYc47vL6RvMxqief0BJnlc6PoZWoyTRPwIDAQABMA0GCSqGSIb3DQEBCwUA
+A4IBAQA34DUMfx0YaxsXnNlCmbkncwgb69VfwWTqtON2MabOlw9fQ0Z5YlwduBSD
+DxkRosVURdqV+EcGxei6opnPkdoJ+1mkCDo360q+R/bJUFqjj7djB7GCwwK/Eud4
+Jjn//eLBChU+DlTjO1yL8haEQR70LyVz37sh28oIRqoTS3Nk2SZg7Gnor1qHwd6j
+OljaM1WiTJfq6XCSZ9/3C5Ix0Vr7xZaP9Dn5lgQ86du6N6tmaKqVobCw3vjITmnr
+eZTC7dKU4/O52d6lHZ1vv8GyvqrRCeiolTVzhW47GvO/n+snC0NMkXvoo7Rzv1S/
+FxHvlhiH5wCbaGnBx4uF5/boedV+
+-----END CERTIFICATE-----
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/x509gen/crl.pem b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/x509gen/crl.pem
new file mode 100644
index 0000000000000000000000000000000000000000..733a0acdc0760a1bbc5ad3dcf93620aad97ffa1e
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/x509gen/crl.pem	
@@ -0,0 +1,13 @@
+-----BEGIN X509 CRL-----
+MIIB6jCB0wIBATANBgkqhkiG9w0BAQsFADB5MRswGQYDVQQDExJEcml2ZXJzIFRl
+c3RpbmcgQ0ExEDAOBgNVBAsTB0RyaXZlcnMxEDAOBgNVBAoTB01vbmdvREIxFjAU
+BgNVBAcTDU5ldyBZb3JrIENpdHkxETAPBgNVBAgTCE5ldyBZb3JrMQswCQYDVQQG
+EwJVUxcNMTkwNTIyMjI0NTUzWhcNMTkwNjIxMjI0NTUzWjAVMBMCAncVFw0xOTA1
+MjIyMjQ1MzJaoA8wDTALBgNVHRQEBAICEAAwDQYJKoZIhvcNAQELBQADggEBACwQ
+W9OF6ExJSzzYbpCRroznkfdLG7ghNSxIpBQUGtcnYbkP4em6TdtAj5K3yBjcKn4a
+hnUoa5EJGr2Xgg0QascV/1GuWEJC9rsYYB9boVi95l1CrkS0pseaunM086iItZ4a
+hRVza8qEMBc3rdsracA7hElYMKdFTRLpIGciJehXzv40yT5XFBHGy/HIT0CD50O7
+BDOHzA+rCFCvxX8UY9myDfb1r1zUW7Gzjn241VT7bcIJmhFE9oV0popzDyqr6GvP
+qB2t5VmFpbnSwkuc4ie8Jizip1P8Hg73lut3oVAHACFGPpfaNIAp4GcSH61zJmff
+9UBe3CJ1INwqyiuqGeA=
+-----END X509 CRL-----
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/x509gen/expired.pem b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/x509gen/expired.pem
new file mode 100644
index 0000000000000000000000000000000000000000..2d92be01aa4c03a878a60546104ffdcbdb402d0c
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/x509gen/expired.pem	
@@ -0,0 +1,49 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpAIBAAKCAQEAw06nN1BoINnY/WJXvi+r0taDMphWQNoyeM85A6NIYKo+vWtN
+fvf6f2JTpg/Q4NJ3txiZE/F6yZaMFC78l1KMoz+zIEPLpSJoIezCaXyl2+AQih8A
+WmAOFAoiWYTiNfWoVM7t0Qzy6yS+rXifuET5Dg1mtWpA6xRFHZEqQTdKX4QzbT5G
+RenoFIBT9wG7xUV+FG1/9s5nx4f5gZDbwMKA7mNq/Jr+rZZQV4lReeGtoYNx1I/Z
+4yd4xswI3RfuB7QDZMNHWZazFxW1N6EP5NJBDZJkYLEkMX36r4Orr/73z4EA5GBx
+zqdSKH9qHLRiBwesfZf7u8xb120u1S1X1J8a5QIDAQABAoIBAQC+Y9swWerYM2WL
+RKYCWZhndQP6e3SBzfMrv951hGQXD38Pyh2Gq5h/O0wN8xcNQz6+t3TqcxnekCrH
+tjI4FZnRvlQRHOXVeeAHSjUO/hr1Z8zXyHbgowi2Ula/64FVVr+cxQgiJTxdK7nR
+g2g4Csy6/SdlrEnSoDTsKMoHPy36Q0GaLDBnthpKIc1Prhntf6vBCgQAHXVfLk6E
+NwddYloL+mfEZESa3Qf2ZYeX/Ovq9agbuQ3cRE7M5FunSo9E7eXt+D+Ntk0usTKV
+BaUEHLRYXV827fMDGc1vBN6WFVfthhYviIEgDdkALwOw4lfIiA2WM3fhCF6Ow9hJ
+as3dpEHBAoGBAO+l4PdUXypWBYQNZKggH79kAFuAOWtLsMqEBO0ZaXXdvFdwdzhR
+jbL7mhRrghgGYpXWIUaNkcbX0XPlkWl2dRzYQqRNjUSEGFabVAxdGZPfiYoupXVl
+Lz/FIG3P6BnEYmczh9MxRpJyk4wlUCKppYPiBrR0Ei/qcbGvciOwLq5VAoGBANCi
+PWG2izO2HuBFgZTuVIvnl7ixQXgG/tvbiEmYvDNYy1E+w1MWY10Ve/JtIncBIVHk
+fEgJPL3hvipAez5ir9Qa1D4PlWxsIrbjuNcLaj+IsRhWBDjMKwRWgmTvvsimcyF5
+39Vs4FujR8cgXy8UnZhYDVRC13PyxmYfJrp4QCpRAoGAKV8nsUsdir+DAEMXp3a0
+RGRNM361avKMOMoF17DVZgW7qBTAYDakEcwh03ij4uXnSxrGb9ms2vkTLcDqE5zh
+pvMmvhqtUrDDSuBR6DiCW+bxZaub4OJw/79WU97aoOgoXMymnC0bk9i35C/k37cN
+3fC9W5XWNfNxYU16lPKrfGkCgYA14hD0UY72Fg03YvwqmLshPvkCbFU6SKQ96B70
+0wuYP1CTdSBBL0EOY2QVonYKQjJ20gn/GNOlPs48X1b1L8u1fhBezuuKiwsULRAq
+Cfqw2f7TCDQi7ygVALrAkuK1M7f8Z1uV5X60bCE3nna21B43oFYg8vpuKb9v1I/O
+DQyVYQKBgQCH/Kxq+7Or/5ciq15Vy6z+PJdsGV9FV9S7zkQOZqJ4PXJn0wG9PXnp
+ugjvmU1iLx0bXs5llByRx792Q/QmdWnwMCohs6bkWaBCf36JJfTkDTzzbez43cCK
+HcYi6gtbiBznWiLWekudRkWdhIFEGU6cSjimy1i4yvwIw85PlEQt/Q==
+-----END RSA PRIVATE KEY-----
+-----BEGIN CERTIFICATE-----
+MIIDljCCAn6gAwIBAgIDAYZJMA0GCSqGSIb3DQEBCwUAMHkxGzAZBgNVBAMTEkRy
+aXZlcnMgVGVzdGluZyBDQTEQMA4GA1UECxMHRHJpdmVyczEQMA4GA1UEChMHTW9u
+Z29EQjEWMBQGA1UEBxMNTmV3IFlvcmsgQ2l0eTERMA8GA1UECBMITmV3IFlvcmsx
+CzAJBgNVBAYTAlVTMB4XDTE5MDUyMDIyMzYzNVoXDTE5MDUyMTIyMzYzNVowcDES
+MBAGA1UEAxMJbG9jYWxob3N0MRAwDgYDVQQLEwdEcml2ZXJzMRAwDgYDVQQKEwdN
+b25nb0RCMRYwFAYDVQQHEw1OZXcgWW9yayBDaXR5MREwDwYDVQQIEwhOZXcgWW9y
+azELMAkGA1UEBhMCVVMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDD
+Tqc3UGgg2dj9Yle+L6vS1oMymFZA2jJ4zzkDo0hgqj69a01+9/p/YlOmD9Dg0ne3
+GJkT8XrJlowULvyXUoyjP7MgQ8ulImgh7MJpfKXb4BCKHwBaYA4UCiJZhOI19ahU
+zu3RDPLrJL6teJ+4RPkODWa1akDrFEUdkSpBN0pfhDNtPkZF6egUgFP3AbvFRX4U
+bX/2zmfHh/mBkNvAwoDuY2r8mv6tllBXiVF54a2hg3HUj9njJ3jGzAjdF+4HtANk
+w0dZlrMXFbU3oQ/k0kENkmRgsSQxffqvg6uv/vfPgQDkYHHOp1Iof2octGIHB6x9
+l/u7zFvXbS7VLVfUnxrlAgMBAAGjMDAuMCwGA1UdEQQlMCOCCWxvY2FsaG9zdIcE
+fwAAAYcQAAAAAAAAAAAAAAAAAAAAATANBgkqhkiG9w0BAQsFAAOCAQEAgPh9C6Yi
+6ykJYfaOETPEkggI9LlLQyQ0VhSJGrcw8DXGuPEkyd2xtczYoh0ijtYD3nlTQnh1
+u+5mEEP05nuMMURzG+v7WzZG8Qfz/SDBY1Lfvb/waI3w3RT/dcZ6jwz39jQhV+rU
+o2F1vr37Hnh1Ehoa2igjKL1w1LmWdoFgHb0p09qQDAGtkP0gxl0t7iujDDRStLQn
+OpWwfOpCaYhtzWwONJn/JIG+JCE/szcRbmc4XKw8t06ffS0mKR/yZBCoekZinnPD
+XRVWAH/UF5XPs0mUlrvhFcT/vjgXSZvpi+UuVv3XL56xwPmXAgKsYUpqLlgbrVxv
+jY93LTJ1azg+Sw==
+-----END CERTIFICATE-----
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/x509gen/password_protected.pem b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/x509gen/password_protected.pem
new file mode 100644
index 0000000000000000000000000000000000000000..cc9e124703503deccbc163d60b349eac560b7aa5
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/x509gen/password_protected.pem	
@@ -0,0 +1,51 @@
+-----BEGIN ENCRYPTED PRIVATE KEY-----
+MIIFHzBJBgkqhkiG9w0BBQ0wPDAbBgkqhkiG9w0BBQwwDgQIC8as6PDVhwECAggA
+MB0GCWCGSAFlAwQBAgQQTYOgCJcRqUI7dsgqNojv/ASCBNCG9fiu642V4AuFK34c
+Q42lvy/cR0CIXLq/rDXN1L685kdeKex7AfDuRtnjY2+7CLJiJimgQNJXDJPHab/k
+MBHbwbBs38fg6eSYX8V08/IyyTege5EJMhYxmieHDC3DXKt0gyHk6hA/r5+Mr49h
+HeVGwqBLJEQ3gVIeHaOleZYspsXXWqOPHnFiqnk/biaJS0+LkDDEiQgTLEYSnOjP
+lexxUc4BV/TN0Z920tZCMfwx7IXD/C+0AkV/Iqq4LALmT702EccB3indaIJ8biGR
+radqDLR32Q+vT9uZHgT8EFiUsISMqhob2mnyTfFV/s9ghWwogjSz0HrRcq6fxdg7
+oeyT9K0ET53AGTGmV0206byPu6qCj1eNvtn+t1Ob+d5hecaTugRMVheWPlc5frsz
+AcewDNa0pv4pZItjAGMqOPJHfzEDnzTJXpLqGYhg044H1+OCY8+1YK7U0u8dO+/3
+f5AoDMq18ipDVTFTooJURej4/Wjbrfad3ZFjp86nxfHPeWM1YjC9+IlLtK1wr0/U
+V8TjGqCkw8yHayz01A86iA8X53YQBg+tyMGjxmivo6LgFGKa9mXGvDkN+B+0+OcA
+PqldAuH/TJhnkqzja767e4n9kcr+TmV19Hn1hcJPTDrRU8+sSqQFsWN4pvHazAYB
+UdWie+EXI0eU2Av9JFgrVcpRipXjB48BaPwuBw8hm+VStCH7ynF4lJy6/3esjYwk
+Mx+NUf8+pp1DRzpzuJa2vAutzqia5r58+zloQMxkgTZtJkQU6OCRoUhHGVk7WNb1
+nxsibOSzyVSP9ZNbHIHAn43vICFGrPubRs200Kc4CdXsOSEWoP0XYebhiNJgGtQs
+KoISsV4dFRLwhaJhIlayTBQz6w6Ph87WbtuiAqoLiuqdXhUGz/79j/6JZqCH8t/H
+eZs4Dhu+HdD/wZKJDYAS+JBsiwYWnI3y/EowZYgLdOMI4u6xYDejhxwEw20LW445
+qjJ7pV/iX2uavazHgC91Bfd4zodfXIQ1IDyTmb51UFwx0ARzG6enntduO6xtcYU9
+MXwfrEpuZ/MkWTLkR0PHPbIPcR1MiVwPKdvrLk42Bzj/urtXYrAFUckMFMzEh+uv
+0lix2hbq/Xwj4dXcY4w9hnC6QQDCJTf9S6MU6OisrZHKk0qZ2Vb4aU/eBcBsHBwo
+X/QGcDHneHxlrrs2eLX26Vh8Odc5h8haeIxnfaa1t+Yv56OKHuAztPMnJOUL7KtQ
+A556LxT0b5IGx0RcfUcbG8XbxEHseACptoDOoguh9923IBI0uXmpi8q0P815LPUu
+0AsE47ATDMGPnXbopejRDicfgMGjykJn8vKO8r/Ia3Fpnomx4iJNCXGqomL+GMpZ
+IhQbKNrRG6XZMlx5kVCT0Qr1nOWMiOTSDCQ5vrG3c1Viu+0bctvidEvs+LCm98tb
+7ty8F0uOno0rYGNQz18OEE1Tj+E19Vauz1U35Z5SsgJJ/GfzhSJ79Srmdg2PsAzk
+AUNTKXux1GLf1cMjTiiU5g+tCEtUL9Me7lsv3L6aFdrCyRbhXUQfJh4NAG8+3Pvh
+EaprThBzKsVvbOfU81mOaH9YMmUgmxG86vxDiNtaWd4v6c1k+HGspJr/q49pcXZP
+ltBMuS9AihstZ1sHJsyQCmNXkA==
+-----END ENCRYPTED PRIVATE KEY-----
+-----BEGIN CERTIFICATE-----
+MIIDgzCCAmugAwIBAgIDBXUHMA0GCSqGSIb3DQEBCwUAMHkxGzAZBgNVBAMTEkRy
+aXZlcnMgVGVzdGluZyBDQTEQMA4GA1UECxMHRHJpdmVyczEQMA4GA1UEChMHTW9u
+Z29EQjEWMBQGA1UEBxMNTmV3IFlvcmsgQ2l0eTERMA8GA1UECBMITmV3IFlvcmsx
+CzAJBgNVBAYTAlVTMB4XDTE5MDUyMzAwMDEyOVoXDTM5MDUyMzAwMDEyOVowaTEP
+MA0GA1UEAxMGY2xpZW50MRAwDgYDVQQLEwdEcml2ZXJzMQwwCgYDVQQKEwNNREIx
+FjAUBgNVBAcTDU5ldyBZb3JrIENpdHkxETAPBgNVBAgTCE5ldyBZb3JrMQswCQYD
+VQQGEwJVUzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOqCb0Lo4XsV
+W327Wlnqc5rwWa5Elw0rFuehSfViRIcYfuFWAPXoOj3fIDsYz6d41G8hp6tkF88p
+swlbzDF8Fc7mXDhauwwl2F/NrWYUXwCT8fKju4DtGd2JlDMi1TRDeofkYCGVPp70
+vNqd0H8iDWWs8OmiNrdBLJwNiGaf9y15ena4ImQGitXLFn+qNSXYJ1Rs8p7Y2PTr
+L+dff5gJCVbANwGII1rjMAsrMACPVmr8c1Lxoq4fSdJiLweosrv2Lk0WWGsO0Seg
+ZY71dNHEyNjItE+VtFEtslJ5L261i3BfF/FqNnH2UmKXzShwfwxyHT8o84gSAltQ
+5/lVJ4QQKosCAwEAAaMkMCIwCwYDVR0PBAQDAgeAMBMGA1UdJQQMMAoGCCsGAQUF
+BwMCMA0GCSqGSIb3DQEBCwUAA4IBAQBOAlKxIMFcTZ+4k8NJv97RSf+zOb5Wu2ct
+uxSZxzgKTxLFUuEM8XQiEz1iHQ3XG+uV1fzA74YLQiKjjLrU0mx54eM1vaRtOXvF
+sJlzZU8Z2+523FVPx4HBPyObQrfXmIoAiHoQ4VUeepkPRpXxpifgWd/OCWhLDr2/
+0Kgcb0ybaGVDpA0UD9uVIwgFjRu6id7wG+lVcdRxJYskTOOaN2o1hMdAKkrpFQbd
+zNRfEoBPUYR3QAmAKP2HBjpgp4ktOHoOKMlfeAuuMCUocSnmPKc3xJaH/6O7rHcf
+/Rm0X411RH8JfoXYsSiPsd601kZefhuWvJH0sJLibRDvT7zs8C1v
+-----END CERTIFICATE-----
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/x509gen/server.pem b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/x509gen/server.pem
new file mode 100644
index 0000000000000000000000000000000000000000..7480f9644763eff444e0490bf78bdc342213c7b8
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/x509gen/server.pem	
@@ -0,0 +1,49 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEogIBAAKCAQEAhNrB0E6GY/kFSd8/vNpu/t952tbnOsD5drV0XPvmuy7SgKDY
+a/S+xb/jPnlZKKehdBnH7qP/gYbv34ZykzcDFZscjPLiGc2cRGP+NQCSFK0d2/7d
+y15zSD3zhj14G8+MkpAejTU+0/qFNZMc5neDvGanTe0+8aWa0DXssM0MuTxIv7j6
+CtsMWeqLLofN7a1Kw2UvmieCHfHMuA/08pJwRnV/+5T9WONBPJja2ZQRrG1BjpI4
+81zSPUZesIqi8yDlExdvgNaRZIEHi/njREqwVgJOZomUY57zmKypiMzbz48dDTsV
+gUStxrEqbaP+BEjQYPX5+QQk4GdMjkLf52LR6QIDAQABAoIBAHSs+hHLJNOf2zkp
+S3y8CUblVMsQeTpsR6otaehPgi9Zy50TpX4KD5D0GMrBH8BIl86y5Zd7h+VlcDzK
+gs0vPxI2izhuBovKuzaE6rf5rFFkSBjxGDCG3o/PeJOoYFdsS3RcBbjVzju0hFCs
+xnDQ/Wz0anJRrTnjyraY5SnQqx/xuhLXkj/lwWoWjP2bUqDprnuLOj16soNu60Um
+JziWbmWx9ty0wohkI/8DPBl9FjSniEEUi9pnZXPElFN6kwPkgdfT5rY/TkMH4lsu
+ozOUc5xgwlkT6kVjXHcs3fleuT/mOfVXLPgNms85JKLucfd6KiV7jYZkT/bXIjQ+
+7CZEn0ECgYEA5QiKZgsfJjWvZpt21V/i7dPje2xdwHtZ8F9NjX7ZUFA7mUPxUlwe
+GiXxmy6RGzNdnLOto4SF0/7ebuF3koO77oLup5a2etL+y/AnNAufbu4S5D72sbiz
+wdLzr3d5JQ12xeaEH6kQNk2SD5/ShctdS6GmTgQPiJIgH0MIdi9F3v0CgYEAlH84
+hMWcC+5b4hHUEexeNkT8kCXwHVcUjGRaYFdSHgovvWllApZDHSWZ+vRcMBdlhNPu
+09Btxo99cjOZwGYJyt20QQLGc/ZyiOF4ximQzabTeFgLkTH3Ox6Mh2Rx9yIruYoX
+nE3UfMDkYELanEJUv0zenKpZHw7tTt5yXXSlEF0CgYBSsEOvVcKYO/eoluZPYQAA
+F2jgzZ4HeUFebDoGpM52lZD+463Dq2hezmYtPaG77U6V3bUJ/TWH9VN/Or290vvN
+v83ECcC2FWlSXdD5lFyqYx/E8gqE3YdgqfW62uqM+xBvoKsA9zvYLydVpsEN9v8m
+6CSvs/2btA4O21e5u5WBTQKBgGtAb6vFpe0gHRDs24SOeYUs0lWycPhf+qFjobrP
+lqnHpa9iPeheat7UV6BfeW3qmBIVl/s4IPE2ld4z0qqZiB0Tf6ssu/TpXNPsNXS6
+dLFz+myC+ufFdNEoQUtQitd5wKbjTCZCOGRaVRgJcSdG6Tq55Fa22mOKPm+mTmed
+ZdKpAoGAFsTYBAHPxs8nzkCJCl7KLa4/zgbgywO6EcQgA7tfelB8bc8vcAMG5o+8
+YqAfwxrzhVSVbJx0fibTARXROmbh2pn010l2wj3+qUajM8NiskCPFbSjGy7HSUze
+P8Kt1uMDJdj55gATzn44au31QBioZY2zXleorxF21cr+BZCJgfA=
+-----END RSA PRIVATE KEY-----
+-----BEGIN CERTIFICATE-----
+MIIDlTCCAn2gAwIBAgICdxUwDQYJKoZIhvcNAQELBQAweTEbMBkGA1UEAxMSRHJp
+dmVycyBUZXN0aW5nIENBMRAwDgYDVQQLEwdEcml2ZXJzMRAwDgYDVQQKEwdNb25n
+b0RCMRYwFAYDVQQHEw1OZXcgWW9yayBDaXR5MREwDwYDVQQIEwhOZXcgWW9yazEL
+MAkGA1UEBhMCVVMwHhcNMTkwNTIyMjIzMjU2WhcNMzkwNTIyMjIzMjU2WjBwMRIw
+EAYDVQQDEwlsb2NhbGhvc3QxEDAOBgNVBAsTB0RyaXZlcnMxEDAOBgNVBAoTB01v
+bmdvREIxFjAUBgNVBAcTDU5ldyBZb3JrIENpdHkxETAPBgNVBAgTCE5ldyBZb3Jr
+MQswCQYDVQQGEwJVUzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAITa
+wdBOhmP5BUnfP7zabv7fedrW5zrA+Xa1dFz75rsu0oCg2Gv0vsW/4z55WSinoXQZ
+x+6j/4GG79+GcpM3AxWbHIzy4hnNnERj/jUAkhStHdv+3ctec0g984Y9eBvPjJKQ
+Ho01PtP6hTWTHOZ3g7xmp03tPvGlmtA17LDNDLk8SL+4+grbDFnqiy6Hze2tSsNl
+L5ongh3xzLgP9PKScEZ1f/uU/VjjQTyY2tmUEaxtQY6SOPNc0j1GXrCKovMg5RMX
+b4DWkWSBB4v540RKsFYCTmaJlGOe85isqYjM28+PHQ07FYFErcaxKm2j/gRI0GD1
++fkEJOBnTI5C3+di0ekCAwEAAaMwMC4wLAYDVR0RBCUwI4IJbG9jYWxob3N0hwR/
+AAABhxAAAAAAAAAAAAAAAAAAAAABMA0GCSqGSIb3DQEBCwUAA4IBAQBol8+YH7MA
+HwnIh7KcJ8h87GkCWsjOJCDJWiYBJArQ0MmgDO0qdx+QEtvLMn3XNtP05ZfK0WyX
+or4cWllAkMFYaFbyB2hYazlD1UAAG+22Rku0UP6pJMLbWe6pnqzx+RL68FYdbZhN
+fCW2xiiKsdPoo2VEY7eeZKrNr/0RFE5EKXgzmobpTBQT1Dl3Ve4aWLoTy9INlQ/g
+z40qS7oq1PjjPLgxINhf4ncJqfmRXugYTOnyFiVXLZTys5Pb9SMKdToGl3NTYWLL
+2AZdjr6bKtT+WtXyHqO0cQ8CkAW0M6VOlMluACllcJxfrtdlQS2S4lUIj76QKBdZ
+khBHXq/b8MFX
+-----END CERTIFICATE-----
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/x509gen/wild.pem b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/x509gen/wild.pem
new file mode 100644
index 0000000000000000000000000000000000000000..d418007486b4bac4f3b22d0e1a39bdffbfbd0015
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.evergreen/x509gen/wild.pem	
@@ -0,0 +1,49 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEowIBAAKCAQEAlenyliMpkLM9aR51iOO7hdLS66pwgafsJlIbtsKAy6WxlcKA
+yecs0yCQfw5z5j3BFgv88dzAFEF+jFG6o/EmAzqmK5uRCQX1EJbl2p8detbzToj9
+Ys1Z1peWE8FkJtZMKUdLdlRQQ57v2VUr0kwtFEUGlSNyVwf4pJ5coyqpukmoUdko
+zrKeclshjydDVo44Ln6WYvN6odz/CZT808fHZ0CXcIEKyDV8zXIcHGX2OUL/ajtZ
++C2pIbAx64nin1BLtHGvDT0Pan1xKDiMCkOdc7va0gLh0qtPjGLsI4vc8iByviGJ
+Kw7hVaj7ym0r2DFzeqghfvNNNHisGXSf+6EcPQIDAQABAoIBAGq/PVefDhfVKaNS
+ZwrkbkDqT/ozUQ1hzwuyZ72JXkCkaYFkEGS0Ufy8MWfnmKuXyYezXZezQqqpwDyW
+bboTGqgt+OkQSwQL0+bOLDmyF0HDEVkYvqS96HyfT+QdTv1AltbFx3woqUadQ9iT
+hzKlv2uxgvBrXx2NtYUypnAhDt5wQQ4n1w46Kl1USb983qWDWyFtHfIQo6vF1JK/
+s6I6oA2tmORPTD3A7E2xT98UMM8B1c/v1F+owAiD+KNmgAN4oWSWBfRGEKg59fZA
+aGWjQrwoWmQQJnMnTsHZc+2hT7waKnyOwOFq1NPXyfCw+4cSeI3B3rPxPyShBM4O
+ZKfajIECgYEAz555nPHhk5GmMpXprryCODy66ChHWulA3fM9r0k/ObBgKqTirAOA
+y0PmA8OxR8acV0V2lZImdwF5Lvnj+c8+fTFSnPKSQHpcZ/lbxo+m2rYwv7+BxUP9
+GJAWzA6xqBde6hNPULml8cNOqT7jwRnLt/DkwY+94Oeh3H5CRYb90Y0CgYEAuNkR
+EieGwCn+TjgatkhMLhYqr234544p3ofL82CFlCcsOXtWqCma6POOi038eBlZiHV9
+EPBq4qQHCZMAPeApTZbiZ+Z8ezC3IxjGSX0jP5QK+gBrkk7nbp24nRMlHOrwizsL
+/Sxu4Y6puZk5aTUZVufPLXokY6Iez0Kd07vyUXECgYBqWHFQi7EQ5nzr0lAVOee1
+qJ3QRrlt/qZESdCh1XH2Obq4fSbCFzVEaK4L5ZQMANaZ+TGpoWfkczPAdS1qCtam
+R7paPAHf1w04EMkKpxA/XS0ROqXdBltA1qVmtmwXfokWeveYkM9IS9Mh6927TlxE
+BrcV0mvfJKaLC30koeWnDQKBgEn1oBzxb7sHklbdn+J7Pu/Zsq6Kg+KyQRJmpzXz
+0r6ahdlh/iQ+sVqvyML4KyIqkmZFDAtxBnM0ShSMmrYnMJ941ZHY6Mmpjj0etofE
+6AuSQmoRLPlXVMYvmSRP+rN9VU2ADKX510usd0BpjE0KD99z1LNPgavTvBwVfWyw
+cJ4hAoGBALgyVPMBPv1d8irbM1WHFe/I3vxjb4DWOY9xclbRWjkW69oZmkouGP07
+52ehzfBtBC87VPLwTEr/ERZqfICBqZvXYFypd2ydGhbDKjDswiUd6nACNKAx5ZPo
+OVwQjVfjGqkKNThoHhvE1YU//+WtCe0YVUGqMA9dyZe1QO3HcqI8
+-----END RSA PRIVATE KEY-----
+-----BEGIN CERTIFICATE-----
+MIIDkzCCAnugAwIBAgIDCRU4MA0GCSqGSIb3DQEBCwUAMHkxGzAZBgNVBAMTEkRy
+aXZlcnMgVGVzdGluZyBDQTEQMA4GA1UECxMHRHJpdmVyczEQMA4GA1UEChMHTW9u
+Z29EQjEWMBQGA1UEBxMNTmV3IFlvcmsgQ2l0eTERMA8GA1UECBMITmV3IFlvcmsx
+CzAJBgNVBAYTAlVTMB4XDTE5MDUyMjIyMzgxOVoXDTM5MDUyMjIyMzgxOVowcDES
+MBAGA1UEAxMJbG9jYWxob3N0MRAwDgYDVQQLEwdEcml2ZXJzMRAwDgYDVQQKEwdN
+b25nb0RCMRYwFAYDVQQHEw1OZXcgWW9yayBDaXR5MREwDwYDVQQIEwhOZXcgWW9y
+azELMAkGA1UEBhMCVVMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCV
+6fKWIymQsz1pHnWI47uF0tLrqnCBp+wmUhu2woDLpbGVwoDJ5yzTIJB/DnPmPcEW
+C/zx3MAUQX6MUbqj8SYDOqYrm5EJBfUQluXanx161vNOiP1izVnWl5YTwWQm1kwp
+R0t2VFBDnu/ZVSvSTC0URQaVI3JXB/iknlyjKqm6SahR2SjOsp5yWyGPJ0NWjjgu
+fpZi83qh3P8JlPzTx8dnQJdwgQrINXzNchwcZfY5Qv9qO1n4LakhsDHrieKfUEu0
+ca8NPQ9qfXEoOIwKQ51zu9rSAuHSq0+MYuwji9zyIHK+IYkrDuFVqPvKbSvYMXN6
+qCF+8000eKwZdJ/7oRw9AgMBAAGjLTArMCkGA1UdEQQiMCCCCWxvY2FsaG9zdIcE
+fwAAAYINKi5tb25nb2RiLm9yZzANBgkqhkiG9w0BAQsFAAOCAQEAMCENVK+w+wP7
+T1XBytsScn7+Bh33sn+A+c7H/6BNOEdTxCQ67L3zBc0XrBFYtiHcAppNBKvvM8cV
+ERWjXlU2nZ+A0WKOZE2nXYQL5lBnnXoIMwcdtJuTJuWw8r3MlVXDcP6bK8tNSQMG
+WYK7PHQ3RNiWNABZejJV9GVP25nO6Wr2gt2xnEwYvUXTnCJtT+NsTE/fU4MlGuUL
+a93Cec86Ij0XTMTcnj4nfZhct30nuqiU4wWBPHCN7BXxRQzIHu68aVHBpwDEAf6j
+PAOKhucGY6DW+dyrW/1BjW6+ZOmJWxJ7GB+x0gjprQbGH67gIvRvTa9wW7NqWyS3
+Go/qT7H6FQ==
+-----END CERTIFICATE-----
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.github/ISSUE_TEMPLATE/bug-report.md b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.github/ISSUE_TEMPLATE/bug-report.md
new file mode 100644
index 0000000000000000000000000000000000000000..fa2163dbb7842ee6153d1e4e30dbe807e1740425
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.github/ISSUE_TEMPLATE/bug-report.md	
@@ -0,0 +1,94 @@
+---
+name: Bug Report
+about: Create a report to help us improve
+title: ''
+labels: ''
+assignees: ''
+
+---
+
+<!--
+You are about to open an issue for the MongoDB PHP library. If you instead
+intended to report an issue with the MongoDB PHP extension, please do so via its
+repository[^1].
+
+If you've identified a security vulnerability in a driver or any other MongoDB
+project, please create a vulnerability report[^2].
+
+[^1]: https://github.com/mongodb/mongo-php-driver
+[^2]: https://docs.mongodb.org/manual/tutorial/create-a-vulnerability-report
+-->
+
+### Bug Report
+
+<!--
+Briefly describe the issue. Feel free to cross-reference your report with any
+other related GitHub or JIRA issues for additional context. Before reporting an
+issue, check that you are using the most recent version of the driver.
+-->
+
+### Environment
+
+<!--
+What operating system and PHP version are you using? Mention if PHP was
+installed through a third-party bundle (e.g. MAMP, XAMPP) and report its version
+if applicable.
+
+What version of MongoDB are you using? Include details about the topology (e.g.
+replica set, sharded cluster) and how you are connecting to the database (e.g.
+TLS connections, authentication). If possible, share your connection string and
+additional URI options (be sure to redact any auth credentials). Please specify
+whether you are self-hosting the database or using a cloud provider, such as
+MongoDB Atlas.
+
+Include version information for the extension, libmongoc, and libbson. This may
+be collected by grepping phpinfo() output:
+
+    php -i | grep -E 'mongodb|libmongoc|libbson'
+
+In some cases, it may be helpful to provide all phpinfo() output (e.g. `php -i`)
+and/or list all installed extensions (e.g. `php -m`).
+
+Include version information for the library. This may be
+collected by running the following from your project's root directory:
+
+    composer show mongodb/mongodb
+-->
+
+### Test Script
+
+<!--
+If possible, attach a complete PHP script that can be executed on its own to
+reproduce the issue. Clarify whether this script can be run from the CLI or if
+it can must be run through a web SAPI.
+
+If the error only presents itself in a web SAPI, note whether the issue can be
+reproduced with PHP's built-in web server[^3]. If not, please share your web
+server version and any relevant configuration details in the Environment section
+above.
+
+[^3]: http://php.net/manual/en/features.commandline.webserver.php
+-->
+
+### Expected and Actual Behavior
+
+<!--
+How did the script fail to perform the expected task? Feel free to include debug
+and/or `var_dump()` output if that helps explain the error.
+
+If the observed behavior is an unexpected exception, please include its full
+message and any relevant backtrace information. If you encountered a
+segmentation fault, please include a GDB backtrace[^4].
+
+[^4]: https://bugs.php.net/bugs-generating-backtrace.php
+-->
+
+### Debug Log
+
+<!--
+If the issue relates to internal driver behavior (e.g. connection issues),
+please include a debug log[^5]. This may be generated by setting the
+`mongodb.debug` INI option to "stderr" or a directory (useful for web SAPIs).
+
+[^5]: https://www.php.net/manual/en/mongodb.configuration.php#ini.mongodb.debug
+-->
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.gitignore b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..ee520b98e87d9d50f391827ffd5a9705ee52d720
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.gitignore	
@@ -0,0 +1,15 @@
+# Composer
+composer.phar
+composer.lock
+vendor/
+
+# PHPUnit
+phpunit.phar
+phpunit.xml
+.phpunit.result.cache
+
+# phpcs
+.phpcs-cache
+phpcs.xml
+
+mongocryptd.pid
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.phpcs/autoload.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.phpcs/autoload.php
new file mode 100644
index 0000000000000000000000000000000000000000..45e90ad160ac4922fee7bb44453cb84c9094c622
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.phpcs/autoload.php	
@@ -0,0 +1,15 @@
+<?php
+
+// Since doctrine/coding-standard requires PHP 7, we can't add it as a dependency
+// yet. This autoload file adds more information to the phpcs error message,
+// telling the user how they can fix the error presented to them by phpcs.
+if (! file_exists(__DIR__ . '/../vendor/doctrine/coding-standard')) {
+    echo <<<ERRORMESSAGE
+==============================================================================
+ERROR: Doctrine coding standard is not installed. To rectify this, please run:
+composer require --dev doctrine/coding-standard=^6.0
+==============================================================================
+
+
+ERRORMESSAGE;
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.travis.yml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.travis.yml
new file mode 100644
index 0000000000000000000000000000000000000000..37b95219a93c4abeaf83e6a1c9db25ce412f5375
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.travis.yml	
@@ -0,0 +1,93 @@
+language: php
+dist: xenial
+php: "7.4"
+
+addons:
+  apt:
+    packages:
+      - gdb
+      - libcurl3
+      - libgssapi-krb5-2
+      - libkrb5-dbg
+      - libldap-2.4-2
+      - libpcap0.8
+      - libsasl2-2
+      - snmp
+      - openssl
+
+cache:
+  directories:
+    - ${HOME}/.cache/pip
+    - ${HOME}/.composer/cache/files
+    - ${HOME}/php-ext
+
+env:
+  global:
+    - DRIVER_VERSION=stable
+    - SERVER_DISTRO=enterprise-ubuntu1604
+    - SERVER_VERSION=4.4.0
+    - DEPLOYMENT=STANDALONE
+    - COMPOSER_OPTIONS=
+
+jobs:
+  include:
+
+    - stage: Smoke Testing
+      env:
+        - CHECKS=phpunit
+    - stage: Smoke Testing
+      php: "7.1"
+      before_install: []
+      before_script:
+        - .travis/install-extension.sh
+        - composer require --no-update doctrine/coding-standard=^6.0
+        - composer install --no-interaction --no-progress --no-suggest ${COMPOSER_OPTIONS}
+      script: vendor/bin/phpcs
+      after_script: []
+      after_failure: []
+      env:
+        - CHECKS=phpcs
+
+    # Test against PHP 8
+    - stage: Test
+      php: "8.0snapshot"
+    - stage: Test
+      php: "8.0snapshot"
+      env:
+        - DEPLOYMENT=REPLICASET
+    - stage: Test
+      php: "8.0snapshot"
+      env:
+        - DEPLOYMENT=SHARDED_CLUSTER_RS
+
+before_install:
+  - pip install "mongo-orchestration>=0.6.7,<1.0" --user `whoami`
+  - export SERVER_FILENAME=mongodb-linux-x86_64-${SERVER_DISTRO}-${SERVER_VERSION}
+  - wget -qO- https://downloads.mongodb.com/linux/${SERVER_FILENAME}.tgz | tar xz
+  - export PATH=${PWD}/${SERVER_FILENAME}/bin:${PATH}
+  - mongod --version
+  - mongo-orchestration --version
+  - export MO_PATH=`python -c 'import mongo_orchestration; from os import path; print(path.dirname(mongo_orchestration.__file__));'`
+
+before_script:
+  - mongo-orchestration start
+  - .travis/setup_mo.sh
+  - .travis/install-extension.sh
+  - php --ri mongodb
+  - composer update --no-interaction --no-progress --no-suggest --prefer-dist --prefer-stable ${COMPOSER_OPTIONS}
+  - ulimit -c
+  - ulimit -c unlimited -S
+
+script:
+  - export MONGODB_URI=`cat /tmp/uri.txt`
+  - echo $MONGODB_URI
+  - vendor/bin/simple-phpunit -v
+
+before_cache:
+  - rm -f ${HOME}/.cache/pip/log/debug.log
+
+after_failure:
+  - find . -name 'core*' -exec ${TRAVIS_BUILD_DIR}/.travis/debug-core.sh {} \;
+
+after_script:
+  - mongo-orchestration stop
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.travis/debug-core.sh b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.travis/debug-core.sh
new file mode 100644
index 0000000000000000000000000000000000000000..6a2a01eec5e12a8989b05a87cd2892c0be0a7c7a
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.travis/debug-core.sh	
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+if [ "${TRAVIS_OS_NAME}" = "osx" ]; then
+    # https://www.ics.uci.edu/~pattis/common/handouts/macmingweclipse/allexperimental/mac-gdb-install.html
+    echo "Cannot debug core files on macOS: ${1}"
+    exit 1
+fi
+
+PHP_BINARY=`which php`
+gdb -batch -ex "bt full" -ex "quit" "${PHP_BINARY}" "${1}"
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.travis/get_uri.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.travis/get_uri.php
new file mode 100644
index 0000000000000000000000000000000000000000..9c1c428959589c8e4873ff7fa5165ec4293453ce
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.travis/get_uri.php	
@@ -0,0 +1,6 @@
+<?php
+
+$uriField = isset($argv[1]) ? $argv[1] : 'mongodb_uri';
+$uriSuffix = isset($argv[2]) ? $argv[2] : '';
+
+echo json_decode(file_get_contents("php://stdin"))->$uriField, $uriSuffix;
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.travis/install-extension.sh b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.travis/install-extension.sh
new file mode 100644
index 0000000000000000000000000000000000000000..9f99f71b5085d5c4714788c1e8df5ed3befcf17b
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.travis/install-extension.sh	
@@ -0,0 +1,40 @@
+#!/bin/sh
+
+INI=~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini
+# tpecl is a helper to compile and cache php extensions
+tpecl () {
+    local ext_name=$1
+    local ext_so=$2
+    local ext_dir=$(php -r "echo ini_get('extension_dir');")
+    local ext_cache=~/php-ext/$(basename $ext_dir)/$ext_name
+    if [[ -e $ext_cache/$ext_so ]]; then
+        echo extension = $ext_cache/$ext_so >> $INI
+    else
+        mkdir -p $ext_cache
+        echo yes | pecl install -f $ext_name &&
+        cp $ext_dir/$ext_so $ext_cache
+    fi
+}
+
+if [ "x${DRIVER_BRANCH}" != "x" ] || [ "x${DRIVER_REPO}" != "x" ]; then
+  CLONE_REPO=${DRIVER_REPO:-https://github.com/mongodb/mongo-php-driver}
+  CHECKOUT_BRANCH=${DRIVER_BRANCH:-master}
+
+  echo "Compiling driver branch ${CHECKOUT_BRANCH} from repository ${CLONE_REPO}"
+
+  mkdir -p /tmp/compile
+  git clone ${CLONE_REPO} /tmp/compile/mongo-php-driver
+  cd /tmp/compile/mongo-php-driver
+
+  git checkout ${CHECKOUT_BRANCH}
+  git submodule update --init
+  phpize
+  ./configure --enable-mongodb-developer-flags
+  make all -j20 > /dev/null
+  make install
+
+  echo "extension=mongodb.so" >> `php --ini | grep "Scan for additional .ini files in" | sed -e "s|.*:\s*||"`/mongodb.ini
+elif [ "x${DRIVER_VERSION}" != "x" ]; then
+  echo "Installing driver version ${DRIVER_VERSION} from PECL"
+  tpecl mongodb-${DRIVER_VERSION} mongodb.so
+fi
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.travis/mo.sh b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.travis/mo.sh
new file mode 100644
index 0000000000000000000000000000000000000000..13941ddb8f6680b1c82d34ff83f6c2c7fcf79991
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.travis/mo.sh	
@@ -0,0 +1,117 @@
+#!/bin/bash
+# Copyright 2012-2014 MongoDB, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+function eval_params {
+    local params=$(sed -e 's|["]|\\\"|g' $1)
+    echo $(eval echo \"$params\")
+} 
+
+function r {
+    echo $1| awk -F'/' '{print $(NF-1)}'| sed 's/standalone/servers/'
+}
+
+function a {
+    echo $(cd $(dirname $1); pwd)/$(basename $1)
+}
+
+function id {
+    local id_line=$(grep id $1 | head -n 1)
+    echo $(expr "$id_line" : '.*: *"\(.*\)" *,*')
+}
+
+function get {
+    echo "GET $1 $(curl --header 'Accept: application/json' --include --silent --request GET $1)"
+}
+
+function post {
+    echo "POST $1 $(curl --header 'Accept: application/json' --include --silent --request POST --data "$2" $1)"
+}
+
+function delete {
+    echo "DELETE $1 $(curl --header 'Accept: application/json' --include --silent --request DELETE $1)"
+}
+
+function code {
+   expr "$1" : '.*HTTP/1.[01] \([0-9]*\)'
+}
+
+function usage {
+    echo "usage: $0 configurations/cluster/file.json action"
+    echo "cluster: servers|replica_sets|sharded_clusters"
+    echo "action: start|status|stop"
+    exit 1
+}
+
+SSL_FILES=$(a ./ssl-files)
+BASE_URL=${MONGO_ORCHESTRATION:-'http://localhost:8889'}
+
+if [ $# -ne 2 ]; then usage; fi
+if [ ! -f "$1" ]; then echo "configuration file '$1' not found"; exit 1; fi
+
+ID=$(id $1)
+if [ ! "$ID" ]; then echo "id field not found in configuration file '$1'"; exit 1; fi
+R=$(r $1)
+
+GET=$(get $BASE_URL/$R/$ID)
+HTTP_CODE=$(code "$GET")
+EXIT_CODE=0
+
+case $2 in
+start)
+    if [ "$HTTP_CODE" != "200" ]
+    then
+        WORKSPACE=${TRAVIS_BUILD_DIR}/orchestrations
+        rm -fr $WORKSPACE
+        mkdir $WORKSPACE
+        LOGPATH=$WORKSPACE
+        DBPATH=$WORKSPACE
+        POST_DATA=$(eval_params $1)
+        echo "DBPATH=$DBPATH"
+        echo "LOGPATH=$LOGPATH"
+        echo "POST_DATA='$POST_DATA'"
+        echo
+        POST=$(post $BASE_URL/$R "$POST_DATA")
+        echo "$POST"
+        HTTP_CODE=$(code "$POST")
+        if [ "$HTTP_CODE" != 200 ]; then EXIT_CODE=1; fi
+    else
+        echo "$GET"
+    fi
+    ;;
+stop)
+    if [ "$HTTP_CODE" == "200" ]
+    then
+        DELETE=$(delete $BASE_URL/$R/$ID)
+        echo "$DELETE"
+        HTTP_CODE=$(code "$DELETE")
+        if [ "$HTTP_CODE" != 204 ]; then EXIT_CODE=1; fi
+    else
+        echo "$GET"
+    fi
+    ;;
+status)
+    if [ "$HTTP_CODE" == "200" ]
+    then
+        echo "$GET"
+    else
+        echo "$GET"
+        EXIT_CODE=1
+    fi
+    ;;
+*)
+    usage
+    ;;
+esac
+exit $EXIT_CODE
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.travis/setup_mo.sh b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.travis/setup_mo.sh
new file mode 100644
index 0000000000000000000000000000000000000000..cf8c3cea80b7c5ba22c85329f554c890b9b2fc9f
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/.travis/setup_mo.sh	
@@ -0,0 +1,65 @@
+#!/bin/bash
+
+echo Loading MO for $DEPLOYMENT
+
+if [[ -z $TRAVIS_BUILD_DIR ]]; then
+    export TRAVIS_BUILD_DIR=`pwd`;
+fi
+
+# Replace the default client certificate with the new one to make sure mo keeps working
+cp ${TRAVIS_BUILD_DIR}/mongo-orchestration/ssl/client.pem ${MO_PATH}/lib/client.pem
+
+URI_FIELD="mongodb_uri"
+URI_SUFFIX=""
+
+case $DEPLOYMENT in
+  SHARDED_CLUSTER)
+    CONFIG="sharded_clusters/cluster.json"
+    URI_SUFFIX="/?retryWrites=false"
+    ;;
+  SHARDED_CLUSTER_RS)
+    CONFIG="sharded_clusters/cluster_replset.json"
+    ;;
+  STANDALONE_AUTH)
+    CONFIG="standalone/standalone-auth.json"
+    URI_FIELD="mongodb_auth_uri"
+    ;;
+  STANDALONE_OLD)
+    CONFIG="standalone/standalone-old.json"
+    ;;
+  STANDALONE_SSL)
+    CONFIG="standalone/standalone-ssl.json"
+    URI_SUFFIX="/?ssl=true&sslallowinvalidcertificates=true"
+    ;;
+  REPLICASET)
+    CONFIG="replica_sets/replicaset.json"
+    ;;
+  REPLICASET_SINGLE)
+    CONFIG="replica_sets/replicaset-one-node.json"
+    ;;
+  REPLICASET_OLD)
+    CONFIG="replica_sets/replicaset-old.json"
+    ;;
+  *)
+    CONFIG="standalone/standalone.json"
+    ;;
+esac
+
+${TRAVIS_BUILD_DIR}/.travis/mo.sh ${TRAVIS_BUILD_DIR}/mongo-orchestration/$CONFIG start > /tmp/mo-result.json
+
+if [ $? -ne 0 ]; then
+  cat /tmp/mo-result.json
+  cat ${TRAVIS_BUILD_DIR}/server.log
+  exit 1
+fi
+
+cat /tmp/mo-result.json | tail -n 1 | php ${TRAVIS_BUILD_DIR}/.travis/get_uri.php $URI_FIELD $URI_SUFFIX > /tmp/uri.txt
+
+echo -n "MongoDB Test URI: "
+cat /tmp/uri.txt
+echo
+
+echo "Raw MO Response:"
+cat /tmp/mo-result.json
+
+echo
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/CONTRIBUTING.md b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/CONTRIBUTING.md
new file mode 100644
index 0000000000000000000000000000000000000000..7f1105f1b35b6228dc955fe0b22fd50aad59b469
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/CONTRIBUTING.md	
@@ -0,0 +1,210 @@
+# Contributing to the PHP Library for MongoDB
+
+## Initializing the Repository
+
+Developers who would like to contribute to the library will need to clone it and
+initialize the project dependencies with [Composer](https://getcomposer.org/):
+
+```
+$ git clone https://github.com/mongodb/mongo-php-library.git
+$ cd mongo-php-library
+$ composer update
+```
+
+In addition to installing project dependencies, Composer will check that the
+required extension version is installed. Directions for installing the extension
+may be found [here](http://php.net/manual/en/mongodb.installation.php).
+
+Installation directions for Composer may be found in its
+[Getting Started](https://getcomposer.org/doc/00-intro.md) guide.
+
+## Testing
+
+The library's test suite uses [PHPUnit](https://phpunit.de/), which is installed
+through the [PHPUnit Bridge](https://symfony.com/phpunit-bridge) dependency by
+Composer.
+
+The test suite may be executed with:
+
+```
+$ vendor/bin/simple-phpunit
+```
+
+The `phpunit.xml.dist` file is used as the default configuration file for the
+test suite. In addition to various PHPUnit options, it defines required
+`MONGODB_URI` and `MONGODB_DATABASE` environment variables. You may customize
+this configuration by creating your own `phpunit.xml` file based on the
+`phpunit.xml.dist` file we provide.
+
+By default, the `simple-phpunit` binary chooses the correct PHPUnit version for
+the PHP version you are running. To run tests against a specific PHPUnit version,
+use the `SYMFONY_PHPUNIT_VERSION` environment variable:
+
+```
+$ SYMFONY_PHPUNIT_VERSION=7.5 vendor/bin/simple-phpunit
+```
+
+## Checking coding standards
+
+The library's code is checked using [PHP_CodeSniffer](https://github.com/squizlabs/PHP_CodeSniffer),
+which is installed as a development dependency by Composer. Due to the PHP
+requirement, the base version of the coding standard is not installed and needs
+to be added manually if you plan to contributing code:
+
+```
+$ composer require --dev doctrine/coding-standard=^6.0
+```
+
+Once the coding standard has been installed, you can check the code for style
+errors:
+
+
+```
+$ vendor/bin/phpcs
+```
+
+To automatically fix all fixable errors, use the `phpcbf` binary:
+
+```
+$ vendor/bin/phpcbf
+```
+
+## Documentation
+
+Documentation for the library lives in the `docs/` directory and is built with
+tools in the related
+[mongodb/docs-php-library](https://github.com/mongodb/docs-php-library)
+repository. The tools repository is already configured to reference our sources.
+
+That said, any changes to the documentation should be tested locally before
+committing. Follow the following steps to build the docs locally with the tools
+repository:
+
+ * Clone the
+   [mongodb/docs-php-library](https://github.com/mongodb/docs-php-library) tools
+   repository.
+ * Install [giza](https://pypi.python.org/pypi/giza/), as noted in the tools
+   README.
+ * Sync your working copy of the documentation to the `source/` directory with
+   `rsync -a --delete /path/to/mongo-php-library/docs/ source/`.
+ * Build the documentation with `giza make publish`. You can suppress
+   informational log messages with the `--level warning` option.
+ * Generated documentation may be found in the `build/master/html` directory.
+
+## Releasing
+
+The follow steps outline the release process for a maintenance branch (e.g.
+releasing the `vX.Y` branch as X.Y.Z).
+
+### Ensure PHP version compatibility
+
+Ensure that the library test suite completes on supported versions of PHP.
+
+### Transition JIRA issues and version
+
+All issues associated with the release version should be in the "Closed" state
+and have a resolution of "Fixed". Issues with other resolutions (e.g.
+"Duplicate", "Works as Designed") should be removed from the release version so
+that they do not appear in the release notes.
+
+Check the corresponding ".x" fix version to see if it contains any issues that
+are resolved as "Fixed" and should be included in this release version.
+
+Update the version's release date and status from the
+[Manage Versions](https://jira.mongodb.org/plugins/servlet/project-config/PHPLIB/versions)
+page.
+
+### Update version info
+
+The PHP library uses [semantic versioning](http://semver.org/). Do not break
+backwards compatibility in a non-major release or your users will kill you.
+
+Before proceeding, ensure that the `master` branch is up-to-date with all code
+changes in this maintenance branch. This is important because we will later
+merge the ensuing release commits up to master with `--strategy=ours`, which
+will ignore changes from the merged commits.
+
+### Tag release
+
+The maintenance branch's HEAD will be the target for our release tag:
+
+```
+$ git tag -a -m "Release X.Y.Z" X.Y.Z
+```
+
+### Push tags
+
+```
+$ git push --tags
+```
+
+### Merge the maintenance branch up to master
+
+```
+$ git checkout master
+$ git merge vX.Y --strategy=ours
+$ git push
+```
+
+The `--strategy=ours` option ensures that all changes from the merged commits
+will be ignored.
+
+### Publish release notes
+
+The following template should be used for creating GitHub release notes via
+[this form](https://github.com/mongodb/mongo-php-library/releases/new).
+
+```
+The PHP team is happy to announce that version X.Y.Z of the MongoDB PHP library is now available. This library is a high-level abstraction for the [`mongodb`](http://php.net/mongodb) extension.
+
+**Release Highlights**
+
+<one or more paragraphs describing important changes in this release>
+
+A complete list of resolved issues in this release may be found at:
+$JIRA_URL
+
+**Documentation**
+
+Documentation for this library may be found at:
+https://docs.mongodb.com/php-library/
+
+**Feedback**
+
+If you encounter any bugs or issues with this library, please report them via this form:
+https://jira.mongodb.org/secure/CreateIssue.jspa?pid=12483&issuetype=1
+
+**Installation**
+
+This library may be installed or upgraded with:
+
+    composer require mongodb/mongodb
+
+Installation instructions for the `mongodb` extension may be found in the [PHP.net documentation](http://php.net/manual/en/mongodb.installation.php).
+```
+
+The URL for the list of resolved JIRA issues will need to be updated with each
+release. You may obtain the list from
+[this form](https://jira.mongodb.org/secure/ReleaseNote.jspa?projectId=12483).
+
+If commits from community contributors were included in this release, append the
+following section:
+
+```
+**Thanks**
+
+Thanks for our community contributors for this release:
+
+ * [$CONTRIBUTOR_NAME](https://github.com/$GITHUB_USERNAME)
+```
+
+Release announcements should also be sent to the [MongoDB Product & Driver Announcements](https://community.mongodb.com/tags/c/community/release-notes/35/php-driver).
+
+Consider announcing each release on Twitter. Significant releases should also be
+announced via [@MongoDB](http://twitter.com/mongodb) as well.
+
+### Update compatibility tables in MongoDB docs
+
+The [compatibility tables](https://docs.mongodb.com/drivers/driver-compatibility-reference#php-driver-compatibility) in
+the MongoDB documentation must be updated to account for new releases. Make sure to update both MongoDB and Language
+compatibility tables, as shown in [this pull request](https://github.com/mongodb/docs-ecosystem/pull/642).
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/LICENSE b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/LICENSE
new file mode 100644
index 0000000000000000000000000000000000000000..d645695673349e3947e8e5ae42332d0ac3164cd7
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/LICENSE	
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/Makefile b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..a1d31b68f06c50819cde24b2803aa9b6ad6f0556
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/Makefile	
@@ -0,0 +1,17 @@
+.PHONY: composer test
+
+COMPOSER_ARGS=update --no-interaction --prefer-source
+
+composer:
+	@command -v composer >/dev/null 2>&1; \
+	if test $$? -eq 0; then \
+		composer $(COMPOSER_ARGS); \
+	elif test -r composer.phar; then \
+		php composer.phar $(COMPOSER_ARGS); \
+	else \
+		echo >&2 "Cannot find composer; aborting."; \
+		false; \
+	fi
+
+test: composer
+	vendor/bin/phpunit
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/README.md b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..cc8bdd9af6fda5775bca7b157f85f2cc55e6d3b6
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/README.md	
@@ -0,0 +1,68 @@
+# MongoDB PHP Library
+
+[![Build Status](https://api.travis-ci.org/mongodb/mongo-php-library.png?branch=master)](https://travis-ci.org/mongodb/mongo-php-library)
+
+This library provides a high-level abstraction around the lower-level
+[PHP driver](https://github.com/mongodb/mongo-php-driver) (`mongodb` extension).
+
+While the extension provides a limited API for executing commands, queries, and
+write operations, this library implements an API similar to that of the
+[legacy PHP driver](https://php.net/manual/en/book.mongo.php). It contains
+abstractions for client, database, and collection objects, and provides methods
+for CRUD operations and common commands (e.g. index and collection management).
+
+If you are developing an application with MongoDB, you should consider using
+this library, or another high-level abstraction, instead of the extension alone.
+
+Additional information about the architecture of this library and the `mongodb`
+extension may be found in
+[Architecture Overview](https://php.net/manual/en/mongodb.overview.php).
+
+## Documentation
+
+ - https://docs.mongodb.com/php-library/
+ - https://docs.mongodb.com/ecosystem/drivers/php/
+
+## Installation
+
+The preferred method of installing this library is with
+[Composer](https://getcomposer.org/) by running the following from your project
+root:
+
+    $ composer require mongodb/mongodb
+
+Additional installation instructions may be found in the
+[library documentation](https://docs.mongodb.com/php-library/current/tutorial/install-php-library/).
+
+Since this library is a high-level abstraction for the driver, it also requires
+that the `mongodb` extension be installed:
+
+    $ pecl install mongodb
+    $ echo "extension=mongodb.so" >> `php --ini | grep "Loaded Configuration" | sed -e "s|.*:\s*||"`
+
+Additional installation instructions for the extension may be found in its
+[PHP.net documentation](https://php.net/manual/en/mongodb.installation.php).
+
+## Reporting Issues
+
+Issues pertaining to the library should be reported in the
+[PHPLIB](https://jira.mongodb.org/secure/CreateIssue!default.jspa?project-field=PHPLIB)
+project in MongoDB's JIRA. Extension-related issues should be reported in the
+[PHPC](https://jira.mongodb.org/secure/CreateIssue!default.jspa?project-field=PHPC)
+project.
+
+For general questions and support requests, please use one of MongoDB's
+[Technical Support](https://docs.mongodb.com/manual/support/) channels.
+
+### Security Vulnerabilities
+
+If you've identified a security vulnerability in a driver or any other MongoDB
+project, please report it according to the instructions in
+[Create a Vulnerability Report](https://docs.mongodb.org/manual/tutorial/create-a-vulnerability-report).
+
+## Development
+
+Development is tracked in the
+[PHPLIB](https://jira.mongodb.org/projects/PHPLIB/summary) project in MongoDB's
+JIRA. Documentation for contributing to this project may be found in
+[CONTRIBUTING.md](CONTRIBUTING.md).
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/composer.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/composer.json
new file mode 100644
index 0000000000000000000000000000000000000000..c6e2822280afe1276a8fa6cf72df2865515452a2
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/composer.json	
@@ -0,0 +1,36 @@
+{
+    "name": "mongodb/mongodb",
+    "description": "MongoDB driver library",
+    "keywords": ["database", "driver", "mongodb", "persistence"],
+    "homepage": "https://jira.mongodb.org/browse/PHPLIB",
+    "license": "Apache-2.0",
+    "authors": [
+        { "name": "Andreas Braun", "email": "andreas.braun@mongodb.com" },
+        { "name": "Jeremy Mikola", "email": "jmikola@gmail.com" }
+    ],
+    "require": {
+        "php": "^7.0 || ^8.0",
+        "ext-hash": "*",
+        "ext-json": "*",
+        "ext-mongodb": "^1.8.1",
+        "jean85/pretty-package-versions": "^1.2",
+        "symfony/polyfill-php80": "^1.19"
+    },
+    "require-dev": {
+        "squizlabs/php_codesniffer": "^3.5, <3.5.5",
+        "symfony/phpunit-bridge": "5.x-dev"
+    },
+    "autoload": {
+        "psr-4": { "MongoDB\\": "src/" },
+        "files": [ "src/functions.php" ]
+    },
+    "autoload-dev": {
+        "psr-4": { "MongoDB\\Tests\\": "tests/" },
+        "files": [ "tests/PHPUnit/Functions.php" ]
+    },
+    "extra": {
+        "branch-alias": {
+            "dev-master": "1.8.x-dev"
+        }
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/.static/.mongodb b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/.static/.mongodb
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBClient-common-option.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBClient-common-option.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..89092358fb74146b2d758ea9b301c8c5dc76d189
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBClient-common-option.yaml	
@@ -0,0 +1,37 @@
+arg_name: option
+name: readConcern
+type: :php:`MongoDB\\Driver\\ReadConcern <class.mongodb-driver-readconcern>`
+description: |
+   :manual:`Read concern </reference/read-concern>` to use for the operation.
+   Defaults to the client's read concern.
+
+   This is not supported for server versions prior to 3.2 and will result in an
+   exception at execution time if used.
+interface: phpmethod
+operation: ~
+optional: true
+---
+arg_name: option
+name: readPreference
+type: :php:`MongoDB\\Driver\\ReadPreference <class.mongodb-driver-readpreference>`
+description: |
+   :manual:`Read preference </reference/read-preference>` to use for the
+   operation. Defaults to the client's read preference.
+interface: phpmethod
+operation: ~
+optional: true
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: typeMap
+---
+arg_name: option
+name: writeConcern
+type: :php:`MongoDB\\Driver\\WriteConcern <class.mongodb-driver-writeconcern>`
+description: |
+   :manual:`Write concern </reference/write-concern>` to use for the operation.
+   Defaults to the client's write concern.
+interface: phpmethod
+operation: ~
+optional: true
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBClient-method-construct-driverOptions.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBClient-method-construct-driverOptions.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..77520c0d2f0e6b778338212b7dadccd73b6c9421
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBClient-method-construct-driverOptions.yaml	
@@ -0,0 +1,176 @@
+arg_name: option
+name: typeMap
+type: array
+description: |
+  Default :php:`type map
+  <manual/en/mongodb.persistence.deserialization.php#mongodb.persistence.typemaps>`
+  to apply to cursors, which determines how BSON documents are converted to PHP
+  values. The |php-library| uses the following type map by default:
+
+  .. code-block:: php
+
+     [
+         'array' => 'MongoDB\Model\BSONArray',
+         'document' => 'MongoDB\Model\BSONDocument',
+         'root' => 'MongoDB\Model\BSONDocument',
+     ]
+interface: phpmethod
+operation: ~
+optional: true
+---
+arg_name: option
+name: allow_invalid_hostname
+type: boolean
+description: |
+  Disables hostname validation if ``true``. Defaults to ``false``.
+
+  Allowing invalid hostnames may expose the driver to a `man-in-the-middle
+  attack <https://en.wikipedia.org/wiki/Man-in-the-middle_attack>`_.
+
+  .. deprecated:: 1.6
+     This option has been deprecated. Use the ``tlsAllowInvalidHostnames`` URI
+     option instead.
+interface: phpmethod
+operation: ~
+optional: true
+---
+arg_name: option
+name: ca_dir
+type: string
+description: |
+  Path to a correctly hashed certificate directory. The system certificate store
+  will be used by default.
+
+  Falls back to the deprecated ``capath`` SSL context option if not specified.
+interface: phpmethod
+operation: ~
+optional: true
+---
+arg_name: option
+name: ca_file
+type: string
+description: |
+  Path to a certificate authority file. The system certificate store will be
+  used by default.
+
+  Falls back to the deprecated ``cafile`` SSL context option if not specified.
+
+  .. deprecated:: 1.6
+     This option has been deprecated. Use the ``tlsCAFile`` URI option instead.
+interface: phpmethod
+operation: ~
+optional: true
+---
+arg_name: option
+name: crl_file
+type: string
+description: |
+  Path to a certificate revocation list file.
+interface: phpmethod
+operation: ~
+optional: true
+---
+arg_name: option
+name: pem_file
+type: string
+description: |
+  Path to a PEM encoded certificate to use for client authentication.
+
+  Falls back to the deprecated ``local_cert`` SSL context option if not
+  specified.
+
+  .. deprecated:: 1.6
+     This option has been deprecated. Use the ``tlsCertificateKeyFile`` URI
+     option instead.
+interface: phpmethod
+operation: ~
+optional: true
+---
+arg_name: option
+name: pem_pwd
+type: string
+description: |
+  Passphrase for the PEM encoded certificate (if applicable).
+
+  Falls back to the deprecated ``passphrase`` SSL context option if not
+  specified.
+
+  .. deprecated:: 1.6
+     This option has been deprecated. Use the ``tlsCertificateKeyFilePassword``
+     URI option instead.
+interface: phpmethod
+operation: ~
+optional: true
+---
+arg_name: option
+name: weak_cert_validation
+type: boolean
+description: |
+  Disables certificate validation ``true``. Defaults to ``false``.
+
+  Falls back to the deprecated ``allow_self_signed`` SSL context option if not
+  specified.
+
+  .. deprecated:: 1.6
+     This option has been deprecated. Use the ``tlsAllowInvalidCertificates``
+     URI option instead.
+interface: phpmethod
+operation: ~
+optional: true
+---
+arg_name: option
+name: context
+type: resource
+description: |
+  :php:`SSL context options <manual/en/context.ssl.php>` to be used as fallbacks
+  for other driver options (as specified). Note that the driver does not consult
+  the default stream context.
+
+  This option is supported for backwards compatibility, but should be considered
+  deprecated.
+interface: phpmethod
+operation: ~
+optional: true
+---
+arg_name: option
+name: autoEncryption
+type: array
+description: |
+  Options to configure client-side field-level encryption in the driver. The
+  encryption options are documented in the :php:`extension documentation
+  <manual/en/mongodb-driver-manager.construct.php#mongodb-driver-manager.construct-driveroptions>`.
+  For the ``keyVaultClient`` option, you may pass a :phpclass:`MongoDB\\Client`
+  instance, which will be unwrapped to provide a :php:`MongoDB\\Driver\\Manager <class.mongodb-driver-manager>`
+  to the extension.
+  .. versionadded:: 1.6
+interface: phpmethod
+operation: ~
+optional: true
+---
+arg_name: option
+name: driver
+type: array
+description: |
+  Additional driver metadata to be passed on to the server handshake. This is an
+  array containing ``name``, ``version``, and ``platform`` fields:
+
+  .. code-block:: php
+
+     [
+         'name' => 'my-driver',
+         'version' => '1.2.3-dev',
+         'platform' => 'some-platform',
+     ]
+
+  .. note::
+
+     This feature is primarily designed for custom drivers and ODMs, which may
+     want to identify themselves to the server for diagnostic purposes.
+     Applications should use the ``appName`` URI option instead of driver
+     metadata.
+
+  .. versionadded:: 1.7
+interface: phpmethod
+operation: ~
+optional: true
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBClient-method-construct-param.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBClient-method-construct-param.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..4b6ff4205a5d92a990081d7878677d0bbe781c9a
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBClient-method-construct-param.yaml	
@@ -0,0 +1,51 @@
+arg_name: param
+name: $uri
+type: string
+description: |
+  The URI of the standalone, replica set, or sharded cluster to which to
+  connect. Refer to :manual:`Connection String URI Format
+  </reference/connection-string>` in the MongoDB manual for more information.
+
+  Defaults to ``"mongodb://127.0.0.1:27017"`` if unspecified.
+
+  Any special characters in the URI components need to be encoded according to
+  `RFC 3986 <http://www.faqs.org/rfcs/rfc3986.html>`_. This is particularly
+  relevant to the username and password, which can often include special
+  characters such as ``@``, ``:``, or ``%``. When connecting via a Unix domain
+  socket, the socket path may contain special characters such as slashes and
+  must be encoded. The :php:`rawurlencode() <rawurlencode>` function may be used
+  to encode constituent parts of the URI.
+interface: phpmethod
+operation: ~
+optional: true
+---
+arg_name: param
+name: $uriOptions
+type: array
+description: |
+  Specifies additional URI options, such as authentication credentials or query
+  string parameters. The options specified in ``$uriOptions`` take precedence
+  over any analogous options present in the ``$uri`` string and do not need to
+  be encoded according to `RFC 3986 <http://www.faqs.org/rfcs/rfc3986.html>`_.
+
+  Refer to the :php:`MongoDB\\Driver\\Manager::__construct()
+  <mongodb-driver-manager.construct>` extension reference and :manual:`MongoDB
+  connection string </reference/connection-string>` documentation for accepted
+  options.
+interface: phpmethod
+operation: ~
+optional: true
+---
+arg_name: param
+name: $driverOptions
+type: array
+description: |
+  Specify driver-specific options, such as SSL options. In addition to any
+  options supported by the :php:`extension <mongodb-driver-manager>`, the
+  |php-library| allows you to specify a default :php:`type map
+  <manual/en/mongodb.persistence.deserialization.php#mongodb.persistence.typemaps>`
+  to apply to the cursors it creates.
+interface: phpmethod
+operation: ~
+optional: true
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBClient-method-createClientEncryption-param.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBClient-method-createClientEncryption-param.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..73ad04d0ba16b0e6efced8a891de73f14845c3d0
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBClient-method-createClientEncryption-param.yaml	
@@ -0,0 +1,4 @@
+source:
+  file: apiargs-common-param.yaml
+  ref: $options
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBClient-method-dropDatabase-option.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBClient-method-dropDatabase-option.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..e219c1459313a3a9c941df9eea9c96e146332139
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBClient-method-dropDatabase-option.yaml	
@@ -0,0 +1,19 @@
+source:
+  file: apiargs-common-option.yaml
+  ref: session
+post: |
+  .. versionadded:: 1.3
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: typeMap
+post: |
+  This will be used for the returned command result document.
+---
+source:
+  file: apiargs-MongoDBClient-common-option.yaml
+  ref: writeConcern
+post: |
+  This is not supported for server versions prior to 3.4 and will result in an
+  exception at execution time if used.
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBClient-method-dropDatabase-param.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBClient-method-dropDatabase-param.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..07b768348cff273fb9074f97473b9d92494014d2
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBClient-method-dropDatabase-param.yaml	
@@ -0,0 +1,10 @@
+source:
+  file: apiargs-common-param.yaml
+  ref: $databaseName
+replacement:
+  action: " to drop"
+---
+source:
+  file: apiargs-common-param.yaml
+  ref: $options
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBClient-method-get-param.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBClient-method-get-param.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..e9d3ccc6c1c263e95c3d7cbcd8d911f2985eb739
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBClient-method-get-param.yaml	
@@ -0,0 +1,6 @@
+source:
+  file: apiargs-common-param.yaml
+  ref: $databaseName
+replacement:
+  action: " to select"
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBClient-method-listDatabases-option.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBClient-method-listDatabases-option.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..4e3d616d8f8e00d8ee9a93eca2e9c5ede7c72e98
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBClient-method-listDatabases-option.yaml	
@@ -0,0 +1,39 @@
+arg_name: option
+name: authorizedDatabases
+type: boolean
+description: |
+  A flag that determines which databases are returned based on the user
+  privileges when access control is enabled. For more information, see the
+  `listDatabases command documentation <https://docs.mongodb.com/manual/reference/command/listDatabases/#dbcmd.listDatabases>`_.
+
+  For servers < 4.0.5, this option is ignored.
+
+  .. versionadded:: 1.7
+interface: phpmethod
+operation: ~
+optional: true
+---
+arg_name: option
+name: filter
+type: array|object
+description: |
+  A query expression to filter the list of databases.
+
+  You can specify a query expression for database fields (e.g. ``name``,
+  ``sizeOnDisk``, ``empty``).
+
+  .. versionadded:: 1.3
+interface: phpmethod
+operation: ~
+optional: true
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: maxTimeMS
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: session
+post: |
+  .. versionadded:: 1.3
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBClient-method-listDatabases-param.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBClient-method-listDatabases-param.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..73ad04d0ba16b0e6efced8a891de73f14845c3d0
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBClient-method-listDatabases-param.yaml	
@@ -0,0 +1,4 @@
+source:
+  file: apiargs-common-param.yaml
+  ref: $options
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBClient-method-selectCollection-option.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBClient-method-selectCollection-option.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..d81d31811c806d7eec7fea8e532fb483ed276d3f
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBClient-method-selectCollection-option.yaml	
@@ -0,0 +1,27 @@
+source:
+  file: apiargs-common-option.yaml
+  ref: readConcern
+replacement:
+  resource: "collection"
+  parent: "client"
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: readPreference
+replacement:
+  resource: "collection"
+  parent: "client"
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: typeMap
+replacement:
+  parent: "client"
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: writeConcern
+replacement:
+  resource: "collection"
+  parent: "client"
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBClient-method-selectCollection-param.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBClient-method-selectCollection-param.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..99c764460536d2337e86c3ca8dd4e691e5707722
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBClient-method-selectCollection-param.yaml	
@@ -0,0 +1,16 @@
+source:
+  file: apiargs-common-param.yaml
+  ref: $databaseName
+replacement:
+  action: " containing the collection to select"
+---
+source:
+  file: apiargs-common-param.yaml
+  ref: $collectionName
+replacement:
+  action: " to select"
+---
+source:
+  file: apiargs-common-param.yaml
+  ref: $options
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBClient-method-selectDatabase-option.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBClient-method-selectDatabase-option.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..e4ffd3c669273c8a71cf5c966541e7af2fa870b7
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBClient-method-selectDatabase-option.yaml	
@@ -0,0 +1,27 @@
+source:
+  file: apiargs-common-option.yaml
+  ref: readConcern
+replacement:
+  resource: "database"
+  parent: "client"
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: readPreference
+replacement:
+  resource: "database"
+  parent: "client"
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: typeMap
+replacement:
+  parent: "client"
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: writeConcern
+replacement:
+  resource: "database"
+  parent: "client"
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBClient-method-selectDatabase-param.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBClient-method-selectDatabase-param.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..8e5f9d45f73876333e3aa158271050aee2928680
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBClient-method-selectDatabase-param.yaml	
@@ -0,0 +1,10 @@
+source:
+  file: apiargs-common-param.yaml
+  ref: $databaseName
+replacement:
+  action: " to select"
+---
+source:
+  file: apiargs-common-param.yaml
+  ref: $options
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBClient-method-watch-option.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBClient-method-watch-option.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..2dd040e957e56c34aa2711c8737ff8632e1372bb
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBClient-method-watch-option.yaml	
@@ -0,0 +1,50 @@
+---
+source:
+  file: apiargs-method-watch-option.yaml
+  ref: batchSize
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: collation
+---
+source:
+  file: apiargs-method-watch-option.yaml
+  ref: fullDocument
+---
+source:
+  file: apiargs-method-watch-option.yaml
+  ref: maxAwaitTimeMS
+---
+source:
+  file: apiargs-MongoDBClient-common-option.yaml
+  ref: readConcern
+---
+source:
+  file: apiargs-MongoDBClient-common-option.yaml
+  ref: readPreference
+post: |
+  This is used for both the initial change stream aggregation and for
+  server selection during an automatic resume.
+---
+source:
+  file: apiargs-method-watch-option.yaml
+  ref: resumeAfter
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: session
+---
+source:
+  file: apiargs-method-watch-option.yaml
+  ref: startAfter
+post: |
+  .. versionadded: 1.5
+---
+source:
+  file: apiargs-method-watch-option.yaml
+  ref: startAtOperationTime
+---
+source:
+  file: apiargs-MongoDBClient-common-option.yaml
+  ref: typeMap
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBClient-method-watch-param.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBClient-method-watch-param.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..b00e450cfcd51e23d4bfe4d8126c59eb1e570182
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBClient-method-watch-param.yaml	
@@ -0,0 +1,8 @@
+source:
+  file: apiargs-method-watch-param.yaml
+  ref: $pipeline
+---
+source:
+  file: apiargs-method-watch-param.yaml
+  ref: $options
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-common-option.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-common-option.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..643308ea570356cac28f0a0a0ddca4d7756e2cd3
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-common-option.yaml	
@@ -0,0 +1,95 @@
+arg_name: option
+name: arrayFilters
+type: array
+description: |
+   An array of filter documents that determines which array elements to modify
+   for an update operation on an array field.
+
+   This is not supported for server versions prior to 3.6 and will result in an
+   exception at execution time if used.
+interface: phpmethod
+operation: ~
+optional: true
+---
+arg_name: option
+name: bypassDocumentValidation
+type: boolean
+description: |
+   If ``true``, allows the write operation to circumvent document level
+   validation. Defaults to ``false``.
+
+   This option is available in MongoDB 3.2+ and is ignored for older server
+   versions, which do not support document level validation.
+interface: phpmethod
+operation: ~
+optional: true
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: collation
+post: |
+   If the collation is unspecified but the collection has a default collation,
+   the operation uses the collation specified for the collection. If no
+   collation is specified for the collection or for the operation, MongoDB uses
+   the simple binary comparison used in prior versions for string comparisons.
+---
+arg_name: option
+name: readConcern
+type: :php:`MongoDB\\Driver\\ReadConcern <class.mongodb-driver-readconcern>`
+description: |
+   :manual:`Read concern </reference/read-concern>` to use for the operation.
+   Defaults to the collection's read concern.
+
+   This is not supported for server versions prior to 3.2 and will result in an
+   exception at execution time if used.
+
+   It is not possible to specify a :manual:`read concern
+   </reference/read-concern>` for individual operations as part of a
+   transaction. Instead, set the ``readConcern`` option when starting the
+   transaction with :php:`startTransaction <mongodb-driver-session.starttransaction>`.
+interface: phpmethod
+operation: ~
+optional: true
+---
+arg_name: option
+name: readPreference
+type: :php:`MongoDB\\Driver\\ReadPreference <class.mongodb-driver-readpreference>`
+description: |
+   :manual:`Read preference </reference/read-preference>` to use for the
+   operation. Defaults to the collection's read preference.
+interface: phpmethod
+operation: ~
+optional: true
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: typeMap
+replacement:
+  parent: "collection"
+---
+arg_name: option
+name: writeConcern
+type: :php:`MongoDB\\Driver\\WriteConcern <class.mongodb-driver-writeconcern>`
+description: |
+   :manual:`Write concern </reference/write-concern>` to use for the operation.
+   Defaults to the collection's write concern.
+
+   It is not possible to specify a :manual:`write concern
+   </reference/write-concern>` for individual operations as part of a
+   transaction. Instead, set the ``writeConcern`` option when starting the
+   transaction with :php:`startTransaction <mongodb-driver-session.starttransaction>`.
+interface: phpmethod
+operation: ~
+optional: true
+---
+arg_name: option
+name: upsert
+type: boolean
+description: |
+   If set to ``true``, creates a new document when no document matches the query
+   criteria. The default value is ``false``, which does not insert a new
+   document when no match is found.
+interface: phpmethod
+operation: ~
+optional: true
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-common-param.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-common-param.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..9c032d151ff063b60936f9726d1b75593c8bdf38
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-common-param.yaml	
@@ -0,0 +1,33 @@
+arg_name: param
+name: $filter
+type: array|object
+description: |
+  The filter criteria that specifies the documents{{action}}.
+interface: phpmethod
+operation: ~
+optional: false
+replacement:
+  action: ""
+---
+arg_name: param
+name: $replacement
+type: array|object
+description: |
+  The replacement document.
+interface: phpmethod
+operation: ~
+optional: false
+---
+arg_name: param
+name: $update
+type: array|object
+description: |
+  Specifies the field and value combinations to update and any relevant update
+  operators. ``$update`` uses MongoDB's :method:`update operators
+  </reference/operator/update>`. Starting with MongoDB 4.2, an `aggregation
+  pipeline <https://docs.mongodb.com/master/reference/command/update/#update-with-an-aggregation-pipeline>`_
+  can be passed as this parameter.
+interface: phpmethod
+operation: ~
+optional: false
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-aggregate-option.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-aggregate-option.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..86edc1d50b7b6d1ca493b9c869fc5752b2ba039c
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-aggregate-option.yaml	
@@ -0,0 +1,78 @@
+source:
+  file: apiargs-aggregate-option.yaml
+  ref: allowDiskUse
+---
+source:
+  file: apiargs-aggregate-option.yaml
+  ref: batchSize
+---
+source:
+  file: apiargs-aggregate-option.yaml
+  ref: bypassDocumentValidation
+---
+source:
+  file: apiargs-aggregate-option.yaml
+  ref: comment
+post: |
+  .. versionadded:: 1.3
+---
+source:
+  file: apiargs-aggregate-option.yaml
+  ref: explain
+post: |
+  .. versionadded:: 1.4
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: hint
+post: |
+  .. versionadded:: 1.3
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: maxTimeMS
+---
+source:
+  file: apiargs-MongoDBCollection-common-option.yaml
+  ref: readConcern
+---
+source:
+  file: apiargs-MongoDBCollection-common-option.yaml
+  ref: readPreference
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: session
+post: |
+  .. versionadded:: 1.3
+---
+source:
+  file: apiargs-MongoDBCollection-common-option.yaml
+  ref: typeMap
+---
+arg_name: option
+name: useCursor
+type: boolean
+description: |
+  Indicates whether the command will request that the server provide results
+  using a cursor. The default is ``true``.
+
+  .. note::
+
+     MongoDB 3.6+ no longer supports returning results without a cursor (excluding
+     when the explain option is used) and specifying false for this option will
+     result in a server error.
+interface: phpmethod
+operation: ~
+optional: true
+---
+source:
+  file: apiargs-MongoDBCollection-common-option.yaml
+  ref: writeConcern
+post: |
+  This only applies when a :ref:`$out <agg-out>` or :ref:`$merge <agg-merge>`
+  stage is specified.
+
+  This is not supported for server versions prior to 3.4 and will result in an
+  exception at execution time if used.
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-aggregate-param.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-aggregate-param.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..cbad3b49b0c834d8d496b649cdddcf379b2aa6e9
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-aggregate-param.yaml	
@@ -0,0 +1,14 @@
+arg_name: param
+name: $pipeline
+type: array
+description: |
+  Specifies an :manual:`aggregation pipeline </core/aggregation-pipeline>`
+  operation.
+interface: phpmethod
+operation: ~
+optional: false
+---
+source:
+  file: apiargs-common-param.yaml
+  ref: $options
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-bulkWrite-option.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-bulkWrite-option.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..d5d2e5df47291c599a1662f5d5ba59c78ad2c5f4
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-bulkWrite-option.yaml	
@@ -0,0 +1,29 @@
+source:
+  file: apiargs-MongoDBCollection-common-option.yaml
+  ref: bypassDocumentValidation
+---
+arg_name: option
+name: ordered
+type: boolean
+description: |
+  If ``true``: when a single write fails, the operation will stop without
+  performing the remaining writes and throw an exception.
+
+  If ``false``: when a single write fails, the operation will continue with the
+  remaining writes, if any, and throw an exception.
+
+  The default is ``true``.
+interface: phpmethod
+operation: ~
+optional: true
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: session
+post: |
+  .. versionadded:: 1.3
+---
+source:
+  file: apiargs-MongoDBCollection-common-option.yaml
+  ref: writeConcern
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-bulkWrite-param.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-bulkWrite-param.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..79423a63778a6090f5f9b4d5cf1621c52ab05552
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-bulkWrite-param.yaml	
@@ -0,0 +1,37 @@
+arg_name: param
+name: $operations
+type: array
+description: |
+  An array containing the write operations to perform.
+  :phpmethod:`MongoDB\\Collection::bulkWrite()` supports
+  :phpmethod:`deleteMany() <MongoDB\\Collection::deleteMany>`,
+  :phpmethod:`deleteOne() <MongoDB\\Collection::deleteOne>`,
+  :phpmethod:`insertOne() <MongoDB\\Collection::insertOne>`,
+  :phpmethod:`replaceOne() <MongoDB\\Collection::replaceOne>`,
+  :phpmethod:`updateMany() <MongoDB\\Collection::updateMany>`, and
+  :phpmethod:`updateOne() <MongoDB\\Collection::updateOne>` operations in the
+  following array structure:
+
+  .. code-block:: php
+
+     [
+         [ 'deleteMany' => [ $filter ] ],
+         [ 'deleteOne'  => [ $filter ] ],
+         [ 'insertOne'  => [ $document ] ],
+         [ 'replaceOne' => [ $filter, $replacement, $options ] ],
+         [ 'updateMany' => [ $filter, $update, $options ] ],
+         [ 'updateOne'  => [ $filter, $update, $options ] ],
+     ]
+
+  Arguments correspond to the respective operation methods. However, the
+  ``writeConcern`` option is specified as a top-level option to
+  :phpmethod:`MongoDB\\Collection::bulkWrite()` instead of each individual
+  operation.
+interface: phpmethod
+operation: ~
+optional: true
+---
+source:
+  file: apiargs-common-param.yaml
+  ref: $options
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-construct-option.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-construct-option.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..7d422ca05966330fd79f7eeb7cdad78a593f18bd
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-construct-option.yaml	
@@ -0,0 +1,25 @@
+source:
+  file: apiargs-common-option.yaml
+  ref: readConcern
+replacement:
+  resource: "collection"
+  parent: "manager"
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: readPreference
+replacement:
+  resource: "collection"
+  parent: "manager"
+---
+source:
+  file: apiargs-MongoDBClient-method-construct-driverOptions.yaml
+  ref: typeMap
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: writeConcern
+replacement:
+  resource: "collection"
+  parent: "manager"
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-construct-param.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-construct-param.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..0827800baa720a08405d592aa1e8fd55466695a1
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-construct-param.yaml	
@@ -0,0 +1,16 @@
+source:
+  file: apiargs-common-param.yaml
+  ref: $manager
+---
+source:
+  file: apiargs-common-param.yaml
+  ref: $databaseName
+---
+source:
+  file: apiargs-common-param.yaml
+  ref: $collectionName
+---
+source:
+  file: apiargs-common-param.yaml
+  ref: $options
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-count-option.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-count-option.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..62227f1cc3022a00bb1b42c3445721ba1b63b9b7
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-count-option.yaml	
@@ -0,0 +1,55 @@
+source:
+  file: apiargs-MongoDBCollection-common-option.yaml
+  ref: collation
+---
+arg_name: option
+name: hint
+type: string|array|object
+description: |
+  The index to use. Specify either the index name as a string or the index key
+  pattern as a document. If specified, then the query system will only consider
+  plans using the hinted index.
+
+  .. versionchanged:: 1.2
+     If a document is provided, it is passed to the command as-is. Previously,
+     the library would convert the key pattern to an index name.
+interface: phpmethod
+operation: ~
+optional: true
+---
+arg_name: option
+name: limit
+type: integer
+description: |
+  The maximum number of matching documents to return.
+interface: phpmethod
+operation: ~
+optional: true
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: maxTimeMS
+---
+source:
+  file: apiargs-MongoDBCollection-common-option.yaml
+  ref: readConcern
+---
+source:
+  file: apiargs-MongoDBCollection-common-option.yaml
+  ref: readPreference
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: session
+post: |
+  .. versionadded:: 1.3
+---
+arg_name: option
+name: skip
+type: integer
+description: |
+  The number of matching documents to skip before returning results.
+interface: phpmethod
+operation: ~
+optional: true
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-count-param.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-count-param.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..e18c616bc01e4ff50282e7df219eae01221ac690
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-count-param.yaml	
@@ -0,0 +1,11 @@
+source:
+  file: apiargs-MongoDBCollection-common-param.yaml
+  ref: $filter
+optional: true
+replacement:
+  action: " to count"
+---
+source:
+  file: apiargs-common-param.yaml
+  ref: $options
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-countDocuments-option.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-countDocuments-option.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..2571b0716b797c64ff402281a82471f2f418b854
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-countDocuments-option.yaml	
@@ -0,0 +1,49 @@
+source:
+  file: apiargs-MongoDBCollection-common-option.yaml
+  ref: collation
+---
+arg_name: option
+name: hint
+type: string|array|object
+description: |
+  The index to use. Specify either the index name as a string or the index key
+  pattern as a document. If specified, then the query system will only consider
+  plans using the hinted index.
+interface: phpmethod
+operation: ~
+optional: true
+---
+arg_name: option
+name: limit
+type: integer
+description: |
+  The maximum number of matching documents to return.
+interface: phpmethod
+operation: ~
+optional: true
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: maxTimeMS
+---
+source:
+  file: apiargs-MongoDBCollection-common-option.yaml
+  ref: readConcern
+---
+source:
+  file: apiargs-MongoDBCollection-common-option.yaml
+  ref: readPreference
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: session
+---
+arg_name: option
+name: skip
+type: integer
+description: |
+  The number of matching documents to skip before returning results.
+interface: phpmethod
+operation: ~
+optional: true
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-countDocuments-param.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-countDocuments-param.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..e18c616bc01e4ff50282e7df219eae01221ac690
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-countDocuments-param.yaml	
@@ -0,0 +1,11 @@
+source:
+  file: apiargs-MongoDBCollection-common-param.yaml
+  ref: $filter
+optional: true
+replacement:
+  action: " to count"
+---
+source:
+  file: apiargs-common-param.yaml
+  ref: $options
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-createIndex-option.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-createIndex-option.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..1a76b33ca9a02953ecfb54d1e1a04839bed89557
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-createIndex-option.yaml	
@@ -0,0 +1,111 @@
+arg_name: option
+name: commitQuorum
+type: string|integer
+description: |
+  Specifies how many data-bearing members of a replica set, including the
+  primary, must complete the index builds successfully before the primary marks
+  the indexes as ready.
+
+  This option accepts the same values for the ``w`` field in a write concern
+  plus ``"votingMembers"``, which indicates all voting data-bearing nodes.
+
+  This is not supported for server versions prior to 4.4 and will result in an
+  exception at execution time if used.
+
+  .. versionadded:: 1.7
+interface: phpmethod
+operation: ~
+optional: true
+---
+arg_name: option
+name: unique
+type: boolean
+description: |
+  Creates a :manual:`unique </core/index-unique>` index.
+interface: phpmethod
+operation: ~
+optional: true
+---
+source:
+  file: apiargs-MongoDBCollection-common-option.yaml
+  ref: collation
+pre: |
+  Specifies the :manual:`collation
+  </reference/bson-type-comparison-order/#collation>` for the index.
+---
+arg_name: option
+name: partialFilterExpression
+type: array|object
+description: |
+  Creates a :manual:`partial </core/index-partial>` index.
+interface: phpmethod
+operation: ~
+optional: true
+---
+arg_name: option
+name: sparse
+type: boolean
+description: |
+  Creates a :manual:`sparse </core/index-sparse>` index.
+interface: phpmethod
+operation: ~
+optional: true
+---
+arg_name: option
+name: expireAfterSeconds
+type: integer
+description: |
+  Creates a :manual:`TTL </core/index-ttl>` index.
+interface: phpmethod
+operation: ~
+optional: true
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: maxTimeMS
+post: |
+  .. versionadded:: 1.3
+---
+arg_name: option
+name: name
+type: string
+description: |
+  A name that uniquely identifies the index. By default, MongoDB creates index
+  names based on the key.
+interface: phpmethod
+operation: ~
+optional: true
+---
+arg_name: option
+name: background
+type: string
+description: |
+  Instructs MongoDB to build the index :manual:`as a background
+  </core/index-creation>` process.
+interface: phpmethod
+operation: ~
+optional: true
+---
+arg_name: option
+name: 2dsphereIndexVersion
+type: integer
+description: |
+  Overrides the server's default version for a :manual:`2dsphere
+  </core/2dsphere>` index.
+interface: phpmethod
+operation: ~
+optional: true
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: session
+post: |
+  .. versionadded:: 1.3
+---
+source:
+  file: apiargs-MongoDBCollection-common-option.yaml
+  ref: writeConcern
+post: |
+  This is not supported for server versions prior to 3.4 and will result in an
+  exception at execution time if used.
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-createIndex-param.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-createIndex-param.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..c2979d913c6d0ce4709f5c73a601b9e42671f280
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-createIndex-param.yaml	
@@ -0,0 +1,20 @@
+arg_name: param
+name: $key
+type: array|object
+description: |
+  Specifies the field or fields to index and the index order.
+
+  For example, the following specifies a descending index on the ``username``
+  field:
+
+  .. code-block:: php
+
+     [ 'username' => -1 ]
+interface: phpmethod
+operation: ~
+optional: false
+---
+source:
+  file: apiargs-common-param.yaml
+  ref: $options
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-createIndexes-option.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-createIndexes-option.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..8808ddd1bf26d5f79a017cbe6c54279ae02b7fc6
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-createIndexes-option.yaml	
@@ -0,0 +1,23 @@
+source:
+  file: apiargs-MongoDBCollection-method-createIndex-option.yaml
+  ref: commitQuorum
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: maxTimeMS
+post: |
+  .. versionadded:: 1.3
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: session
+post: |
+  .. versionadded:: 1.3
+---
+source:
+  file: apiargs-MongoDBCollection-common-option.yaml
+  ref: writeConcern
+post: |
+  This is not supported for server versions prior to 3.4 and will result in an
+  exception at execution time if used.
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-createIndexes-param.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-createIndexes-param.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..e98d9aad0283f2f464ec276a946055215187ca58
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-createIndexes-param.yaml	
@@ -0,0 +1,23 @@
+arg_name: param
+name: $indexes
+type: array
+description: |
+  The indexes to create on the collection.
+
+  For example, the following specifies a unique index on the ``username`` field
+  and a compound index on the ``email`` and ``createdAt`` fields:
+
+  .. code-block:: php
+
+     [
+         [ 'key' => [ 'username' => -1 ], 'unique' => true ],
+         [ 'key' => [ 'email' => 1, 'createdAt' => 1 ] ],
+     ]
+interface: phpmethod
+operation: ~
+optional: false
+---
+source:
+  file: apiargs-common-param.yaml
+  ref: $options
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-deleteMany-option.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-deleteMany-option.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..55f6af9b391f921e333c34eb75c4c20aa60ba799
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-deleteMany-option.yaml	
@@ -0,0 +1,23 @@
+source:
+  file: apiargs-MongoDBCollection-common-option.yaml
+  ref: collation
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: hint
+post: |
+  This option is available in MongoDB 4.4+ and will result in an exception at
+  execution time if specified for an older server version.
+
+  .. versionadded:: 1.7
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: session
+post: |
+  .. versionadded:: 1.3
+---
+source:
+  file: apiargs-MongoDBCollection-common-option.yaml
+  ref: writeConcern
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-deleteMany-param.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-deleteMany-param.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..92797eb53300474be133459bb267341935b0faf8
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-deleteMany-param.yaml	
@@ -0,0 +1,11 @@
+source:
+  file: apiargs-MongoDBCollection-common-param.yaml
+  ref: $filter
+optional: false
+replacement:
+  action: " to delete"
+---
+source:
+  file: apiargs-common-param.yaml
+  ref: $options
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-deleteOne-option.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-deleteOne-option.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..55f6af9b391f921e333c34eb75c4c20aa60ba799
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-deleteOne-option.yaml	
@@ -0,0 +1,23 @@
+source:
+  file: apiargs-MongoDBCollection-common-option.yaml
+  ref: collation
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: hint
+post: |
+  This option is available in MongoDB 4.4+ and will result in an exception at
+  execution time if specified for an older server version.
+
+  .. versionadded:: 1.7
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: session
+post: |
+  .. versionadded:: 1.3
+---
+source:
+  file: apiargs-MongoDBCollection-common-option.yaml
+  ref: writeConcern
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-deleteOne-param.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-deleteOne-param.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..92797eb53300474be133459bb267341935b0faf8
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-deleteOne-param.yaml	
@@ -0,0 +1,11 @@
+source:
+  file: apiargs-MongoDBCollection-common-param.yaml
+  ref: $filter
+optional: false
+replacement:
+  action: " to delete"
+---
+source:
+  file: apiargs-common-param.yaml
+  ref: $options
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-distinct-option.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-distinct-option.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..3c2ae6ed202dc7c4d4e3649d73f539a0eb41db8f
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-distinct-option.yaml	
@@ -0,0 +1,28 @@
+source:
+  file: apiargs-MongoDBCollection-common-option.yaml
+  ref: collation
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: maxTimeMS
+---
+source:
+  file: apiargs-MongoDBCollection-common-option.yaml
+  ref: readConcern
+---
+source:
+  file: apiargs-MongoDBCollection-common-option.yaml
+  ref: readPreference
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: session
+post: |
+  .. versionadded:: 1.3
+---
+source:
+  file: apiargs-MongoDBCollection-common-option.yaml
+  ref: typeMap
+post: |
+  .. versionadded:: 1.5
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-distinct-param.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-distinct-param.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..37cd9b50b22323d6d28d33594513207cf93f057c
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-distinct-param.yaml	
@@ -0,0 +1,20 @@
+arg_name: param
+name: $fieldName
+type: string
+description: |
+  The field for which to return distinct values.
+interface: phpmethod
+operation: ~
+optional: false
+---
+source:
+  file: apiargs-MongoDBCollection-common-param.yaml
+  ref: $filter
+optional: true
+replacement:
+  action: " from which to retrieve the distinct values"
+---
+source:
+  file: apiargs-common-param.yaml
+  ref: $options
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-drop-option.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-drop-option.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..b1f39752a3f64b98e56f367c7de364ebbe7d8482
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-drop-option.yaml	
@@ -0,0 +1,19 @@
+source:
+  file: apiargs-MongoDBCollection-common-option.yaml
+  ref: typeMap
+post: |
+  This will be used for the returned command result document.
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: session
+post: |
+  .. versionadded:: 1.3
+---
+source:
+  file: apiargs-MongoDBCollection-common-option.yaml
+  ref: writeConcern
+post: |
+  This is not supported for server versions prior to 3.4 and will result in an
+  exception at execution time if used.
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-drop-param.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-drop-param.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..73ad04d0ba16b0e6efced8a891de73f14845c3d0
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-drop-param.yaml	
@@ -0,0 +1,4 @@
+source:
+  file: apiargs-common-param.yaml
+  ref: $options
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-dropIndex-option.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-dropIndex-option.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..00db41c6cfb6e693c15ff6618eb5cae05ad07465
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-dropIndex-option.yaml	
@@ -0,0 +1,25 @@
+source:
+  file: apiargs-common-option.yaml
+  ref: maxTimeMS
+post: |
+  .. versionadded:: 1.3
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: session
+post: |
+  .. versionadded:: 1.3
+---
+source:
+  file: apiargs-MongoDBCollection-common-option.yaml
+  ref: typeMap
+post: |
+  This will be used for the returned command result document.
+---
+source:
+  file: apiargs-MongoDBCollection-common-option.yaml
+  ref: writeConcern
+post: |
+  This is not supported for server versions prior to 3.4 and will result in an
+  exception at execution time if used.
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-dropIndex-param.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-dropIndex-param.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..7cac6d1de809d93512da773bad576665f409e523
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-dropIndex-param.yaml	
@@ -0,0 +1,15 @@
+arg_name: param
+name: $indexName
+type: string| :phpclass:`MongoDB\\Model\\IndexInfo`
+description: |
+  The name or model object of the index to drop. View the existing indexes on
+  the collection using the :phpmethod:`listIndexes()
+  <MongoDB\\Collection::listIndexes>` method.
+interface: phpmethod
+operation: ~
+optional: false
+---
+source:
+  file: apiargs-common-param.yaml
+  ref: $options
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-dropIndexes-option.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-dropIndexes-option.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..0b1970c36a7f3cd8451e9b1caf5065224cb84618
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-dropIndexes-option.yaml	
@@ -0,0 +1,23 @@
+source:
+  file: apiargs-common-option.yaml
+  ref: maxTimeMS
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: session
+post: |
+  .. versionadded:: 1.3
+---
+source:
+  file: apiargs-MongoDBCollection-common-option.yaml
+  ref: typeMap
+post: |
+  This will be used for the returned command result document.
+---
+source:
+  file: apiargs-MongoDBCollection-common-option.yaml
+  ref: writeConcern
+post: |
+  This is not supported for server versions prior to 3.4 and will result in an
+  exception at execution time if used.
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-dropIndexes-param.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-dropIndexes-param.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..73ad04d0ba16b0e6efced8a891de73f14845c3d0
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-dropIndexes-param.yaml	
@@ -0,0 +1,4 @@
+source:
+  file: apiargs-common-param.yaml
+  ref: $options
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-estimateDocumentCount-option.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-estimateDocumentCount-option.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..f70487a16506f87f9ee8b5aef2064b74375c6f35
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-estimateDocumentCount-option.yaml	
@@ -0,0 +1,16 @@
+source:
+  file: apiargs-common-option.yaml
+  ref: maxTimeMS
+---
+source:
+  file: apiargs-MongoDBCollection-common-option.yaml
+  ref: readConcern
+---
+source:
+  file: apiargs-MongoDBCollection-common-option.yaml
+  ref: readPreference
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: session
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-estimateDocumentCount-param.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-estimateDocumentCount-param.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..73ad04d0ba16b0e6efced8a891de73f14845c3d0
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-estimateDocumentCount-param.yaml	
@@ -0,0 +1,4 @@
+source:
+  file: apiargs-common-param.yaml
+  ref: $options
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-explain-option.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-explain-option.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..7c6a4dcd002cce8418642d48c5c46aaacb663ce4
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-explain-option.yaml	
@@ -0,0 +1,20 @@
+source:
+  file: apiargs-MongoDBCollection-common-option.yaml
+  ref: readPreference
+---
+source:
+  file: apiargs-MongoDBCollection-common-option.yaml
+  ref: typeMap
+post: |
+  This will be used for the returned command result document.
+---
+arg_name: option
+name: verbosity
+type: string
+description: |
+  The verbosity level at which to run the command. See the :manual:`explain
+  </reference/command/explain>` command for more information.
+interface: phpmethod
+operation: ~
+optional: true
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-explain-param.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-explain-param.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..59f156376639901756885db28d2b227a68793c74
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-explain-param.yaml	
@@ -0,0 +1,13 @@
+arg_name: param
+name: $explainable
+type: :phpclass:`MongoDB\\Operation\\Explainable`
+description: |
+  The command to explain.
+interface: phpmethod
+operation: ~
+optional: false
+---
+source:
+  file: apiargs-common-param.yaml
+  ref: $options
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-find-option.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-find-option.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..d6ff4c53258000c1abb197f55a1a734b5031ad9f
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-find-option.yaml	
@@ -0,0 +1,261 @@
+arg_name: option
+name: projection
+type: array|object
+description: |
+  The :ref:`projection specification <projections>` to determine which fields to
+  include in the returned documents. See :manual:`Project Fields to Return from
+  Query </tutorial/project-fields-from-query-results>` and
+  :manual:`Projection Operators </reference/operator/projection>` in the MongoDB
+  manual.
+interface: phpmethod
+operation: ~
+optional: true
+---
+arg_name: option
+name: sort
+type: array|object
+description: |
+  The sort specification for the ordering of the results.
+interface: phpmethod
+operation: ~
+optional: true
+---
+arg_name: option
+name: skip
+type: integer
+description: |
+  Number of documents to skip. Defaults to ``0``.
+interface: phpmethod
+operation: ~
+optional: true
+---
+arg_name: option
+name: limit
+type: integer
+description: |
+  The maximum number of documents to return. If unspecified, then defaults to no
+  limit. A limit of ``0`` is equivalent to setting no limit.
+
+  A negative limit is similar to a positive limit but closes the cursor after
+  returning a single batch of results. As such, with a negative limit, if the
+  limited result set does not fit into a single batch, the number of documents
+  received will be less than the specified limit. By passing a negative limit, the
+  client indicates to the server that it will not ask for a subsequent batch via
+  getMore.
+interface: phpmethod
+operation: ~
+optional: true
+---
+arg_name: option
+name: allowDiskUse
+type: boolean
+description: |
+  Enables writing to temporary files. When set to ``true``, queries can write
+  data to the ``_tmp`` sub-directory in the ``dbPath`` directory. The default is
+  ``false``.
+interface: phpmethod
+operation: ~
+optional: true
+---
+arg_name: option
+name: batchSize
+type: integer
+description: |
+  The number of documents to return in the first batch. Defaults to ``101``. A
+  batchSize of ``0`` means that the cursor will be established, but no documents
+  will be returned in the first batch.
+
+  Unlike the previous wire protocol version, a batchSize of ``1`` for the
+  :dbcommand:`find` command does not close the cursor.
+interface: phpmethod
+operation: ~
+optional: true
+---
+source:
+  file: apiargs-MongoDBCollection-common-option.yaml
+  ref: collation
+---
+arg_name: option
+name: comment
+type: string
+description: |
+  A comment to attach to the query to help interpret and trace query
+  :dbcommand:`profile` data.
+interface: phpmethod
+operation: ~
+optional: true
+---
+arg_name: option
+name: cursorType
+type: integer
+description: |
+  Indicates the type of cursor to use. ``cursorType`` supports the following
+  values:
+
+   - ``MongoDB\Operation\Find::NON_TAILABLE`` (*default*)
+   - ``MongoDB\Operation\Find::TAILABLE``
+interface: phpmethod
+operation: ~
+optional: true
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: hint
+post: |
+  .. versionadded:: 1.2
+---
+arg_name: option
+name: maxAwaitTimeMS
+type: integer
+description: |
+  Positive integer denoting the time limit in milliseconds for the server to
+  block a getMore operation if no data is available. This option should only be
+  used if cursorType is TAILABLE_AWAIT.
+
+  .. versionadded:: 1.2
+interface: phpmethod
+operation: ~
+optional: true
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: maxTimeMS
+---
+source:
+  file: apiargs-MongoDBCollection-common-option.yaml
+  ref: readConcern
+---
+source:
+  file: apiargs-MongoDBCollection-common-option.yaml
+  ref: readPreference
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: session
+post: |
+  .. versionadded:: 1.3
+---
+arg_name: option
+name: max
+type: array|object
+description: |
+  The exclusive upper bound for a specific index.
+
+  .. versionadded:: 1.2
+interface: phpmethod
+operation: ~
+optional: true
+---
+arg_name: option
+name: maxScan
+type: integer
+description: |
+  Maximum number of documents or index keys to scan when executing the query.
+
+  .. deprecated:: 1.4
+  .. versionadded:: 1.2
+interface: phpmethod
+operation: ~
+optional: true
+---
+arg_name: option
+name: min
+type: array|object
+description: |
+  The inclusive lower bound for a specific index.
+
+  .. versionadded:: 1.2
+interface: phpmethod
+operation: ~
+optional: true
+---
+arg_name: option
+name: oplogReplay
+type: boolean
+description: |
+  Internal use for replica sets. To use ``oplogReplay``, you must include the
+  following condition in the filter:
+
+  .. code-block:: javascript
+
+     { ts: { $gte: <timestamp> } }
+
+  The :php:`MongoDB\\BSON\\Timestamp <class.mongodb-bson-timestamp>` class
+  reference describes how to represent MongoDB's BSON timestamp type with PHP.
+
+  .. deprecated:: 1.7
+interface: phpmethod
+operation: ~
+optional: true
+---
+arg_name: option
+name: noCursorTimeout
+type: boolean
+description: |
+  Prevents the server from timing out idle cursors after an inactivity period
+  (10 minutes).
+interface: phpmethod
+operation: ~
+optional: true
+---
+arg_name: option
+name: returnKey
+type: boolean
+description: |
+  If true, returns only the index keys in the resulting documents.
+
+  .. versionadded:: 1.2
+interface: phpmethod
+operation: ~
+optional: true
+---
+arg_name: option
+name: showRecordId
+type: boolean
+description: |
+  Determines whether to return the record identifier for each document. If true,
+  adds a field $recordId to the returned documents.
+
+  .. versionadded:: 1.2
+interface: phpmethod
+operation: ~
+optional: true
+---
+arg_name: option
+name: snapshot
+type: boolean
+description: |
+  Prevents the cursor from returning a document more than once because of an
+  intervening write operation.
+
+  .. deprecated:: 1.4
+  .. versionadded:: 1.2
+interface: phpmethod
+operation: ~
+optional: true
+---
+arg_name: option
+name: allowPartialResults
+type: boolean
+description: |
+  For queries against a sharded collection, returns partial results from the
+  :program:`mongos` if some shards are unavailable instead of throwing an error.
+interface: phpmethod
+operation: ~
+optional: true
+---
+source:
+  file: apiargs-MongoDBCollection-common-option.yaml
+  ref: typeMap
+---
+arg_name: option
+name: modifiers
+type: array|object
+description: |
+  :manual:`Meta operators </reference/operator/query-modifier>` that modify the
+  output or behavior of a query. Use of these operators is deprecated in favor
+  of named options.
+interface: phpmethod
+operation: ~
+optional: true
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-find-param.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-find-param.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..5683a7bba7b0787deb5d01a1dc92fbdc73d08d32
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-find-param.yaml	
@@ -0,0 +1,11 @@
+source:
+  file: apiargs-MongoDBCollection-common-param.yaml
+  ref: $filter
+optional: true
+replacement:
+  action: " to query"
+---
+source:
+  file: apiargs-common-param.yaml
+  ref: $options
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-findOne-option.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-findOne-option.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..2371aabe23d9c35475d8bc82bdfac76aa9cdaa17
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-findOne-option.yaml	
@@ -0,0 +1,78 @@
+source:
+  file: apiargs-MongoDBCollection-method-find-option.yaml
+  ref: projection
+---
+source:
+  file: apiargs-MongoDBCollection-method-find-option.yaml
+  ref: sort
+---
+source:
+  file: apiargs-MongoDBCollection-method-find-option.yaml
+  ref: skip
+---
+source:
+  file: apiargs-MongoDBCollection-method-find-option.yaml
+  ref: allowDiskUse
+---
+source:
+  file: apiargs-MongoDBCollection-common-option.yaml
+  ref: collation
+---
+source:
+  file: apiargs-MongoDBCollection-method-find-option.yaml
+  ref: comment
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: hint
+post: |
+  .. versionadded:: 1.2
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: maxTimeMS
+---
+source:
+  file: apiargs-MongoDBCollection-common-option.yaml
+  ref: readConcern
+---
+source:
+  file: apiargs-MongoDBCollection-common-option.yaml
+  ref: readPreference
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: session
+post: |
+  .. versionadded:: 1.3
+---
+source:
+  file: apiargs-MongoDBCollection-common-option.yaml
+  ref: typeMap
+post: |
+  This will be used for the returned result document.
+---
+source:
+  file: apiargs-MongoDBCollection-method-find-option.yaml
+  ref: max
+---
+source:
+  file: apiargs-MongoDBCollection-method-find-option.yaml
+  ref: maxScan
+---
+source:
+  file: apiargs-MongoDBCollection-method-find-option.yaml
+  ref: min
+---
+source:
+  file: apiargs-MongoDBCollection-method-find-option.yaml
+  ref: returnKey
+---
+source:
+  file: apiargs-MongoDBCollection-method-find-option.yaml
+  ref: showRecordId
+---
+source:
+  file: apiargs-MongoDBCollection-method-find-option.yaml
+  ref: modifiers
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-findOne-param.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-findOne-param.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..5683a7bba7b0787deb5d01a1dc92fbdc73d08d32
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-findOne-param.yaml	
@@ -0,0 +1,11 @@
+source:
+  file: apiargs-MongoDBCollection-common-param.yaml
+  ref: $filter
+optional: true
+replacement:
+  action: " to query"
+---
+source:
+  file: apiargs-common-param.yaml
+  ref: $options
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-findOneAndDelete-option.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-findOneAndDelete-option.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..520b4de1966d93a0fffc9937238bead3a1e813b7
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-findOneAndDelete-option.yaml	
@@ -0,0 +1,35 @@
+source:
+  file: apiargs-MongoDBCollection-method-find-option.yaml
+  ref: projection
+---
+source:
+  file: apiargs-MongoDBCollection-method-find-option.yaml
+  ref: sort
+---
+source:
+  file: apiargs-MongoDBCollection-common-option.yaml
+  ref: collation
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: maxTimeMS
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: session
+post: |
+  .. versionadded:: 1.3
+---
+source:
+  file: apiargs-MongoDBCollection-common-option.yaml
+  ref: typeMap
+post: |
+  This will be used for the returned result document.
+---
+source:
+  file: apiargs-MongoDBCollection-common-option.yaml
+  ref: writeConcern
+post: |
+  This is not supported for server versions prior to 3.2 and will result in an
+  exception at execution time if used.
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-findOneAndDelete-param.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-findOneAndDelete-param.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..92797eb53300474be133459bb267341935b0faf8
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-findOneAndDelete-param.yaml	
@@ -0,0 +1,11 @@
+source:
+  file: apiargs-MongoDBCollection-common-param.yaml
+  ref: $filter
+optional: false
+replacement:
+  action: " to delete"
+---
+source:
+  file: apiargs-common-param.yaml
+  ref: $options
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-findOneAndReplace-option.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-findOneAndReplace-option.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..6b282dd29438eb04430c172467e6d57500f5d9bc
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-findOneAndReplace-option.yaml	
@@ -0,0 +1,65 @@
+source:
+  file: apiargs-MongoDBCollection-method-find-option.yaml
+  ref: projection
+---
+source:
+  file: apiargs-MongoDBCollection-method-find-option.yaml
+  ref: sort
+---
+source:
+  file: apiargs-MongoDBCollection-common-option.yaml
+  ref: collation
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: hint
+post: |
+  This option is available in MongoDB 4.4+ and will result in an exception at
+  execution time if specified for an older server version.
+
+  .. versionadded:: 1.7
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: maxTimeMS
+---
+source:
+  file: apiargs-MongoDBCollection-common-option.yaml
+  ref: bypassDocumentValidation
+---
+arg_name: option
+name: returnDocument
+type: integer
+description: |
+  Specifies whether to return the document before the replacement is applied, or
+  after. ``returnDocument`` supports the following values:
+
+  - ``MongoDB\Operation\FindOneAndReplace::RETURN_DOCUMENT_BEFORE`` (*default*)
+  - ``MongoDB\Operation\FindOneAndReplace::RETURN_DOCUMENT_AFTER``
+interface: phpmethod
+operation: ~
+optional: true
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: session
+post: |
+  .. versionadded:: 1.3
+---
+source:
+  file: apiargs-MongoDBCollection-common-option.yaml
+  ref: typeMap
+post: |
+  This will be used for the returned result document.
+---
+source:
+  file: apiargs-MongoDBCollection-common-option.yaml
+  ref: upsert
+---
+source:
+  file: apiargs-MongoDBCollection-common-option.yaml
+  ref: writeConcern
+post: |
+  This is not supported for server versions prior to 3.2 and will result in an
+  exception at execution time if used.
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-findOneAndReplace-param.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-findOneAndReplace-param.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..32ed6b35f8986da96f1dde1789dd8cd88bc56a78
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-findOneAndReplace-param.yaml	
@@ -0,0 +1,15 @@
+source:
+  file: apiargs-MongoDBCollection-common-param.yaml
+  ref: $filter
+optional: false
+replacement:
+  action: " to replace"
+---
+source:
+  file: apiargs-MongoDBCollection-common-param.yaml
+  ref: $replacement
+---
+source:
+  file: apiargs-common-param.yaml
+  ref: $options
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-findOneAndUpdate-option.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-findOneAndUpdate-option.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..8393d26aa12a4e6e1c3a1d041d142386dac0a720
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-findOneAndUpdate-option.yaml	
@@ -0,0 +1,71 @@
+source:
+  file: apiargs-MongoDBCollection-method-find-option.yaml
+  ref: projection
+---
+source:
+  file: apiargs-MongoDBCollection-method-find-option.yaml
+  ref: sort
+---
+source:
+  file: apiargs-MongoDBCollection-common-option.yaml
+  ref: arrayFilters
+post: |
+  .. versionadded:: 1.3
+---
+source:
+  file: apiargs-MongoDBCollection-common-option.yaml
+  ref: collation
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: hint
+post: |
+  This option is available in MongoDB 4.4+ and will result in an exception at
+  execution time if specified for an older server version.
+
+  .. versionadded:: 1.7
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: maxTimeMS
+---
+source:
+  file: apiargs-MongoDBCollection-common-option.yaml
+  ref: bypassDocumentValidation
+---
+arg_name: option
+name: returnDocument
+type: integer
+description: |
+  Specifies whether to return the document before the update is applied, or
+  after. ``returnDocument`` supports the following values:
+
+  - ``MongoDB\Operation\FindOneAndUpdate::RETURN_DOCUMENT_BEFORE`` (*default*)
+  - ``MongoDB\Operation\FindOneAndUpdate::RETURN_DOCUMENT_AFTER``
+interface: phpmethod
+operation: ~
+optional: true
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: session
+post: |
+  .. versionadded:: 1.3
+---
+source:
+  file: apiargs-MongoDBCollection-common-option.yaml
+  ref: typeMap
+post: |
+  This will be used for the returned result document.
+---
+source:
+  file: apiargs-MongoDBCollection-common-option.yaml
+  ref: upsert
+---
+source:
+  file: apiargs-MongoDBCollection-common-option.yaml
+  ref: writeConcern
+post: |
+  This is not supported for server versions prior to 3.2 and will result in an
+  exception at execution time if used.
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-findOneAndUpdate-param.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-findOneAndUpdate-param.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..a335678a3ebdf04603383d73a73a1ede41f32ff2
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-findOneAndUpdate-param.yaml	
@@ -0,0 +1,15 @@
+source:
+  file: apiargs-MongoDBCollection-common-param.yaml
+  ref: $filter
+optional: false
+replacement:
+  action: " to update"
+---
+source:
+  file: apiargs-MongoDBCollection-common-param.yaml
+  ref: $update
+---
+source:
+  file: apiargs-common-param.yaml
+  ref: $options
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-insertMany-option.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-insertMany-option.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..39193578044fe9339b86a83d67e8409258e59a5a
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-insertMany-option.yaml	
@@ -0,0 +1,18 @@
+source:
+  file: apiargs-MongoDBCollection-common-option.yaml
+  ref: bypassDocumentValidation
+---
+source:
+  file: apiargs-MongoDBCollection-method-bulkWrite-option.yaml
+  ref: ordered
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: session
+post: |
+  .. versionadded:: 1.3
+---
+source:
+  file: apiargs-MongoDBCollection-common-option.yaml
+  ref: writeConcern
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-insertMany-param.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-insertMany-param.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..78246d30dd13e1ce48cb2e0276d50d750712bd47
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-insertMany-param.yaml	
@@ -0,0 +1,13 @@
+arg_name: param
+name: $documents
+type: array
+description: |
+  The documents to insert into the collection.
+interface: phpmethod
+operation: ~
+optional: false
+---
+source:
+  file: apiargs-common-param.yaml
+  ref: $options
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-insertOne-option.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-insertOne-option.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..61d795c7673b4fb5d6e4de24e24fa0c5ae672800
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-insertOne-option.yaml	
@@ -0,0 +1,14 @@
+source:
+  file: apiargs-MongoDBCollection-common-option.yaml
+  ref: bypassDocumentValidation
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: session
+post: |
+  .. versionadded:: 1.3
+---
+source:
+  file: apiargs-MongoDBCollection-common-option.yaml
+  ref: writeConcern
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-insertOne-param.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-insertOne-param.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..5dc231d308bccd020897d0e297e31ec738003e14
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-insertOne-param.yaml	
@@ -0,0 +1,13 @@
+arg_name: param
+name: $document
+type: array|object
+description: |
+  The document to insert into the collection.
+interface: phpmethod
+operation: ~
+optional: false
+---
+source:
+  file: apiargs-common-param.yaml
+  ref: $options
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-listIndexes-option.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-listIndexes-option.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..cbfb65016fd37100236906b061cf78f09c9c40e2
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-listIndexes-option.yaml	
@@ -0,0 +1,10 @@
+source:
+  file: apiargs-common-option.yaml
+  ref: maxTimeMS
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: session
+post: |
+  .. versionadded:: 1.3
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-listIndexes-param.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-listIndexes-param.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..73ad04d0ba16b0e6efced8a891de73f14845c3d0
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-listIndexes-param.yaml	
@@ -0,0 +1,4 @@
+source:
+  file: apiargs-common-param.yaml
+  ref: $options
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-mapReduce-option.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-mapReduce-option.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..33ef3892c084097e7b79bf53152752f3fbeed6b3
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-mapReduce-option.yaml	
@@ -0,0 +1,105 @@
+source:
+  file: apiargs-MongoDBCollection-common-option.yaml
+  ref: bypassDocumentValidation
+post: |
+  This only applies when results are output to a collection.
+---
+source:
+  file: apiargs-MongoDBCollection-common-option.yaml
+  ref: collation
+---
+arg_name: option
+name: finalize
+type: :php:`MongoDB\\BSON\\Javascript <class.mongodb-bson-javascript>`
+description: |
+  Follows the reduce method and modifies the output.
+
+  .. note::
+
+     Passing a Javascript instance with a scope is deprecated. Put all scope
+     variables in the ``scope`` option of the MapReduce operation.
+interface: phpmethod
+operation: ~
+optional: true
+---
+arg_name: option
+name: jsMode
+type: boolean
+description: |
+  Specifies whether to convert intermediate data into BSON format between the
+  execution of the map and reduce functions. The default is ``false``.
+interface: phpmethod
+operation: ~
+optional: true
+---
+arg_name: option
+name: limit
+type: integer
+description: |
+  Specifies a maximum number of documents for the input into the map function.
+interface: phpmethod
+operation: ~
+optional: true
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: maxTimeMS
+---
+arg_name: option
+name: query
+type: document
+description: |
+  Specifies the selection criteria using query operators for determining the
+  documents input to the map function.
+interface: phpmethod
+operation: ~
+optional: true
+---
+source:
+  file: apiargs-MongoDBCollection-common-option.yaml
+  ref: readConcern
+---
+source:
+  file: apiargs-MongoDBCollection-common-option.yaml
+  ref: readPreference
+post: |
+  This option will be ignored when results are output to a collection.
+---
+arg_name: option
+name: scope
+type: document
+description: |
+  Specifies global variables that are accessible in the map, reduce, and finalize
+  functions.
+interface: phpmethod
+operation: ~
+optional: true
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: session
+post: |
+  .. versionadded:: 1.3
+---
+source:
+  file: apiargs-MongoDBCollection-method-find-option.yaml
+  ref: sort
+---
+source:
+  file: apiargs-MongoDBCollection-common-option.yaml
+  ref: typeMap
+---
+arg_name: option
+name: verbose
+type: boolean
+description: |
+  Specifies whether to include the timing information in the result information.
+  The default is ``true``.
+interface: phpmethod
+operation: ~
+optional: true
+---
+source:
+  file: apiargs-MongoDBCollection-common-option.yaml
+  ref: writeConcern
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-mapReduce-param.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-mapReduce-param.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..e8254f3e287f7de5592cf43c0c5bcb4b228ff29d
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-mapReduce-param.yaml	
@@ -0,0 +1,46 @@
+arg_name: param
+name: $map
+type: :php:`MongoDB\\BSON\\Javascript <mongodb-bson-javascript>`
+description: |
+  A JavaScript function that associates or "maps" a value with a key and emits
+  the key and value pair.
+
+  .. note::
+
+     Passing a Javascript instance with a scope is deprecated. Put all scope
+     variables in the ``scope`` option of the MapReduce operation.
+interface: phpmethod
+operation: ~
+optional: false
+---
+arg_name: param
+name: $reduce
+type: :php:`MongoDB\\BSON\\Javascript <class.mongodb-bson-javascript>`
+description: |
+  A JavaScript function that "reduces" to a single object all the values
+  associated with a particular key.
+
+  .. note::
+
+     Passing a Javascript instance with a scope is deprecated. Put all scope
+     variables in the ``scope`` option of the MapReduce operation.
+interface: phpmethod
+operation: ~
+optional: false
+---
+arg_name: param
+name: $out
+type: string|document
+description: |
+  Specifies where to output the result of the map-reduce operation. You can
+  either output to a collection or return the result inline. On a primary member
+  of a replica set you can output either to a collection or inline, but on a
+  secondary, only inline output is possible.
+interface: phpmethod
+operation: ~
+optional: false
+---
+source:
+  file: apiargs-common-param.yaml
+  ref: $options
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-replaceOne-option.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-replaceOne-option.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..cfc3a71d41c539b7fd7b147cb29579b455cb5a1b
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-replaceOne-option.yaml	
@@ -0,0 +1,31 @@
+source:
+  file: apiargs-MongoDBCollection-common-option.yaml
+  ref: upsert
+---
+source:
+  file: apiargs-MongoDBCollection-common-option.yaml
+  ref: bypassDocumentValidation
+---
+source:
+  file: apiargs-MongoDBCollection-common-option.yaml
+  ref: collation
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: hint
+post: |
+  This option is available in MongoDB 4.2+ and will result in an exception at
+  execution time if specified for an older server version.
+
+  .. versionadded:: 1.6
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: session
+post: |
+  .. versionadded:: 1.3
+---
+source:
+  file: apiargs-MongoDBCollection-common-option.yaml
+  ref: writeConcern
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-replaceOne-param.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-replaceOne-param.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..32ed6b35f8986da96f1dde1789dd8cd88bc56a78
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-replaceOne-param.yaml	
@@ -0,0 +1,15 @@
+source:
+  file: apiargs-MongoDBCollection-common-param.yaml
+  ref: $filter
+optional: false
+replacement:
+  action: " to replace"
+---
+source:
+  file: apiargs-MongoDBCollection-common-param.yaml
+  ref: $replacement
+---
+source:
+  file: apiargs-common-param.yaml
+  ref: $options
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-updateMany-option.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-updateMany-option.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..b94cb750a32bd64628cb3015a6586883ef84aad4
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-updateMany-option.yaml	
@@ -0,0 +1,37 @@
+source:
+  file: apiargs-MongoDBCollection-common-option.yaml
+  ref: upsert
+---
+source:
+  file: apiargs-MongoDBCollection-common-option.yaml
+  ref: arrayFilters
+post: |
+  .. versionadded:: 1.3
+---
+source:
+  file: apiargs-MongoDBCollection-common-option.yaml
+  ref: bypassDocumentValidation
+---
+source:
+  file: apiargs-MongoDBCollection-common-option.yaml
+  ref: collation
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: hint
+post: |
+  This option is available in MongoDB 4.2+ and will result in an exception at
+  execution time if specified for an older server version.
+
+  .. versionadded:: 1.6
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: session
+post: |
+  .. versionadded:: 1.3
+---
+source:
+  file: apiargs-MongoDBCollection-common-option.yaml
+  ref: writeConcern
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-updateMany-param.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-updateMany-param.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..a335678a3ebdf04603383d73a73a1ede41f32ff2
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-updateMany-param.yaml	
@@ -0,0 +1,15 @@
+source:
+  file: apiargs-MongoDBCollection-common-param.yaml
+  ref: $filter
+optional: false
+replacement:
+  action: " to update"
+---
+source:
+  file: apiargs-MongoDBCollection-common-param.yaml
+  ref: $update
+---
+source:
+  file: apiargs-common-param.yaml
+  ref: $options
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-updateOne-option.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-updateOne-option.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..b94cb750a32bd64628cb3015a6586883ef84aad4
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-updateOne-option.yaml	
@@ -0,0 +1,37 @@
+source:
+  file: apiargs-MongoDBCollection-common-option.yaml
+  ref: upsert
+---
+source:
+  file: apiargs-MongoDBCollection-common-option.yaml
+  ref: arrayFilters
+post: |
+  .. versionadded:: 1.3
+---
+source:
+  file: apiargs-MongoDBCollection-common-option.yaml
+  ref: bypassDocumentValidation
+---
+source:
+  file: apiargs-MongoDBCollection-common-option.yaml
+  ref: collation
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: hint
+post: |
+  This option is available in MongoDB 4.2+ and will result in an exception at
+  execution time if specified for an older server version.
+
+  .. versionadded:: 1.6
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: session
+post: |
+  .. versionadded:: 1.3
+---
+source:
+  file: apiargs-MongoDBCollection-common-option.yaml
+  ref: writeConcern
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-updateOne-param.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-updateOne-param.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..a335678a3ebdf04603383d73a73a1ede41f32ff2
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-updateOne-param.yaml	
@@ -0,0 +1,15 @@
+source:
+  file: apiargs-MongoDBCollection-common-param.yaml
+  ref: $filter
+optional: false
+replacement:
+  action: " to update"
+---
+source:
+  file: apiargs-MongoDBCollection-common-param.yaml
+  ref: $update
+---
+source:
+  file: apiargs-common-param.yaml
+  ref: $options
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-watch-option.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-watch-option.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..a873beec512b2fab9591f3096b972d92a5b211e2
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-watch-option.yaml	
@@ -0,0 +1,52 @@
+---
+source:
+  file: apiargs-method-watch-option.yaml
+  ref: batchSize
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: collation
+---
+source:
+  file: apiargs-method-watch-option.yaml
+  ref: fullDocument
+---
+source:
+  file: apiargs-method-watch-option.yaml
+  ref: maxAwaitTimeMS
+---
+source:
+  file: apiargs-MongoDBCollection-common-option.yaml
+  ref: readConcern
+---
+source:
+  file: apiargs-MongoDBCollection-common-option.yaml
+  ref: readPreference
+post: |
+  This is used for both the initial change stream aggregation and for
+  server selection during an automatic resume.
+---
+source:
+  file: apiargs-method-watch-option.yaml
+  ref: resumeAfter
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: session
+---
+source:
+  file: apiargs-method-watch-option.yaml
+  ref: startAfter
+post: |
+  .. versionadded: 1.5
+---
+source:
+  file: apiargs-method-watch-option.yaml
+  ref: startAtOperationTime
+post: |
+  .. versionadded:: 1.4
+---
+source:
+  file: apiargs-MongoDBCollection-common-option.yaml
+  ref: typeMap
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-watch-param.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-watch-param.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..b00e450cfcd51e23d4bfe4d8126c59eb1e570182
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-watch-param.yaml	
@@ -0,0 +1,8 @@
+source:
+  file: apiargs-method-watch-param.yaml
+  ref: $pipeline
+---
+source:
+  file: apiargs-method-watch-param.yaml
+  ref: $options
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-withOptions-option.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-withOptions-option.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..681144f3a66f8a85e920c63b99e490831e139e40
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-withOptions-option.yaml	
@@ -0,0 +1,27 @@
+source:
+  file: apiargs-common-option.yaml
+  ref: readConcern
+replacement:
+  resource: "collection"
+  parent: "original collection"
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: readPreference
+replacement:
+  resource: "collection"
+  parent: "original collection"
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: typeMap
+replacement:
+  parent: "original collection"
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: writeConcern
+replacement:
+  resource: "collection"
+  parent: "original collection"
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-withOptions-param.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-withOptions-param.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..73ad04d0ba16b0e6efced8a891de73f14845c3d0
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBCollection-method-withOptions-param.yaml	
@@ -0,0 +1,4 @@
+source:
+  file: apiargs-common-param.yaml
+  ref: $options
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBDatabase-common-option.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBDatabase-common-option.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..69b4c13dadbe592a3bac7d9c992fa2a7a6fa8835
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBDatabase-common-option.yaml	
@@ -0,0 +1,39 @@
+arg_name: option
+name: readConcern
+type: :php:`MongoDB\\Driver\\ReadConcern <class.mongodb-driver-readconcern>`
+description: |
+   :manual:`Read concern </reference/read-concern>` to use for the operation.
+   Defaults to the database's read concern.
+
+   This is not supported for server versions prior to 3.2 and will result in an
+   exception at execution time if used.
+interface: phpmethod
+operation: ~
+optional: true
+---
+arg_name: option
+name: readPreference
+type: :php:`MongoDB\\Driver\\ReadPreference <class.mongodb-driver-readpreference>`
+description: |
+   :manual:`Read preference </reference/read-preference>` to use for the
+   operation. Defaults to the database's read preference.
+interface: phpmethod
+operation: ~
+optional: true
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: typeMap
+replacement:
+  parent: "database"
+---
+arg_name: option
+name: writeConcern
+type: :php:`MongoDB\\Driver\\WriteConcern <class.mongodb-driver-writeconcern>`
+description: |
+   :manual:`Write concern </reference/write-concern>` to use for the operation.
+   Defaults to the database's write concern.
+interface: phpmethod
+operation: ~
+optional: true
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBDatabase-method-aggregate-option.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBDatabase-method-aggregate-option.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..5d80f32aaf916a90f9ff56f2f68f740a37b7a287
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBDatabase-method-aggregate-option.yaml	
@@ -0,0 +1,54 @@
+source:
+  file: apiargs-aggregate-option.yaml
+  ref: allowDiskUse
+---
+source:
+  file: apiargs-aggregate-option.yaml
+  ref: batchSize
+---
+source:
+  file: apiargs-aggregate-option.yaml
+  ref: bypassDocumentValidation
+---
+source:
+  file: apiargs-aggregate-option.yaml
+  ref: comment
+---
+source:
+  file: apiargs-aggregate-option.yaml
+  ref: explain
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: hint
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: maxTimeMS
+---
+source:
+  file: apiargs-MongoDBDatabase-common-option.yaml
+  ref: readConcern
+---
+source:
+  file: apiargs-MongoDBDatabase-common-option.yaml
+  ref: readPreference
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: session
+---
+source:
+  file: apiargs-MongoDBDatabase-common-option.yaml
+  ref: typeMap
+---
+source:
+  file: apiargs-MongoDBDatabase-common-option.yaml
+  ref: writeConcern
+post: |
+  This only applies when a :ref:`$out <agg-out>` or :ref:`$merge <agg-merge>`
+  stage is specified.
+
+  This is not supported for server versions prior to 3.4 and will result in an
+  exception at execution time if used.
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBDatabase-method-aggregate-param.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBDatabase-method-aggregate-param.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..cbad3b49b0c834d8d496b649cdddcf379b2aa6e9
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBDatabase-method-aggregate-param.yaml	
@@ -0,0 +1,14 @@
+arg_name: param
+name: $pipeline
+type: array
+description: |
+  Specifies an :manual:`aggregation pipeline </core/aggregation-pipeline>`
+  operation.
+interface: phpmethod
+operation: ~
+optional: false
+---
+source:
+  file: apiargs-common-param.yaml
+  ref: $options
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBDatabase-method-command-option.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBDatabase-method-command-option.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..934e325db1168195884898b7fc513896c5a5aa2e
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBDatabase-method-command-option.yaml	
@@ -0,0 +1,17 @@
+source:
+  file: apiargs-common-option.yaml
+  ref: readPreference
+description: |
+   :manual:`Read preference </reference/read-preference>` to use for the
+   operation. Defaults to the database's read preference.
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: session
+post: |
+  .. versionadded:: 1.3
+---
+source:
+  file: apiargs-MongoDBDatabase-common-option.yaml
+  ref: typeMap
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBDatabase-method-command-param.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBDatabase-method-command-param.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..5a4b03d7bd484ee1e7cef74308e70276a20eb2ab
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBDatabase-method-command-param.yaml	
@@ -0,0 +1,13 @@
+arg_name: param
+name: $command
+type: array|object
+description: |
+  The :manual:`database command </reference/command>` document.
+interface: phpmethod
+operation: ~
+optional: false
+---
+source:
+  file: apiargs-common-param.yaml
+  ref: $options
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBDatabase-method-construct-option.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBDatabase-method-construct-option.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..d398069a8873be7f32188b69b2b82cbf3817ef97
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBDatabase-method-construct-option.yaml	
@@ -0,0 +1,25 @@
+source:
+  file: apiargs-common-option.yaml
+  ref: readConcern
+replacement:
+  resource: "database"
+  parent: "manager"
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: readPreference
+replacement:
+  resource: "database"
+  parent: "manager"
+---
+source:
+  file: apiargs-MongoDBClient-method-construct-driverOptions.yaml
+  ref: typeMap
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: writeConcern
+replacement:
+  resource: "database"
+  parent: "manager"
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBDatabase-method-construct-param.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBDatabase-method-construct-param.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..5ef826c175444b2b9ebac88b1789ac5c3e0cc7d6
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBDatabase-method-construct-param.yaml	
@@ -0,0 +1,12 @@
+source:
+  file: apiargs-common-param.yaml
+  ref: $manager
+---
+source:
+  file: apiargs-common-param.yaml
+  ref: $databaseName
+---
+source:
+  file: apiargs-common-param.yaml
+  ref: $options
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBDatabase-method-createCollection-option.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBDatabase-method-createCollection-option.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..76dbf405a705a490e838a059469c54df91325893
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBDatabase-method-createCollection-option.yaml	
@@ -0,0 +1,239 @@
+arg_name: option
+name: autoIndexId
+type: boolean
+description: |
+  Specify ``false`` to disable the automatic creation of an index on the ``_id``
+  field.
+
+  .. important::
+
+     For replica sets, do not set ``autoIndexId`` to ``false``.
+
+  .. deprecated:: 1.4
+     This option has been deprecated since MongoDB 3.2. As of MongoDB 4.0, this
+     option cannot be ``false`` when creating a replicated collection (i.e. a
+     collection outside of the ``local`` database in any mongod mode).
+interface: phpmethod
+operation: ~
+optional: true
+---
+arg_name: option
+name: capped
+type: boolean
+description: |
+  To create a capped collection, specify ``true``. If you specify ``true``, you
+  must also set a maximum size in the ``size`` option.
+interface: phpmethod
+operation: ~
+optional: true
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: collation
+pre: |
+  Specifies the :manual:`collation
+  </reference/bson-type-comparison-order/#collation>` for the collection.
+---
+arg_name: option
+name: flags
+type: integer
+description: |
+  Available for the MMAPv1 storage engine only to set the ``usePowerOf2Sizes``
+  and ``noPadding`` flags.
+
+  The |php-library| provides constants that you can combine with a :php:`bitwise
+  OR operator <language.operators.bitwise>` to set the flag values:
+
+  - ``MongoDB\Operation\CreateCollection::USE_POWER_OF_2_SIZES``: ``1``
+  - ``MongoDB\Operation\CreateCollection::NO_PADDING``: ``2``
+
+  Defaults to ``1``.
+
+  .. note::
+
+     MongoDB 3.0 and later ignores the ``usePowerOf2Sizes`` flag. See
+     :manual:`collMod </reference/command/collMod>` and
+     :manual:`db.createCollection()
+     </reference/method/db.createCollection>` for more information.
+interface: phpmethod
+operation: ~
+optional: true
+---
+arg_name: option
+name: indexOptionDefaults
+type: array|object
+description: |
+  Allows users to specify a default configuration for indexes when creating a
+  collection.
+
+  The ``indexOptionDefaults`` option accepts a ``storageEngine`` document,
+  which should take the following form::
+
+     { <storage-engine-name>: <options> }
+
+  Storage engine configurations specified when creating indexes are validated
+  and logged to the :term:`oplog` during replication to support replica sets
+  with members that use different storage engines.
+interface: phpmethod
+operation: ~
+optional: true
+---
+arg_name: option
+name: max
+type: integer
+description: |
+  The maximum number of documents allowed in the capped collection. The ``size``
+  option takes precedence over this limit. If a capped collection reaches the
+  ``size`` limit before it reaches the maximum number of documents, MongoDB
+  removes old documents. If you prefer to use the ``max`` limit, ensure that the
+  ``size`` limit, which is required for a capped collection, is sufficient to
+  contain the maximum number of documents.
+interface: phpmethod
+operation: ~
+optional: true
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: maxTimeMS
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: session
+post: |
+  .. versionadded:: 1.3
+---
+arg_name: option
+name: size
+type: integer
+description: |
+  Specify a maximum size in bytes for a capped collection. Once a capped
+  collection reaches its maximum size, MongoDB removes the older documents to
+  make space for the new documents. The ``size`` option is required for capped
+  collections and ignored for other collections.
+interface: phpmethod
+operation: ~
+optional: true
+---
+arg_name: option
+name: storageEngine
+type: array|object
+description: |
+  Available for the WiredTiger storage engine only.
+
+  Allows users to specify configuration to the storage engine on a
+  per-collection basis when creating a collection. The value of the
+  ``storageEngine`` option should take the following form::
+
+     { <storage-engine-name>: <options> }
+
+  Storage engine configurations specified when creating collections are
+  validated and logged to the :term:`oplog` during replication to support
+  replica sets with members that use different storage engines.
+interface: phpmethod
+operation: ~
+optional: true
+---
+source:
+  file: apiargs-MongoDBDatabase-common-option.yaml
+  ref: typeMap
+post: |
+  This will be used for the returned command result document.
+---
+arg_name: option
+name: validator
+type: array|object
+description: |
+  Allows users to specify :manual:`validation rules or expressions
+  </core/document-validation>` for the collection. For more information, see
+  :manual:`Document Validation </core/document-validation>` in the MongoDB
+  manual.
+
+  The ``validator`` option takes an array that specifies the validation rules or
+  expressions. You can specify the expressions using the same operators as
+  MongoDB's :manual:`query operators </reference/operator/query>` with the
+  exception of :query:`$geoNear`, :query:`$near`, :query:`$nearSphere`,
+  :query:`$text`, and :query:`$where`.
+
+  .. note::
+
+     - Validation occurs during updates and inserts. Existing documents do not
+       undergo validation checks until modification.
+
+     - You cannot specify a validator for collections in the ``admin``,
+       ``local``, and ``config`` databases.
+
+     - You cannot specify a validator for ``system.*`` collections.
+operation: ~
+interface: phpmethod
+optional: true
+---
+arg_name: option
+name: validationAction
+type: string
+description: |
+   Determines whether to ``error`` on invalid documents or just ``warn`` about
+   the violations but allow invalid documents to be inserted.
+
+   .. important::
+
+      Validation of documents only applies to those documents as determined by
+      the ``validationLevel``.
+
+   .. list-table::
+      :header-rows: 1
+
+      * - ``validationAction``
+
+        - Description
+
+      * - ``"error"``
+
+        - **Default**. Documents must pass validation before the write occurs.
+          Otherwise, the write operation fails.
+
+      * - ``"warn"``
+
+        - Documents do not have to pass validation. If the document fails
+          validation, the write operation logs the validation failure.
+interface: phpmethod
+operation: ~
+optional: true
+---
+arg_name: option
+name: validationLevel
+type: string
+description: |
+   Determines how strictly MongoDB applies the validation rules to existing
+   documents during an update.
+
+   .. list-table::
+      :header-rows: 1
+
+      * - ``validationLevel``
+
+        - Description
+
+      * - ``"off"``
+
+        - No validation for inserts or updates.
+
+      * - ``"strict"``
+
+        - **Default**. Apply validation rules to all inserts and all updates.
+
+      * - ``"moderate"``
+
+        - Apply validation rules to inserts and to updates on existing *valid*
+          documents. Do not apply rules to updates on existing *invalid*
+          documents.
+interface: phpmethod
+operation: ~
+optional: true
+---
+source:
+  file: apiargs-MongoDBDatabase-common-option.yaml
+  ref: writeConcern
+post: |
+  This is not supported for server versions prior to 3.4 and will result in an
+  exception at execution time if used.
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBDatabase-method-createCollection-param.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBDatabase-method-createCollection-param.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..b6bb2dccd669d3113492157d86ac0254389a5a0e
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBDatabase-method-createCollection-param.yaml	
@@ -0,0 +1,10 @@
+source:
+  file: apiargs-common-param.yaml
+  ref: $collectionName
+replacement:
+  action: " to create"
+---
+source:
+  file: apiargs-common-param.yaml
+  ref: $options
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBDatabase-method-drop-option.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBDatabase-method-drop-option.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..89969685772b629f7463ef0ec5c886884a237da4
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBDatabase-method-drop-option.yaml	
@@ -0,0 +1,19 @@
+source:
+  file: apiargs-common-option.yaml
+  ref: session
+post: |
+  .. versionadded:: 1.3
+---
+source:
+  file: apiargs-MongoDBDatabase-common-option.yaml
+  ref: typeMap
+post: |
+  This will be used for the returned command result document.
+---
+source:
+  file: apiargs-MongoDBDatabase-common-option.yaml
+  ref: writeConcern
+post: |
+  This is not supported for server versions prior to 3.4 and will result in an
+  exception at execution time if used.
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBDatabase-method-drop-param.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBDatabase-method-drop-param.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..73ad04d0ba16b0e6efced8a891de73f14845c3d0
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBDatabase-method-drop-param.yaml	
@@ -0,0 +1,4 @@
+source:
+  file: apiargs-common-param.yaml
+  ref: $options
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBDatabase-method-dropCollection-option.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBDatabase-method-dropCollection-option.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..89969685772b629f7463ef0ec5c886884a237da4
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBDatabase-method-dropCollection-option.yaml	
@@ -0,0 +1,19 @@
+source:
+  file: apiargs-common-option.yaml
+  ref: session
+post: |
+  .. versionadded:: 1.3
+---
+source:
+  file: apiargs-MongoDBDatabase-common-option.yaml
+  ref: typeMap
+post: |
+  This will be used for the returned command result document.
+---
+source:
+  file: apiargs-MongoDBDatabase-common-option.yaml
+  ref: writeConcern
+post: |
+  This is not supported for server versions prior to 3.4 and will result in an
+  exception at execution time if used.
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBDatabase-method-dropCollection-param.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBDatabase-method-dropCollection-param.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..c8e0a614e7125f9951a8af44b3dafa15169c2b52
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBDatabase-method-dropCollection-param.yaml	
@@ -0,0 +1,10 @@
+source:
+  file: apiargs-common-param.yaml
+  ref: $collectionName
+replacement:
+  action: " to drop"
+---
+source:
+  file: apiargs-common-param.yaml
+  ref: $options
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBDatabase-method-get-param.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBDatabase-method-get-param.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..651c85f949840464c61dd40ce6e8001eeeaaffec
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBDatabase-method-get-param.yaml	
@@ -0,0 +1,6 @@
+source:
+  file: apiargs-common-param.yaml
+  ref: $collectionName
+replacement:
+  action: " to select"
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBDatabase-method-listCollections-option.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBDatabase-method-listCollections-option.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..0d9ab968d2ca7823b1936949f69c56a990702d9e
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBDatabase-method-listCollections-option.yaml	
@@ -0,0 +1,22 @@
+arg_name: option
+name: filter
+type: array|object
+description: |
+  A query expression to filter the list of collections.
+
+  You can specify a query expression for collection fields (e.g. ``name``,
+  ``options``).
+interface: phpmethod
+operation: ~
+optional: true
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: maxTimeMS
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: session
+post: |
+  .. versionadded:: 1.3
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBDatabase-method-listCollections-param.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBDatabase-method-listCollections-param.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..73ad04d0ba16b0e6efced8a891de73f14845c3d0
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBDatabase-method-listCollections-param.yaml	
@@ -0,0 +1,4 @@
+source:
+  file: apiargs-common-param.yaml
+  ref: $options
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBDatabase-method-modifyCollection-option.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBDatabase-method-modifyCollection-option.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..ca8d6fef12e5a74041bc32dfdc44f5cd16fa9323
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBDatabase-method-modifyCollection-option.yaml	
@@ -0,0 +1,14 @@
+source:
+  file: apiargs-common-option.yaml
+  ref: session
+---
+source:
+  file: apiargs-MongoDBDatabase-common-option.yaml
+  ref: typeMap
+post: |
+  This will be used for the returned command result document.
+---
+source:
+  file: apiargs-MongoDBDatabase-common-option.yaml
+  ref: writeConcern
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBDatabase-method-modifyCollection-param.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBDatabase-method-modifyCollection-param.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..16597b3af8de2355afd65d79330f30f3bcce10e5
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBDatabase-method-modifyCollection-param.yaml	
@@ -0,0 +1,20 @@
+source:
+  file: apiargs-common-param.yaml
+  ref: $collectionName
+replacement:
+  subject: "collection or view"
+  action: " to modify"
+---
+arg_name: param
+name: $collectionOptions
+type: array
+description: |
+  Collection or view options to assign.
+interface: phpmethod
+operation: ~
+optional: false
+---
+source:
+  file: apiargs-common-param.yaml
+  ref: $options
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBDatabase-method-selectCollection-option.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBDatabase-method-selectCollection-option.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..932c1b16ba0e055f43424ba0bc6e247d38e8cf6f
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBDatabase-method-selectCollection-option.yaml	
@@ -0,0 +1,27 @@
+source:
+  file: apiargs-common-option.yaml
+  ref: readConcern
+replacement:
+  resource: "collection"
+  parent: "database"
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: readPreference
+replacement:
+  resource: "collection"
+  parent: "database"
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: typeMap
+replacement:
+  parent: "database"
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: writeConcern
+replacement:
+  resource: "collection"
+  parent: "database"
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBDatabase-method-selectCollection-param.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBDatabase-method-selectCollection-param.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..46d4e72a6322801f8f79b16545991a3330f37909
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBDatabase-method-selectCollection-param.yaml	
@@ -0,0 +1,10 @@
+source:
+  file: apiargs-common-param.yaml
+  ref: $collectionName
+replacement:
+  action: " to select"
+---
+source:
+  file: apiargs-common-param.yaml
+  ref: $options
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBDatabase-method-selectGridFSBucket-option.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBDatabase-method-selectGridFSBucket-option.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..2039d114a20418eb16f5254493ff79680245db6e
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBDatabase-method-selectGridFSBucket-option.yaml	
@@ -0,0 +1,52 @@
+arg_name: option
+name: bucketName
+type: string
+description: |
+  The bucket name, which will be used as a prefix for the files and chunks
+  collections. Defaults to ``"fs"``.
+interface: phpmethod
+operation: ~
+optional: true
+---
+arg_name: option
+name: chunkSizeBytes
+type: integer
+description: |
+  The chunk size in bytes. Defaults to ``261120`` (i.e. 255 KiB).
+interface: phpmethod
+operation: ~
+optional: true
+---
+source:
+  file: apiargs-MongoDBGridFSBucket-common-option.yaml
+  ref: disableMD5
+post: |
+  .. versionadded: 1.4
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: readConcern
+replacement:
+  resource: "bucket"
+  parent: "database"
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: readPreference
+replacement:
+  resource: "bucket"
+  parent: "database"
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: typeMap
+replacement:
+  parent: "database"
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: writeConcern
+replacement:
+  resource: "bucket"
+  parent: "database"
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBDatabase-method-selectGridFSBucket-param.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBDatabase-method-selectGridFSBucket-param.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..73ad04d0ba16b0e6efced8a891de73f14845c3d0
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBDatabase-method-selectGridFSBucket-param.yaml	
@@ -0,0 +1,4 @@
+source:
+  file: apiargs-common-param.yaml
+  ref: $options
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBDatabase-method-watch-option.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBDatabase-method-watch-option.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..b1ad02793a9de2af18b5b753be8bd252fdc1d274
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBDatabase-method-watch-option.yaml	
@@ -0,0 +1,50 @@
+---
+source:
+  file: apiargs-method-watch-option.yaml
+  ref: batchSize
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: collation
+---
+source:
+  file: apiargs-method-watch-option.yaml
+  ref: fullDocument
+---
+source:
+  file: apiargs-method-watch-option.yaml
+  ref: maxAwaitTimeMS
+---
+source:
+  file: apiargs-MongoDBDatabase-common-option.yaml
+  ref: readConcern
+---
+source:
+  file: apiargs-MongoDBDatabase-common-option.yaml
+  ref: readPreference
+post: |
+  This is used for both the initial change stream aggregation and for
+  server selection during an automatic resume.
+---
+source:
+  file: apiargs-method-watch-option.yaml
+  ref: resumeAfter
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: session
+---
+source:
+  file: apiargs-method-watch-option.yaml
+  ref: startAfter
+post: |
+  .. versionadded: 1.5
+---
+source:
+  file: apiargs-method-watch-option.yaml
+  ref: startAtOperationTime
+---
+source:
+  file: apiargs-MongoDBDatabase-common-option.yaml
+  ref: typeMap
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBDatabase-method-watch-param.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBDatabase-method-watch-param.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..b00e450cfcd51e23d4bfe4d8126c59eb1e570182
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBDatabase-method-watch-param.yaml	
@@ -0,0 +1,8 @@
+source:
+  file: apiargs-method-watch-param.yaml
+  ref: $pipeline
+---
+source:
+  file: apiargs-method-watch-param.yaml
+  ref: $options
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBDatabase-method-withOptions-option.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBDatabase-method-withOptions-option.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..c048182c1751d76c6bab2708e4ddef0d9d793747
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBDatabase-method-withOptions-option.yaml	
@@ -0,0 +1,27 @@
+source:
+  file: apiargs-common-option.yaml
+  ref: readConcern
+replacement:
+  resource: "database"
+  parent: "original database"
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: readPreference
+replacement:
+  resource: "database"
+  parent: "original database"
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: typeMap
+replacement:
+  parent: "original database"
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: writeConcern
+replacement:
+  resource: "database"
+  parent: "original database"
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBDatabase-method-withOptions-param.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBDatabase-method-withOptions-param.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..73ad04d0ba16b0e6efced8a891de73f14845c3d0
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBDatabase-method-withOptions-param.yaml	
@@ -0,0 +1,4 @@
+source:
+  file: apiargs-common-param.yaml
+  ref: $options
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBGridFSBucket-common-option.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBGridFSBucket-common-option.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..bf2de660ac9cf7f4b13ab4684624cd6d2ebe524e
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBGridFSBucket-common-option.yaml	
@@ -0,0 +1,61 @@
+arg_name: option
+name: _id
+type: mixed
+description: |
+  Value to use as the file document identifier. Defaults to a new
+  :php:`MongoDB\\BSON\\ObjectId <class.mongodb-bson-objectid>` object.
+interface: phpmethod
+operation: ~
+optional: true
+---
+arg_name: option
+name: chunkSizeBytes
+type: integer
+description: |
+  The chunk size in bytes. Defaults to the bucket's ``chunkSizeBytes`` option.
+interface: phpmethod
+operation: ~
+optional: true
+---
+arg_name: option
+name: disableMD5
+type: boolean
+description: |
+  Whether to disable automatic MD5 generation when storing files.
+
+  Defaults to ``false``.
+interface: phpmethod
+operation: ~
+optional: true
+---
+arg_name: option
+name: metadata
+type: array|object
+description: |
+  User data for the ``metadata`` field of the file document. If not specified,
+  the ``metadata`` field will not be set on the file document.
+interface: phpmethod
+operation: ~
+optional: true
+---
+arg_name: option
+name: revision
+type: integer
+description: |
+  The revision of the file to retrieve. Files with the name ``filename`` will be
+  differentiated by their ``uploadDate`` field.
+
+  Revision numbers are defined as follows:
+
+  - 0 = the original stored file
+  - 1 = the first revision
+  - 2 = the second revision
+  - etc...
+  - -2 = the second most recent revision
+  - -1 = the most recent revision
+
+   Defaults to -1 (i.e. the most recent revision).
+interface: phpmethod
+operation: ~
+optional: true
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBGridFSBucket-common-param.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBGridFSBucket-common-param.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..f1d6b136a8e1e1a2c695143c10afb5e50bad06e6
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBGridFSBucket-common-param.yaml	
@@ -0,0 +1,39 @@
+arg_name: param
+name: $filename
+type: string
+description: |
+  The ``filename`` of the file{{action}}.
+interface: phpmethod
+operation: ~
+optional: false
+replacement:
+  action: ""
+---
+arg_name: param
+name: $id
+type: mixed
+description: |
+  The ``_id`` of the file{{action}}.
+interface: phpmethod
+operation: ~
+optional: false
+replacement:
+  action: ""
+---
+arg_name: param
+name: $stream
+type: resource
+description: |
+  The GridFS stream resource.
+interface: phpmethod
+operation: ~
+---
+arg_name: param
+name: $destination
+type: resource
+description: |
+  Writable stream, to which the GridFS file's contents will be written.
+interface: phpmethod
+operation: ~
+optional: false
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBGridFSBucket-method-construct-option.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBGridFSBucket-method-construct-option.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..c8a7eb795e1f57eaddb0578d072bc14ff4809cfa
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBGridFSBucket-method-construct-option.yaml	
@@ -0,0 +1,50 @@
+arg_name: option
+name: bucketName
+type: string
+description: |
+  The bucket name, which will be used as a prefix for the files and chunks
+  collections. Defaults to ``"fs"``.
+interface: phpmethod
+operation: ~
+optional: true
+---
+arg_name: option
+name: chunkSizeBytes
+type: integer
+description: |
+  The chunk size in bytes. Defaults to ``261120`` (i.e. 255 KiB).
+interface: phpmethod
+operation: ~
+optional: true
+---
+source:
+  file: apiargs-MongoDBGridFSBucket-common-option.yaml
+  ref: disableMD5
+post: |
+  .. versionadded: 1.4
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: readConcern
+replacement:
+  resource: "bucket"
+  parent: "database"
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: readPreference
+replacement:
+  resource: "bucket"
+  parent: "database"
+---
+source:
+  file: apiargs-MongoDBClient-method-construct-driverOptions.yaml
+  ref: typeMap
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: writeConcern
+replacement:
+  resource: "bucket"
+  parent: "database"
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBGridFSBucket-method-construct-param.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBGridFSBucket-method-construct-param.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..5ef826c175444b2b9ebac88b1789ac5c3e0cc7d6
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBGridFSBucket-method-construct-param.yaml	
@@ -0,0 +1,12 @@
+source:
+  file: apiargs-common-param.yaml
+  ref: $manager
+---
+source:
+  file: apiargs-common-param.yaml
+  ref: $databaseName
+---
+source:
+  file: apiargs-common-param.yaml
+  ref: $options
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBGridFSBucket-method-delete-param.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBGridFSBucket-method-delete-param.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..7e8baa214420494e3ae9a9bbed00339cc51475d9
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBGridFSBucket-method-delete-param.yaml	
@@ -0,0 +1,6 @@
+source:
+  file: apiargs-MongoDBGridFSBucket-common-param.yaml
+  ref: $id
+replacement:
+  resource: " to delete"
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBGridFSBucket-method-downloadToStream-param.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBGridFSBucket-method-downloadToStream-param.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..39d48dc5da6dabdaccfae9d60b8d78353b03e13c
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBGridFSBucket-method-downloadToStream-param.yaml	
@@ -0,0 +1,10 @@
+source:
+  file: apiargs-MongoDBGridFSBucket-common-param.yaml
+  ref: $id
+replacement:
+  resource: " to download"
+---
+source:
+  file: apiargs-MongoDBGridFSBucket-common-param.yaml
+  ref: $destination
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBGridFSBucket-method-downloadToStreamByName-option.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBGridFSBucket-method-downloadToStreamByName-option.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..9dc941d97354a9c9997ef7baeefa6c681e644b3e
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBGridFSBucket-method-downloadToStreamByName-option.yaml	
@@ -0,0 +1,4 @@
+source:
+  file: apiargs-MongoDBGridFSBucket-common-option.yaml
+  ref: revision
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBGridFSBucket-method-downloadToStreamByName-param.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBGridFSBucket-method-downloadToStreamByName-param.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..2704877be2c3a8d807531ac28f34a93d650e3c0f
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBGridFSBucket-method-downloadToStreamByName-param.yaml	
@@ -0,0 +1,14 @@
+source:
+  file: apiargs-MongoDBGridFSBucket-common-param.yaml
+  ref: $filename
+replacement:
+  resource: " to download"
+---
+source:
+  file: apiargs-MongoDBGridFSBucket-common-param.yaml
+  ref: $destination
+---
+source:
+  file: apiargs-common-param.yaml
+  ref: $options
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBGridFSBucket-method-find-option.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBGridFSBucket-method-find-option.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..1f2e9d8eb3671b287a15bbddc0f94dd8a5af3334
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBGridFSBucket-method-find-option.yaml	
@@ -0,0 +1,76 @@
+source:
+  file: apiargs-MongoDBCollection-method-find-option.yaml
+  ref: projection
+---
+source:
+  file: apiargs-MongoDBCollection-method-find-option.yaml
+  ref: sort
+---
+source:
+  file: apiargs-MongoDBCollection-method-find-option.yaml
+  ref: skip
+---
+source:
+  file: apiargs-MongoDBCollection-method-find-option.yaml
+  ref: limit
+---
+source:
+  file: apiargs-MongoDBCollection-method-find-option.yaml
+  ref: allowDiskUse
+---
+source:
+  file: apiargs-MongoDBCollection-method-find-option.yaml
+  ref: batchSize
+---
+source:
+  file: apiargs-MongoDBCollection-method-find-option.yaml
+  ref: collation
+---
+source:
+  file: apiargs-MongoDBCollection-method-find-option.yaml
+  ref: comment
+---
+source:
+  file: apiargs-MongoDBCollection-method-find-option.yaml
+  ref: cursorType
+---
+source:
+  file: apiargs-MongoDBCollection-method-find-option.yaml
+  ref: maxTimeMS
+---
+source:
+  file: apiargs-MongoDBCollection-method-find-option.yaml
+  ref: readConcern
+description: |
+   :manual:`Read concern </reference/read-concern>` to use for the operation.
+   Defaults to the bucket's read concern.
+---
+source:
+  file: apiargs-MongoDBCollection-method-find-option.yaml
+  ref: readPreference
+description: |
+   :manual:`Read preference </reference/read-preference>` to use for the
+   operation. Defaults to the bucket's read preference.
+---
+source:
+  file: apiargs-MongoDBCollection-method-find-option.yaml
+  ref: oplogReplay
+---
+source:
+  file: apiargs-MongoDBCollection-method-find-option.yaml
+  ref: noCursorTimeout
+---
+source:
+  file: apiargs-MongoDBCollection-method-find-option.yaml
+  ref: allowPartialResults
+---
+source:
+  file: apiargs-MongoDBCollection-method-find-option.yaml
+  ref: typeMap
+replacement:
+  parent: "bucket"
+---
+source:
+  file: apiargs-MongoDBCollection-method-find-option.yaml
+  ref: modifiers
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBGridFSBucket-method-findOne-option.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBGridFSBucket-method-findOne-option.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..3d0d0ed8e6d384e1b598037875e1fc2032030f8b
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBGridFSBucket-method-findOne-option.yaml	
@@ -0,0 +1,46 @@
+source:
+  file: apiargs-MongoDBCollection-method-find-option.yaml
+  ref: projection
+---
+source:
+  file: apiargs-MongoDBCollection-method-find-option.yaml
+  ref: sort
+---
+source:
+  file: apiargs-MongoDBCollection-method-find-option.yaml
+  ref: skip
+---
+source:
+  file: apiargs-MongoDBCollection-method-find-option.yaml
+  ref: allowDiskUse
+---
+source:
+  file: apiargs-MongoDBCollection-common-option.yaml
+  ref: collation
+---
+source:
+  file: apiargs-MongoDBCollection-method-find-option.yaml
+  ref: comment
+---
+source:
+  file: apiargs-common-option.yaml
+  ref: maxTimeMS
+---
+source:
+  file: apiargs-MongoDBCollection-method-find-option.yaml
+  ref: readConcern
+---
+source:
+  file: apiargs-MongoDBGridFSBucket-method-find-option.yaml
+  ref: readPreference
+---
+source:
+  file: apiargs-MongoDBGridFSBucket-method-find-option.yaml
+  ref: typeMap
+post: |
+  This will be used for the returned result document.
+---
+source:
+  file: apiargs-MongoDBCollection-method-find-option.yaml
+  ref: modifiers
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBGridFSBucket-method-getFileDocumentForStream-param.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBGridFSBucket-method-getFileDocumentForStream-param.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..0801cb21d716912347a01035158ac045d866b25e
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBGridFSBucket-method-getFileDocumentForStream-param.yaml	
@@ -0,0 +1,4 @@
+source:
+  file: apiargs-MongoDBGridFSBucket-common-param.yaml
+  ref: $stream
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBGridFSBucket-method-getFileIdForStream-param.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBGridFSBucket-method-getFileIdForStream-param.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..0801cb21d716912347a01035158ac045d866b25e
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBGridFSBucket-method-getFileIdForStream-param.yaml	
@@ -0,0 +1,4 @@
+source:
+  file: apiargs-MongoDBGridFSBucket-common-param.yaml
+  ref: $stream
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBGridFSBucket-method-openDownloadStream-param.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBGridFSBucket-method-openDownloadStream-param.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..54e7c8c211acf7665fd2019b3e2d13e0faf568e6
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBGridFSBucket-method-openDownloadStream-param.yaml	
@@ -0,0 +1,6 @@
+source:
+  file: apiargs-MongoDBGridFSBucket-common-param.yaml
+  ref: $id
+replacement:
+  resource: " to download"
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBGridFSBucket-method-openDownloadStreamByName-option.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBGridFSBucket-method-openDownloadStreamByName-option.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..9dc941d97354a9c9997ef7baeefa6c681e644b3e
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBGridFSBucket-method-openDownloadStreamByName-option.yaml	
@@ -0,0 +1,4 @@
+source:
+  file: apiargs-MongoDBGridFSBucket-common-option.yaml
+  ref: revision
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBGridFSBucket-method-openDownloadStreamByName-param.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBGridFSBucket-method-openDownloadStreamByName-param.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..eb8ec932cc06265b5a059701438862fbf20c0751
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBGridFSBucket-method-openDownloadStreamByName-param.yaml	
@@ -0,0 +1,10 @@
+source:
+  file: apiargs-MongoDBGridFSBucket-common-param.yaml
+  ref: $filename
+replacement:
+  resource: " to download"
+---
+source:
+  file: apiargs-common-param.yaml
+  ref: $options
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBGridFSBucket-method-openUploadStream-option.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBGridFSBucket-method-openUploadStream-option.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..592040d6952763e4b79a7c8b9f09fb10a558c765
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBGridFSBucket-method-openUploadStream-option.yaml	
@@ -0,0 +1,18 @@
+source:
+  file: apiargs-MongoDBGridFSBucket-common-option.yaml
+  ref: _id
+---
+source:
+  file: apiargs-MongoDBGridFSBucket-common-option.yaml
+  ref: chunkSizeBytes
+---
+source:
+  file: apiargs-MongoDBGridFSBucket-common-option.yaml
+  ref: disableMD5
+post: |
+  .. versionadded: 1.4
+---
+source:
+  file: apiargs-MongoDBGridFSBucket-common-option.yaml
+  ref: metadata
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBGridFSBucket-method-openUploadStream-param.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBGridFSBucket-method-openUploadStream-param.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..6b8efb34785438033d788ce940ad062fb8c06892
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBGridFSBucket-method-openUploadStream-param.yaml	
@@ -0,0 +1,10 @@
+source:
+  file: apiargs-MongoDBGridFSBucket-common-param.yaml
+  ref: $filename
+replacement:
+  resource: " to create"
+---
+source:
+  file: apiargs-common-param.yaml
+  ref: $options
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBGridFSBucket-method-rename-param.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBGridFSBucket-method-rename-param.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..e1b140aea92a9aedc14591a81d2daed05113eb5f
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBGridFSBucket-method-rename-param.yaml	
@@ -0,0 +1,15 @@
+source:
+  file: apiargs-MongoDBGridFSBucket-common-param.yaml
+  ref: $id
+replacement:
+  resource: " to rename"
+---
+arg_name: param
+name: $newFilename
+type: string
+description: |
+  The new ``filename`` value.
+interface: phpmethod
+operation: ~
+optional: false
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBGridFSBucket-method-uploadFromStream-option.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBGridFSBucket-method-uploadFromStream-option.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..592040d6952763e4b79a7c8b9f09fb10a558c765
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBGridFSBucket-method-uploadFromStream-option.yaml	
@@ -0,0 +1,18 @@
+source:
+  file: apiargs-MongoDBGridFSBucket-common-option.yaml
+  ref: _id
+---
+source:
+  file: apiargs-MongoDBGridFSBucket-common-option.yaml
+  ref: chunkSizeBytes
+---
+source:
+  file: apiargs-MongoDBGridFSBucket-common-option.yaml
+  ref: disableMD5
+post: |
+  .. versionadded: 1.4
+---
+source:
+  file: apiargs-MongoDBGridFSBucket-common-option.yaml
+  ref: metadata
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBGridFSBucket-method-uploadFromStream-param.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBGridFSBucket-method-uploadFromStream-param.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..48fa2db4c1795f6e8e139740cd3f9c24fffab753
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-MongoDBGridFSBucket-method-uploadFromStream-param.yaml	
@@ -0,0 +1,19 @@
+source:
+  file: apiargs-MongoDBGridFSBucket-common-param.yaml
+  ref: $filename
+replacement:
+  resource: " to create"
+---
+arg_name: param
+name: $source
+type: resource
+description: |
+  Readable stream, from which the new GridFS file's contents will be read.
+interface: phpmethod
+operation: ~
+optional: false
+---
+source:
+  file: apiargs-common-param.yaml
+  ref: $options
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-aggregate-option.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-aggregate-option.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..3de7a09dbc39f873077204a5be65535bb5f53a18
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-aggregate-option.yaml	
@@ -0,0 +1,52 @@
+arg_name: option
+name: allowDiskUse
+type: boolean
+description: |
+  Enables writing to temporary files. When set to ``true``, aggregation stages
+  can write data to the ``_tmp`` sub-directory in the ``dbPath`` directory. The
+  default is ``false``.
+interface: phpmethod
+operation: ~
+optional: true
+---
+arg_name: option
+name: batchSize
+type: integer
+description: |
+  Specifies the initial batch size for the cursor. A batchSize of ``0`` means an
+  empty first batch and is useful for quickly returning a cursor or failure
+  message without doing significant server-side work.
+interface: phpmethod
+operation: ~
+optional: true
+---
+source:
+  file: apiargs-MongoDBCollection-common-option.yaml
+  ref: bypassDocumentValidation
+post: |
+  This only applies when using the :ref:`$out <agg-out>` and
+  :ref:`$out <agg-merge>` stages.
+
+  Document validation requires MongoDB 3.2 or later: if you are using an earlier
+  version of MongoDB, this option will be ignored.
+---
+arg_name: option
+name: comment
+type: string
+description: |
+  Users can specify an arbitrary string to help trace the operation through the
+  database profiler, currentOp, and logs.
+interface: phpmethod
+operation: ~
+optional: true
+---
+arg_name: option
+name: explain
+type: boolean
+description: |
+  Specifies whether or not to return the information on the processing of the
+  pipeline.
+interface: phpmethod
+operation: ~
+optional: true
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-common-option.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-common-option.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..41f918205969019f845ebc9f5b34d1db7084a390
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-common-option.yaml	
@@ -0,0 +1,103 @@
+arg_name: option
+name: collation
+type: array|object
+description: |
+   :manual:`Collation </reference/collation>` allows users to specify
+   language-specific rules for string comparison, such as rules for lettercase
+   and accent marks. When specifying collation, the ``locale`` field is
+   mandatory; all other collation fields are optional. For descriptions of the
+   fields, see :manual:`Collation Document
+   </reference/collation/#collation-document>`.
+
+   This option is available in MongoDB 3.4+ and will result in an exception at
+   execution time if specified for an older server version.
+interface: phpmethod
+operation: ~
+optional: true
+---
+arg_name: option
+name: hint
+type: string|array|object
+description: |
+  The index to use. Specify either the index name as a string or the index key
+  pattern as a document. If specified, then the query system will only consider
+  plans using the hinted index.
+interface: phpmethod
+operation: ~
+optional: true
+---
+arg_name: option
+name: maxTimeMS
+type: integer
+description: |
+   The cumulative time limit in milliseconds for processing operations on the
+   cursor. MongoDB aborts the operation at the earliest following
+   :term:`interrupt point`.
+interface: phpmethod
+operation: ~
+optional: true
+---
+arg_name: option
+name: readConcern
+type: :php:`MongoDB\\Driver\\ReadConcern <class.mongodb-driver-readconcern>`
+description: |
+  The default read concern to use for {{resource}} operations. Defaults to the
+  {{parent}}'s read concern.
+interface: phpmethod
+operation: ~
+optional: true
+replacement:
+  resource: "collection"
+  parent: "client"
+---
+arg_name: option
+name: readPreference
+type: :php:`MongoDB\\Driver\\ReadPreference <class.mongodb-driver-readpreference>`
+description: |
+  The default read preference to use for {{resource}} operations. Defaults to
+  the {{parent}}'s read preference.
+interface: phpmethod
+operation: ~
+optional: true
+replacement:
+  resource: "collection"
+  parent: "client"
+---
+arg_name: option
+name: session
+type: :php:`MongoDB\\Driver\\Session <class.mongodb-driver-session>`
+description: |
+  Client session to associate with the operation.
+
+  Sessions are not supported for server versions prior to 3.6.
+interface: phpmethod
+operation: ~
+optional: true
+---
+arg_name: option
+name: typeMap
+type: array
+description: |
+  The :php:`type map
+  <manual/en/mongodb.persistence.deserialization.php#mongodb.persistence.typemaps>`
+  to apply to cursors, which determines how BSON documents are converted to PHP
+  values. Defaults to the {{parent}}'s type map.
+interface: phpmethod
+operation: ~
+optional: true
+replacement:
+  parent: "client"
+---
+arg_name: option
+name: writeConcern
+type: :php:`MongoDB\\Driver\\WriteConcern <class.mongodb-driver-writeconcern>`
+description: |
+  The default write concern to use for {{resource}} operations. Defaults
+  to the {{parent}}'s write concern.
+interface: phpmethod
+operation: ~
+optional: true
+replacement:
+  resource: "collection"
+  parent: "client"
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-common-param.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-common-param.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..a8d7908255c5df04e93f0f60fa231cd4d24b5737
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-common-param.yaml	
@@ -0,0 +1,42 @@
+arg_name: param
+name: $manager
+type: :php:`MongoDB\\Driver\\Manager <class.mongodb-driver-manager>`
+description: |
+  The :php:`Manager <mongodb-driver-manager>` instance from the driver. The
+  manager maintains connections between the driver and your MongoDB instances.
+interface: phpmethod
+operation: ~
+optional: false
+---
+arg_name: param
+name: $databaseName
+type: string
+description: |
+  The name of the database{{action}}.
+interface: phpmethod
+operation: ~
+optional: false
+replacement:
+  action: ""
+---
+arg_name: param
+name: $collectionName
+type: string
+description: |
+  The name of the {{subject}}{{action}}.
+interface: phpmethod
+operation: ~
+optional: false
+replacement:
+  subject: "collection"
+  action: ""
+---
+arg_name: param
+name: $options
+type: array
+description: |
+  An array specifying the desired options.
+interface: phpmethod
+operation: ~
+optional: true
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-function-with_transaction-param.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-function-with_transaction-param.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..78875e913395c3937da622e5657800c138508bba
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-function-with_transaction-param.yaml	
@@ -0,0 +1,31 @@
+arg_name: param
+name: $session
+type: :php:`MongoDB\\Driver\\Session <mongodb-driver-session>`
+description: |
+  A client session used to execute the transaction.
+interface: phpmethod
+operation: ~
+optional: false
+---
+arg_name: param
+name: $callback
+type: callback
+description: |
+  A callback that will be run inside the transaction. The callback must accept a
+  :php:`MongoDB\\Driver\\Session <mongodb-driver-session>` object as first
+  argument.
+interface: phpmethod
+operation: ~
+optional: false
+---
+arg_name: param
+name: $transactionOptions
+type: array
+description: |
+  Transaction options, which will be passed to
+  :php:`MongoDB\\Driver\\Session::startTransaction <mongodb-driver-session.starttransaction>`.
+  See the extension documentation for a list of supported options.
+interface: phpmethod
+operation: ~
+optional: true
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-method-watch-option.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-method-watch-option.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..89887884f73199e99b2bf059c67ea2c0d4102907
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-method-watch-option.yaml	
@@ -0,0 +1,105 @@
+---
+arg_name: option
+name: batchSize
+type: integer
+description: |
+  Specifies the maximum number of change events to return in each batch of the
+  response from the MongoDB cluster.
+interface: phpmethod
+operation: ~
+optional: true
+---
+arg_name: option
+name: fullDocument
+type: string
+description: |
+  Allowed values are 'default' and 'updateLookup'. Defaults to 'default'.
+  When set to 'updateLookup', the change notification for partial updates will
+  include both a delta describing the changes to the document, as well as a
+  copy of the entire document that was changed from some time after the change
+  occurred. The following values are supported:
+
+  - ``MongoDB\Operation\Watch::FULL_DOCUMENT_DEFAULT`` (*default*)
+  - ``MongoDB\Operation\Watch::FULL_DOCUMENT_UPDATE_LOOKUP``
+
+  .. note::
+
+     This is an option of the ``$changeStream`` pipeline stage.
+interface: phpmethod
+operation: ~
+optional: true
+---
+arg_name: option
+name: maxAwaitTimeMS
+type: integer
+description: |
+  Positive integer denoting the time limit in milliseconds for the server to
+  block a getMore operation if no data is available.
+interface: phpmethod
+operation: ~
+optional: true
+---
+arg_name: option
+name: resumeAfter
+type: array|object
+description: |
+  Specifies the logical starting point for the new change stream. The ``_id``
+  field in documents returned by the change stream may be used here.
+
+  Using this option in conjunction with ``startAfter`` and/or
+  ``startAtOperationTime`` will result in a server error. The options are
+  mutually exclusive.
+
+  .. note::
+
+     This is an option of the ``$changeStream`` pipeline stage.
+interface: phpmethod
+operation: ~
+optional: true
+---
+arg_name: option
+name: startAfter
+type: array|object
+description: |
+  Specifies the logical starting point for the new change stream. The ``_id``
+  field in documents returned by the change stream may be used here. Unlike
+  ``resumeAfter``, this option can be used with a resume token from an
+  "invalidate" event.
+
+  Using this option in conjunction with ``resumeAfter`` and/or
+  ``startAtOperationTime`` will result in a server error. The options are
+  mutually exclusive.
+
+  This is not supported for server versions prior to 4.2 and will result in an
+  exception at execution time if used.
+
+  .. note::
+
+     This is an option of the ``$changeStream`` pipeline stage.
+interface: phpmethod
+operation: ~
+optional: true
+---
+arg_name: option
+name: startAtOperationTime
+type: :php:`MongoDB\\BSON\\TimestampInterface <class.mongodb-bson-timestampinterface>`
+description: |
+  If specified, the change stream will only provide changes that occurred at or
+  after the specified timestamp. Command responses from a MongoDB 4.0+ server
+  include an ``operationTime`` that can be used here. By default, the
+  ``operationTime`` returned by the initial ``aggregate`` command will be used
+  if available.
+
+  Using this option in conjunction with ``resumeAfter`` and/or ``startAfter``
+  will result in a server error. The options are mutually exclusive.
+
+  This is not supported for server versions prior to 4.0 and will result in an
+  exception at execution time if used.
+
+  .. note::
+
+     This is an option of the ``$changeStream`` pipeline stage.
+interface: phpmethod
+operation: ~
+optional: true
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-method-watch-param.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-method-watch-param.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..e0da852c46feef8c7e50f2f91df73f0a1fdd7efc
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/apiargs-method-watch-param.yaml	
@@ -0,0 +1,13 @@
+arg_name: param
+name: $pipeline
+type: array|object
+description: |
+  The pipeline of stages to append to an initial ``$changeStream`` stage.
+interface: phpmethod
+operation: ~
+optional: true
+---
+source:
+  file: apiargs-common-param.yaml
+  ref: $options
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/extracts-bulkwriteexception.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/extracts-bulkwriteexception.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..f002063f08ad69947d950ca3afc04cdead250e02
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/extracts-bulkwriteexception.yaml	
@@ -0,0 +1,21 @@
+ref: bulkwriteexception-result
+content: |
+  If a :php:`MongoDB\\Driver\\Exception\\BulkWriteException
+  <mongodb-driver-exception-bulkwriteexception>` is thrown, users should call
+  :php:`getWriteResult() <mongodb-driver-writeexception.getwriteresult>` and
+  inspect the returned :php:`MongoDB\\Driver\\WriteResult
+  <mongodb-driver-writeresult>` object to determine the nature of the error.
+
+  For example, a write operation may have been successfully applied to the
+  primary server but failed to satisfy the write concern (e.g. replication took
+  too long). Alternatively, a write operation may have failed outright (e.g.
+  unique key violation).
+---
+ref: bulkwriteexception-ordered
+content: |
+  In the case of a bulk write, the result may indicate multiple successful write
+  operations and/or errors. If the ``ordered`` option is ``true``, some
+  operations may have succeeded before the first error was encountered and the
+  exception thrown. If the ``ordered`` option is ``false``, multiple errors may
+  have been encountered.
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/extracts-error.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/extracts-error.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..cfada049ab8a4516be8ba1497090f20fa3860c59
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/extracts-error.yaml	
@@ -0,0 +1,52 @@
+ref: error-driver-bulkwriteexception
+content: |
+  :php:`MongoDB\\Driver\\Exception\\BulkWriteException
+  <mongodb-driver-exception-bulkwriteexception>` for errors related to the write
+  operation. Users should inspect the value returned by :php:`getWriteResult()
+  <mongodb-driver-writeexception.getwriteresult>` to determine the nature of the
+  error.
+---
+ref: error-driver-invalidargumentexception
+content: |
+  :php:`MongoDB\\Driver\\Exception\\InvalidArgumentException
+  <mongodb-driver-exception-invalidargumentexception>` for errors related to the
+  parsing of parameters or options at the driver level.
+---
+ref: error-driver-runtimeexception
+content: |
+  :php:`MongoDB\\Driver\\Exception\\RuntimeException
+  <mongodb-driver-exception-runtimeexception>` for other errors at the driver
+  level (e.g. connection errors).
+---
+ref: error-badmethodcallexception-write-result
+content: |
+  :phpclass:`MongoDB\\Exception\\BadMethodCallException` if this method is
+  called and the write operation used an unacknowledged :manual:`write concern
+  </reference/write-concern>`.
+---
+ref: error-invalidargumentexception
+content: |
+  :phpclass:`MongoDB\\Exception\\InvalidArgumentException` for errors related to
+  the parsing of parameters or options.
+---
+ref: error-unexpectedvalueexception
+content: |
+  :phpclass:`MongoDB\\Exception\\UnexpectedValueException` if the command
+  response from the server was malformed.
+---
+ref: error-unsupportedexception
+content: |
+  :phpclass:`MongoDB\\Exception\\UnsupportedException` if options are used and
+  not supported by the selected server (e.g. ``collation``, ``readConcern``,
+  ``writeConcern``).
+---
+ref: error-gridfs-filenotfoundexception
+content: |
+  :phpclass:`MongoDB\\GridFS\\Exception\\FileNotFoundException` if no file was
+  found for the selection criteria.
+---
+ref: error-gridfs-corruptfileexception
+content: |
+  :phpclass:`MongoDB\\GridFS\\Exception\\CorruptFileException` if the file's
+  metadata or chunk documents contain unexpected or invalid data.
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/extracts-note.yaml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/extracts-note.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..7790f0c3285af3b76bd22fa84ab734c37b8b09e4
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/includes/extracts-note.yaml	
@@ -0,0 +1,12 @@
+ref: note-bson-comparison
+content: |
+  When evaluating query criteria, MongoDB compares types and values according to
+  its own :manual:`comparison rules for BSON types
+  </reference/bson-type-comparison-order>`, which differs from PHP's
+  :php:`comparison <manual/en/types.comparisons.php>` and :php:`type juggling
+  <manual/en/language.types.type-juggling.php>` rules. When matching a special
+  BSON type the query criteria should use the respective :php:`BSON class
+  <manual/en/book.bson.php>` in the driver (e.g. use
+  :php:`MongoDB\\BSON\\ObjectId <class.mongodb-bson-objectid>` to match an
+  :manual:`ObjectId </reference/object-id/>`).
+...
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/index.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/index.txt
new file mode 100644
index 0000000000000000000000000000000000000000..ffdd4b16f4fe1ec6d895fe8015297ef9f1a72a16
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/index.txt	
@@ -0,0 +1,67 @@
+===================
+MongoDB PHP Library
+===================
+
+.. default-domain:: mongodb
+
+The |php-library| provides a high-level abstraction around the lower-level
+`PHP driver <https://php.net/mongodb>`_, also known as the ``mongodb``
+extension.
+
+The ``mongodb`` extension provides a limited API to connect to the database and
+execute generic commands, queries, and write operations. In contrast, the
+|php-library| provides a full-featured API and models client, database, and
+collection objects. Each of those classes provide various helper methods for
+performing operations in context. For example, :phpclass:`MongoDB\\Collection`
+implements methods for executing CRUD operations and managing indexes on the
+collection, among other things.
+
+If you are developing a PHP application with MongoDB, you should consider using
+the |php-library| instead of the extension alone.
+
+New to the PHP Library?
+-----------------------
+
+If you have some experience with MongoDB but are new to the PHP library, the
+following pages should help you get started:
+
+- :doc:`/tutorial/install-php-library`
+
+- :doc:`/tutorial/crud`
+
+- :doc:`/tutorial/commands`
+
+- :doc:`/tutorial/gridfs`
+
+- :doc:`/reference/bson`
+
+If you have previously worked with the
+`legacy PHP driver <http://php.net/manual/en/book.mongo.php>`_ (i.e. ``mongo``
+extension), it will be helpful to review the :doc:`/upgrade` for a summary of
+API changes between the old driver and this library.
+
+New to MongoDB?
+---------------
+
+If you are a new MongoDB user, the following links should help you become more
+familiar with MongoDB and introduce some of the concepts and terms you will
+encounter in the library documentation:
+
+- :manual:`Introduction to MongoDB </introduction>`
+
+- :manual:`Databases and Collections </core/databases-and-collections>`
+
+- :manual:`Documents </core/document>` and
+  :manual:`BSON Types </reference/bson-types>`
+
+- :manual:`MongoDB CRUD Operations </crud>`
+
+.. class:: hidden
+
+   .. toctree::
+      :titlesonly:
+
+      Installation </tutorial/install-php-library>
+      /tutorial
+      /upgrade
+      /reference
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/pretty.js b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/pretty.js
new file mode 100644
index 0000000000000000000000000000000000000000..cd0aa1e1ae00e2bb49e06f13b1a6d98e6165eac5
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/pretty.js	
@@ -0,0 +1,4 @@
+$(document).ready(function() {
+    $('pre code').parent().addClass('prettyprint well');
+    prettyPrint();
+});
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference.txt
new file mode 100644
index 0000000000000000000000000000000000000000..1d2c76db3c4fbcf7a1aeaef7394e039717196dfd
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference.txt	
@@ -0,0 +1,19 @@
+=========
+Reference
+=========
+
+.. default-domain:: mongodb
+
+.. toctree::
+   :titlesonly:
+
+   /reference/bson
+   /reference/class/MongoDBClient
+   /reference/class/MongoDBDatabase
+   /reference/class/MongoDBCollection
+   /reference/class/MongoDBGridFSBucket
+   /reference/write-result-classes
+   /reference/result-classes
+   /reference/enumeration-classes
+   /reference/functions
+   /reference/exception-classes
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/bson.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/bson.txt
new file mode 100644
index 0000000000000000000000000000000000000000..c366ea8a89cc0dd147e19c29e21e978c816dd2a5
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/bson.txt	
@@ -0,0 +1,261 @@
+====
+BSON
+====
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Overview
+--------
+
+MongoDB stores data records as BSON documents. BSON is a binary representation
+of :term:`JSON` documents, though it contains more data types than JSON. For the
+BSON spec, see `bsonspec.org <http://bsonspec.org/>`_.
+
+By default, the |php-library| returns BSON documents as
+:phpclass:`MongoDB\\Model\\BSONDocument` objects and BSON arrays as
+:phpclass:`MongoDB\\Model\\BSONArray` objects, respectively.
+
+BSON Classes
+------------
+
+.. phpclass:: MongoDB\\Model\\BSONArray
+
+   This class extends PHP's :php:`ArrayObject <arrayobject>` class. It also
+   implements PHP's :php:`JsonSerializable <jsonserializable>` interface and the
+   driver's :php:`MongoDB\\BSON\\Serializable <mongodb-bson-serializable>` and
+   :php:`MongoDB\\BSON\\Unserializable <mongodb-bson-unserializable>`
+   interfaces.
+
+   By default, the library will deserialize BSON arrays as instances of this
+   class. During BSON and JSON serialization, instances of this class will
+   serialize as an array type (:php:`array_values() <array_values>` is used
+   internally to numerically reindex the array).
+
+.. phpclass:: MongoDB\\Model\\BSONDocument
+
+   This class extends PHP's :php:`ArrayObject <arrayobject>` class. It also
+   implements PHP's :php:`JsonSerializable <jsonserializable>` interface and the
+   driver's :php:`MongoDB\\BSON\\Serializable <mongodb-bson-serializable>` and
+   :php:`MongoDB\\BSON\\Unserializable <mongodb-bson-unserializable>`
+   interfaces.
+
+   By default, the library will deserialize BSON documents as instances of this
+   class. During BSON and JSON serialization, instances of this class will
+   serialize as a document type (:php:`object casting
+   <types.type-juggling#language.types.typecasting>` is used internally).
+
+.. _php-type-map:
+
+Type Maps
+---------
+
+Most methods that read data from MongoDB support a ``typeMap`` option, which
+allows control over how BSON is converted to PHP. Additionally,
+the :phpclass:`MongoDB\\Client`, :phpclass:`MongoDB\\Database`, and
+:phpclass:`MongoDB\\Collection` classes accept a ``typeMap`` option, which can
+be used to specify a default type map to apply to any supporting methods and
+selected classes (e.g. :phpmethod:`MongoDB\\Client::selectDatabase()`).
+
+The :phpclass:`MongoDB\\Client`, :phpclass:`MongoDB\\Database`, and
+:phpclass:`MongoDB\\Collection` classes use the following type map by
+default:
+
+.. code-block:: php
+
+   [
+       'array' => 'MongoDB\Model\BSONArray',
+       'document' => 'MongoDB\Model\BSONDocument',
+       'root' => 'MongoDB\Model\BSONDocument',
+   ]
+
+The type map above will convert BSON documents and arrays to
+:phpclass:`MongoDB\\Model\\BSONDocument` and
+:phpclass:`MongoDB\\Model\\BSONArray` objects, respectively. The ``root`` and
+``document`` keys are used to distinguish the top-level BSON document from
+embedded documents, respectively.
+
+A type map may specify any class that implements
+:php:`MongoDB\\BSON\\Unserializable <mongodb-bson-unserializable>` as well as
+``"array"``, ``"stdClass``", and ``"object"`` (``"stdClass``" and ``"object"``
+are aliases of one another).
+
+.. seealso:: :php:`Deserialization from BSON <manual/en/mongodb.persistence.deserialization.php>` in the PHP manual
+
+``Persistable`` Classes
+-----------------------
+
+The driver's :php:`persistence specification <mongodb.persistence>` outlines how
+classes implementing its :php:`MongoDB\\BSON\\Persistable
+<mongodb-bson-persistable>` interface are serialized to and deserialized from
+BSON. The :php:`Persistable <mongodb-bson-persistable>` interface is analogous
+to PHP's :php:`Serializable interface <class.serializable>`.
+
+The driver automatically handles serialization and deserialization for classes
+implementing the :php:`Persistable <mongodb-bson-persistable>` interface without
+requiring the use of the ``typeMap`` option. This is done by encoding the name
+of the PHP class in a special property within the BSON document.
+
+.. note::
+
+   When deserializing a PHP variable from BSON, the encoded class name of a
+   :php:`Persistable <mongodb-bson-persistable>` object will override any class
+   specified in the type map, but it will not override ``"array"`` and
+   ``"stdClass"`` or ``"object"``. This is discussed in the 
+   :php:`persistence specification <mongodb.persistence>` but it bears
+   repeating.
+
+Consider the following class definition:
+
+.. code-block:: php
+
+   <?php
+
+   class Person implements MongoDB\BSON\Persistable
+   {
+       private $id;
+       private $name;
+       private $createdAt;
+       
+       public function __construct($name)
+       {
+           $this->id = new MongoDB\BSON\ObjectId;
+           $this->name = (string) $name;
+           $this->createdAt = new MongoDB\BSON\UTCDateTime;
+       }
+
+       function bsonSerialize()
+       {
+           return [
+               '_id' => $this->id,
+               'name' => $this->name,
+               'createdAt' => $this->createdAt,
+           ];
+       }
+
+       function bsonUnserialize(array $data)
+       {
+           $this->id = $data['_id'];
+           $this->name = $data['name'];
+           $this->createdAt = $data['createdAt'];
+       }
+   }
+
+The following example constructs a ``Person`` object, inserts it into the
+database, and reads it back as an object of the same type:
+
+.. code-block:: php
+
+   <?php
+
+   $collection = (new MongoDB\Client)->test->persons;
+
+   $result = $collection->insertOne(new Person('Bob'));
+
+   $person = $collection->findOne(['_id' => $result->getInsertedId()]);
+
+   var_dump($person);
+
+The output would then resemble:
+
+.. code-block:: none
+
+   object(Person)#18 (3) {
+     ["id":"Person":private]=>
+     object(MongoDB\BSON\ObjectId)#15 (1) {
+       ["oid"]=>
+       string(24) "56fad2c36118fd2e9820cfc1"
+     }
+     ["name":"Person":private]=>
+     string(3) "Bob"
+     ["createdAt":"Person":private]=>
+     object(MongoDB\BSON\UTCDateTime)#17 (1) {
+       ["milliseconds"]=>
+       int(1459278531218)
+     }
+   }
+
+The same document in the MongoDB shell might display as:
+
+.. code-block:: js
+
+   {
+     "_id" : ObjectId("56fad2c36118fd2e9820cfc1"),
+     "__pclass" : BinData(128,"UGVyc29u"),
+     "name" : "Bob",
+     "createdAt" : ISODate("2016-03-29T19:08:51.218Z")
+   }
+
+.. note::
+
+   :php:`MongoDB\\BSON\\Persistable <mongodb-bson-persistable>` may only be used
+   for root and embedded BSON documents. It may not be used for BSON arrays.
+
+Emulating the Legacy Driver
+---------------------------
+
+The legacy :php:`mongo extension <mongo>` returned both BSON documents and
+arrays as PHP arrays. While PHP arrays are convenient to work with, this
+behavior was problematic:
+
+- Different BSON types could deserialize to the same PHP value (e.g.
+  ``{"0": "foo"}`` and ``["foo"]``), which made it impossible to infer the
+  original BSON type.
+
+- Numerically-indexed PHP arrays would be serialized as BSON documents if there
+  was a gap in their key sequence. Such gaps were easily caused by unsetting a
+  key to remove an element and forgetting to numerically reindex the array.
+
+The |php-library|'s :phpclass:`BSONDocument <MongoDB\\Model\\BSONDocument>` and
+:phpclass:`BSONArray <MongoDB\\Model\\BSONArray>` classes address these concerns
+by preserving the BSON type information during serialization and
+deserialization; however, some users may still prefer the legacy behavior. If
+desired, you can use the ``typeMap`` option to have the library return
+everything as a PHP array:
+
+.. code-block:: php
+
+   <?php
+
+   $client = new MongoDB\Client(
+       'mongodb://127.0.0.1/',
+       [],
+       [
+           'typeMap' => [
+               'array' => 'array',
+               'document' => 'array',
+               'root' => 'array',
+           ],
+       ]
+   );
+
+   $document = $client->test->zips->findOne(['_id' => '94301']);
+
+   var_dump($document);
+
+The above example would output something similar to:
+
+.. code-block:: php
+
+   array(5) {
+     ["_id"]=>
+     string(5) "94301"
+     ["city"]=>
+     string(9) "PALO ALTO"
+     ["loc"]=>
+     array(2) {
+       [0]=>
+       float(-122.149685)
+       [1]=>
+       float(37.444324)
+     }
+     ["pop"]=>
+     int(15965)
+     ["state"]=>
+     string(2) "CA"
+   }
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/class/MongoDBClient.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/class/MongoDBClient.txt
new file mode 100644
index 0000000000000000000000000000000000000000..b677ebb1d00f7c1943c19080188a0d1cd9c5969e
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/class/MongoDBClient.txt	
@@ -0,0 +1,45 @@
+=====================
+MongoDB\\Client Class
+=====================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpclass:: MongoDB\\Client
+
+   This class serves as an entry point for the |php-library|. It is the
+   preferred class for connecting to a MongoDB server or cluster of servers and
+   acts as a gateway for accessing individual databases and collections.
+   :phpclass:`MongoDB\\Client` is analogous to the driver's
+   :php:`MongoDB\\Driver\\Manager <mongodb-driver-manager>` class, which it
+   `composes <https://en.wikipedia.org/wiki/Object_composition>`_.
+
+Methods
+-------
+
+.. toctree::
+   :titlesonly:
+
+   /reference/method/MongoDBClient__construct
+   /reference/method/MongoDBClient__get
+   /reference/method/MongoDBClient-createClientEncryption
+   /reference/method/MongoDBClient-dropDatabase
+   /reference/method/MongoDBClient-getManager
+   /reference/method/MongoDBClient-getReadConcern
+   /reference/method/MongoDBClient-getReadPreference
+   /reference/method/MongoDBClient-getTypeMap
+   /reference/method/MongoDBClient-getWriteConcern
+   /reference/method/MongoDBClient-listDatabaseNames
+   /reference/method/MongoDBClient-listDatabases
+   /reference/method/MongoDBClient-selectCollection
+   /reference/method/MongoDBClient-selectDatabase
+   /reference/method/MongoDBClient-startSession
+   /reference/method/MongoDBClient-watch
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/class/MongoDBCollection.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/class/MongoDBCollection.txt
new file mode 100644
index 0000000000000000000000000000000000000000..4ccd2c177b6f0cbbbe9c53b91fb6b6881f1a924b
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/class/MongoDBCollection.txt	
@@ -0,0 +1,98 @@
+=========================
+MongoDB\\Collection Class
+=========================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpclass:: MongoDB\\Collection
+
+   Provides methods for common operations on collections and documents,
+   including CRUD operations and index management.
+
+   You can construct collections directly using the driver's
+   :php:`MongoDB\\Driver\\Manager <class.mongodb-driver-manager>` class or
+   select a collection from the library's :phpclass:`MongoDB\\Client` or
+   :phpclass:`MongoDB\\Database` classes. A collection may also be cloned from
+   an existing :phpclass:`MongoDB\\Collection` object via the
+   :phpmethod:`withOptions() <MongoDB\\Collection::withOptions>` method.
+
+   :phpclass:`MongoDB\\Collection` supports the :php:`readConcern
+   <mongodb-driver-readconcern>`, :php:`readPreference
+   <mongodb-driver-readpreference>`, :php:`typeMap
+   <manual/en/mongodb.persistence.deserialization.php#mongodb.persistence.typemaps>`,
+   and :php:`writeConcern <mongodb-driver-writeconcern>` options. If you omit an
+   option, the collection inherits the value from the :php:`Manager
+   <mongodb-driver-manager>` constructor argument or the :phpclass:`Client
+   <MongoDB\\Client>` or :phpclass:`Database <MongoDB\\Database>` object used to
+   select the collection.
+
+   Operations within the :phpclass:`MongoDB\\Collection` class inherit the
+   collection's options.
+
+Type Map Limitations
+--------------------
+
+   The :manual:`aggregate </reference/command/aggregate>` (when not using a
+   cursor), :manual:`distinct </reference/command/distinct>`, and
+   :manual:`findAndModify </reference/command/findAndModify>` helpers do not
+   support a ``typeMap`` option due to a driver limitation. The
+   :phpmethod:`aggregate() <MongoDB\\Collection::aggregate>`,
+   :phpmethod:`distinct() <MongoDB\\Collection::distinct>`,
+   :phpmethod:`findOneAndReplace() <MongoDB\\Collection::findOneAndReplace>`,
+   :phpmethod:`findOneAndUpdate() <MongoDB\\Collection::findOneAndUpdate>`, and
+   :phpmethod:`findOneAndDelete() <MongoDB\\Collection::findOneAndDelete>`
+   methods return BSON documents as `stdClass` objects and BSON arrays as
+   arrays.
+
+Methods
+-------
+
+.. toctree::
+   :titlesonly:
+
+   /reference/method/MongoDBCollection__construct
+   /reference/method/MongoDBCollection-aggregate
+   /reference/method/MongoDBCollection-bulkWrite
+   /reference/method/MongoDBCollection-count
+   /reference/method/MongoDBCollection-countDocuments
+   /reference/method/MongoDBCollection-createIndex
+   /reference/method/MongoDBCollection-createIndexes
+   /reference/method/MongoDBCollection-deleteMany
+   /reference/method/MongoDBCollection-deleteOne
+   /reference/method/MongoDBCollection-distinct
+   /reference/method/MongoDBCollection-drop
+   /reference/method/MongoDBCollection-dropIndex
+   /reference/method/MongoDBCollection-dropIndexes
+   /reference/method/MongoDBCollection-estimatedDocumentCount
+   /reference/method/MongoDBCollection-explain
+   /reference/method/MongoDBCollection-find
+   /reference/method/MongoDBCollection-findOne
+   /reference/method/MongoDBCollection-findOneAndDelete
+   /reference/method/MongoDBCollection-findOneAndReplace
+   /reference/method/MongoDBCollection-findOneAndUpdate
+   /reference/method/MongoDBCollection-getCollectionName
+   /reference/method/MongoDBCollection-getDatabaseName
+   /reference/method/MongoDBCollection-getManager
+   /reference/method/MongoDBCollection-getNamespace
+   /reference/method/MongoDBCollection-getReadConcern
+   /reference/method/MongoDBCollection-getReadPreference
+   /reference/method/MongoDBCollection-getTypeMap
+   /reference/method/MongoDBCollection-getWriteConcern
+   /reference/method/MongoDBCollection-insertMany
+   /reference/method/MongoDBCollection-insertOne
+   /reference/method/MongoDBCollection-listIndexes
+   /reference/method/MongoDBCollection-mapReduce
+   /reference/method/MongoDBCollection-replaceOne
+   /reference/method/MongoDBCollection-updateMany
+   /reference/method/MongoDBCollection-updateOne
+   /reference/method/MongoDBCollection-watch
+   /reference/method/MongoDBCollection-withOptions
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/class/MongoDBDatabase.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/class/MongoDBDatabase.txt
new file mode 100644
index 0000000000000000000000000000000000000000..464c32c50ba434b6df12bb407eba04e94495841b
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/class/MongoDBDatabase.txt	
@@ -0,0 +1,66 @@
+=======================
+MongoDB\\Database Class
+=======================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpclass:: MongoDB\\Database
+
+   Provides methods for common operations on a database, such as executing
+   database commands and managing collections.
+
+   You can construct a database directly using the driver's
+   :php:`MongoDB\\Driver\\Manager <class.mongodb-driver-manager>` class or
+   select a database from the library's :phpclass:`MongoDB\\Client` class. A
+   database may also be cloned from an existing :phpclass:`MongoDB\\Database`
+   object via the :phpmethod:`withOptions() <MongoDB\\Database::withOptions>`
+   method.
+
+   :phpclass:`MongoDB\\Database` supports the :php:`readConcern
+   <mongodb-driver-readconcern>`, :php:`readPreference
+   <mongodb-driver-readpreference>`, :php:`typeMap
+   <manual/en/mongodb.persistence.deserialization.php#mongodb.persistence.typemaps>`,
+   and :php:`writeConcern <mongodb-driver-writeconcern>` options. If you omit an
+   option, the database inherits the value from the :php:`Manager
+   <mongodb-driver-manager>` constructor argument or the :phpclass:`Client
+   <MongoDB\\Client>` object used to select the database.
+
+   Operations within the :phpclass:`MongoDB\\Database` class inherit the
+   Database's options.
+
+Methods
+-------
+
+.. toctree::
+   :titlesonly:
+
+   /reference/method/MongoDBDatabase__construct
+   /reference/method/MongoDBDatabase__get
+   /reference/method/MongoDBDatabase-aggregate
+   /reference/method/MongoDBDatabase-command
+   /reference/method/MongoDBDatabase-createCollection
+   /reference/method/MongoDBDatabase-drop
+   /reference/method/MongoDBDatabase-dropCollection
+   /reference/method/MongoDBDatabase-getDatabaseName
+   /reference/method/MongoDBDatabase-getManager
+   /reference/method/MongoDBDatabase-getReadConcern
+   /reference/method/MongoDBDatabase-getReadPreference
+   /reference/method/MongoDBDatabase-getTypeMap
+   /reference/method/MongoDBDatabase-getWriteConcern
+   /reference/method/MongoDBDatabase-listCollectionNames
+   /reference/method/MongoDBDatabase-listCollections
+   /reference/method/MongoDBDatabase-modifyCollection
+   /reference/method/MongoDBDatabase-selectCollection
+   /reference/method/MongoDBDatabase-selectGridFSBucket
+   /reference/method/MongoDBDatabase-watch
+   /reference/method/MongoDBDatabase-withOptions
+
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/class/MongoDBGridFSBucket.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/class/MongoDBGridFSBucket.txt
new file mode 100644
index 0000000000000000000000000000000000000000..cea877f43c3ab46d3e72437e9462c6ec79f4009d
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/class/MongoDBGridFSBucket.txt	
@@ -0,0 +1,59 @@
+=============================
+MongoDB\\GridFS\\Bucket Class
+=============================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpclass:: MongoDB\\GridFS\\Bucket
+
+   :manual:`GridFS </core/gridfs>` is a specification for storing and retrieving
+   files in MongoDB. GridFS uses two collections to store files. One collection
+   stores the file chunks (e.g. ``fs.chunks``), and the other stores file
+   metadata (e.g. ``fs.files``). The :phpclass:`MongoDB\\GridFS\\Bucket` class
+   provides an interface around these collections for working with the files as
+   PHP :php:`Streams <stream>`.
+
+   You can construct a GridFS bucket using the driver's
+   :php:`Manager <class.mongodb-driver-manager>` class, or select a bucket from
+   the library's :phpclass:`MongoDB\\Database` class via the
+   :phpmethod:`selectGridFSBucket() <MongoDB\\Database::selectGridFSBucket>`
+   method.
+
+Methods
+-------
+
+.. toctree::
+   :titlesonly:
+
+   /reference/method/MongoDBGridFSBucket__construct
+   /reference/method/MongoDBGridFSBucket-delete
+   /reference/method/MongoDBGridFSBucket-downloadToStream
+   /reference/method/MongoDBGridFSBucket-downloadToStreamByName
+   /reference/method/MongoDBGridFSBucket-drop
+   /reference/method/MongoDBGridFSBucket-find
+   /reference/method/MongoDBGridFSBucket-findOne
+   /reference/method/MongoDBGridFSBucket-getBucketName
+   /reference/method/MongoDBGridFSBucket-getChunksCollection
+   /reference/method/MongoDBGridFSBucket-getChunkSizeBytes
+   /reference/method/MongoDBGridFSBucket-getDatabaseName
+   /reference/method/MongoDBGridFSBucket-getFileDocumentForStream
+   /reference/method/MongoDBGridFSBucket-getFileIdForStream
+   /reference/method/MongoDBGridFSBucket-getFilesCollection
+   /reference/method/MongoDBGridFSBucket-getReadConcern
+   /reference/method/MongoDBGridFSBucket-getReadPreference
+   /reference/method/MongoDBGridFSBucket-getTypeMap
+   /reference/method/MongoDBGridFSBucket-getWriteConcern
+   /reference/method/MongoDBGridFSBucket-openDownloadStream
+   /reference/method/MongoDBGridFSBucket-openDownloadStreamByName
+   /reference/method/MongoDBGridFSBucket-openUploadStream
+   /reference/method/MongoDBGridFSBucket-rename
+   /reference/method/MongoDBGridFSBucket-uploadFromStream
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/enumeration-classes.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/enumeration-classes.txt
new file mode 100644
index 0000000000000000000000000000000000000000..7eac097e34846e0af9d237b79ef4f501441f1064
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/enumeration-classes.txt	
@@ -0,0 +1,190 @@
+===================
+Enumeration Classes
+===================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+MongoDB\\Model\\CollectionInfo
+------------------------------
+
+Definition
+~~~~~~~~~~
+
+.. phpclass:: MongoDB\\Model\\CollectionInfo
+
+   This class models information about a collection. Instances of this class are
+   returned by traversing a :phpclass:`MongoDB\\Model\\CollectionInfoIterator`,
+   which is returned by :phpmethod:`MongoDB\\Database::listCollections()`.
+
+.. versionchanged:: 1.4
+
+   This class implements PHP's :php:`ArrayAccess <arrayaccess>` interface. This
+   provides a mechanism for accessing index fields for which there exists no
+   helper method. :php:`isset() <isset>` may be used to check for the existence
+   of a field before accessing it with ``[]``.
+
+   .. note::
+
+      The :phpclass:`MongoDB\\Model\\CollectionInfo` class is immutable. Attempting
+      to modify it via the :php:`ArrayAccess <arrayaccess>` interface will
+      result in a :phpclass:`MongoDB\\Exception\\BadMethodCallException`.
+
+Methods
+~~~~~~~
+
+.. toctree::
+   :titlesonly:
+
+   /reference/method/MongoDBModelCollectionInfo-getCappedMax
+   /reference/method/MongoDBModelCollectionInfo-getCappedSize
+   /reference/method/MongoDBModelCollectionInfo-getName
+   /reference/method/MongoDBModelCollectionInfo-getOptions
+   /reference/method/MongoDBModelCollectionInfo-isCapped
+
+----
+
+MongoDB\\Model\\CollectionInfoIterator
+--------------------------------------
+
+Definition
+~~~~~~~~~~
+
+.. phpclass:: MongoDB\\Model\\CollectionInfoIterator
+
+   This interface extends PHP's :php:`Iterator <manual/en/class.iterator.php>`
+   interface. An instance of this interface is returned by
+   :phpmethod:`MongoDB\\Database::listCollections()`.
+
+Methods
+~~~~~~~
+
+This interface adds no new methods to :php:`Iterator
+<manual/en/class.iterator.php>`, but specifies that :php:`current()
+<manual/en/iterator.current.php>` will return an instance of
+:phpclass:`MongoDB\\Model\\CollectionInfo`.
+
+----
+
+MongoDB\\Model\\DatabaseInfo
+----------------------------
+
+Definition
+~~~~~~~~~~
+
+.. phpclass:: MongoDB\\Model\\DatabaseInfo
+
+   This class models information about a database. Instances of this class are
+   returned by traversing a :phpclass:`MongoDB\\Model\\DatabaseInfoIterator`,
+   which is returned by :phpmethod:`MongoDB\\Client::listDatabases()`.
+
+.. versionchanged:: 1.4
+
+   This class implements PHP's :php:`ArrayAccess <arrayaccess>` interface. This
+   provides a mechanism for accessing index fields for which there exists no
+   helper method. :php:`isset() <isset>` may be used to check for the existence
+   of a field before accessing it with ``[]``.
+
+   .. note::
+
+      The :phpclass:`MongoDB\\Model\\DatabaseInfo` class is immutable. Attempting
+      to modify it via the :php:`ArrayAccess <arrayaccess>` interface will
+      result in a :phpclass:`MongoDB\\Exception\\BadMethodCallException`.
+
+Methods
+~~~~~~~
+
+.. toctree::
+   :titlesonly:
+
+   /reference/method/MongoDBModelDatabaseInfo-getName
+   /reference/method/MongoDBModelDatabaseInfo-getSizeOnDisk
+   /reference/method/MongoDBModelDatabaseInfo-isEmpty
+
+----
+
+MongoDB\\Model\\DatabaseInfoIterator
+------------------------------------
+
+Definition
+~~~~~~~~~~
+
+.. phpclass:: MongoDB\\Model\\DatabaseInfoIterator
+
+   This interface extends PHP's :php:`Iterator <manual/en/class.iterator.php>`
+   interface. An instance of this interface is returned by
+   :phpmethod:`MongoDB\\Client::listDatabases()`.
+
+Methods
+~~~~~~~
+
+This interface adds no new methods to :php:`Iterator
+<manual/en/class.iterator.php>`, but specifies that :php:`current()
+<manual/en/iterator.current.php>` will return an instance of
+:phpclass:`MongoDB\\Model\\DatabaseInfo`.
+
+----
+
+MongoDB\\Model\\IndexInfo
+-------------------------
+
+.. phpclass:: MongoDB\\Model\\IndexInfo
+
+   This class models information about an index. Instances of this class are
+   returned by traversing a :phpclass:`MongoDB\\Model\\IndexInfoIterator`,
+   which is returned by :phpmethod:`MongoDB\\Collection::listIndexes()`.
+
+   This class implements PHP's :php:`ArrayAccess <arrayaccess>` interface. This
+   provides a mechanism for accessing index fields for which there exists no
+   helper method. :php:`isset() <isset>` may be used to check for the existence
+   of a field before accessing it with ``[]``.
+
+   .. note::
+
+      The :phpclass:`MongoDB\\Model\\IndexInfo` class is immutable. Attempting
+      to modify it via the :php:`ArrayAccess <arrayaccess>` interface will
+      result in a :phpclass:`MongoDB\\Exception\\BadMethodCallException`.
+
+Methods
+~~~~~~~
+
+.. toctree::
+   :titlesonly:
+
+   /reference/method/MongoDBModelIndexInfo-getKey
+   /reference/method/MongoDBModelIndexInfo-getName
+   /reference/method/MongoDBModelIndexInfo-getNamespace
+   /reference/method/MongoDBModelIndexInfo-getVersion
+   /reference/method/MongoDBModelIndexInfo-is2dSphere
+   /reference/method/MongoDBModelIndexInfo-isGeoHaystack
+   /reference/method/MongoDBModelIndexInfo-isSparse
+   /reference/method/MongoDBModelIndexInfo-isText
+   /reference/method/MongoDBModelIndexInfo-isTtl
+   /reference/method/MongoDBModelIndexInfo-isUnique
+
+----
+
+MongoDB\\Model\\IndexInfoIterator
+---------------------------------
+
+Definition
+~~~~~~~~~~
+
+.. phpclass:: MongoDB\\Model\\IndexInfoIterator
+
+   This interface extends PHP's :php:`Iterator <manual/en/class.iterator.php>`
+   interface. An instance of this interface is returned by
+   :phpmethod:`MongoDB\\Collection::listIndexes()`.
+
+Methods
+~~~~~~~
+
+This interface adds no new methods to :php:`Iterator
+<manual/en/class.iterator.php>`, but specifies that :php:`current()
+<manual/en/iterator.current.php>` will return an instance of
+:phpclass:`MongoDB\\Model\\IndexInfo`.
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/exception-classes.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/exception-classes.txt
new file mode 100644
index 0000000000000000000000000000000000000000..289e4ffa461681aa12336575ab7e68aff4679ac9
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/exception-classes.txt	
@@ -0,0 +1,140 @@
+=================
+Exception Classes
+=================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+MongoDB\\Exception\\BadMethodCallException
+------------------------------------------
+
+.. phpclass:: MongoDB\\Exception\\BadMethodCallException
+
+   This exception is thrown when an unsupported method is invoked on an object.
+
+   For example, using an unacknowledged write concern with
+   :phpmethod:`MongoDB\\Collection::insertMany()` will return a
+   :phpclass:`MongoDB\\InsertManyResult` object. It is a logical error to call
+   :phpmethod:`MongoDB\\InsertManyResult::getInsertedCount()`, since the number
+   of inserted documents can only be determined from the response of an
+   acknowledged write operation.
+
+   This class extends PHP's :php:`BadMethodCallException
+   <badmethodcallexception>` class and implements the library's
+   :phpclass:`Exception <MongoDB\\Exception\\Exception>` interface.
+
+----
+
+MongoDB\\Exception\\InvalidArgumentException
+--------------------------------------------
+
+.. phpclass:: MongoDB\\Exception\\InvalidArgumentException
+
+   Thrown for errors related to the parsing of parameters or options within the
+   library.
+
+   This class extends the driver's :php:`InvalidArgumentException
+   <mongodb-driver-exception-invalidargumentexception>` class and implements the
+   library's :phpclass:`Exception <MongoDB\\Exception\\Exception>` interface.
+
+----
+
+MongoDB\\Exception\\UnexpectedValueException
+--------------------------------------------
+
+.. phpclass:: MongoDB\\Exception\\UnexpectedValueException
+
+   This exception is thrown when a command response from the server is
+   malformed or not what the library expected. This exception means that an
+   assertion in some operation, which abstracts a database command, has failed.
+   It may indicate a corrupted BSON response or bug in the server, driver, or
+   library.
+
+   This class extends the driver's :php:`UnexpectedValueException
+   <mongodb-driver-exception-unexpectedvalueexception>` class and implements the
+   library's :phpclass:`Exception <MongoDB\\Exception\\Exception>` interface.
+
+----
+
+MongoDB\\Exception\\UnsupportedException
+----------------------------------------
+
+.. phpclass:: MongoDB\\Exception\\UnsupportedException
+
+   This exception is thrown if an option is used and not supported by the
+   selected server. It is used sparingly in cases where silently ignoring the
+   unsupported option might otherwise lead to unexpected behavior.
+
+   For example, the ``collation`` option for
+   :phpmethod:`MongoDB\\Collection::deleteOne()` is only supported by
+   MongoDB 3.4+. Since collation determines how a document is matched, silently
+   ignoring the option for an older server version could result in an
+   unintended document being deleted.
+
+   This class extends the library's :phpclass:`RuntimeException
+   <MongoDB\\Exception\\RuntimeException>` class.
+
+   .. note::
+
+      Unlike :phpclass:`InvalidArgumentException
+      <MongoDB\\Exception\\InvalidArgumentException>`, which may be thrown when
+      an operation's parameters and options are parsed during construction, the
+      selected server is not known until an operation is executed.
+
+----
+
+MongoDB\\GridFS\\Exception\\CorruptFileException
+------------------------------------------------
+
+.. phpclass:: MongoDB\\GridFS\\Exception\\CorruptFileException
+
+   This exception is thrown if a GridFS file's metadata or chunk documents
+   contain unexpected or invalid data.
+
+   When selecting a GridFS file, this may be thrown if a metadata field has an
+   incorrect type or its value is out of range (e.g. negative ``length``). When
+   reading a GridFS file, this may be thrown if a chunk's index is out of
+   sequence or its binary data's length out of range.
+
+   This class extends the library's :phpclass:`RuntimeException
+   <MongoDB\\Exception\\RuntimeException>` class.
+
+----
+
+MongoDB\\GridFS\\Exception\\FileNotFoundException
+-------------------------------------------------
+
+.. phpclass:: MongoDB\\GridFS\\Exception\\FileNotFoundException
+
+   This exception is thrown if no GridFS file was found for the selection
+   criteria (e.g. ``id``, ``filename``).
+
+   This class extends the library's :phpclass:`RuntimeException
+   <MongoDB\\Exception\\RuntimeException>` class.
+
+----
+
+MongoDB\\Exception\\Exception
+-----------------------------
+
+.. phpclass:: MongoDB\\Exception\\Exception
+
+   This interface extends the driver's :php:`Exception
+   <mongodb-driver-exception-exception>` interface and is implemented by all
+   exception classes within the library.
+
+----
+
+MongoDB\\Exception\\RuntimeException
+------------------------------------
+
+.. phpclass:: MongoDB\\Exception\\RuntimeException
+
+   This class extends the driver's :php:`RuntimeException
+   <mongodb-driver-exception-runtimeexception>` class, which in turn extends
+   PHP's :php:`RuntimeException <runtimeexception>` class.
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/function/with_transaction.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/function/with_transaction.txt
new file mode 100644
index 0000000000000000000000000000000000000000..f7b7b92d5109328e47292d22c3fc12334d4e207b
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/function/with_transaction.txt	
@@ -0,0 +1,79 @@
+===========================
+MongoDB\\with_transaction()
+===========================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+.. versionadded:: 1.5
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\with_transaction()
+
+   Execute a callback within a transaction using the given client session
+
+   .. code-block:: php
+
+      function with_transaction(MongoDB\Driver\Session $session, callable $callback, array $transactionOptions = []): void
+
+   This method has the following parameters:
+
+   .. include:: /includes/apiargs/function-with_transaction-param.rst
+
+Behavior
+--------
+
+This function is responsible for starting a transaction, invoking a callback,
+and committing a transaction. It also applies logic to retry this process after
+certain errors within a preset time limit. The callback is expected to execute
+one or more operations within the transactionby passing the callback's
+:php:`MongoDB\\Driver\\Session <mongodb-driver-session>` argument as an option to
+those operations; however, that is not enforced.
+
+.. note::
+
+  Applications are strongly encouraged to use an
+  `idempotent <https://en.wikipedia.org/wiki/Idempotence>`_ callback, since it
+  may be invoked multiple times if retryable errors are encountered during
+  either callback execution or committing.
+
+Any exception thrown during execution of the callback will be caught and
+evaluated. If an exception has a ``TransientTransactionError`` error label, the
+transaction will be aborted, restarted, and the callback will be invoked again.
+For any other exception, the transaction will be aborted and the exception
+re-thrown to propagate the error to the caller of ``with_transaction()``.
+
+Following successful execution of the callback, the transaction will be
+committed. If an exception with an UnknownTransactionCommitResult error label is
+encountered, the commit will be retried. If an exception with a
+``TransientTransactionError`` error label is encountered, the transaction will
+be restarted and control will return to invoking the callback. Any other
+exception will be re-thrown to propagate the error to the caller of
+``with_transaction()``.
+
+When an error occurs during callback execution or committing, the process is
+only retried if fewer than 120 seconds have elapsed since ``with_transaction()``
+was first called. This time limit is not configurable. After this time, any
+exception that would normally result in a retry attempt will instead be
+re-thrown.
+
+Errors/Exceptions
+-----------------
+
+.. include:: /includes/extracts/error-invalidargumentexception.rst
+.. include:: /includes/extracts/error-driver-runtimeexception.rst
+
+See Also
+--------
+
+- :php:`MongoDB\\Driver\\Session::startTransaction <mongodb-driver-session.starttransaction>`
+- :php:`MongoDB\\Driver\\Session::commitTransaction <mongodb-driver-session.committransaction>`
+- :manual:`Transactions: Drivers API </core/transactions-in-applications>` documentation in the MongoDB manual
+- `Convenient API for Transactions <https://github.com/mongodb/specifications/blob/master/source/transactions-convenient-api/transactions-convenient-api.rst>`_ specification
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/functions.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/functions.txt
new file mode 100644
index 0000000000000000000000000000000000000000..4ce49e3f98e04a77a56ec760abcd522997bfcd0c
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/functions.txt	
@@ -0,0 +1,16 @@
+=========
+Functions
+=========
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+.. toctree::
+   :titlesonly:
+
+   /reference/function/with_transaction
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBBulkWriteResult-getDeletedCount.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBBulkWriteResult-getDeletedCount.txt
new file mode 100644
index 0000000000000000000000000000000000000000..d0501d3f5d85904f8a5015b6181014b306584ca4
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBBulkWriteResult-getDeletedCount.txt	
@@ -0,0 +1,42 @@
+===========================================
+MongoDB\\BulkWriteResult::getDeletedCount()
+===========================================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\BulkWriteResult::getDeletedCount()
+
+   Return the total number of documents that were deleted by all delete
+   operations in the bulk write.
+
+   .. code-block:: php
+
+      function getDeletedCount(): integer
+
+   This method should only be called if the write was acknowledged.
+
+Return Values
+-------------
+
+The total number of documents that were deleted by all delete operations in the
+bulk write.
+
+Errors/Exceptions
+-----------------
+
+.. include:: /includes/extracts/error-badmethodcallexception-write-result.rst
+
+See Also
+--------
+
+- :php:`MongoDB\\Driver\\WriteResult::getDeletedCount()
+  <manual/en/mongodb-driver-writeresult.getdeletedcount.php>`
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBBulkWriteResult-getInsertedCount.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBBulkWriteResult-getInsertedCount.txt
new file mode 100644
index 0000000000000000000000000000000000000000..6eb1b5de1d147a5f6cc81c69f14ee4fce1f3c70d
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBBulkWriteResult-getInsertedCount.txt	
@@ -0,0 +1,42 @@
+============================================
+MongoDB\\BulkWriteResult::getInsertedCount()
+============================================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\BulkWriteResult::getInsertedCount()
+
+   Return the total number of documents that were inserted by all insert
+   operations in the bulk write.
+
+   .. code-block:: php
+
+      function getInsertedCount(): integer
+
+   This method should only be called if the write was acknowledged.
+
+Return Values
+-------------
+
+The total number of documents that were inserted by all insert operations in the
+bulk write.
+
+Errors/Exceptions
+-----------------
+
+.. include:: /includes/extracts/error-badmethodcallexception-write-result.rst
+
+See Also
+--------
+
+- :php:`MongoDB\\Driver\\WriteResult::getInsertedCount()
+  <manual/en/mongodb-driver-writeresult.getinsertedcount.php>`
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBBulkWriteResult-getInsertedIds.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBBulkWriteResult-getInsertedIds.txt
new file mode 100644
index 0000000000000000000000000000000000000000..bcbcd536d50604b492da17dbe9fa5c4ddef4252f
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBBulkWriteResult-getInsertedIds.txt	
@@ -0,0 +1,38 @@
+==========================================
+MongoDB\\BulkWriteResult::getInsertedIds()
+==========================================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\BulkWriteResult::getInsertedIds()
+
+   Return a map of IDs (i.e. ``_id`` field values) for documents that were
+   inserted by all insert operations in the bulk write.
+
+   .. code-block:: php
+
+      function getInsertedIds(): array
+
+   Since IDs are created by the driver, this method may be called irrespective
+   of whether the write was acknowledged.
+
+Return Values
+-------------
+
+A map of IDs (i.e. ``_id`` field values) for documents that were inserted by all
+insert operations in the bulk write.
+
+The index of each ID in the map corresponds to each document's position in the
+bulk operation. If a document had an ID prior to inserting (i.e. the driver did
+not generate an ID), the index will contain its ``_id`` field value. Any
+driver-generated ID will be a :php:`MongoDB\\BSON\\ObjectId
+<class.mongodb-bson-objectid>` instance.
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBBulkWriteResult-getMatchedCount.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBBulkWriteResult-getMatchedCount.txt
new file mode 100644
index 0000000000000000000000000000000000000000..af1ad98f649c8087bf19c33ee385d96c5f4032ca
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBBulkWriteResult-getMatchedCount.txt	
@@ -0,0 +1,51 @@
+===========================================
+MongoDB\\BulkWriteResult::getMatchedCount()
+===========================================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\BulkWriteResult::getMatchedCount()
+
+   Return the total number of documents that were matched by all update and
+   replace operations in the bulk write.
+
+   .. code-block:: php
+
+      function getMatchedCount(): integer
+
+   This method should only be called if the write was acknowledged.
+
+   .. note::
+
+      If an update/replace operation results in no change to the document
+      (e.g. setting the value of a field to its current value), the matched
+      count may be greater than the value returned by
+      :phpmethod:`getModifiedCount()
+      <MongoDB\\BulkWriteResult::getModifiedCount()>`.
+
+Return Values
+-------------
+
+The total number of documents that were matched by all update and replace
+operations in the bulk write.
+
+Errors/Exceptions
+-----------------
+
+.. include:: /includes/extracts/error-badmethodcallexception-write-result.rst
+
+See Also
+--------
+
+- :phpmethod:`MongoDB\\BulkWriteResult::getModifiedCount()`
+- :php:`MongoDB\\Driver\\WriteResult::getMatchedCount()
+  <manual/en/mongodb-driver-writeresult.getmatchedcount.php>`
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBBulkWriteResult-getModifiedCount.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBBulkWriteResult-getModifiedCount.txt
new file mode 100644
index 0000000000000000000000000000000000000000..2e8f708b00f65d2b3807feee6ef0fe8935c8bcb9
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBBulkWriteResult-getModifiedCount.txt	
@@ -0,0 +1,50 @@
+============================================
+MongoDB\\BulkWriteResult::getModifiedCount()
+============================================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\BulkWriteResult::getModifiedCount()
+
+   Return the total number of documents that were modified by all update and
+   replace operations in the bulk write.
+
+   .. code-block:: php
+
+      function getModifiedCount(): integer|null
+
+   This method should only be called if the write was acknowledged.
+
+   .. note::
+
+      If an update/replace operation results in no change to the document
+      (e.g. setting the value of a field to its current value), the modified
+      count may be less than the value returned by :phpmethod:`getMatchedCount()
+      <MongoDB\\BulkWriteResult::getMatchedCount()>`.
+
+Return Values
+-------------
+
+The total number of documents that were modified by all update and replace
+operations in the bulk write.
+
+Errors/Exceptions
+-----------------
+
+.. include:: /includes/extracts/error-badmethodcallexception-write-result.rst
+
+See Also
+--------
+
+- :phpmethod:`MongoDB\\BulkWriteResult::getMatchedCount()`
+- :php:`MongoDB\\Driver\\WriteResult::getModifiedCount()
+  <manual/en/mongodb-driver-writeresult.getmodifiedcount.php>`
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBBulkWriteResult-getUpsertedCount.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBBulkWriteResult-getUpsertedCount.txt
new file mode 100644
index 0000000000000000000000000000000000000000..1f0dff2b93b5fe3c2af0e4dcbd800b613eb732c0
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBBulkWriteResult-getUpsertedCount.txt	
@@ -0,0 +1,42 @@
+============================================
+MongoDB\\BulkWriteResult::getUpsertedCount()
+============================================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\BulkWriteResult::getUpsertedCount()
+
+   Return the total number of documents that were upserted by all update and
+   replace operations in the bulk write.
+
+   .. code-block:: php
+
+      function getUpsertedCount(): integer
+
+   This method should only be called if the write was acknowledged.
+
+Return Values
+-------------
+
+The total number of documents that were upserted by all update and replace
+operations in the bulk write.
+
+Errors/Exceptions
+-----------------
+
+.. include:: /includes/extracts/error-badmethodcallexception-write-result.rst
+
+See Also
+--------
+
+- :php:`MongoDB\\Driver\\WriteResult::getUpsertedCount()
+  <manual/en/mongodb-driver-writeresult.getupsertedcount.php>`
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBBulkWriteResult-getUpsertedIds.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBBulkWriteResult-getUpsertedIds.txt
new file mode 100644
index 0000000000000000000000000000000000000000..6abad98f2242a734e749d4be2d2fe0afd60559b4
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBBulkWriteResult-getUpsertedIds.txt	
@@ -0,0 +1,46 @@
+==========================================
+MongoDB\\BulkWriteResult::getUpsertedIds()
+==========================================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\BulkWriteResult::getUpsertedIds()
+
+   Return a map of IDs (i.e. ``_id`` field values) for documents that were
+   upserted by all update and replace operations in the bulk write.
+
+   .. code-block:: php
+
+      function getUpsertedIds(): array
+
+Return Values
+-------------
+
+A map of IDs (i.e. ``_id`` field values) for documents that were upserted by all
+update and replace operations in the bulk write.
+
+The index of each ID in the map corresponds to each document's position in the
+bulk operation. If a document had an ID prior to upserting (i.e. the server did
+not generate an ID), the index will contain its ``_id`` field value. Any
+server-generated ID will be a :php:`MongoDB\\BSON\\ObjectId
+<class.mongodb-bson-objectid>` instance.
+
+Errors/Exceptions
+-----------------
+
+.. include:: /includes/extracts/error-badmethodcallexception-write-result.rst
+
+See Also
+--------
+
+- :php:`MongoDB\\Driver\\WriteResult::getUpsertedIds()
+  <manual/en/mongodb-driver-writeresult.getupsertedids.php>`
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBBulkWriteResult-isAcknowledged.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBBulkWriteResult-isAcknowledged.txt
new file mode 100644
index 0000000000000000000000000000000000000000..1a857caaa0c333607e696c0c5768ee3b87b39eda
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBBulkWriteResult-isAcknowledged.txt	
@@ -0,0 +1,34 @@
+==========================================
+MongoDB\\BulkWriteResult::isAcknowledged()
+==========================================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\BulkWriteResult::isAcknowledged()
+
+   Return whether the write was acknowledged.
+
+   .. code-block:: php
+
+      function isAcknowledged(): boolean
+
+Return Values
+-------------
+
+A boolean indicating whether the write was acknowledged.
+
+See Also
+--------
+
+- :php:`MongoDB\\Driver\\WriteResult::isAcknowledged()
+  <manual/en/mongodb-driver-writeresult.isacknowledged.php>`
+- :manual:`Write Concern </reference/write-concern>` in the MongoDB manual
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBChangeStream-current.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBChangeStream-current.txt
new file mode 100644
index 0000000000000000000000000000000000000000..8057dbaa2e3992f917f3ace76f5d04fb5610ef4c
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBChangeStream-current.txt	
@@ -0,0 +1,106 @@
+================================
+MongoDB\\ChangeStream::current()
+================================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\ChangeStream::current()
+
+   Returns the current event in the change stream.
+
+   .. code-block:: php
+
+      function current(): array|object|null
+
+   The structure of each event document will vary based on the operation type.
+   See :manual:`Change Events </reference/change-events/>` in the MongoDB manual
+   for more information.
+
+Return Values
+-------------
+
+An array or object for the current event in the change stream, or ``null`` if
+there is no current event (i.e. :phpmethod:`MongoDB\\ChangeStream::valid()`
+returns ``false``). The return type will depend on the ``typeMap`` option for
+:phpmethod:`MongoDB\\Collection::watch()`.
+
+Examples
+--------
+
+This example reports events while iterating a change stream.
+
+.. code-block:: php
+
+   <?php
+
+   $uri = 'mongodb://rs1.example.com,rs2.example.com/?replicaSet=myReplicaSet';
+
+   $collection = (new MongoDB\Client($uri))->test->inventory;
+
+   $changeStream = $collection->watch();
+
+   for ($changeStream->rewind(); true; $changeStream->next()) {
+       if ( ! $changeStream->valid()) {
+           continue;
+       }
+
+       $event = $changeStream->current();
+
+       $ns = sprintf('%s.%s', $event['ns']['db'], $event['ns']['coll']);
+       $id = json_encode($event['documentKey']['_id']);
+
+       switch ($event['operationType']) {
+           case 'delete':
+               printf("Deleted document in %s with _id: %s\n\n", $ns, $id);
+               break;
+
+           case 'insert':
+               printf("Inserted new document in %s\n", $ns);
+               echo json_encode($event['fullDocument']), "\n\n";
+               break;
+
+           case 'replace':
+               printf("Replaced new document in %s with _id: %s\n", $ns, $id);
+               echo json_encode($event['fullDocument']), "\n\n";
+               break;
+
+           case 'update':
+               printf("Updated document in %s with _id: %s\n", $ns, $id);
+               echo json_encode($event['updateDescription']), "\n\n";
+               break;
+       }
+   }
+
+Assuming that a document was inserted, updated, and deleted while the above
+script was iterating the change stream, the output would then resemble:
+
+.. code-block:: none
+
+   Inserted new document in test.inventory
+   {"_id":{"$oid":"5a81fc0d6118fd1af1790d32"},"name":"Widget","quantity":5}
+
+   Updated document in test.inventory with _id: {"$oid":"5a81fc0d6118fd1af1790d32"}
+   {"updatedFields":{"quantity":4},"removedFields":[]}
+
+   Deleted document in test.inventory with _id: {"$oid":"5a81fc0d6118fd1af1790d32"}
+
+See Also
+--------
+
+- :phpmethod:`MongoDB\\Client::watch()`
+- :phpmethod:`MongoDB\\Collection::watch()`
+- :phpmethod:`MongoDB\\Database::watch()`
+- :php:`Iterator::current() <iterator.current>`
+- :ref:`Tailable Cursor Iteration <php-tailable-cursor>`
+- :manual:`Change Streams </changeStreams>` documentation in the MongoDB manual
+- :manual:`Change Events </reference/change-events/>` documentation in the
+  MongoDB manual
\ No newline at end of file
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBChangeStream-getCursorId.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBChangeStream-getCursorId.txt
new file mode 100644
index 0000000000000000000000000000000000000000..1938d3c00080b9c498474abce36dc791d5ee9750
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBChangeStream-getCursorId.txt	
@@ -0,0 +1,60 @@
+====================================
+MongoDB\\ChangeStream::getCursorId()
+====================================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\ChangeStream::getCursorId()
+
+   Returns the change stream cursor's ID.
+
+   .. code-block:: php
+
+      function getCursorId(): MongoDB\Driver\CursorId
+
+Return Values
+-------------
+
+A :php:`MongoDB\\Driver\\CursorId <class.mongodb-driver-cursorid>` object.
+
+Examples
+--------
+
+This example reports the cursor ID for a change stream.
+
+.. code-block:: php
+
+   <?php
+
+   $uri = 'mongodb://rs1.example.com,rs2.example.com/?replicaSet=myReplicaSet';
+
+   $collection = (new MongoDB\Client($uri))->test->inventory;
+
+   $changeStream = $collection->watch();
+
+   var_dump($changeStream->getCursorId());
+
+The output would then resemble::
+
+   object(MongoDB\Driver\CursorId)#5 (1) {
+     ["id"]=>
+     int(8462642181784669708)
+   }
+
+See Also
+--------
+
+- :phpmethod:`MongoDB\\Client::watch()`
+- :phpmethod:`MongoDB\\Collection::watch()`
+- :phpmethod:`MongoDB\\Database::watch()`
+- :php:`MongoDB\\Driver\\CursorId <class.mongodb-driver-cursorid>`
+- :php:`MongoDB\\Driver\\Cursor::getId() <manual/en/mongodb-driver-cursor.getid.php>`
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBChangeStream-getResumeToken.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBChangeStream-getResumeToken.txt
new file mode 100644
index 0000000000000000000000000000000000000000..0930d45cf413c9997c7de969bcabf99ed105700c
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBChangeStream-getResumeToken.txt	
@@ -0,0 +1,75 @@
+=======================================
+MongoDB\\ChangeStream::getResumeToken()
+=======================================
+
+.. versionadded:: 1.5
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\ChangeStream::getResumeToken()
+
+   Returns the cached resume token that will be used to resume the change
+   stream.
+
+   .. code-block:: php
+
+      function getResumeToken(): array|object|null
+
+Return Values
+-------------
+
+An array or object, or ``null`` if there is no cached resume token. The return
+type will depend on the ``typeMap`` option for the ``watch()`` method used to
+create the change stream.
+
+Examples
+--------
+
+This example captures the resume token for a change stream after encountering
+an ``invalidate`` event and uses it to construct a second change stream using
+the ``startAfter`` option.
+
+.. code-block:: php
+
+   <?php
+
+   $uri = 'mongodb://rs1.example.com,rs2.example.com/?replicaSet=myReplicaSet';
+
+   $collection = (new MongoDB\Client($uri))->test->inventory;
+
+   $changeStream = $collection->watch();
+
+   for ($changeStream->rewind(); true; $changeStream->next()) {
+       if ( ! $changeStream->valid()) {
+           continue;
+       }
+
+       $event = $changeStream->current();
+
+       if ($event['operationType'] === 'invalidate') {
+           $startAfter = $changeStream->getResumeToken();
+           break;
+       }
+
+       printf("%d: %s\n", $changeStream->key(), $event['operationType']);
+   }
+
+   $changeStream = $collection->watch([], ['startAfter' => $startAfter]);
+
+See Also
+--------
+
+- :phpmethod:`MongoDB\\Client::watch()`
+- :phpmethod:`MongoDB\\Collection::watch()`
+- :phpmethod:`MongoDB\\Database::watch()`
+- :manual:`Resume a Change Stream </changeStreams#resume-a-change-stream>`
+  documentation in the MongoDB manual
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBChangeStream-key.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBChangeStream-key.txt
new file mode 100644
index 0000000000000000000000000000000000000000..6225c11f6fff308a45610c032e97c53766901457
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBChangeStream-key.txt	
@@ -0,0 +1,76 @@
+============================
+MongoDB\\ChangeStream::key()
+============================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\ChangeStream::key()
+
+   Returns the index of the current event in the change stream.
+
+   .. code-block:: php
+
+      function key(): integer|null
+
+   The index of the first event in a change stream starts at zero and will
+   increment by one for each subsequent event.
+
+Return Values
+-------------
+
+The index of the current event in the change stream, or ``null`` if there is no
+current event (i.e. :phpmethod:`MongoDB\\ChangeStream::valid()` returns
+``false``).
+
+Examples
+--------
+
+This example reports the index of events while iterating a change stream.
+
+.. code-block:: php
+
+   <?php
+
+   $uri = 'mongodb://rs1.example.com,rs2.example.com/?replicaSet=myReplicaSet';
+
+   $collection = (new MongoDB\Client($uri))->test->inventory;
+
+   $changeStream = $collection->watch();
+
+   for ($changeStream->rewind(); true; $changeStream->next()) {
+       if ( ! $changeStream->valid()) {
+           continue;
+       }
+
+       $event = $changeStream->current();
+
+       printf("%d: %s\n", $changeStream->key(), $event['operationType']);
+   }
+
+Assuming that a document was inserted, updated, and deleted while the above
+script was iterating the change stream, the output would then resemble:
+
+.. code-block:: none
+
+   0: insert
+   1: update
+   2: delete
+
+See Also
+--------
+
+- :phpmethod:`MongoDB\\Client::watch()`
+- :phpmethod:`MongoDB\\Collection::watch()`
+- :phpmethod:`MongoDB\\Database::watch()`
+- :php:`Iterator::key() <iterator.key>`
+- :ref:`Tailable Cursor Iteration <php-tailable-cursor>`
+- :manual:`Change Streams </changeStreams>` documentation in the MongoDB manual
\ No newline at end of file
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBChangeStream-next.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBChangeStream-next.txt
new file mode 100644
index 0000000000000000000000000000000000000000..c25f039b3cb9b3d980b0759a1f9b560fed04569a
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBChangeStream-next.txt	
@@ -0,0 +1,44 @@
+=============================
+MongoDB\\ChangeStream::next()
+=============================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\ChangeStream::next()
+
+   Advances the change stream and attempts to load the next event.
+
+   .. code-block:: php
+
+      function next(): void
+
+   .. note::
+
+      Advancing the change stream does not guarantee that there will be a
+      current event to access. You should still call
+      :phpmethod:`MongoDB\\ChangeStream::valid()` to check for a current event
+      at each step of iteration.
+
+Errors/Exceptions
+-----------------
+
+.. include:: /includes/extracts/error-driver-runtimeexception.rst
+
+See Also
+--------
+
+- :phpmethod:`MongoDB\\Client::watch()`
+- :phpmethod:`MongoDB\\Collection::watch()`
+- :phpmethod:`MongoDB\\Database::watch()`
+- :php:`Iterator::next() <iterator.next>`
+- :ref:`Tailable Cursor Iteration <php-tailable-cursor>`
+- :manual:`Change Streams </changeStreams>` documentation in the MongoDB manual
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBChangeStream-rewind.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBChangeStream-rewind.txt
new file mode 100644
index 0000000000000000000000000000000000000000..e59a1399b565e2e5ad2d4f9eedc230c48a964b03
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBChangeStream-rewind.txt	
@@ -0,0 +1,54 @@
+===============================
+MongoDB\\ChangeStream::rewind()
+===============================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\ChangeStream::rewind()
+
+   Rewinds the change stream and attempts to load the first event.
+
+   .. code-block:: php
+
+      function rewind(): void
+
+   This method should be called at the start of change stream iteration.
+
+   .. note::
+
+      Rewinding the change stream does not guarantee that there will be a
+      current event to access. You should still call
+      :phpmethod:`MongoDB\\ChangeStream::valid()` to check for a current event
+      at each step of iteration. After initially rewinding the change stream,
+      :phpmethod:`MongoDB\\ChangeStream::next()` should be used to iterate
+      further.
+
+Errors/Exceptions
+-----------------
+
+:php:`MongoDB\\Driver\\Exception\\LogicException
+<mongodb-driver-exception-logicexception>` if this method is called after a call
+to :phpmethod:`MongoDB\\ChangeStream::next()` (i.e. the underlying
+:php:`MongoDB\\Driver\\Cursor <class.mongodb-driver-cursor>` has already been
+advanced).
+
+.. include:: /includes/extracts/error-driver-runtimeexception.rst
+
+See Also
+--------
+
+- :phpmethod:`MongoDB\\Client::watch()`
+- :phpmethod:`MongoDB\\Collection::watch()`
+- :phpmethod:`MongoDB\\Database::watch()`
+- :php:`Iterator::rewind() <iterator.rewind>`
+- :ref:`Tailable Cursor Iteration <php-tailable-cursor>`
+- :manual:`Change Streams </changeStreams>` documentation in the MongoDB manual
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBChangeStream-valid.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBChangeStream-valid.txt
new file mode 100644
index 0000000000000000000000000000000000000000..69ea1cd6836598f3032c6cb879b594bf4c21458e
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBChangeStream-valid.txt	
@@ -0,0 +1,42 @@
+==============================
+MongoDB\\ChangeStream::valid()
+==============================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\ChangeStream::valid()
+
+   Returns whether there is a current event in the change stream.
+
+   .. code-block:: php
+
+      function valid(): boolean
+
+   When manually iterating the change stream using
+   :php:`Iterator </manual/en/class.iterator.php>` methods, this method should
+   be used to determine if :phpmethod:`MongoDB\\ChangeStream::current()` and
+   :phpmethod:`MongoDB\\ChangeStream::key()` can be called.
+
+Return Values
+-------------
+
+A boolean indicating whether there is a current event in the change stream.
+
+See Also
+--------
+
+- :phpmethod:`MongoDB\\Client::watch()`
+- :phpmethod:`MongoDB\\Collection::watch()`
+- :phpmethod:`MongoDB\\Database::watch()`
+- :php:`Iterator::valid() <iterator.valid>`
+- :ref:`Tailable Cursor Iteration <php-tailable-cursor>`
+- :manual:`Change Streams </changeStreams>` documentation in the MongoDB manual
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBClient-createClientEncryption.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBClient-createClientEncryption.txt
new file mode 100644
index 0000000000000000000000000000000000000000..9b6f817eabdab7b51f410aa2acc98f9bb4db7520
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBClient-createClientEncryption.txt	
@@ -0,0 +1,51 @@
+=========================================
+MongoDB\\Client::createClientEncryption()
+=========================================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\Client::createClientEncryption()
+
+   Returns a :php:`MongoDB\\Driver\\ClientEncryption <class.mongodb-driver-clientencryption>`
+   object for manual encryption and decryption of values.
+
+   .. code-block:: php
+
+      function createClientEncryption(array $options): MongoDB\Driver\ClientEncryption
+
+   This method has the following parameters:
+
+   .. include:: /includes/apiargs/MongoDBClient-method-createClientEncryption-param.rst
+
+   The ``$options`` parameter supports all options documented in the
+   :php:`extension manual <manual/en/mongodb-driver-manager.createclientencryption.php>`.
+   For the ``keyVaultClient`` option, an instance of :phpclass:`MongoDB\\Client`
+   is automatically unwrapped and the :php:`MongoDB\\Driver\\Manager <class.mongodb-driver-manager>`
+   instance is passed to the extension.
+
+Return Values
+-------------
+
+A :php:`MongoDB\\Driver\\ClientEncryption <class.mongodb-driver-clientencryption>`
+instance which can be used to encrypt and decrypt values.
+
+Errors/Exceptions
+-----------------
+
+.. include:: /includes/extracts/error-invalidargumentexception.rst
+.. include:: /includes/extracts/error-driver-invalidargumentexception.rst
+
+See Also
+--------
+
+- :php:`MongoDB\\Driver\\Manager::createClientEncryption()
+  <manual/en/mongodb-driver-manager.createclientencryption.php>`
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBClient-dropDatabase.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBClient-dropDatabase.txt
new file mode 100644
index 0000000000000000000000000000000000000000..ccb303ffbb5eccd6e9d68965fa6fd6f0c95a7f37
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBClient-dropDatabase.txt	
@@ -0,0 +1,78 @@
+===============================
+MongoDB\\Client::dropDatabase()
+===============================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\Client::dropDatabase()
+
+   Drop a database on the server.
+
+   .. code-block:: php
+
+      function dropDatabase($databaseName, array $options []): array|object
+
+   This method has the following parameters:
+
+   .. include:: /includes/apiargs/MongoDBClient-method-dropDatabase-param.rst
+
+   The ``$options`` parameter supports the following options:
+
+   .. include:: /includes/apiargs/MongoDBClient-method-dropDatabase-option.rst
+
+Return Values
+-------------
+
+An array or object with the result document of the :manual:`dropDatabase
+</reference/command/dropDatabase>` command. The return type will depend on the
+``typeMap`` option.
+
+Errors/Exceptions
+-----------------
+
+.. include:: /includes/extracts/error-unsupportedexception.rst
+.. include:: /includes/extracts/error-invalidargumentexception.rst
+.. include:: /includes/extracts/error-driver-runtimeexception.rst
+
+Example
+-------
+
+The following example drops the ``test`` database:
+
+.. code-block:: php
+
+   <?php
+
+   $client = new MongoDB\Client;
+
+   $result = $client->dropDatabase('test');
+
+   var_dump($result);
+
+The output would then resemble::
+
+   object(MongoDB\Model\BSONDocument)#8 (1) {
+     ["storage":"ArrayObject":private]=>
+     array(2) {
+       ["dropped"]=>
+       string(4) "test"
+       ["ok"]=>
+       float(1)
+     }
+   }
+
+See Also
+--------
+
+- :phpmethod:`MongoDB\\Database::drop()`
+- :manual:`dropDatabase </reference/command/dropDatabase>` command reference in
+  the MongoDB manual
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBClient-getManager.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBClient-getManager.txt
new file mode 100644
index 0000000000000000000000000000000000000000..c320595d3c4ebd644bab834a9ab1bb8274be311d
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBClient-getManager.txt	
@@ -0,0 +1,35 @@
+=============================
+MongoDB\\Client::getManager()
+=============================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\Client::getManager()
+
+   Accessor for the
+   :php:`MongoDB\\Driver\\Manager <class.mongodb-driver-manager>` used by this
+   :phpclass:`Client <MongoDB\\Client>`.
+
+   .. code-block:: php
+
+      function getManager(): MongoDB\Manager
+
+Return Values
+-------------
+
+A :php:`MongoDB\\Driver\\Manager <class.mongodb-driver-manager>` object.
+
+See Also
+--------
+
+- :phpmethod:`MongoDB\\Collection::getManager()`
+- :phpmethod:`MongoDB\\Database::getManager()`
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBClient-getReadConcern.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBClient-getReadConcern.txt
new file mode 100644
index 0000000000000000000000000000000000000000..b7c4c60bce9325c2981a05216d9a1afe8fc3b05a
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBClient-getReadConcern.txt	
@@ -0,0 +1,58 @@
+=================================
+MongoDB\\Client::getReadConcern()
+=================================
+
+.. versionadded:: 1.2
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\Client::getReadConcern()
+
+   Returns the read concern for this client.
+
+   .. code-block:: php
+
+      function getReadConcern(): MongoDB\Driver\ReadConcern
+
+Return Values
+-------------
+
+A :php:`MongoDB\\Driver\\ReadConcern <class.mongodb-driver-readconcern>` object.
+
+Example
+-------
+
+.. code-block:: php
+
+   <?php
+
+   $client = new MongoDB\Client('mongodb://127.0.0.1/', [
+       'readConcernLevel' => 'majority',
+   ]);
+
+   var_dump($client->getReadConcern());
+
+The output would then resemble::
+
+   object(MongoDB\Driver\ReadConcern)#5 (1) {
+     ["level"]=>
+     string(8) "majority"
+   }
+
+See Also
+--------
+
+- :manual:`Read Concern </reference/read-concern>` in the MongoDB manual
+- :php:`MongoDB\\Driver\\ReadConcern::isDefault() <mongodb-driver-readconcern.isdefault>`
+- :phpmethod:`MongoDB\\Collection::getReadConcern()`
+- :phpmethod:`MongoDB\\Database::getReadConcern()`
+- :phpmethod:`MongoDB\\GridFS\\Bucket::getReadConcern()`
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBClient-getReadPreference.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBClient-getReadPreference.txt
new file mode 100644
index 0000000000000000000000000000000000000000..96d8eec5958b9058303d9a94b11e06c1322a8dba
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBClient-getReadPreference.txt	
@@ -0,0 +1,58 @@
+====================================
+MongoDB\\Client::getReadPreference()
+====================================
+
+.. versionadded:: 1.2
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\Client::getReadPreference()
+
+   Returns the read preference for this client.
+
+   .. code-block:: php
+
+      function getReadPreference(): MongoDB\Driver\ReadPreference
+
+Return Values
+-------------
+
+A :php:`MongoDB\\Driver\\ReadPreference <class.mongodb-driver-readpreference>`
+object.
+
+Example
+-------
+
+.. code-block:: php
+
+   <?php
+
+   $client = new MongoDB\Client('mongodb://127.0.0.1/', [
+       'readPreference' => 'primaryPreferred',
+   ]);
+
+   var_dump($client->getReadPreference());
+
+The output would then resemble::
+
+   object(MongoDB\Driver\ReadPreference)#5 (1) {
+     ["mode"]=>
+     string(16) "primaryPreferred"
+   }
+
+See Also
+--------
+
+- :manual:`Read Preference </reference/read-preference>` in the MongoDB manual
+- :phpmethod:`MongoDB\\Collection::getReadPreference()`
+- :phpmethod:`MongoDB\\Database::getReadPreference()`
+- :phpmethod:`MongoDB\\GridFS\\Bucket::getReadPreference()`
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBClient-getTypeMap.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBClient-getTypeMap.txt
new file mode 100644
index 0000000000000000000000000000000000000000..04697f3353c16a08637adb2923226f003b1d1431
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBClient-getTypeMap.txt	
@@ -0,0 +1,65 @@
+=============================
+MongoDB\\Client::getTypeMap()
+=============================
+
+.. versionadded:: 1.2
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\Client::getTypeMap()
+
+   Returns the type map for this client.
+
+   .. code-block:: php
+
+      function getTypeMap(): array
+
+Return Values
+-------------
+
+A :ref:`type map <php-type-map>` array.
+
+Example
+-------
+
+.. code-block:: php
+
+   <?php
+
+   $client = new MongoDB\Client('mongodb://127.0.0.1/', [], [
+       'typeMap' => [
+           'root' => 'array',
+           'document' => 'array',
+           'array' => 'array',
+       ],
+   ]);
+
+   var_dump($client->getTypeMap());
+
+The output would then resemble::
+
+   array(3) {
+     ["root"]=>
+     string(5) "array"
+     ["document"]=>
+     string(5) "array"
+     ["array"]=>
+     string(5) "array"
+   }
+
+See Also
+--------
+
+- :doc:`/reference/bson`
+- :phpmethod:`MongoDB\\Collection::getTypeMap()`
+- :phpmethod:`MongoDB\\Database::getTypeMap()`
+- :phpmethod:`MongoDB\\GridFS\\Bucket::getTypeMap()`
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBClient-getWriteConcern.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBClient-getWriteConcern.txt
new file mode 100644
index 0000000000000000000000000000000000000000..b779aae96a28c0c2e978937fd0332ce4be6b0133
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBClient-getWriteConcern.txt	
@@ -0,0 +1,59 @@
+==================================
+MongoDB\\Client::getWriteConcern()
+==================================
+
+.. versionadded:: 1.2
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\Client::getWriteConcern()
+
+   Returns the write concern for this client.
+
+   .. code-block:: php
+
+      function getWriteConcern(): MongoDB\Driver\WriteConcern
+
+Return Values
+-------------
+
+A :php:`MongoDB\\Driver\\WriteConcern <class.mongodb-driver-writeconcern>`
+object.
+
+Example
+-------
+
+.. code-block:: php
+
+   <?php
+
+   $client = new MongoDB\Client('mongodb://127.0.0.1/', [
+       'journal' => true,
+   ]);
+
+   var_dump($client->getWriteConcern());
+
+The output would then resemble::
+
+   object(MongoDB\Driver\WriteConcern)#4 (1) {
+     ["j"]=>
+     bool(true)
+   }
+
+See Also
+--------
+
+- :manual:`Write Concern </reference/read-concern>` in the MongoDB manual
+- :php:`MongoDB\\Driver\\WriteConcern::isDefault() <mongodb-driver-writeconcern.isdefault>`
+- :phpmethod:`MongoDB\\Collection::getWriteConcern()`
+- :phpmethod:`MongoDB\\Database::getWriteConcern()`
+- :phpmethod:`MongoDB\\GridFS\\Bucket::getWriteConcern()`
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBClient-listDatabaseNames.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBClient-listDatabaseNames.txt
new file mode 100644
index 0000000000000000000000000000000000000000..5047b88d70a750892cf6466fda74e67147de200c
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBClient-listDatabaseNames.txt	
@@ -0,0 +1,75 @@
+====================================
+MongoDB\\Client::listDatabaseNames()
+====================================
+
+.. versionadded:: 1.7
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\Client::listDatabaseNames()
+
+   Returns names for all databases on the server.
+
+   .. code-block:: php
+
+      function listDatabaseNames(array $options = []): Iterator
+
+   This method has the following parameters:
+
+   .. include:: /includes/apiargs/MongoDBClient-method-listDatabases-param.rst
+
+   The ``$options`` parameter supports the following options:
+
+   .. include:: /includes/apiargs/MongoDBClient-method-listDatabases-option.rst
+
+Return Values
+-------------
+
+An :php:`Iterator <class.iterator.php>`, which provides the name of each
+database on the server.
+
+Errors/Exceptions
+-----------------
+
+.. include:: /includes/extracts/error-unexpectedvalueexception.rst
+.. include:: /includes/extracts/error-invalidargumentexception.rst
+.. include:: /includes/extracts/error-driver-runtimeexception.rst
+
+Example
+-------
+
+The following example lists all databases on the server:
+
+.. code-block:: php
+
+   <?php
+
+   $client = new MongoDB\Client;
+
+   foreach ($client->listDatabaseNames() as $databaseName) {
+       var_dump($databaseName);
+   }
+
+The output would then resemble::
+
+   string(5) "local"
+   string(4) "test"
+
+See Also
+--------
+
+- :phpmethod:`MongoDB\\Client::listDatabases()`
+- :manual:`listDatabases </reference/command/listDatabases>` command reference
+  in the MongoDB manual
+- `Enumerating Databases
+  <https://github.com/mongodb/specifications/blob/master/source/enumerate-databases.rst>`_
+  specification
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBClient-listDatabases.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBClient-listDatabases.txt
new file mode 100644
index 0000000000000000000000000000000000000000..7f27cee8e3325e0ef406679368265c043ba84512
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBClient-listDatabases.txt	
@@ -0,0 +1,88 @@
+================================
+MongoDB\\Client::listDatabases()
+================================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\Client::listDatabases()
+
+   Returns information for all databases on the server.
+
+   .. code-block:: php
+
+      function listDatabases(array $options = []): MongoDB\Model\DatabaseInfoIterator
+
+   This method has the following parameters:
+
+   .. include:: /includes/apiargs/MongoDBClient-method-listDatabases-param.rst
+
+   The ``$options`` parameter supports the following options:
+
+   .. include:: /includes/apiargs/MongoDBClient-method-listDatabases-option.rst
+
+Return Values
+-------------
+
+A traversable :phpclass:`MongoDB\\Model\\DatabaseInfoIterator`, which contains
+a :phpclass:`MongoDB\\Model\\DatabaseInfo` object for each database on the
+server.
+
+Errors/Exceptions
+-----------------
+
+.. include:: /includes/extracts/error-unexpectedvalueexception.rst
+.. include:: /includes/extracts/error-invalidargumentexception.rst
+.. include:: /includes/extracts/error-driver-runtimeexception.rst
+
+Example
+-------
+
+The following example lists all databases on the server:
+
+.. code-block:: php
+
+   <?php
+
+   $client = new MongoDB\Client;
+
+   foreach ($client->listDatabases() as $databaseInfo) {
+       var_dump($databaseInfo);
+   }
+
+The output would then resemble::
+
+   object(MongoDB\Model\DatabaseInfo)#4 (3) {
+     ["name"]=>
+     string(5) "local"
+     ["sizeOnDisk"]=>
+     float(65536)
+     ["empty"]=>
+     bool(false)
+   }
+   object(MongoDB\Model\DatabaseInfo)#7 (3) {
+     ["name"]=>
+     string(4) "test"
+     ["sizeOnDisk"]=>
+     float(32768)
+     ["empty"]=>
+     bool(false)
+   }
+
+See Also
+--------
+
+- :phpmethod:`MongoDB\\Client::listDatabaseNames()`
+- :manual:`listDatabases </reference/command/listDatabases>` command reference
+  in the MongoDB manual
+- `Enumerating Databases
+  <https://github.com/mongodb/specifications/blob/master/source/enumerate-databases.rst>`_
+  specification
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBClient-selectCollection.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBClient-selectCollection.txt
new file mode 100644
index 0000000000000000000000000000000000000000..6ce12df7b1226bdbd7c7989bd25fc5bc8d02270b
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBClient-selectCollection.txt	
@@ -0,0 +1,83 @@
+===================================
+MongoDB\\Client::selectCollection()
+===================================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\Client::selectCollection()
+
+   Selects a collection on the server.
+
+   .. code-block:: php
+
+      function selectCollection($databaseName, $collectionName, array $options = []): MongoDB\Collection
+
+   This method has the following parameters:
+
+   .. include:: /includes/apiargs/MongoDBClient-method-selectCollection-param.rst
+
+   The ``$options`` parameter supports the following options:
+
+   .. include:: /includes/apiargs/MongoDBClient-method-selectCollection-option.rst
+
+Return Values
+-------------
+
+A :phpclass:`MongoDB\\Collection` object.
+
+Errors/Exceptions
+-----------------
+
+.. include:: /includes/extracts/error-invalidargumentexception.rst
+
+Behavior
+--------
+
+The selected collection inherits options such as read preference and type
+mapping from the :phpclass:`Client <MongoDB\\Client>` object. Options may be
+overridden via the ``$options`` parameter.
+
+Example
+-------
+
+The following example selects the ``users`` collection in the ``test`` database:
+
+.. code-block:: php
+
+   <?php
+
+   $client = new MongoDB\Client;
+
+   $collection = $client->selectCollection('test', 'users');
+
+The following example selects the ``users`` collection in the ``test`` database
+with a custom read preference:
+
+.. code-block:: php
+
+   <?php
+
+   $client = new MongoDB\Client;
+
+   $collection = $client->selectCollection(
+       'test',
+       'users',
+       [
+           'readPreference' => new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_SECONDARY),
+       ]
+   );
+
+See Also
+--------
+
+- :phpmethod:`MongoDB\\Collection::__construct()`
+- :phpmethod:`MongoDB\\Database::selectCollection()`
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBClient-selectDatabase.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBClient-selectDatabase.txt
new file mode 100644
index 0000000000000000000000000000000000000000..10dc4d8ad8cbbc97269f1483a0f37bef07c0c508
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBClient-selectDatabase.txt	
@@ -0,0 +1,82 @@
+=================================
+MongoDB\\Client::selectDatabase()
+=================================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\Client::selectDatabase()
+
+   Selects a database on the server.
+
+   .. code-block:: php
+
+      function selectDatabase($databaseName, array $options = []): MongoDB\Database
+
+   This method has the following parameters:
+
+   .. include:: /includes/apiargs/MongoDBClient-method-selectDatabase-param.rst
+
+   The ``$options`` parameter supports the following options:
+
+   .. include:: /includes/apiargs/MongoDBClient-method-selectDatabase-option.rst
+
+Return Values
+-------------
+
+A :phpclass:`MongoDB\\Database` object.
+
+Errors/Exceptions
+-----------------
+
+.. include:: /includes/extracts/error-invalidargumentexception.rst
+
+Behavior
+--------
+
+The selected database inherits options such as read preference and type mapping
+from the :phpclass:`Client <MongoDB\\Client>` object. Options may be overridden
+via the ``$options`` parameter.
+
+Example
+-------
+
+The following example selects the ``test`` database:
+
+.. code-block:: php
+
+   <?php
+
+   $client = new MongoDB\Client;
+
+   $db = $client->selectDatabase('test');
+
+The following examples selects the ``test`` database with a custom read
+preference:
+
+.. code-block:: php
+
+   <?php
+
+   $client = new MongoDB\Client;
+
+   $db = $client->selectDatabase(
+       'test',
+       [
+           'readPreference' => new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_SECONDARY),
+       ]
+   );
+
+See Also
+--------
+
+- :phpmethod:`MongoDB\\Client::__get()`
+- :phpmethod:`MongoDB\\Database::__construct()`
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBClient-startSession.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBClient-startSession.txt
new file mode 100644
index 0000000000000000000000000000000000000000..c3fcce89a2d867fff532f219da402c7bec2a6310
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBClient-startSession.txt	
@@ -0,0 +1,82 @@
+===============================
+MongoDB\\Client::startSession()
+===============================
+
+.. versionadded:: 1.3
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\Client::startSession()
+
+   Start a new client session for use with this client.
+
+   .. code-block:: php
+
+      function startSession(array $options = []): MongoDB\Driver\Session
+
+   Refer to the :php:`MongoDB\\Driver\\Manager::startSession()
+   <mongodb-driver-manager.startsession>` extension reference for accepted
+   options.
+
+Return Values
+-------------
+
+A :php:`MongoDB\Driver\Session <mongodb-driver-session>` object.
+
+Errors/Exceptions
+-----------------
+
+.. include:: /includes/extracts/error-driver-invalidargumentexception.rst
+.. include:: /includes/extracts/error-driver-runtimeexception.rst
+
+Example
+-------
+
+The following example starts a new session:
+
+.. code-block:: php
+
+   <?php
+
+   $client = new MongoDB\Client;
+
+   $session = $client->startSession();
+
+   var_dump($session);
+
+The output would then resemble::
+
+   object(MongoDB\Driver\Session)#2043 (4) {
+     ["logicalSessionId"]=>
+     array(1) {
+       ["id"]=>
+       object(MongoDB\BSON\Binary)#225 (2) {
+         ["data"]=>
+         string(16) "................"
+         ["type"]=>
+         int(4)
+       }
+     }
+     ["clusterTime"]=>
+     NULL
+     ["causalConsistency"]=>
+     bool(true)
+     ["operationTime"]=>
+     NULL
+   }
+
+See Also
+--------
+
+- :php:`MongoDB\\Driver\\Manager::startSession()
+  <manual/en/mongodb-driver-manager.startsession.php>`
+- :ref:`Causal Consistency <causal-consistency>` in the MongoDB manual
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBClient-watch.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBClient-watch.txt
new file mode 100644
index 0000000000000000000000000000000000000000..0e7aab34a9cf18471ad2d63a6ead8034bba2c962
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBClient-watch.txt	
@@ -0,0 +1,123 @@
+========================
+MongoDB\\Client::watch()
+========================
+
+.. versionadded:: 1.4
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\Client::watch()
+
+   Executes a :manual:`change stream </changeStreams>` operation on the client.
+   The change stream can be watched for cluster-level changes.
+
+   .. code-block:: php
+
+      function watch(array $pipeline = [], array $options = []): MongoDB\ChangeStream
+
+   This method has the following parameters:
+
+   .. include:: /includes/apiargs/MongoDBClient-method-watch-param.rst
+
+   The ``$options`` parameter supports the following options:
+
+   .. include:: /includes/apiargs/MongoDBClient-method-watch-option.rst
+
+Return Values
+-------------
+
+A :phpclass:`MongoDB\\ChangeStream` object, which allows for iteration of
+events in the change stream via the :php:`Iterator <class.iterator>` interface.
+
+Errors/Exceptions
+-----------------
+
+.. include:: /includes/extracts/error-unexpectedvalueexception.rst
+.. include:: /includes/extracts/error-unsupportedexception.rst
+.. include:: /includes/extracts/error-invalidargumentexception.rst
+.. include:: /includes/extracts/error-driver-runtimeexception.rst
+
+Examples
+--------
+
+This example reports events while iterating a change stream.
+
+.. code-block:: php
+
+   <?php
+
+   $uri = 'mongodb://rs1.example.com,rs2.example.com/?replicaSet=myReplicaSet';
+
+   $client = new MongoDB\Client($uri);
+
+   $changeStream = $client->watch();
+
+   for ($changeStream->rewind(); true; $changeStream->next()) {
+       if ( ! $changeStream->valid()) {
+           continue;
+       }
+
+       $event = $changeStream->current();
+
+       if ($event['operationType'] === 'invalidate') {
+           break;
+       }
+
+       $ns = sprintf('%s.%s', $event['ns']['db'], $event['ns']['coll']);
+       $id = json_encode($event['documentKey']['_id']);
+
+       switch ($event['operationType']) {
+           case 'delete':
+               printf("Deleted document in %s with _id: %s\n\n", $ns, $id);
+               break;
+
+           case 'insert':
+               printf("Inserted new document in %s\n", $ns);
+               echo json_encode($event['fullDocument']), "\n\n";
+               break;
+
+           case 'replace':
+               printf("Replaced new document in %s with _id: %s\n", $ns, $id);
+               echo json_encode($event['fullDocument']), "\n\n";
+               break;
+
+           case 'update':
+               printf("Updated document in %s with _id: %s\n", $ns, $id);
+               echo json_encode($event['updateDescription']), "\n\n";
+               break;
+       }
+   }
+
+Assuming that a document was inserted, updated, and deleted while the above
+script was iterating the change stream, the output would then resemble:
+
+.. code-block:: none
+
+   Inserted new document in app.user
+   {"_id":{"$oid":"5b329b6674083047cc05e607"},"username":"bob"}
+
+   Inserted new document in app.products
+   {"_id":{"$oid":"5b329b6a74083047cc05e608"},"name":"Widget","quantity":5}
+
+   Inserted new document in logs.messages
+   {"_id":{"$oid":"5b329b7374083047cc05e609"},"msg":"bob purchased a widget"}
+
+See Also
+--------
+
+- :phpmethod:`MongoDB\\Collection::watch()`
+- :phpmethod:`MongoDB\\Database::watch()`
+- :manual:`Aggregation Pipeline </core/aggregation-pipeline>` documentation in
+  the MongoDB Manual
+- :manual:`Change Streams </changeStreams>` documentation in the MongoDB manual
+- :manual:`Change Events </reference/change-events/>` documentation in the
+  MongoDB manual
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBClient__construct.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBClient__construct.txt
new file mode 100644
index 0000000000000000000000000000000000000000..ad864d1869dbff99de377f2c1c608ce7e50a53fa
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBClient__construct.txt	
@@ -0,0 +1,143 @@
+==============================
+MongoDB\\Client::__construct()
+==============================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\Client::__construct()
+
+   Constructs a new :phpclass:`Client <MongoDB\\Client>` instance.
+
+   .. code-block:: php
+
+      function __construct($uri = 'mongodb://127.0.0.1/', array $uriOptions = [], array $driverOptions = [])
+
+   This constructor has the following parameters:
+
+   .. include:: /includes/apiargs/MongoDBClient-method-construct-param.rst
+
+   The ``$driverOptions`` parameter supports the following options:
+
+   .. include:: /includes/apiargs/MongoDBClient-method-construct-driverOptions.rst
+
+Errors/Exceptions
+-----------------
+
+.. include:: /includes/extracts/error-invalidargumentexception.rst
+.. include:: /includes/extracts/error-driver-invalidargumentexception.rst
+.. include:: /includes/extracts/error-driver-runtimeexception.rst
+
+Behavior
+--------
+
+A :php:`MongoDB\\Driver\\Manager <mongodb-driver-manager>` is constructed
+internally. Per the `Server Discovery and Monitoring
+<https://github.com/mongodb/specifications/blob/master/source/server-discovery-and-monitoring/server-discovery-and-monitoring.rst#single-threaded-client-construction>`_
+specification, :php:`MongoDB\\Driver\\Manager::__construct()
+<mongodb-driver-manager.construct>` performs no I/O. Connections will be
+initialized on demand, when the first operation is executed.
+
+Examples
+--------
+
+Connecting to a Replica Set
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+If you do not specify a ``$uri`` value, the driver connects to a standalone
+:program:`mongod` on ``127.0.0.1`` via port ``27017``. The following example
+demonstrates how to connect to a replica set with a custom read preference:
+
+.. code-block:: php
+
+   <?php
+
+   $client = new MongoDB\Client(
+       'mongodb://rs1.example.com,rs2.example.com/?replicaSet=myReplicaSet',
+       [
+           'readPreference' => 'secondaryPreferred',
+       ]
+   );
+
+Connecting with SSL and Authentication
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The following example demonstrates how to connect to a MongoDB replica set with
+SSL and authentication, as is used for `MongoDB Atlas
+<https://cloud.mongodb.com/?jmp=docs>`_:
+
+.. code-block:: php
+
+   <?php
+
+   $client = new MongoDB\Client(
+       'mongodb://myUsername:myPassword@rs1.example.com,rs2.example.com/?ssl=true&replicaSet=myReplicaSet&authSource=admin'
+   );
+
+Alternatively, the authentication credentials and URI parameters may be
+specified in the constructor's ``$uriOptions`` parameter:
+
+.. code-block:: php
+
+   <?php
+
+   $client = new MongoDB\Client(
+       'mongodb://rs1.example.com,rs2.example.com/'
+       [
+           'username' => 'myUsername',
+           'password' => 'myPassword',
+           'ssl' => true,
+           'replicaSet' => 'myReplicaSet',
+           'authSource' => 'admin',
+       ],
+   );
+
+The driver supports additional :php:`SSL options
+<mongodb-driver-manager.construct#mongodb-driver-manager.construct-driveroptions>`,
+which may be specified in the constructor's ``$driverOptions`` parameter. Those
+options are covered in the :php:`MongoDB\\Driver\\Manager::__construct()
+<mongodb-driver-manager.construct>` documentation.
+
+Specifying a Custom Type Map
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+By default, the |php-library| deserializes BSON documents and arrays
+as :phpclass:`MongoDB\\Model\\BSONDocument` and
+:phpclass:`MongoDB\\Model\\BSONArray` objects, respectively. The following
+example demonstrates how to have the library unserialize everything as a PHP
+array, as was done in the legacy :php:`mongo extension <mongo>`.
+
+.. code-block:: php
+
+   <?php
+
+   $client = new MongoDB\Client(
+       null,
+       [],
+       [
+           'typeMap' => [
+               'root' => 'array',
+               'document' => 'array',
+               'array' => 'array',
+           ],
+       ]
+   );
+
+See Also
+--------
+
+- :php:`MongoDB\\Driver\\Manager::__construct()
+  <mongodb-driver-manager.construct>`
+- :manual:`Connection String URI Format </reference/connection-string>` in the
+  MongoDB manual
+- `Server Discovery and Monitoring
+  <https://github.com/mongodb/specifications/blob/master/source/server-discovery-and-monitoring/server-discovery-and-monitoring.rst#single-threaded-client-construction>`_
+  specification
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBClient__get.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBClient__get.txt
new file mode 100644
index 0000000000000000000000000000000000000000..c082457823d517dbf62525ffd9e0d513ef96ea7a
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBClient__get.txt	
@@ -0,0 +1,69 @@
+========================
+MongoDB\\Client::__get()
+========================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\Client::__get()
+
+   Selects a database on the server. This :php:`magic method <oop5.magic>` is
+   an alias for the :phpmethod:`selectDatabase()
+   <MongoDB\\Client::selectDatabase>` method.
+
+   .. code-block:: php
+
+      function __get($databaseName): MongoDB\Database
+
+   This method has the following parameters:
+
+   .. include:: /includes/apiargs/MongoDBClient-method-get-param.rst
+
+Return Values
+-------------
+
+A :phpclass:`MongoDB\\Database` object.
+
+Behavior
+--------
+
+The selected database inherits options such as read preference and type mapping
+from the :phpclass:`Client <MongoDB\\Client>` object. If you wish to override
+any options, use the :phpmethod:`MongoDB\\Client::selectDatabase` method.
+
+.. note::
+
+   To select databases whose names contain special characters, such as
+   ``-``, use complex syntax, as in ``$client->{'that-database'}``.
+
+   Alternatively, :phpmethod:`MongoDB\\Client::selectDatabase()` supports
+   selecting databases whose names contain special characters.
+
+Examples
+--------
+
+The following example selects the ``test`` and ``another-app`` databases:
+
+.. code-block:: php
+
+   <?php
+
+   $client = new MongoDB\Client;
+
+   $test = $client->test;
+   $anotherApp = $client->{'another-app'};
+
+See Also
+--------
+
+- :phpmethod:`MongoDB\\Client::selectDatabase()`
+- :phpmethod:`MongoDB\\Database::__construct()`
+- :php:`Property Overloading <oop5.overloading>` in the PHP Manual
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-aggregate.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-aggregate.txt
new file mode 100644
index 0000000000000000000000000000000000000000..d26d8c8e952b64c275dc0bcd4fb83f81684b4837
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-aggregate.txt	
@@ -0,0 +1,88 @@
+================================
+MongoDB\\Collection::aggregate()
+================================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\Collection::aggregate()
+
+   Executes an :manual:`aggregation framework pipeline
+   </core/aggregation-pipeline>` operation on the collection.
+
+   .. code-block:: php
+
+      function aggregate(array $pipeline, array $options = []): Traversable
+
+   This method has the following parameters:
+
+   .. include:: /includes/apiargs/MongoDBCollection-method-aggregate-param.rst
+
+   The ``$options`` parameter supports the following options:
+
+   .. include:: /includes/apiargs/MongoDBCollection-method-aggregate-option.rst
+
+Return Values
+-------------
+
+A :php:`MongoDB\\Driver\\Cursor <class.mongodb-driver-cursor>` or
+:php:`ArrayIterator <arrayiterator>` object. In both cases, the return value
+will be :php:`Traversable <traversable>`.
+
+Errors/Exceptions
+-----------------
+
+.. include:: /includes/extracts/error-unexpectedvalueexception.rst
+.. include:: /includes/extracts/error-unsupportedexception.rst
+.. include:: /includes/extracts/error-invalidargumentexception.rst
+.. include:: /includes/extracts/error-driver-runtimeexception.rst
+
+.. _php-coll-agg-method-behavior:
+
+Behavior
+--------
+
+:phpmethod:`MongoDB\\Collection::aggregate()`'s return value depends on the
+MongoDB server version and whether the ``useCursor`` option is specified. If
+``useCursor`` is ``true``, a :php:`MongoDB\\Driver\\Cursor
+<class.mongodb-driver-cursor>` object is returned. If ``useCursor`` is
+``false``, an :php:`ArrayIterator <arrayiterator>` is returned that wraps the
+``result`` array from the command response document. In both cases, the return
+value will be :php:`Traversable <traversable>`.
+
+Examples
+--------
+
+The following aggregation example uses a collection called ``names`` and groups
+the ``first_name`` field together, counts the total number of results in each
+group, and sorts the results by name.
+
+.. code-block:: php
+
+   <?php
+
+   $collection = (new MongoDB\Client)->test->names;
+
+   $cursor = $collection->aggregate(
+       [
+           ['$group' => ['_id' => '$first_name', 'name_count' => ['$sum' => 1]]],
+           ['$sort' => ['_id' => 1]],
+       ]
+   );
+
+See Also
+--------
+
+- :phpmethod:`MongoDB\\Database::aggregate()`
+- :manual:`aggregate </reference/command/aggregate>` command reference in the
+  MongoDB manual
+- :manual:`Aggregation Pipeline </core/aggregation-pipeline>` documentation in
+  the MongoDB Manual
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-bulkWrite.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-bulkWrite.txt
new file mode 100644
index 0000000000000000000000000000000000000000..e58688cbd4577a6a9935a58ceacbecf6acc112e9
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-bulkWrite.txt	
@@ -0,0 +1,64 @@
+================================
+MongoDB\\Collection::bulkWrite()
+================================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\Collection::bulkWrite()
+
+   Executes multiple write operations.
+
+   .. code-block:: php
+
+      function bulkWrite(array $operations, array $options = []): MongoDB\BulkWriteResult
+
+   This method has the following parameters:
+
+   .. include:: /includes/apiargs/MongoDBCollection-method-bulkWrite-param.rst
+
+   The ``$options`` parameter supports the following options:
+
+   .. include:: /includes/apiargs/MongoDBCollection-method-bulkWrite-option.rst
+
+Return Values
+-------------
+
+A :phpclass:`MongoDB\\BulkWriteResult` object, which encapsulates a
+:php:`MongoDB\\Driver\\WriteResult <class.mongodb-driver-writeresult>` object.
+
+Errors/Exceptions
+-----------------
+
+.. include:: /includes/extracts/error-unsupportedexception.rst
+.. include:: /includes/extracts/error-invalidargumentexception.rst
+.. include:: /includes/extracts/error-driver-bulkwriteexception.rst
+.. include:: /includes/extracts/error-driver-runtimeexception.rst
+
+Behavior
+--------
+
+.. include:: /includes/extracts/bulkwriteexception-result.rst
+.. include:: /includes/extracts/bulkwriteexception-ordered.rst
+
+.. todo: add output and examples
+
+See Also
+--------
+
+- :phpmethod:`MongoDB\\Collection::deleteMany()`
+- :phpmethod:`MongoDB\\Collection::deleteOne()`
+- :phpmethod:`MongoDB\\Collection::insertMany()`
+- :phpmethod:`MongoDB\\Collection::insertOne()`
+- :phpmethod:`MongoDB\\Collection::replaceOne()`
+- :phpmethod:`MongoDB\\Collection::updateMany()`
+- :phpmethod:`MongoDB\\Collection::updateOne()`
+- :doc:`/tutorial/crud`
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-count.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-count.txt
new file mode 100644
index 0000000000000000000000000000000000000000..0c590630486f8cda8699f071f32d4dd09080f22e
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-count.txt	
@@ -0,0 +1,70 @@
+============================
+MongoDB\\Collection::count()
+============================
+
+.. deprecated:: 1.4
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\Collection::count()
+
+   Count the number of documents that match the filter criteria.
+
+   .. code-block:: php
+
+      function count($filter = [], array $options = []): integer
+
+   This method has the following parameters:
+
+   .. include:: /includes/apiargs/MongoDBCollection-method-count-param.rst
+
+   The ``$options`` parameter supports the following options:
+
+   .. include:: /includes/apiargs/MongoDBCollection-method-count-option.rst
+
+Return Values
+-------------
+
+The number of documents matching the filter criteria.
+
+Errors/Exceptions
+-----------------
+
+.. include:: /includes/extracts/error-unexpectedvalueexception.rst
+.. include:: /includes/extracts/error-unsupportedexception.rst
+.. include:: /includes/extracts/error-invalidargumentexception.rst
+.. include:: /includes/extracts/error-driver-runtimeexception.rst
+
+Behavior
+--------
+
+This method is deprecated and cannot be executed within a transaction. It has
+always been implemented using the :manual:`count </reference/command/count>`
+command. The behavior of the ``count`` command differs depending on the options
+passed to it and may or may not provide an accurate count. When no query filter
+is provided, the ``count`` command provides an estimate using collection
+metadata. Even when provided with a query filter the ``count`` command can
+return inaccurate results with a sharded cluster if orphaned documents exist or
+if a chunk migration is in progress. The
+:phpmethod:`MongoDB\\Collection::countDocuments()` method avoids these sharded
+cluster problems entirely when used with MongoDB 3.6+, and when a primary read
+preference with older sharded clusters.
+
+.. include:: /includes/extracts/note-bson-comparison.rst
+
+See Also
+--------
+
+- :manual:`count </reference/command/count>` command reference in the MongoDB
+  manual
+- :phpmethod:`MongoDB\\Collection::countDocuments()`
+- :phpmethod:`MongoDB\\Collection::estimatedDocumentCount()`
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-countDocuments.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-countDocuments.txt
new file mode 100644
index 0000000000000000000000000000000000000000..b66171c27125ae6ef23bfa910319214776c8541a
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-countDocuments.txt	
@@ -0,0 +1,89 @@
+=====================================
+MongoDB\\Collection::countDocuments()
+=====================================
+
+.. versionadded:: 1.4
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\Collection::countDocuments()
+
+   Count the number of documents that match the filter criteria.
+
+   .. code-block:: php
+
+      function countDocuments($filter = [], array $options = []): integer
+
+   This method has the following parameters:
+
+   .. include:: /includes/apiargs/MongoDBCollection-method-countDocuments-param.rst
+
+   The ``$options`` parameter supports the following options:
+
+   .. include:: /includes/apiargs/MongoDBCollection-method-countDocuments-option.rst
+
+Return Values
+-------------
+
+The number of documents matching the filter criteria.
+
+Errors/Exceptions
+-----------------
+
+.. include:: /includes/extracts/error-unexpectedvalueexception.rst
+.. include:: /includes/extracts/error-unsupportedexception.rst
+.. include:: /includes/extracts/error-invalidargumentexception.rst
+.. include:: /includes/extracts/error-driver-runtimeexception.rst
+
+Behavior
+--------
+
+Internally, this method uses the ``$group`` aggregation pipeline operator to
+obtain the result. If a ``filter`` parameter is given, this is converted into
+a ``$match`` pipeline operator. Optional ``$skip`` and ``$limit`` stages are
+added between ``$match`` and ``group`` if present in the options.
+
+.. note::
+
+   This method counts documents on the server side. To obtain an approximate
+   total number of documents without filters, the
+   :phpmethod:`MongoDB\\Collection::estimatedDocumentCount()` method can be
+   used. This method estimates the number of documents based on collection
+   metadata, thus sacrificing accuracy for performance.
+
+Since this method uses an aggregation pipeline, some query operators accepted
+within a :phpmethod:`MongoDB\\Collection::count()` ``filter`` cannot be used.
+Consider the following alternatives to these restricted operators:
+
+.. list-table::
+   :header-rows: 1
+
+   * - Restricted
+     - Alternative Syntax
+
+   * - :query:`$near`
+     - :query:`$geoWithin` with :query:`$center`
+
+   * - :query:`$nearSphere`
+     - :query:`$geoWithin` with :query:`$centerSphere`
+
+   * - :query:`$where`
+     - :query:`$expr` (requires MongoDB 3.6+)
+
+.. include:: /includes/extracts/note-bson-comparison.rst
+
+.. todo: add output and examples
+
+See Also
+--------
+
+- :phpmethod:`MongoDB\\Collection::estimatedDocumentCount()`
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-createIndex.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-createIndex.txt
new file mode 100644
index 0000000000000000000000000000000000000000..bdae57123a5d7ad9d924ad81f54d9c0451f189c1
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-createIndex.txt	
@@ -0,0 +1,109 @@
+==================================
+MongoDB\\Collection::createIndex()
+==================================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\Collection::createIndex()
+
+   Create an index for the collection.
+
+   .. code-block:: php
+
+      function createIndex($key, array $options = []): string
+
+   This method has the following parameters:
+
+   .. include:: /includes/apiargs/MongoDBCollection-method-createIndex-param.rst
+
+   The ``$options`` parameter accepts all index options that your MongoDB
+   version supports. MongoDB includes the following options:
+
+   .. include:: /includes/apiargs/MongoDBCollection-method-createIndex-option.rst
+
+   For a full list of the supported index creation options, refer to the
+   :manual:`createIndexes </reference/command/createIndexes>` command reference
+   in the MongoDB manual.
+
+Return Values
+-------------
+
+The name of the created index as a string.
+
+Errors/Exceptions
+-----------------
+
+.. include:: /includes/extracts/error-unsupportedexception.rst
+.. include:: /includes/extracts/error-invalidargumentexception.rst
+.. include:: /includes/extracts/error-driver-runtimeexception.rst
+
+Examples
+--------
+
+Create a Compound Index
+~~~~~~~~~~~~~~~~~~~~~~~
+
+The following example creates a :manual:`compound index </core/index-compound>`
+on the ``borough`` and ``cuisine`` fields in the ``restaurants`` collection in
+the ``test`` database.
+
+.. code-block:: php
+
+   <?php
+
+   $collection = (new MongoDB\Client)->selectCollection('test', 'restaurants');
+
+   $indexName = $collection->createIndex(['borough' => 1, 'cuisine' => 1]);
+
+   var_dump($indexName);
+
+The output would then resemble::
+
+   string(19) "borough_1_cuisine_1"
+
+Create a Partial Index
+~~~~~~~~~~~~~~~~~~~~~~
+
+The following example adds a :manual:`partial index </core/index-partial>` on
+the ``borough`` field in the ``restaurants`` collection in the ``test``
+database. The partial index indexes only documents where the ``borough`` field
+exists.
+
+.. code-block:: php
+
+   <?php
+
+   $collection = (new MongoDB\Client)->selectCollection('test', 'restaurants');
+
+   $indexName = $collection->createIndex(
+      ['borough' => 1],
+      [
+          'partialFilterExpression' => [
+              'borough' => ['$exists' => true],
+          ],
+      ]
+   );
+
+   var_dump($indexName);
+
+The output would then resemble::
+
+   string(9) "borough_1"
+
+See Also
+--------
+
+- :phpmethod:`MongoDB\\Collection::createIndexes()`
+- :doc:`/tutorial/indexes`
+- :manual:`createIndexes </reference/command/createIndexes>` command reference
+  in the MongoDB manual
+- :manual:`Index </indexes>` documentation in the MongoDB Manual
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-createIndexes.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-createIndexes.txt
new file mode 100644
index 0000000000000000000000000000000000000000..05a3c0be380fffbc737e67f4fe78abbfe1fd3d5d
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-createIndexes.txt	
@@ -0,0 +1,100 @@
+====================================
+MongoDB\\Collection::createIndexes()
+====================================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\Collection::createIndexes($indexes)
+
+   Create one or more indexes for the collection.
+
+   .. code-block:: php
+
+      function createIndexes(array $indexes, array $options = []): string[]
+
+   This method has the following parameters:
+
+   .. include:: /includes/apiargs/MongoDBCollection-method-createIndexes-param.rst
+
+   The ``$options`` parameter supports the following options:
+
+   .. include:: /includes/apiargs/MongoDBCollection-method-createIndexes-option.rst
+
+Return Values
+-------------
+
+The names of the created indexes as an array of strings.
+
+Errors/Exceptions
+-----------------
+
+.. include:: /includes/extracts/error-unsupportedexception.rst
+.. include:: /includes/extracts/error-invalidargumentexception.rst
+.. include:: /includes/extracts/error-driver-runtimeexception.rst
+
+``$indexes`` parameter
+----------------------
+
+The ``$indexes`` parameter is an array of index specification documents. Each
+element in ``$indexes`` must itself be an array or object with a ``key`` field,
+which corresponds to the ``$key`` parameter of :phpmethod:`createIndex()
+<MongoDB\\Collection::createIndex()>`. The array or object may include other
+fields that correspond to index options accepted by :phpmethod:`createIndex()
+<MongoDB\\Collection::createIndex()>` (excluding ``writeConcern``).
+
+For example, the following ``$indexes`` parameter creates two indexes. The first
+is an ascending unique index on the ``username`` field and the second is a
+2dsphere index on the ``loc`` field with a custom name::
+
+   [
+       [ 'key' => [ 'username' => 1 ], 'unique' => true ],
+       [ 'key' => [ 'loc' => '2dsphere' ], 'name' => 'geo_index' ],
+   ]
+
+Example
+-------
+
+The following example creates two indexes on the ``restaurants`` collection in
+the ``test`` database. One index is a compound index on the ``borough`` and
+``cuisine`` fields and the other is 2dsphere index on the ``loc`` field with a
+custom name.
+
+.. code-block:: php
+
+   <?php
+
+   $collection = (new MongoDB\Client)->selectCollection('test', 'restaurants');
+
+   $indexNames = $collection->createIndexes([
+       [ 'key' => [ 'borough' => 1, 'cuisine' => 1] ],
+       [ 'key' => [ 'loc' => '2dsphere'], 'name' => 'geo_index' ],
+   ]);
+
+   var_dump($indexNames);
+
+The output would then resemble::
+
+   array(2) {
+     [0]=>
+     string(19) "borough_1_cuisine_1"
+     [1]=>
+     string(9) "geo_index"
+   }
+
+See Also
+--------
+
+- :phpmethod:`MongoDB\\Collection::createIndex()`
+- :doc:`/tutorial/indexes`
+- :manual:`createIndexes </reference/command/createIndexes>` command reference
+  in the MongoDB manual
+- :manual:`Index </indexes>` documentation in the MongoDB Manual
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-deleteMany.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-deleteMany.txt
new file mode 100644
index 0000000000000000000000000000000000000000..df1a1ac818c4cc77bc574b42f8217837e1448395
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-deleteMany.txt	
@@ -0,0 +1,82 @@
+=================================
+MongoDB\\Collection::deleteMany()
+=================================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\Collection::deleteMany()
+
+   Deletes all documents that match the filter criteria.
+
+   .. code-block:: php
+
+      function deleteMany($filter, array $options = []): MongoDB\DeleteResult
+
+   This method has the following parameters:
+
+   .. include:: /includes/apiargs/MongoDBCollection-method-deleteMany-param.rst
+
+   The ``$options`` parameter supports the following options:
+
+   .. include:: /includes/apiargs/MongoDBCollection-method-deleteMany-option.rst
+
+Return Values
+-------------
+
+A :phpclass:`MongoDB\\DeleteResult` object, which encapsulates a
+:php:`MongoDB\\Driver\\WriteResult <class.mongodb-driver-writeresult>` object.
+
+Errors/Exceptions
+-----------------
+
+.. include:: /includes/extracts/error-unsupportedexception.rst
+.. include:: /includes/extracts/error-invalidargumentexception.rst
+.. include:: /includes/extracts/error-driver-bulkwriteexception.rst
+.. include:: /includes/extracts/error-driver-runtimeexception.rst
+
+Behavior
+--------
+
+.. include:: /includes/extracts/note-bson-comparison.rst
+.. include:: /includes/extracts/bulkwriteexception-result.rst
+
+Example
+-------
+
+The following example deletes all of the documents in the ``users`` collection
+that have ``"ny"`` as the value for the ``state`` field:
+
+.. code-block:: php
+
+   <?php
+
+   $collection = (new MongoDB\Client)->test->users;
+   $collection->drop();
+
+   $collection->insertOne(['name' => 'Bob', 'state' => 'ny']);
+   $collection->insertOne(['name' => 'Alice', 'state' => 'ny']);
+   $deleteResult = $collection->deleteMany(['state' => 'ny']);
+
+   printf("Deleted %d document(s)\n", $deleteResult->getDeletedCount());
+
+The output would then resemble::
+
+   Deleted 2 document(s)
+
+See Also
+--------
+
+- :phpmethod:`MongoDB\\Collection::deleteOne()`
+- :phpmethod:`MongoDB\\Collection::bulkWrite()`
+- :doc:`/tutorial/crud`
+- :manual:`delete </reference/command/delete>` command reference in the MongoDB
+  manual
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-deleteOne.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-deleteOne.txt
new file mode 100644
index 0000000000000000000000000000000000000000..0c31bfb5f5b38d1153bf5b43ab586ea51c66feb7
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-deleteOne.txt	
@@ -0,0 +1,84 @@
+================================
+MongoDB\\Collection::deleteOne()
+================================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\Collection::deleteOne()
+
+   Deletes at most one document that matches the filter criteria. If multiple
+   documents match the filter criteria, only the :term:`first <natural order>`
+   matching document will be deleted.
+
+   .. code-block:: php
+
+      function deleteOne($filter, array $options = []): MongoDB\DeleteResult
+
+   This method has the following parameters:
+
+   .. include:: /includes/apiargs/MongoDBCollection-method-deleteOne-param.rst
+
+   The ``$options`` parameter supports the following options:
+
+   .. include:: /includes/apiargs/MongoDBCollection-method-deleteOne-option.rst
+
+Return Values
+-------------
+
+A :phpclass:`MongoDB\\DeleteResult` object, which encapsulates a
+:php:`MongoDB\\Driver\\WriteResult <class.mongodb-driver-writeresult>` object.
+
+Errors/Exceptions
+-----------------
+
+.. include:: /includes/extracts/error-unsupportedexception.rst
+.. include:: /includes/extracts/error-invalidargumentexception.rst
+.. include:: /includes/extracts/error-driver-bulkwriteexception.rst
+.. include:: /includes/extracts/error-driver-runtimeexception.rst
+
+Behavior
+--------
+
+.. include:: /includes/extracts/note-bson-comparison.rst
+.. include:: /includes/extracts/bulkwriteexception-result.rst
+
+Example
+-------
+
+The following example deletes one document in the ``users`` collection that has
+has ``"ny"`` as the value for the ``state`` field:
+
+.. code-block:: php
+
+   <?php
+
+   $collection = (new MongoDB\Client)->test->users;
+   $collection->drop();
+
+   $collection->insertOne(['name' => 'Bob', 'state' => 'ny']);
+   $collection->insertOne(['name' => 'Alice', 'state' => 'ny']);
+   $deleteResult = $collection->deleteOne(['state' => 'ny']);
+
+   printf("Deleted %d document(s)\n", $deleteResult->getDeletedCount());
+
+The output would then resemble::
+
+   Deleted 1 document(s)
+
+See Also
+--------
+
+- :phpmethod:`MongoDB\\Collection::deleteMany()`
+- :phpmethod:`MongoDB\\Collection::bulkWrite()`
+- :doc:`/tutorial/crud`
+- :manual:`delete </reference/command/delete>` command reference  in the MongoDB
+  manual
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-distinct.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-distinct.txt
new file mode 100644
index 0000000000000000000000000000000000000000..bf7ffb4c0e526a20b35b6cd988d5b5ef1b4f6601
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-distinct.txt	
@@ -0,0 +1,262 @@
+===============================
+MongoDB\\Collection::distinct()
+===============================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\Collection::distinct()
+
+   Finds the distinct values for a specified field across the collection.
+
+   .. code-block:: php
+
+      function distinct($fieldName, $filter = [], array $options = []): mixed[]
+
+   This method has the following parameters:
+
+   .. include:: /includes/apiargs/MongoDBCollection-method-distinct-param.rst
+
+   The ``$options`` parameter supports the following options:
+
+   .. include:: /includes/apiargs/MongoDBCollection-method-distinct-option.rst
+
+Return Values
+-------------
+
+An array of the distinct values.
+
+Errors/Exceptions
+-----------------
+
+.. include:: /includes/extracts/error-unexpectedvalueexception.rst
+.. include:: /includes/extracts/error-unsupportedexception.rst
+.. include:: /includes/extracts/error-invalidargumentexception.rst
+.. include:: /includes/extracts/error-driver-runtimeexception.rst
+
+Behavior
+--------
+
+.. include:: /includes/extracts/note-bson-comparison.rst
+
+Examples
+--------
+
+Return Distinct Values for a Field
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The following example identifies the distinct values for the ``borough`` field
+in the ``restaurants`` collection in the ``test`` database.
+
+.. code-block:: php
+
+   <?php
+
+   $collection = (new MongoDB\Client)->test->restaurants;
+
+   $distinct = $collection->distinct('borough');
+
+   var_dump($distinct);
+
+The output would then resemble::
+
+   array(6) {
+     [0]=>
+     string(5) "Bronx"
+     [1]=>
+     string(8) "Brooklyn"
+     [2]=>
+     string(9) "Manhattan"
+     [3]=>
+     string(7) "Missing"
+     [4]=>
+     string(6) "Queens"
+     [5]=>
+     string(13) "Staten Island"
+   }
+
+Return Distinct Values Using a Filter
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The following example identifies the distinct values for the ``cuisine`` field
+in the ``restaurants`` collection in the ``test`` database for documents where
+the ``borough`` is ``Queens``:
+
+.. code-block:: php
+
+   <?php
+
+   $collection = (new MongoDB\Client)->test->restaurants;
+
+   $distinct = $collection->distinct('cuisine', ['borough' => 'Queens']);
+
+   var_dump($distinct);
+
+The output would then resemble::
+
+   array(75) {
+     [0]=>
+     string(6) "Afghan"
+     [1]=>
+     string(7) "African"
+     [2]=>
+     string(9) "American "
+     [3]=>
+     string(8) "Armenian"
+     [4]=>
+     string(5) "Asian"
+     [5]=>
+     string(10) "Australian"
+     [6]=>
+     string(15) "Bagels/Pretzels"
+     [7]=>
+     string(6) "Bakery"
+     [8]=>
+     string(11) "Bangladeshi"
+     [9]=>
+     string(8) "Barbecue"
+     [10]=>
+     string(55) "Bottled beverages, including water, sodas, juices, etc."
+     [11]=>
+     string(9) "Brazilian"
+     [12]=>
+     string(4) "Cafe"
+     [13]=>
+     string(16) "Café/Coffee/Tea"
+     [14]=>
+     string(5) "Cajun"
+     [15]=>
+     string(9) "Caribbean"
+     [16]=>
+     string(7) "Chicken"
+     [17]=>
+     string(7) "Chinese"
+     [18]=>
+     string(13) "Chinese/Cuban"
+     [19]=>
+     string(16) "Chinese/Japanese"
+     [20]=>
+     string(11) "Continental"
+     [21]=>
+     string(6) "Creole"
+     [22]=>
+     string(5) "Czech"
+     [23]=>
+     string(12) "Delicatessen"
+     [24]=>
+     string(6) "Donuts"
+     [25]=>
+     string(16) "Eastern European"
+     [26]=>
+     string(8) "Egyptian"
+     [27]=>
+     string(7) "English"
+     [28]=>
+     string(8) "Filipino"
+     [29]=>
+     string(6) "French"
+     [30]=>
+     string(17) "Fruits/Vegetables"
+     [31]=>
+     string(6) "German"
+     [32]=>
+     string(5) "Greek"
+     [33]=>
+     string(10) "Hamburgers"
+     [34]=>
+     string(16) "Hotdogs/Pretzels"
+     [35]=>
+     string(31) "Ice Cream, Gelato, Yogurt, Ices"
+     [36]=>
+     string(6) "Indian"
+     [37]=>
+     string(10) "Indonesian"
+     [38]=>
+     string(5) "Irish"
+     [39]=>
+     string(7) "Italian"
+     [40]=>
+     string(8) "Japanese"
+     [41]=>
+     string(13) "Jewish/Kosher"
+     [42]=>
+     string(30) "Juice, Smoothies, Fruit Salads"
+     [43]=>
+     string(6) "Korean"
+     [44]=>
+     string(64) "Latin (Cuban, Dominican, Puerto Rican, South & Central American)"
+     [45]=>
+     string(13) "Mediterranean"
+     [46]=>
+     string(7) "Mexican"
+     [47]=>
+     string(14) "Middle Eastern"
+     [48]=>
+     string(8) "Moroccan"
+     [49]=>
+     string(25) "Not Listed/Not Applicable"
+     [50]=>
+     string(18) "Nuts/Confectionary"
+     [51]=>
+     string(5) "Other"
+     [52]=>
+     string(9) "Pakistani"
+     [53]=>
+     string(16) "Pancakes/Waffles"
+     [54]=>
+     string(8) "Peruvian"
+     [55]=>
+     string(5) "Pizza"
+     [56]=>
+     string(13) "Pizza/Italian"
+     [57]=>
+     string(6) "Polish"
+     [58]=>
+     string(10) "Portuguese"
+     [59]=>
+     string(7) "Russian"
+     [60]=>
+     string(6) "Salads"
+     [61]=>
+     string(10) "Sandwiches"
+     [62]=>
+     string(30) "Sandwiches/Salads/Mixed Buffet"
+     [63]=>
+     string(7) "Seafood"
+     [64]=>
+     string(9) "Soul Food"
+     [65]=>
+     string(18) "Soups & Sandwiches"
+     [66]=>
+     string(12) "Southwestern"
+     [67]=>
+     string(7) "Spanish"
+     [68]=>
+     string(5) "Steak"
+     [69]=>
+     string(5) "Tapas"
+     [70]=>
+     string(7) "Tex-Mex"
+     [71]=>
+     string(4) "Thai"
+     [72]=>
+     string(7) "Turkish"
+     [73]=>
+     string(10) "Vegetarian"
+     [74]=>
+     string(29) "Vietnamese/Cambodian/Malaysia"
+   }
+
+See Also
+--------
+
+- :manual:`distinct </reference/command/distinct>` command reference in the
+  MongoDB manual
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-drop.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-drop.txt
new file mode 100644
index 0000000000000000000000000000000000000000..c1762871bfe95e84e420e92a93f8f7e236b3afc6
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-drop.txt	
@@ -0,0 +1,81 @@
+===========================
+MongoDB\\Collection::drop()
+===========================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\Collection::drop()
+
+   Drop the collection.
+
+   .. code-block:: php
+
+      function drop(array $options = []): array|object
+
+   This method has the following parameters:
+
+   .. include:: /includes/apiargs/MongoDBCollection-method-drop-param.rst
+
+   The ``$options`` parameter supports the following options:
+
+   .. include:: /includes/apiargs/MongoDBCollection-method-drop-option.rst
+
+Return Values
+-------------
+
+An array or object with the result document of the :manual:`drop
+</reference/command/drop>` command. The return type will depend on the
+``typeMap`` option.
+
+Errors/Exceptions
+-----------------
+
+.. include:: /includes/extracts/error-unsupportedexception.rst
+.. include:: /includes/extracts/error-invalidargumentexception.rst
+.. include:: /includes/extracts/error-driver-runtimeexception.rst
+
+Example
+-------
+
+The following operation drops the ``restaurants`` collection in the ``test``
+database:
+
+.. code-block:: php
+
+   <?php
+
+   $collection = (new MongoDB\Client)->test->restaurants;
+
+   $result = $collection->drop();
+
+   var_dump($result);
+
+The output would then resemble::
+
+   object(MongoDB\Model\BSONDocument)#9 (1) {
+     ["storage":"ArrayObject":private]=>
+     array(3) {
+       ["ns"]=>
+       string(16) "test.restaurants"
+       ["nIndexesWas"]=>
+       int(3)
+       ["ok"]=>
+       float(1)
+     }
+   }
+
+See Also
+--------
+
+- :phpmethod:`MongoDB\\Database::dropCollection()`
+- :manual:`drop </reference/command/drop>` command reference in the MongoDB
+  manual
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-dropIndex.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-dropIndex.txt
new file mode 100644
index 0000000000000000000000000000000000000000..880349bdf8878275184f24a5bda4d87de3c563e6
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-dropIndex.txt	
@@ -0,0 +1,81 @@
+================================
+MongoDB\\Collection::dropIndex()
+================================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\Collection::dropIndex()
+
+   Drop an index from the collection.
+
+   .. code-block:: php
+
+      function dropIndex($indexName, array $options = []): array|object
+
+   This method has the following parameters:
+
+   .. include:: /includes/apiargs/MongoDBCollection-method-dropIndex-param.rst
+
+   The ``$options`` parameter supports the following options:
+
+   .. include:: /includes/apiargs/MongoDBCollection-method-dropIndex-option.rst
+
+Return Values
+-------------
+
+An array or object with the result document of the :manual:`dropIndexes
+</reference/command/dropIndexes>` command. The return type will depend on the
+``typeMap`` option.
+
+Errors/Exceptions
+-----------------
+
+.. include:: /includes/extracts/error-unsupportedexception.rst
+.. include:: /includes/extracts/error-invalidargumentexception.rst
+.. include:: /includes/extracts/error-driver-runtimeexception.rst
+
+Example
+-------
+
+The following drops an indexes with name ``borough_1`` from the ``restaurants``
+collection in the ``test`` database:
+
+.. code-block:: php
+
+   <?php
+
+   $collection = (new MongoDB\Client)->test->restaurants;
+
+   $result = $collection->dropIndex('borough_1');
+
+   var_dump($result);
+
+The output would then resemble::
+
+   object(MongoDB\Model\BSONDocument)#9 (1) {
+     ["storage":"ArrayObject":private]=>
+     array(2) {
+       ["nIndexesWas"]=>
+       int(2)
+       ["ok"]=>
+       float(1)
+     }
+   }
+
+See Also
+--------
+
+- :phpmethod:`MongoDB\\Collection::dropIndexes()`
+- :doc:`/tutorial/indexes`
+- :manual:`dropIndexes </reference/command/dropIndexes>` command reference in
+  the MongoDB manual
+- :manual:`Index documentation </indexes>` in the MongoDB manual
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-dropIndexes.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-dropIndexes.txt
new file mode 100644
index 0000000000000000000000000000000000000000..8cdf9e43a496efc9032b0a5db019777506bc4c8d
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-dropIndexes.txt	
@@ -0,0 +1,84 @@
+==================================
+MongoDB\\Collection::dropIndexes()
+==================================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\Collection::dropIndexes()
+
+   Drop all indexes in the collection, except for the required index on the
+   ``_id`` field.
+
+   .. code-block:: php
+
+      function dropIndexes(array $options = []): array|object
+
+   This method has the following parameters:
+
+   .. include:: /includes/apiargs/MongoDBCollection-method-dropIndex-param.rst
+
+   The ``$options`` parameter supports the following options:
+
+   .. include:: /includes/apiargs/MongoDBCollection-method-dropIndex-option.rst
+
+Return Values
+-------------
+
+An array or object with the result document of the :manual:`dropIndexes
+</reference/command/dropIndexes>` command. The return type will depend on the
+``typeMap`` option.
+
+Errors/Exceptions
+-----------------
+
+.. include:: /includes/extracts/error-unsupportedexception.rst
+.. include:: /includes/extracts/error-invalidargumentexception.rst
+.. include:: /includes/extracts/error-driver-runtimeexception.rst
+
+Example
+-------
+
+The following drops all indexes from the ``restaurants`` collection in the
+``test`` database:
+
+.. code-block:: php
+
+   <?php
+
+   $collection = (new MongoDB\Client)->test->restaurants;
+
+   $result = $collection->dropIndexes();
+
+   var_dump($result);
+
+The output would then resemble::
+
+   object(MongoDB\Model\BSONDocument)#9 (1) {
+     ["storage":"ArrayObject":private]=>
+     array(3) {
+       ["nIndexesWas"]=>
+       int(3)
+       ["msg"]=>
+       string(38) "non-_id indexes dropped for collection"
+       ["ok"]=>
+       float(1)
+     }
+   }
+
+See Also
+--------
+
+- :phpmethod:`MongoDB\\Collection::dropIndex()`
+- :doc:`/tutorial/indexes`
+- :manual:`dropIndexes </reference/command/dropIndexes>` command reference in
+  the MongoDB manual
+- :manual:`Index documentation </indexes>` in the MongoDB manual
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-estimatedDocumentCount.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-estimatedDocumentCount.txt
new file mode 100644
index 0000000000000000000000000000000000000000..097e03b4159e09370e2ece487ac3a781b6c1fb8e
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-estimatedDocumentCount.txt	
@@ -0,0 +1,60 @@
+=============================================
+MongoDB\\Collection::estimatedDocumentCount()
+=============================================
+
+.. versionadded:: 1.4
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\Collection::estimatedDocumentCount()
+
+   Gets an estimated number of documents in the collection using collection metadata.
+
+   .. code-block:: php
+
+      function countDocuments(array $options = []): integer
+
+   This method has the following parameters:
+
+   .. include:: /includes/apiargs/MongoDBCollection-method-estimateDocumentCount-param.rst
+
+   The ``$options`` parameter supports the following options:
+
+   .. include:: /includes/apiargs/MongoDBCollection-method-estimateDocumentCount-option.rst
+
+Return Values
+-------------
+
+An estimated number of documents in the collection.
+
+Errors/Exceptions
+-----------------
+
+.. include:: /includes/extracts/error-unexpectedvalueexception.rst
+.. include:: /includes/extracts/error-unsupportedexception.rst
+.. include:: /includes/extracts/error-invalidargumentexception.rst
+.. include:: /includes/extracts/error-driver-runtimeexception.rst
+
+Behavior
+--------
+
+This method returns an estimate of the count of documents in the collection
+using collection metadata, rather than counting the documents or consulting an
+index. This method does not take a ``session`` option and cannot be executed
+within a transaction.
+
+See Also
+--------
+
+- :manual:`count </reference/command/count>` command reference in the MongoDB
+  manual
+- :phpmethod:`MongoDB\\Collection::countDocuments()`
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-explain.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-explain.txt
new file mode 100644
index 0000000000000000000000000000000000000000..5ae73c911faf7b0a0ab647474c22435b18940735
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-explain.txt	
@@ -0,0 +1,279 @@
+==============================
+MongoDB\\Collection::explain()
+==============================
+
+.. versionadded:: 1.4
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\Collection::explain()
+
+   Explain the given command.
+
+   .. code-block:: php
+
+      function explain(MongoDB\\Operation\\Explainable $explainable, array $options = []): array|object
+
+   This method has the following parameters:
+
+   .. include:: /includes/apiargs/MongoDBCollection-method-explain-param.rst
+
+   The ``$options`` parameter supports the following options:
+
+   .. include:: /includes/apiargs/MongoDBCollection-method-explain-option.rst
+
+Return Values
+-------------
+
+An array or object with the result document of the :manual:`explain
+</reference/command/explain>` command. The return type will depend on the
+``typeMap`` option.
+
+Errors/Exceptions
+-----------------
+
+.. include:: /includes/extracts/error-unsupportedexception.rst
+.. include:: /includes/extracts/error-invalidargumentexception.rst
+.. include:: /includes/extracts/error-driver-runtimeexception.rst
+
+Explainable Commands
+--------------------
+
+Explainable commands include, but are not limited to:
+
+   - :phpclass:`MongoDB\\Operation\\Aggregate`
+   - :phpclass:`MongoDB\\Operation\\Count`
+   - :phpclass:`MongoDB\\Operation\\DeleteMany`
+   - :phpclass:`MongoDB\\Operation\\DeleteOne`
+   - :phpclass:`MongoDB\\Operation\\Distinct`
+   - :phpclass:`MongoDB\\Operation\\Find`
+   - :phpclass:`MongoDB\\Operation\\FindOne`
+   - :phpclass:`MongoDB\\Operation\\FindOneAndDelete`
+   - :phpclass:`MongoDB\\Operation\\FindOneAndReplace`
+   - :phpclass:`MongoDB\\Operation\\FindOneAndUpdate`
+   - :phpclass:`MongoDB\\Operation\\UpdateMany`
+   - :phpclass:`MongoDB\\Operation\\UpdateOne`
+
+Examples
+--------
+
+This example explains a count command.
+
+.. code-block:: php
+
+   <?php
+
+   $collection = (new MongoDB\Client)->test->restaurants;
+
+   $count = new MongoDB\Operation\Count(
+       $collection->getDatabaseName(),
+       $collection->getCollectionName(),
+       ['cuisine' => 'Italian']
+   );
+
+   $result = $collection->explain($count);
+
+   var_dump($result);
+
+The output would then resemble::
+
+   object(MongoDB\Model\BSONDocument)#29 (1) {
+     ["storage":"ArrayObject":private]=>
+     array(4) {
+       ["queryPlanner"]=>
+       object(MongoDB\Model\BSONDocument)#21 (1) {
+         ["storage":"ArrayObject":private]=>
+         array(6) {
+           ["plannerVersion"]=>
+           int(1)
+           ["namespace"]=>
+           string(16) "test.restaurants"
+           ["indexFilterSet"]=>
+           bool(false)
+           ["parsedQuery"]=>
+           object(MongoDB\Model\BSONDocument)#15 (1) {
+             ["storage":"ArrayObject":private]=>
+             array(1) {
+               ["cuisine"]=>
+               object(MongoDB\Model\BSONDocument)#14 (1) {
+                 ["storage":"ArrayObject":private]=>
+                 array(1) {
+                   ["$eq"]=>
+                   string(7) "Italian"
+                 }
+               }
+             }
+           }
+           ["winningPlan"]=>
+           object(MongoDB\Model\BSONDocument)#19 (1) {
+             ["storage":"ArrayObject":private]=>
+             array(2) {
+               ["stage"]=>
+               string(5) "COUNT"
+               ["inputStage"]=>
+               object(MongoDB\Model\BSONDocument)#18 (1) {
+                 ["storage":"ArrayObject":private]=>
+                 array(3) {
+                   ["stage"]=>
+                   string(8) "COLLSCAN"
+                   ["filter"]=>
+                   object(MongoDB\Model\BSONDocument)#17 (1) {
+                     ["storage":"ArrayObject":private]=>
+                     array(1) {
+                       ["cuisine"]=>
+                       object(MongoDB\Model\BSONDocument)#16 (1) {
+                         ["storage":"ArrayObject":private]=>
+                         array(1) {
+                           ["$eq"]=>
+                           string(7) "Italian"
+                         }
+                       }
+                     }
+                   }
+                   ["direction"]=>
+                   string(7) "forward"
+                 }
+               }
+             }
+           }
+           ["rejectedPlans"]=>
+           object(MongoDB\Model\BSONArray)#20 (1) {
+             ["storage":"ArrayObject":private]=>
+             array(0) {
+             }
+           }
+         }
+       }
+       ["executionStats"]=>
+       object(MongoDB\Model\BSONDocument)#27 (1) {
+         ["storage":"ArrayObject":private]=>
+         array(7) {
+           ["executionSuccess"]=>
+           bool(true)
+           ["nReturned"]=>
+           int(0)
+           ["executionTimeMillis"]=>
+           int(24)
+           ["totalKeysExamined"]=>
+           int(0)
+           ["totalDocsExamined"]=>
+           int(25359)
+           ["executionStages"]=>
+           object(MongoDB\Model\BSONDocument)#25 (1) {
+             ["storage":"ArrayObject":private]=>
+             array(14) {
+               ["stage"]=>
+               string(5) "COUNT"
+               ["nReturned"]=>
+               int(0)
+               ["executionTimeMillisEstimate"]=>
+               int(20)
+               ["works"]=>
+               int(25361)
+               ["advanced"]=>
+               int(0)
+               ["needTime"]=>
+               int(25360)
+               ["needYield"]=>
+               int(0)
+               ["saveState"]=>
+               int(198)
+               ["restoreState"]=>
+               int(198)
+               ["isEOF"]=>
+               int(1)
+               ["invalidates"]=>
+               int(0)
+               ["nCounted"]=>
+               int(1069)
+               ["nSkipped"]=>
+               int(0)
+               ["inputStage"]=>
+               object(MongoDB\Model\BSONDocument)#24 (1) {
+                 ["storage":"ArrayObject":private]=>
+                 array(14) {
+                   ["stage"]=>
+                   string(8) "COLLSCAN"
+                   ["filter"]=>
+                   object(MongoDB\Model\BSONDocument)#23 (1) {
+                     ["storage":"ArrayObject":private]=>
+                     array(1) {
+                       ["cuisine"]=>
+                       object(MongoDB\Model\BSONDocument)#22 (1) {
+                         ["storage":"ArrayObject":private]=>
+                         array(1) {
+                           ["$eq"]=>
+                           string(7) "Italian"
+                         }
+                       }
+                     }
+                   }
+                   ["nReturned"]=>
+                   int(1069)
+                   ["executionTimeMillisEstimate"]=>
+                   int(20)
+                   ["works"]=>
+                   int(25361)
+                   ["advanced"]=>
+                   int(1069)
+                   ["needTime"]=>
+                   int(24291)
+                   ["needYield"]=>
+                   int(0)
+                   ["saveState"]=>
+                   int(198)
+                   ["restoreState"]=>
+                   int(198)
+                   ["isEOF"]=>
+                   int(1)
+                   ["invalidates"]=>
+                   int(0)
+                   ["direction"]=>
+                   string(7) "forward"
+                   ["docsExamined"]=>
+                   int(25359)
+                 }
+               }
+             }
+           }
+           ["allPlansExecution"]=>
+           object(MongoDB\Model\BSONArray)#26 (1) {
+             ["storage":"ArrayObject":private]=>
+             array(0) {
+             }
+           }
+         }
+       }
+       ["serverInfo"]=>
+       object(MongoDB\Model\BSONDocument)#28 (1) {
+         ["storage":"ArrayObject":private]=>
+         array(4) {
+           ["host"]=>
+           string(9) "localhost"
+           ["port"]=>
+           int(27017)
+           ["version"]=>
+           string(5) "3.6.1"
+           ["gitVersion"]=>
+           string(40) "025d4f4fe61efd1fb6f0005be20cb45a004093d1"
+         }
+       }
+       ["ok"]=>
+       float(1)
+     }
+   }
+
+See Also
+--------
+
+- :manual:`explain </reference/command/explain>` command reference in the MongoDB
+  manual
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-find.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-find.txt
new file mode 100644
index 0000000000000000000000000000000000000000..34eed99ad5f088f0ac428f67b672c9b6e48aa2fa
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-find.txt	
@@ -0,0 +1,168 @@
+===========================
+MongoDB\\Collection::find()
+===========================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\Collection::find()
+
+   Finds documents matching the query.
+
+   .. code-block:: php
+
+      function find($filter = [], array $options = []): MongoDB\Driver\Cursor
+
+   This method has the following parameters:
+
+   .. include:: /includes/apiargs/MongoDBCollection-method-find-param.rst
+
+   The ``$options`` parameter supports the following options:
+
+   .. include:: /includes/apiargs/MongoDBCollection-method-find-option.rst
+
+Return Values
+-------------
+
+A :php:`MongoDB\\Driver\\Cursor <class.mongodb-driver-cursor>` object.
+
+Errors/Exceptions
+-----------------
+
+.. include:: /includes/extracts/error-unsupportedexception.rst
+.. include:: /includes/extracts/error-invalidargumentexception.rst
+.. include:: /includes/extracts/error-driver-runtimeexception.rst
+
+Behavior
+--------
+
+.. include:: /includes/extracts/note-bson-comparison.rst
+
+Examples
+--------
+
+The following example finds restaurants based on the ``cuisine`` and ``borough``
+fields and uses a :manual:`projection
+</tutorial/project-fields-from-query-results>` to limit the fields that are
+returned. It also limits the results to 5 documents.
+
+.. code-block:: php
+
+   $collection = (new MongoDB\Client)->test->restaurants;
+
+   $cursor = $collection->find(
+       [
+           'cuisine' => 'Italian',
+           'borough' => 'Manhattan',
+       ],
+       [
+           'limit' => 5,
+           'projection' => [
+               'name' => 1,
+               'borough' => 1,
+               'cuisine' => 1,
+           ],
+       ]
+   );
+
+   foreach ($cursor as $restaurant) {
+      var_dump($restaurant);
+   };
+
+The output would then resemble::
+
+   object(MongoDB\Model\BSONDocument)#10 (1) {
+     ["storage":"ArrayObject":private]=>
+     array(4) {
+       ["_id"]=>
+       object(MongoDB\BSON\ObjectId)#8 (1) {
+         ["oid"]=>
+         string(24) "576023c6b02fa9281da3f983"
+       }
+       ["borough"]=>
+       string(9) "Manhattan"
+       ["cuisine"]=>
+       string(7) "Italian"
+       ["name"]=>
+       string(23) "Isle Of Capri Resturant"
+     }
+   }
+   object(MongoDB\Model\BSONDocument)#13 (1) {
+     ["storage":"ArrayObject":private]=>
+     array(4) {
+       ["_id"]=>
+       object(MongoDB\BSON\ObjectId)#12 (1) {
+         ["oid"]=>
+         string(24) "576023c6b02fa9281da3f98d"
+       }
+       ["borough"]=>
+       string(9) "Manhattan"
+       ["cuisine"]=>
+       string(7) "Italian"
+       ["name"]=>
+       string(18) "Marchis Restaurant"
+     }
+   }
+   object(MongoDB\Model\BSONDocument)#8 (1) {
+     ["storage":"ArrayObject":private]=>
+     array(4) {
+       ["_id"]=>
+       object(MongoDB\BSON\ObjectId)#10 (1) {
+         ["oid"]=>
+         string(24) "576023c6b02fa9281da3f99b"
+       }
+       ["borough"]=>
+       string(9) "Manhattan"
+       ["cuisine"]=>
+       string(7) "Italian"
+       ["name"]=>
+       string(19) "Forlinis Restaurant"
+     }
+   }
+   object(MongoDB\Model\BSONDocument)#12 (1) {
+     ["storage":"ArrayObject":private]=>
+     array(4) {
+       ["_id"]=>
+       object(MongoDB\BSON\ObjectId)#13 (1) {
+         ["oid"]=>
+         string(24) "576023c6b02fa9281da3f9a8"
+       }
+       ["borough"]=>
+       string(9) "Manhattan"
+       ["cuisine"]=>
+       string(7) "Italian"
+       ["name"]=>
+       string(22) "Angelo Of Mulberry St."
+     }
+   }
+   object(MongoDB\Model\BSONDocument)#10 (1) {
+     ["storage":"ArrayObject":private]=>
+     array(4) {
+       ["_id"]=>
+       object(MongoDB\BSON\ObjectId)#8 (1) {
+         ["oid"]=>
+         string(24) "576023c6b02fa9281da3f9b4"
+       }
+       ["borough"]=>
+       string(9) "Manhattan"
+       ["cuisine"]=>
+       string(7) "Italian"
+       ["name"]=>
+       string(16) "V & T Restaurant"
+     }
+   }
+
+See Also
+--------
+
+- :phpmethod:`MongoDB\\Collection::findOne()`
+- :manual:`find </reference/command/find>` command reference in the MongoDB
+  manual
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-findOne.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-findOne.txt
new file mode 100644
index 0000000000000000000000000000000000000000..0bf95f648a6d870194ae8308681e7cee295b61e8
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-findOne.txt	
@@ -0,0 +1,125 @@
+==============================
+MongoDB\\Collection::findOne()
+==============================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\Collection::findOne()
+
+   Finds a single document matching the query.
+
+   .. code-block:: php
+
+      function findOne($filter = [], array $options = []): array|object|null
+
+   This method has the following parameters:
+
+   .. include:: /includes/apiargs/MongoDBCollection-method-findOne-param.rst
+
+   The ``$options`` parameter supports the following options:
+
+   .. include:: /includes/apiargs/MongoDBCollection-method-findOne-option.rst
+
+Return Values
+-------------
+
+An array or object for the :term:`first document <natural order>` that matched
+the query, or ``null`` if no document matched the query. The return type will
+depend on the ``typeMap`` option.
+
+Errors/Exceptions
+-----------------
+
+.. include:: /includes/extracts/error-unsupportedexception.rst
+.. include:: /includes/extracts/error-invalidargumentexception.rst
+.. include:: /includes/extracts/error-driver-runtimeexception.rst
+
+Behavior
+--------
+
+.. include:: /includes/extracts/note-bson-comparison.rst
+
+Examples
+--------
+
+Matching BSON Types in Query Criteria
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+In the following example, documents in the ``restaurants`` collection use an
+:manual:`ObjectId </reference/object-id/>` for their identifier (the default)
+and documents in the ``zips`` collection use a string. Since ObjectId is a
+special BSON type, the query criteria for selecting a restaurant must use the
+:php:`MongoDB\\BSON\\ObjectId <class.mongodb-bson-objectid>` class.
+
+.. code-block:: php
+
+   $database = (new MongoDB\Client)->test;
+
+   $zip = $database->zips->findOne(['_id' => '10036']);
+
+   $restaurant = $database->restaurants->findOne([
+       '_id' => new MongoDB\BSON\ObjectId('594d5ef280a846852a4b3f70'),
+   ]);
+
+Projecting Fields
+~~~~~~~~~~~~~~~~~
+
+The following example finds a restaurant based on the ``cuisine`` and
+``borough`` fields and uses a :manual:`projection
+</tutorial/project-fields-from-query-results>` to limit the fields that are
+returned.
+
+.. code-block:: php
+
+   $collection = (new MongoDB\Client)->test->restaurants;
+
+   $restaurant = $collection->findOne(
+       [
+           'cuisine' => 'Italian',
+           'borough' => 'Manhattan',
+       ],
+       [
+           'projection' => [
+               'name' => 1,
+               'borough' => 1,
+               'cuisine' => 1,
+           ],
+       ]
+   );
+
+   var_dump($restaurant);
+
+The output would then resemble::
+
+   object(MongoDB\Model\BSONDocument)#10 (1) {
+     ["storage":"ArrayObject":private]=>
+     array(4) {
+       ["_id"]=>
+       object(MongoDB\BSON\ObjectId)#8 (1) {
+         ["oid"]=>
+         string(24) "576023c6b02fa9281da3f983"
+       }
+       ["borough"]=>
+       string(9) "Manhattan"
+       ["cuisine"]=>
+       string(7) "Italian"
+       ["name"]=>
+       string(23) "Isle Of Capri Resturant"
+     }
+   }
+
+See Also
+--------
+
+- :phpmethod:`MongoDB\\Collection::find()`
+- :manual:`find </reference/command/find>` command reference in the MongoDB
+  manual
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-findOneAndDelete.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-findOneAndDelete.txt
new file mode 100644
index 0000000000000000000000000000000000000000..1253bad4075e51257f29ae851f3ef3cd24f3377c
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-findOneAndDelete.txt	
@@ -0,0 +1,101 @@
+=======================================
+MongoDB\\Collection::findOneAndDelete()
+=======================================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\Collection::findOneAndDelete()
+
+   Finds a single document matching the query and deletes it.
+
+   .. code-block:: php
+
+      function findOneAndDelete($filter = [], array $options = []): object|null
+
+   This method has the following parameters:
+
+   .. include:: /includes/apiargs/MongoDBCollection-method-findOneAndDelete-param.rst
+
+   The ``$options`` parameter supports the following options:
+
+   .. include:: /includes/apiargs/MongoDBCollection-method-findOneAndDelete-option.rst
+
+Return Values
+-------------
+
+An array or object for the document that was deleted, or ``null`` if no document
+matched the query. The return type will depend on the ``typeMap`` option.
+
+Errors/Exceptions
+-----------------
+
+.. include:: /includes/extracts/error-unexpectedvalueexception.rst
+.. include:: /includes/extracts/error-unsupportedexception.rst
+.. include:: /includes/extracts/error-invalidargumentexception.rst
+.. include:: /includes/extracts/error-driver-runtimeexception.rst
+
+Behavior
+--------
+
+.. include:: /includes/extracts/note-bson-comparison.rst
+
+Examples
+--------
+
+The following example finds and deletes the document with ``restaurant_id`` of
+``"40375376"`` from the ``restaurants`` collection in the ``test`` database:
+
+.. code-block:: php
+
+   <?php
+
+   $collection = (new MongoDB\Client)->test->restaurants;
+
+   $deletedRestaurant = $collection->findOneAndDelete(
+       [ 'restaurant_id' => '40375376' ],
+       [
+           'projection' => [
+               'name' => 1,
+               'borough' => 1,
+               'restaurant_id' => 1,
+           ],
+       ]
+   );
+
+   var_dump($deletedRestaurant);
+
+The output would then resemble::
+
+   object(MongoDB\Model\BSONDocument)#17 (1) {
+     ["storage":"ArrayObject":private]=>
+     array(4) {
+       ["_id"]=>
+       object(MongoDB\BSON\ObjectId)#11 (1) {
+         ["oid"]=>
+         string(24) "594d5ef280a846852a4b3f70"
+       }
+       ["borough"]=>
+       string(9) "Manhattan"
+       ["name"]=>
+       string(15) "Agra Restaurant"
+       ["restaurant_id"]=>
+       string(8) "40375376"
+     }
+   }
+
+See Also
+--------
+
+- :phpmethod:`MongoDB\\Collection::findOneAndReplace()`
+- :phpmethod:`MongoDB\\Collection::findOneAndUpdate()`
+- :manual:`findAndModify </reference/command/findAndModify>` command reference
+  in the MongoDB manual
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-findOneAndReplace.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-findOneAndReplace.txt
new file mode 100644
index 0000000000000000000000000000000000000000..6a96a30b01b9ad4e6e83e0dc031ea1e416b09e34
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-findOneAndReplace.txt	
@@ -0,0 +1,151 @@
+========================================
+MongoDB\\Collection::findOneAndReplace()
+========================================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\Collection::findOneAndReplace()
+
+   Finds a single document matching the query and replaces it.
+
+   .. code-block:: php
+
+      function findOneAndReplace($filter, $replacement, array $options = []): object|null
+
+   This method has the following parameters:
+
+   .. include:: /includes/apiargs/MongoDBCollection-method-findOneAndReplace-param.rst
+
+   The ``$options`` parameter supports the following options:
+
+   .. include:: /includes/apiargs/MongoDBCollection-method-findOneAndReplace-option.rst
+
+Return Values
+-------------
+
+An array object for either the original or the replaced document, depending on
+the specified value of the ``returnDocument`` option. By default, the original
+document is returned. If no document matched the query, ``null`` is returned.
+The return type will depend on the ``typeMap`` option.
+
+Errors/Exceptions
+-----------------
+
+.. include:: /includes/extracts/error-unexpectedvalueexception.rst
+.. include:: /includes/extracts/error-unsupportedexception.rst
+.. include:: /includes/extracts/error-invalidargumentexception.rst
+.. include:: /includes/extracts/error-driver-runtimeexception.rst
+
+Behavior
+--------
+
+.. include:: /includes/extracts/note-bson-comparison.rst
+
+Examples
+--------
+
+Consider the following document in the ``restaurants`` collection in the
+``test`` database:
+
+.. code-block:: javascript
+
+   {
+     "_id" : ObjectId("576023c7b02fa9281da4139e"),
+     "address" : {
+       "building" : "977",
+       "coord" : [
+         -74.06940569999999,
+         40.6188443
+       ],
+       "street" : "Bay Street",
+       "zipcode" : "10305"
+     },
+     "borough" : "Staten Island",
+     "cuisine" : "French",
+     "grades" : [
+       {
+         "date" : ISODate("2014-08-15T00:00:00Z"),
+         "grade" : "A",
+         "score" : 7
+       },
+       {
+         "date" : ISODate("2014-02-13T00:00:00Z"),
+         "grade" : "A",
+         "score" : 5
+       },
+       {
+         "date" : ISODate("2013-06-07T00:00:00Z"),
+         "grade" : "A",
+         "score" : 11
+       }
+     ],
+     "name" : "Zest",
+     "restaurant_id" : "41220906"
+   }
+
+The following operation replaces the document with ``restaurant_id`` of
+``"41220906"`` with a new document:
+
+.. code-block:: php
+
+   <?php
+
+   $collection = (new MongoDB\Client)->teset->restaurants;
+
+   $replacedRestaurant = $collection->findOneAndReplace(
+       [ 'restaurant_id' => '41220906' ],
+       [
+           'Borough' => 'Staten Island',
+           'cuisine' => 'Italian',
+           'grades' => [],
+           'name' => 'Staten Island Pastaria',
+           'restaurant_id' => '999999999',
+       ],
+       [ 'returnDocument' => MongoDB\Operation\FindOneAndReplace::RETURN_DOCUMENT_AFTER ]
+   );
+
+   var_dump($replacedRestaurant);
+
+The output would then resemble::
+
+   object(MongoDB\Model\BSONDocument)#18 (1) {
+     ["storage":"ArrayObject":private]=>
+     array(6) {
+       ["_id"]=>
+       object(MongoDB\BSON\ObjectId)#11 (1) {
+         ["oid"]=>
+         string(24) "594d5ef380a846852a4b5837"
+       }
+       ["Borough"]=>
+       string(13) "Staten Island"
+       ["cuisine"]=>
+       string(7) "Italian"
+       ["grades"]=>
+       object(MongoDB\Model\BSONArray)#17 (1) {
+         ["storage":"ArrayObject":private]=>
+         array(0) {
+         }
+       }
+       ["name"]=>
+       string(22) "Staten Island Pastaria"
+       ["restaurant_id"]=>
+       string(9) "999999999"
+     }
+   }
+
+See Also
+--------
+
+- :phpmethod:`MongoDB\\Collection::findOneAndDelete()`
+- :phpmethod:`MongoDB\\Collection::findOneAndUpdate()`
+- :manual:`findAndModify </reference/command/findAndModify>` command reference
+  in the MongoDB manual
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-findOneAndUpdate.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-findOneAndUpdate.txt
new file mode 100644
index 0000000000000000000000000000000000000000..377d255edb23e3be899905bbe660ee0491b1d907
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-findOneAndUpdate.txt	
@@ -0,0 +1,118 @@
+=======================================
+MongoDB\\Collection::findOneAndUpdate()
+=======================================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\Collection::findOneAndUpdate()
+
+   Finds a single document matching the query and updates it.
+
+   .. code-block:: php
+
+      function findOneAndUpdate($filter, $update, array $options = []): object|null
+
+   This method has the following parameters:
+
+   .. include:: /includes/apiargs/MongoDBCollection-method-findOneAndUpdate-param.rst
+
+   The ``$options`` parameter supports the following options:
+
+   .. include:: /includes/apiargs/MongoDBCollection-method-findOneAndUpdate-option.rst
+
+Return Values
+-------------
+
+An array or object for either the original or the updated document, depending on
+the specified value of the ``returnDocument`` option. By default, the original
+document is returned. If no document matched the query, ``null`` is returned.
+The return type will depend on the ``typeMap`` option.
+
+Errors/Exceptions
+-----------------
+
+.. include:: /includes/extracts/error-unexpectedvalueexception.rst
+.. include:: /includes/extracts/error-unsupportedexception.rst
+.. include:: /includes/extracts/error-invalidargumentexception.rst
+.. include:: /includes/extracts/error-driver-runtimeexception.rst
+
+Behavior
+--------
+
+.. include:: /includes/extracts/note-bson-comparison.rst
+
+Examples
+--------
+
+The following operation updates the restaurant with ``restaurant_id`` of
+``"40361708"`` in the ``restaurants`` collection in the ``test`` database by
+setting its building number to ``"761"``:
+
+.. code-block:: php
+
+   <?php
+
+   $collection = (new MongoDB\Client)->test->restaurants;
+
+   $updatedRestaurant = $collection->findOneAndUpdate(
+       [ 'restaurant_id' => '40361708' ],
+       [ '$set' => [ 'address.building' => '761' ]],
+       [
+           'projection' => [ 'address' => 1 ],
+           'returnDocument' => MongoDB\Operation\FindOneAndUpdate::RETURN_DOCUMENT_AFTER,
+       ]
+   );
+
+   var_dump($updatedRestaurant);
+
+The output would then resemble::
+
+   object(MongoDB\Model\BSONDocument)#20 (1) {
+     ["storage":"ArrayObject":private]=>
+     array(2) {
+       ["_id"]=>
+       object(MongoDB\BSON\ObjectId)#12 (1) {
+         ["oid"]=>
+         string(24) "594d5ef280a846852a4b3dee"
+       }
+       ["address"]=>
+       object(MongoDB\Model\BSONDocument)#19 (1) {
+         ["storage":"ArrayObject":private]=>
+         array(4) {
+           ["building"]=>
+           string(3) "761"
+           ["coord"]=>
+           object(MongoDB\Model\BSONArray)#18 (1) {
+             ["storage":"ArrayObject":private]=>
+             array(2) {
+               [0]=>
+               float(-73.9925306)
+               [1]=>
+               float(40.7309346)
+             }
+           }
+           ["street"]=>
+           string(8) "Broadway"
+           ["zipcode"]=>
+           string(5) "10003"
+         }
+       }
+     }
+   }
+
+See Also
+--------
+
+- :phpmethod:`MongoDB\\Collection::findOneAndDelete()`
+- :phpmethod:`MongoDB\\Collection::findOneAndReplace()`
+- :manual:`findAndModify </reference/command/findAndModify>` command reference
+  in the MongoDB manual
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-getCollectionName.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-getCollectionName.txt
new file mode 100644
index 0000000000000000000000000000000000000000..86fe3e5ec91b87421868e97845544b2e419dd513
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-getCollectionName.txt	
@@ -0,0 +1,51 @@
+========================================
+MongoDB\\Collection::getCollectionName()
+========================================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\Collection::getCollectionName()
+
+   Returns the name of this collection.
+
+   .. code-block:: php
+
+      function getCollectionName(): string
+
+Return Values
+-------------
+
+The name of this collection as a string.
+
+Example
+-------
+
+The following returns the collection name for the ``zips`` collection in the
+``test`` database.
+
+.. code-block:: php
+
+   <?php
+
+   $collection = (new MongoDB\Client)->test->zips;
+
+   echo $collection->getCollectionName();
+
+The output would then resemble::
+
+   zips
+
+See Also
+--------
+
+- :phpmethod:`MongoDB\\Collection::getDatabaseName()`
+- :phpmethod:`MongoDB\\Collection::getNamespace()`
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-getDatabaseName.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-getDatabaseName.txt
new file mode 100644
index 0000000000000000000000000000000000000000..93500c8095c882057e3b0368abd52158b364fb31
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-getDatabaseName.txt	
@@ -0,0 +1,52 @@
+======================================
+MongoDB\\Collection::getDatabaseName()
+======================================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\Collection::getDatabaseName()
+
+   Returns the name of the database containing this collection.
+
+   .. code-block:: php
+
+      function getDatabaseName(): string
+
+Return Values
+-------------
+
+The name of the database containing this collection as a string.
+
+Example
+-------
+
+The following returns the database name for the ``zips`` collection in the
+``test`` database.
+
+.. code-block:: php
+
+   <?php
+
+   $collection = (new MongoDB\Client)->test->zips;
+
+   echo $collection->getDatabaseName();
+
+The output would then resemble::
+
+   test
+
+See Also
+--------
+
+- :phpmethod:`MongoDB\\Collection::getCollectionName()`
+- :phpmethod:`MongoDB\\Collection::getNamespace()`
+
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-getManager.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-getManager.txt
new file mode 100644
index 0000000000000000000000000000000000000000..e0bbea08846ad46cb10f898b3c973bde8a73aab9
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-getManager.txt	
@@ -0,0 +1,35 @@
+=================================
+MongoDB\\Collection::getManager()
+=================================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\Collection::getManager()
+
+   Accessor for the
+   :php:`MongoDB\\Driver\\Manager <class.mongodb-driver-manager>` used by this
+   :phpclass:`Collection <MongoDB\\Collection>`.
+
+   .. code-block:: php
+
+      function getManager(): MongoDB\Manager
+
+Return Values
+-------------
+
+A :php:`MongoDB\\Driver\\Manager <class.mongodb-driver-manager>` object.
+
+See Also
+--------
+
+- :phpmethod:`MongoDB\\Client::getManager()`
+- :phpmethod:`MongoDB\\Database::getManager()`
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-getNamespace.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-getNamespace.txt
new file mode 100644
index 0000000000000000000000000000000000000000..74f1b022e9ca722fce78107e7408e75283369895
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-getNamespace.txt	
@@ -0,0 +1,52 @@
+===================================
+MongoDB\\Collection::getNamespace()
+===================================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\Collection::getNamespace()
+
+   Returns the :term:`namespace` of the collection. A namespace is the canonical
+   name of an index or collection in MongoDB.
+
+   .. code-block:: php
+
+      function getNamespace(): string
+
+Return Values
+-------------
+
+The namespace of this collection as a string.
+
+Example
+-------
+
+The following returns the namespace of the ``zips`` collection in the ``test``
+database.
+
+.. code-block:: php
+
+   <?php
+
+   $collection = (new MongoDB\Client)->test->zips;
+
+   echo $collection->getNamespace();
+
+The output would then resemble::
+
+   test.zips
+
+See Also
+--------
+
+- :phpmethod:`MongoDB\\Collection::getCollectionName()`
+- :phpmethod:`MongoDB\\Collection::getDatabaseName()`
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-getReadConcern.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-getReadConcern.txt
new file mode 100644
index 0000000000000000000000000000000000000000..ff1cfeb04aabc0f28822b35f0760775fc4a678da
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-getReadConcern.txt	
@@ -0,0 +1,58 @@
+=====================================
+MongoDB\\Collection::getReadConcern()
+=====================================
+
+.. versionadded:: 1.2
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\Collection::getReadConcern()
+
+   Returns the read concern for this collection.
+
+   .. code-block:: php
+
+      function getReadConcern(): MongoDB\Driver\ReadConcern
+
+Return Values
+-------------
+
+A :php:`MongoDB\\Driver\\ReadConcern <class.mongodb-driver-readconcern>` object.
+
+Example
+-------
+
+.. code-block:: php
+
+   <?php
+
+   $collection = (new MongoDB\Client)->selectCollection('test', 'users', [
+      'readConcern' => new MongoDB\Driver\ReadConcern(MongoDB\Driver\ReadConcern::MAJORITY),
+   ]);
+
+   var_dump($collection->getReadConcern());
+
+The output would then resemble::
+
+   object(MongoDB\Driver\ReadConcern)#5 (1) {
+     ["level"]=>
+     string(8) "majority"
+   }
+
+See Also
+--------
+
+- :manual:`Read Concern </reference/read-concern>` in the MongoDB manual
+- :php:`MongoDB\\Driver\\ReadConcern::isDefault() <mongodb-driver-readconcern.isdefault>`
+- :phpmethod:`MongoDB\\Client::getReadConcern()`
+- :phpmethod:`MongoDB\\Database::getReadConcern()`
+- :phpmethod:`MongoDB\\GridFS\\Bucket::getReadConcern()`
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-getReadPreference.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-getReadPreference.txt
new file mode 100644
index 0000000000000000000000000000000000000000..4eac30d3afb6bd0f8d28a3b9ffa44b7f91c217c5
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-getReadPreference.txt	
@@ -0,0 +1,58 @@
+========================================
+MongoDB\\Collection::getReadPreference()
+========================================
+
+.. versionadded:: 1.2
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\Collection::getReadPreference()
+
+   Returns the read preference for this collection.
+
+   .. code-block:: php
+
+      function getReadPreference(): MongoDB\Driver\ReadPreference
+
+Return Values
+-------------
+
+A :php:`MongoDB\\Driver\\ReadPreference <class.mongodb-driver-readpreference>`
+object.
+
+Example
+-------
+
+.. code-block:: php
+
+   <?php
+
+   $collection = (new MongoDB\Client)->selectCollection('test', 'users', [
+       'readPreference' => new MongoDB\Driver\ReadPreference('primaryPreferred'),
+   ]);
+
+   var_dump($collection->getReadPreference());
+
+The output would then resemble::
+
+   object(MongoDB\Driver\ReadPreference)#5 (1) {
+     ["mode"]=>
+     string(16) "primaryPreferred"
+   }
+
+See Also
+--------
+
+- :manual:`Read Preference </reference/read-preference>` in the MongoDB manual
+- :phpmethod:`MongoDB\\Client::getReadPreference()`
+- :phpmethod:`MongoDB\\Database::getReadPreference()`
+- :phpmethod:`MongoDB\\GridFS\\Bucket::getReadPreference()`
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-getTypeMap.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-getTypeMap.txt
new file mode 100644
index 0000000000000000000000000000000000000000..11e56426a602da65d0520d30efee89c7dece1d12
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-getTypeMap.txt	
@@ -0,0 +1,65 @@
+=================================
+MongoDB\\Collection::getTypeMap()
+=================================
+
+.. versionadded:: 1.2
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\Collection::getTypeMap()
+
+   Returns the type map for this collection.
+
+   .. code-block:: php
+
+      function getTypeMap(): array
+
+Return Values
+-------------
+
+A :ref:`type map <php-type-map>` array.
+
+Example
+-------
+
+.. code-block:: php
+
+   <?php
+
+   $collection = (new MongoDB\Client)->selectCollection('test', 'users', [
+       'typeMap' => [
+           'root' => 'array',
+           'document' => 'array',
+           'array' => 'array',
+       ],
+   ]);
+
+   var_dump($collection->getTypeMap());
+
+The output would then resemble::
+
+   array(3) {
+     ["root"]=>
+     string(5) "array"
+     ["document"]=>
+     string(5) "array"
+     ["array"]=>
+     string(5) "array"
+   }
+
+See Also
+--------
+
+- :doc:`/reference/bson`
+- :phpmethod:`MongoDB\\Client::getTypeMap()`
+- :phpmethod:`MongoDB\\Database::getTypeMap()`
+- :phpmethod:`MongoDB\\GridFS\\Bucket::getTypeMap()`
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-getWriteConcern.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-getWriteConcern.txt
new file mode 100644
index 0000000000000000000000000000000000000000..4fa26ee1fcb2ecd7562346e26d50d24efa6e1708
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-getWriteConcern.txt	
@@ -0,0 +1,61 @@
+======================================
+MongoDB\\Collection::getWriteConcern()
+======================================
+
+.. versionadded:: 1.2
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\Collection::getWriteConcern()
+
+   Returns the write concern for this collection.
+
+   .. code-block:: php
+
+      function getWriteConcern(): MongoDB\Driver\WriteConcern
+
+Return Values
+-------------
+
+A :php:`MongoDB\\Driver\\WriteConcern <class.mongodb-driver-writeconcern>`
+object.
+
+Example
+-------
+
+.. code-block:: php
+
+   <?php
+
+   $collection = (new MongoDB\Client)->selectCollection('test', 'users', [
+      'writeConcern' => new MongoDB\Driver\WriteConcern(1, 0, true),
+   ]);
+
+   var_dump($collection->getWriteConcern());
+
+The output would then resemble::
+
+   object(MongoDB\Driver\WriteConcern)#5 (2) {
+     ["w"]=>
+     int(1)
+     ["j"]=>
+     bool(true)
+   }
+
+See Also
+--------
+
+- :manual:`Write Concern </reference/read-concern>` in the MongoDB manual
+- :php:`MongoDB\\Driver\\WriteConcern::isDefault() <mongodb-driver-writeconcern.isdefault>`
+- :phpmethod:`MongoDB\\Client::getWriteConcern()`
+- :phpmethod:`MongoDB\\Database::getWriteConcern()`
+- :phpmethod:`MongoDB\\GridFS\\Bucket::getWriteConcern()`
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-insertMany.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-insertMany.txt
new file mode 100644
index 0000000000000000000000000000000000000000..8b7eb53b008fbf5b561659bf2a115e4e22ad7b73
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-insertMany.txt	
@@ -0,0 +1,107 @@
+=================================
+MongoDB\\Collection::insertMany()
+=================================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\Collection::insertMany()
+
+   Insert multiple documents.
+
+   .. code-block:: php
+
+      function insertMany(array $documents, array $options = []): MongoDB\InsertManyResult
+
+   This method has the following parameters:
+
+   .. include:: /includes/apiargs/MongoDBCollection-method-insertMany-param.rst
+
+   The ``$options`` parameter supports the following options:
+
+   .. include:: /includes/apiargs/MongoDBCollection-method-insertMany-option.rst
+
+Return Values
+-------------
+
+A :phpclass:`MongoDB\\InsertManyResult` object, which encapsulates a
+:php:`MongoDB\\Driver\\WriteResult <class.mongodb-driver-writeresult>` object.
+
+Errors/Exceptions
+-----------------
+
+.. include:: /includes/extracts/error-invalidargumentexception.rst
+.. include:: /includes/extracts/error-driver-bulkwriteexception.rst
+.. include:: /includes/extracts/error-driver-runtimeexception.rst
+
+Behavior
+--------
+
+.. include:: /includes/extracts/bulkwriteexception-result.rst
+.. include:: /includes/extracts/bulkwriteexception-ordered.rst
+
+Example
+-------
+
+.. start-crud-include
+
+The following operation inserts two documents into the ``users`` collection
+in the ``test`` database:
+
+.. code-block:: php
+
+   <?php
+
+   $collection = (new MongoDB\Client)->test->users;
+
+   $insertManyResult = $collection->insertMany([
+       [
+           'username' => 'admin',
+           'email' => 'admin@example.com',
+           'name' => 'Admin User',
+       ],
+       [
+           'username' => 'test',
+           'email' => 'test@example.com',
+           'name' => 'Test User',
+       ],
+   ]);
+
+   printf("Inserted %d document(s)\n", $insertManyResult->getInsertedCount());
+
+   var_dump($insertManyResult->getInsertedIds());
+
+The output would then resemble::
+
+   Inserted 2 document(s)
+   array(2) {
+     [0]=>
+     object(MongoDB\BSON\ObjectId)#11 (1) {
+       ["oid"]=>
+       string(24) "579a25921f417dd1e5518141"
+     }
+     [1]=>
+     object(MongoDB\BSON\ObjectId)#12 (1) {
+       ["oid"]=>
+       string(24) "579a25921f417dd1e5518142"
+     }
+   }
+
+.. end-crud-include
+
+See Also
+--------
+
+- :phpmethod:`MongoDB\\Collection::insertOne()`
+- :phpmethod:`MongoDB\\Collection::bulkWrite()`
+- :doc:`/tutorial/crud`
+- :manual:`insert </reference/command/insert>` command reference in the MongoDB
+  manual
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-insertOne.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-insertOne.txt
new file mode 100644
index 0000000000000000000000000000000000000000..0d25f6d515fd60ab448e4db02ac7ef45e170a747
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-insertOne.txt	
@@ -0,0 +1,91 @@
+================================
+MongoDB\\Collection::insertOne()
+================================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\Collection::insertOne()
+
+   Insert one document.
+
+   .. code-block:: php
+
+      function insertOne($document, array $options = []): MongoDB\InsertOneResult
+
+   This method has the following parameters:
+
+   .. include:: /includes/apiargs/MongoDBCollection-method-insertOne-param.rst
+
+   The ``$options`` parameter supports the following options:
+
+   .. include:: /includes/apiargs/MongoDBCollection-method-insertOne-option.rst
+
+Return Values
+-------------
+
+A :phpclass:`MongoDB\\InsertOneResult` object, which encapsulates a
+:php:`MongoDB\\Driver\\WriteResult <class.mongodb-driver-writeresult>` object.
+
+Errors/Exceptions
+-----------------
+
+.. include:: /includes/extracts/error-invalidargumentexception.rst
+.. include:: /includes/extracts/error-driver-bulkwriteexception.rst
+.. include:: /includes/extracts/error-driver-runtimeexception.rst
+
+Behavior
+--------
+
+.. include:: /includes/extracts/bulkwriteexception-result.rst
+
+Example
+-------
+
+.. start-crud-include
+
+The following operation inserts a document into the ``users`` collection in the
+``test`` database:
+
+.. code-block:: php
+
+   <?php
+
+   $collection = (new MongoDB\Client)->test->users;
+
+   $insertOneResult = $collection->insertOne([
+       'username' => 'admin',
+       'email' => 'admin@example.com',
+       'name' => 'Admin User',
+   ]);
+
+   printf("Inserted %d document(s)\n", $insertOneResult->getInsertedCount());
+
+   var_dump($insertOneResult->getInsertedId());
+
+The output would then resemble::
+
+   Inserted 1 document(s)
+   object(MongoDB\BSON\ObjectId)#11 (1) {
+     ["oid"]=>
+     string(24) "579a25921f417dd1e5518141"
+   }
+
+.. end-crud-include
+
+See Also
+--------
+
+- :phpmethod:`MongoDB\\Collection::insertMany()`
+- :phpmethod:`MongoDB\\Collection::bulkWrite()`
+- :doc:`/tutorial/crud`
+- :manual:`insert </reference/command/insert>` command reference in the MongoDB
+  manual
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-listIndexes.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-listIndexes.txt
new file mode 100644
index 0000000000000000000000000000000000000000..e39a9bbba95bc00e7d82f9707e40a5e1bcf37442
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-listIndexes.txt	
@@ -0,0 +1,111 @@
+==================================
+MongoDB\\Collection::listIndexes()
+==================================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\Collection::listIndexes()
+
+   Returns information for all indexes for this collection.
+
+   .. code-block:: php
+
+      function listIndexes(array $options = []): MongoDB\Model\IndexInfoIterator
+
+   This method has the following parameters:
+
+   .. include:: /includes/apiargs/MongoDBCollection-method-listIndexes-param.rst
+
+   The ``$options`` parameter supports the following options:
+
+   .. include:: /includes/apiargs/MongoDBCollection-method-listIndexes-option.rst
+
+Return Values
+-------------
+
+A traversable :phpclass:`MongoDB\\Model\\IndexInfoIterator`, which contains a
+:phpclass:`MongoDB\\Model\\IndexInfo` object for each index for the collection.
+
+Errors/Exceptions
+-----------------
+
+.. include:: /includes/extracts/error-invalidargumentexception.rst
+.. include:: /includes/extracts/error-driver-runtimeexception.rst
+
+Example
+-------
+
+The following example lists all of the indexes for the ``restaurants``
+collection in the ``test`` database:
+
+.. code-block:: php
+
+   <?php
+
+   $collection = (new MongoDB\Client)->test->restaurants;
+
+   foreach ($collection->listIndexes() as $index) {
+      var_dump($index);
+   }
+
+The output would then resemble::
+
+   object(MongoDB\Model\IndexInfo)#8 (4) {
+     ["v"]=>
+     int(1)
+     ["key"]=>
+     array(1) {
+       ["_id"]=>
+       int(1)
+     }
+     ["name"]=>
+     string(4) "_id_"
+     ["ns"]=>
+     string(16) "test.restaurants"
+   }
+   object(MongoDB\Model\IndexInfo)#12 (4) {
+     ["v"]=>
+     int(1)
+     ["key"]=>
+     array(1) {
+       ["cuisine"]=>
+       float(-1)
+     }
+     ["name"]=>
+     string(10) "cuisine_-1"
+     ["ns"]=>
+     string(16) "test.restaurants"
+   }
+   object(MongoDB\Model\IndexInfo)#8 (4) {
+     ["v"]=>
+     int(1)
+     ["key"]=>
+     array(1) {
+       ["borough"]=>
+       float(1)
+     }
+     ["name"]=>
+     string(9) "borough_1"
+     ["ns"]=>
+     string(16) "test.restaurants"
+   }
+
+See Also
+--------
+
+- :doc:`/tutorial/indexes`
+- :manual:`listIndexes </reference/command/listIndexes>` command reference in
+  the MongoDB manual
+- :manual:`Index documentation </core/indexes>` in the MongoDB manual
+- `Enumerating Collections
+  <https://github.com/mongodb/specifications/blob/master/source/enumerate-indexes.rst>`_
+  specification
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-mapReduce.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-mapReduce.txt
new file mode 100644
index 0000000000000000000000000000000000000000..2796e38577cb32c58763a0dd5e272bf175793e51
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-mapReduce.txt	
@@ -0,0 +1,126 @@
+=================================
+MongoDB\\Collection::mapReduce()
+=================================
+
+.. versionadded:: 1.2
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\Collection::mapReduce()
+
+   The :manual:`mapReduce </reference/command/mapReduce>` command allows you to
+   run map-reduce aggregation operations over a collection.
+
+   .. code-block:: php
+
+      function mapReduce($map, $reduce, $out, array $options = []): MongoDB\MapReduceResult
+
+   This method has the following parameters:
+
+   .. include:: /includes/apiargs/MongoDBCollection-method-mapReduce-param.rst
+
+   The ``$options`` parameter supports the following options:
+
+   .. include:: /includes/apiargs/MongoDBCollection-method-mapReduce-option.rst
+
+Return Values
+-------------
+
+A :phpclass:`MongoDB\\MapReduceResult` object, which allows for iteration of
+map-reduce results irrespective of the output method (e.g. inline, collection)
+via the :php:`IteratorAggregate <iteratoraggregate>` interface. It also
+provides access to command statistics.
+
+Errors/Exceptions
+-----------------
+
+.. include:: /includes/extracts/error-unsupportedexception.rst
+.. include:: /includes/extracts/error-invalidargumentexception.rst
+.. include:: /includes/extracts/error-unexpectedvalueexception.rst
+.. include:: /includes/extracts/error-driver-runtimeexception.rst
+
+Behavior
+--------
+
+In MongoDB, the map-reduce operation can write results to a collection
+or return the results inline. If you write map-reduce output to a
+collection, you can perform subsequent map-reduce operations on the
+same input collection that merge replace, merge, or reduce new results
+with previous results. See :manual:`Map-Reduce </core/map-reduce>` and
+:manual:`Perform Incremental Map-Reduce </tutorial/perform-incremental-map-reduce>`
+for details and examples.
+
+When returning the results of a map-reduce operation *inline*, the
+result documents must be within the :limit:`BSON Document Size` limit,
+which is currently 16 megabytes.
+
+MongoDB supports map-reduce operations on :manual:`sharded collections
+</sharding>`. Map-reduce operations can also output
+the results to a sharded collection. See
+:manual:`Map-Reduce and Sharded Collections </core/map-reduce-sharded-collections>`.
+
+Example
+-------
+
+This example will use city populations to calculate the overall population of
+each state.
+
+.. code-block:: php
+
+   <?php
+
+   $collection = (new MongoDB\Client)->test->zips;
+
+   $map = new MongoDB\BSON\Javascript('function() { emit(this.state, this.pop); }');
+   $reduce = new MongoDB\BSON\Javascript('function(key, values) { return Array.sum(values) }');
+   $out = ['inline' => 1];
+
+   $populations = $collection->mapReduce($map, $reduce, $out);
+
+   foreach ($populations as $pop) {
+      var_dump($pop);
+   };
+
+The output would then resemble::
+
+   object(stdClass)#2293 (2) {
+      ["_id"]=>
+      string(2) "AK"
+      ["value"]=>
+      float(544698)
+   }
+   object(stdClass)#2300 (2) {
+      ["_id"]=>
+      string(2) "AL"
+      ["value"]=>
+      float(4040587)
+   }
+   object(stdClass)#2293 (2) {
+      ["_id"]=>
+      string(2) "AR"
+      ["value"]=>
+      float(2350725)
+   }
+   object(stdClass)#2300 (2) {
+      ["_id"]=>
+      string(2) "AZ"
+      ["value"]=>
+      float(3665228)
+   }
+
+See Also
+--------
+
+- :manual:`mapReduce </reference/command/mapReduce>` command reference in the MongoDB
+  manual
+- :manual:`Map-Reduce </core/map-reduce>` documentation in the MongoDB manual
+
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-replaceOne.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-replaceOne.txt
new file mode 100644
index 0000000000000000000000000000000000000000..ba43452b8582e873134d46120d1b6df6874ee5af
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-replaceOne.txt	
@@ -0,0 +1,93 @@
+=================================
+MongoDB\\Collection::replaceOne()
+=================================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\Collection::replaceOne()
+
+   Replace at most one document that matches the filter criteria. If multiple
+   documents match the filter criteria, only the :term:`first <natural order>`
+   matching document will be replaced.
+
+   .. code-block:: php
+
+      function replaceOne($filter, $replacement, array $options = []): MongoDB\UpdateResult
+
+   This method has the following parameters:
+
+   .. include:: /includes/apiargs/MongoDBCollection-method-replaceOne-param.rst
+
+   The ``$options`` parameter supports the following options:
+
+   .. include:: /includes/apiargs/MongoDBCollection-method-replaceOne-option.rst
+
+Return Values
+-------------
+
+A :phpclass:`MongoDB\\UpdateResult` object, which encapsulates a
+:php:`MongoDB\\Driver\\WriteResult <class.mongodb-driver-writeresult>` object.
+
+Errors/Exceptions
+-----------------
+
+.. include:: /includes/extracts/error-unsupportedexception.rst
+.. include:: /includes/extracts/error-invalidargumentexception.rst
+.. include:: /includes/extracts/error-driver-bulkwriteexception.rst
+.. include:: /includes/extracts/error-driver-runtimeexception.rst
+
+Behavior
+--------
+
+.. include:: /includes/extracts/note-bson-comparison.rst
+.. include:: /includes/extracts/bulkwriteexception-result.rst
+
+Example
+-------
+
+The following example replaces the document with ``restaurant_id`` of
+``"40356068"`` in the ``restaurants`` collection in the ``test`` database:
+
+.. code-block:: php
+
+   <?php
+
+   $collection = (new MongoDB\Client)->test->restaurants;
+
+   $updateResult = $collection->replaceOne(
+       [ 'restaurant_id' => '40356068' ],
+       [
+           'name' => 'New Restaurant',
+           'restaurant_id' => '99988877',
+           'borough' => 'Queens',
+           'cuisine' => 'Cafe',
+           'grades' => [],
+       ]
+   );
+
+   printf("Matched %d document(s)\n", $updateResult->getMatchedCount());
+   printf("Modified %d document(s)\n", $updateResult->getModifiedCount());
+
+The output would then resemble::
+
+   Matched 1 document(s)
+   Modified 1 document(s)
+
+See Also
+--------
+
+- :phpmethod:`MongoDB\\Collection::updateMany()`
+- :phpmethod:`MongoDB\\Collection::updateOne()`
+- :phpmethod:`MongoDB\\Collection::bulkWrite()`
+- :doc:`/tutorial/crud`
+- :manual:`update </reference/command/update>` command reference in the MongoDB
+  manual
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-updateMany.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-updateMany.txt
new file mode 100644
index 0000000000000000000000000000000000000000..bd72fdf9c3135213043ba6401992e12cfd5eee94
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-updateMany.txt	
@@ -0,0 +1,83 @@
+=================================
+MongoDB\\Collection::updateMany()
+=================================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\Collection::updateMany()
+
+   Update all documents that match the filter criteria.
+
+   .. code-block:: php
+
+      function updateMany($filter, $update, array $options = []): MongoDB\UpdateResult
+
+   This method has the following parameters:
+
+   .. include:: /includes/apiargs/MongoDBCollection-method-updateMany-param.rst
+
+   The ``$options`` parameter supports the following options:
+
+   .. include:: /includes/apiargs/MongoDBCollection-method-updateMany-option.rst
+
+Return Values
+-------------
+
+A :phpclass:`MongoDB\\UpdateResult` object, which encapsulates a
+:php:`MongoDB\\Driver\\WriteResult <class.mongodb-driver-writeresult>` object.
+
+Errors/Exceptions
+-----------------
+
+.. include:: /includes/extracts/error-unsupportedexception.rst
+.. include:: /includes/extracts/error-invalidargumentexception.rst
+.. include:: /includes/extracts/error-driver-bulkwriteexception.rst
+.. include:: /includes/extracts/error-driver-runtimeexception.rst
+
+Behavior
+--------
+
+.. include:: /includes/extracts/note-bson-comparison.rst
+.. include:: /includes/extracts/bulkwriteexception-result.rst
+
+Examples
+--------
+
+The following example updates all of the documents with the ``borough`` of
+``"Queens"`` by setting the ``active`` field to ``true``:
+
+.. code-block:: php
+
+   $collection = (new MongoDB\Client)->test->restaurants;
+
+   $updateResult = $collection->updateMany(
+       [ 'borough' => 'Queens' ],
+       [ '$set' => [ 'active' => 'True' ]]
+   );
+
+   printf("Matched %d document(s)\n", $updateResult->getMatchedCount());
+   printf("Modified %d document(s)\n", $updateResult->getModifiedCount());
+
+The output would then resemble::
+
+   Matched 5656 document(s)
+   Modified 5656 document(s)
+
+See Also
+--------
+
+- :phpmethod:`MongoDB\\Collection::replaceOne()`
+- :phpmethod:`MongoDB\\Collection::updateOne()`
+- :phpmethod:`MongoDB\\Collection::bulkWrite()`
+- :doc:`/tutorial/crud`
+- :manual:`update </reference/command/update>` command reference in the MongoDB
+  manual
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-updateOne.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-updateOne.txt
new file mode 100644
index 0000000000000000000000000000000000000000..bed657f92e2da96428d5bc9adf075ffe476c1a58
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-updateOne.txt	
@@ -0,0 +1,85 @@
+================================
+MongoDB\\Collection::updateOne()
+================================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\Collection::updateOne()
+
+   Update at most one document that matches the filter criteria. If multiple
+   documents match the filter criteria, only the :term:`first <natural order>`
+   matching document will be updated.
+
+   .. code-block:: php
+
+      function updateOne($filter, $update, array $options = []): MongoDB\UpdateResult
+
+   This method has the following parameters:
+
+   .. include:: /includes/apiargs/MongoDBCollection-method-updateOne-param.rst
+
+   The ``$options`` parameter supports the following options:
+
+   .. include:: /includes/apiargs/MongoDBCollection-method-updateOne-option.rst
+
+Return Values
+-------------
+
+A :phpclass:`MongoDB\\UpdateResult` object, which encapsulates a
+:php:`MongoDB\\Driver\\WriteResult <class.mongodb-driver-writeresult>` object.
+
+Errors/Exceptions
+-----------------
+
+.. include:: /includes/extracts/error-unsupportedexception.rst
+.. include:: /includes/extracts/error-invalidargumentexception.rst
+.. include:: /includes/extracts/error-driver-bulkwriteexception.rst
+.. include:: /includes/extracts/error-driver-runtimeexception.rst
+
+Behavior
+--------
+
+.. include:: /includes/extracts/note-bson-comparison.rst
+.. include:: /includes/extracts/bulkwriteexception-result.rst
+
+Examples
+--------
+
+The following example updates one document with the ``restaurant_id`` of
+``"40356151"`` by setting the ``name`` field to ``"Brunos on Astoria"``:
+
+.. code-block:: php
+
+   $collection = (new MongoDB\Client)->test->restaurants;
+
+   $updateResult = $collection->updateOne(
+       [ 'restaurant_id' => '40356151' ],
+       [ '$set' => [ 'name' => 'Brunos on Astoria' ]]
+   );
+
+   printf("Matched %d document(s)\n", $updateResult->getMatchedCount());
+   printf("Modified %d document(s)\n", $updateResult->getModifiedCount());
+
+The output would then resemble::
+
+   Matched 1 document(s)
+   Modified 1 document(s)
+
+See Also
+--------
+
+- :phpmethod:`MongoDB\\Collection::replaceOne()`
+- :phpmethod:`MongoDB\\Collection::updateMany()`
+- :phpmethod:`MongoDB\\Collection::bulkWrite()`
+- :doc:`/tutorial/crud`
+- :manual:`update </reference/command/update>` command reference in the MongoDB
+  manual
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-watch.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-watch.txt
new file mode 100644
index 0000000000000000000000000000000000000000..50ef408dc3f85b3a0f460c9d44e9d7c05d79b860
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-watch.txt	
@@ -0,0 +1,123 @@
+============================
+MongoDB\\Collection::watch()
+============================
+
+.. versionadded:: 1.3
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\Collection::watch()
+
+   Executes a :manual:`change stream </changeStreams>` operation on the
+   collection. The change stream can be watched for collection-level changes.
+
+   .. code-block:: php
+
+      function watch(array $pipeline = [], array $options = []): MongoDB\ChangeStream
+
+   This method has the following parameters:
+
+   .. include:: /includes/apiargs/MongoDBCollection-method-watch-param.rst
+
+   The ``$options`` parameter supports the following options:
+
+   .. include:: /includes/apiargs/MongoDBCollection-method-watch-option.rst
+
+Return Values
+-------------
+
+A :phpclass:`MongoDB\\ChangeStream` object, which allows for iteration of
+events in the change stream via the :php:`Iterator <class.iterator>` interface.
+
+Errors/Exceptions
+-----------------
+
+.. include:: /includes/extracts/error-unexpectedvalueexception.rst
+.. include:: /includes/extracts/error-unsupportedexception.rst
+.. include:: /includes/extracts/error-invalidargumentexception.rst
+.. include:: /includes/extracts/error-driver-runtimeexception.rst
+
+Examples
+--------
+
+This example reports events while iterating a change stream.
+
+.. code-block:: php
+
+   <?php
+
+   $uri = 'mongodb://rs1.example.com,rs2.example.com/?replicaSet=myReplicaSet';
+
+   $collection = (new MongoDB\Client($uri))->test->inventory;
+
+   $changeStream = $collection->watch();
+
+   for ($changeStream->rewind(); true; $changeStream->next()) {
+       if ( ! $changeStream->valid()) {
+           continue;
+       }
+
+       $event = $changeStream->current();
+
+       if ($event['operationType'] === 'invalidate') {
+           break;
+       }
+
+       $ns = sprintf('%s.%s', $event['ns']['db'], $event['ns']['coll']);
+       $id = json_encode($event['documentKey']['_id']);
+
+       switch ($event['operationType']) {
+           case 'delete':
+               printf("Deleted document in %s with _id: %s\n\n", $ns, $id);
+               break;
+
+           case 'insert':
+               printf("Inserted new document in %s\n", $ns);
+               echo json_encode($event['fullDocument']), "\n\n";
+               break;
+
+           case 'replace':
+               printf("Replaced new document in %s with _id: %s\n", $ns, $id);
+               echo json_encode($event['fullDocument']), "\n\n";
+               break;
+
+           case 'update':
+               printf("Updated document in %s with _id: %s\n", $ns, $id);
+               echo json_encode($event['updateDescription']), "\n\n";
+               break;
+       }
+   }
+
+Assuming that a document was inserted, updated, and deleted while the above
+script was iterating the change stream, the output would then resemble:
+
+.. code-block:: none
+
+   Inserted new document in test.user
+   {"_id":{"$oid":"5b329c4874083047cc05e60a"},"username":"bob"}
+
+   Inserted new document in test.products
+   {"_id":{"$oid":"5b329c4d74083047cc05e60b"},"name":"Widget","quantity":5}
+
+   Updated document in test.user with _id: {"$oid":"5b329a4f74083047cc05e603"}
+   {"updatedFields":{"username":"robert"},"removedFields":[]}
+
+See Also
+--------
+
+- :phpmethod:`MongoDB\\Client::watch()`
+- :phpmethod:`MongoDB\\Database::watch()`
+- :manual:`Aggregation Pipeline </core/aggregation-pipeline>` documentation in
+  the MongoDB Manual
+- :manual:`Change Streams </changeStreams>` documentation in the MongoDB manual
+- :manual:`Change Events </reference/change-events/>` documentation in the
+  MongoDB manual
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-withOptions.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-withOptions.txt
new file mode 100644
index 0000000000000000000000000000000000000000..92e09f6e350794530ea1f176527cc3927fefb3ed
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection-withOptions.txt	
@@ -0,0 +1,61 @@
+==================================
+MongoDB\\Collection::withOptions()
+==================================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\Collection::withOptions()
+
+   Returns a clone of the Collection object, but with different options.
+
+   .. code-block:: php
+
+      function withOptions(array $options = []): MongoDB\Collection
+
+   This method has the following parameters:
+
+   .. include:: /includes/apiargs/MongoDBCollection-method-withOptions-param.rst
+
+   The ``$options`` parameter supports the following options:
+
+   .. include:: /includes/apiargs/MongoDBCollection-method-withOptions-option.rst
+
+Return Values
+-------------
+
+A :phpclass:`MongoDB\\Collection` object.
+
+Errors/Exceptions
+-----------------
+
+.. include:: /includes/extracts/error-invalidargumentexception.rst
+
+Example
+-------
+
+The following example clones an existing Collection object with a new read
+preference:
+
+.. code-block:: php
+
+   <?php
+
+   $collection = (new MongoDB\Client)->selectCollection('test', 'restaurants');
+
+   $newCollection = $sourceCollection->withOptions([
+       'readPreference' => new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_SECONDARY),
+   ]);
+
+See Also
+--------
+
+- :phpmethod:`MongoDB\\Collection::__construct()`
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection__construct.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection__construct.txt
new file mode 100644
index 0000000000000000000000000000000000000000..c3ef0c6bfcd8a7c9eef23e666e984218c560b187
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBCollection__construct.txt	
@@ -0,0 +1,54 @@
+==================================
+MongoDB\\Collection::__construct()
+==================================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\Collection::__construct()
+
+   Constructs a new :phpclass:`Collection <MongoDB\\Collection>` instance.
+
+   .. code-block:: php
+
+      function __construct(MongoDB\Driver\Manager $manager, $databaseName, $collectionName, array $options = [])
+
+   This constructor has the following parameters:
+
+   .. include:: /includes/apiargs/MongoDBCollection-method-construct-param.rst
+
+   The ``$options`` parameter supports the following options:
+
+   .. include:: /includes/apiargs/MongoDBCollection-method-construct-option.rst
+
+Errors/Exceptions
+-----------------
+
+.. include:: /includes/extracts/error-invalidargumentexception.rst
+
+Behavior
+--------
+
+If you construct a Collection explicitly, the Collection inherits any options
+from the :php:`MongoDB\\Driver\\Manager <class.mongodb-driver-manager>` object.
+If you select the Collection from a :phpclass:`Client <MongoDB\\Client>` or
+:phpclass:`Database <MongoDB\\Database>` object, the Collection inherits its
+options from that object.
+
+.. todo: add an example
+
+See Also
+--------
+
+- :phpmethod:`MongoDB\\Collection::withOptions()`
+- :phpmethod:`MongoDB\\Client::selectCollection()`
+- :phpmethod:`MongoDB\\Database::selectCollection()`
+- :phpmethod:`MongoDB\\Database::__get()`
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBDatabase-aggregate.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBDatabase-aggregate.txt
new file mode 100644
index 0000000000000000000000000000000000000000..a7884bfe153e45e37263d9687e25ca7b43530986
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBDatabase-aggregate.txt	
@@ -0,0 +1,81 @@
+==============================
+MongoDB\\Database::aggregate()
+==============================
+
+.. versionadded:: 1.5
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\Database::aggregate()
+
+   Runs a specified :manual:`admin/diagnostic pipeline
+   </reference/operator/aggregation-pipeline/#db-aggregate-stages>` which does
+   not require an underlying collection. For aggregations on collection data,
+   see :phpmethod:`MongoDB\\Collection::aggregate()`.
+
+   .. code-block:: php
+
+      function aggregate(array $pipeline, array $options = []): Traversable
+
+   This method has the following parameters:
+
+   .. include:: /includes/apiargs/MongoDBDatabase-method-aggregate-param.rst
+
+   The ``$options`` parameter supports the following options:
+
+   .. include:: /includes/apiargs/MongoDBDatabase-method-aggregate-option.rst
+
+Return Values
+-------------
+
+A :php:`MongoDB\\Driver\\Cursor <class.mongodb-driver-cursor>` or
+:php:`ArrayIterator <arrayiterator>` object. In both cases, the return value
+will be :php:`Traversable <traversable>`.
+
+Errors/Exceptions
+-----------------
+
+.. include:: /includes/extracts/error-unexpectedvalueexception.rst
+.. include:: /includes/extracts/error-unsupportedexception.rst
+.. include:: /includes/extracts/error-invalidargumentexception.rst
+.. include:: /includes/extracts/error-driver-runtimeexception.rst
+
+.. _php-db-agg-method-behavior:
+
+Examples
+--------
+
+The following aggregation example lists all running commands using the
+``$currentOp`` aggregation pipeline stage, then filters this list to only show
+running command operations.
+
+.. code-block:: php
+
+   <?php
+
+   $database = (new MongoDB\Client)->admin;
+
+   $cursor = $database->aggregate(
+       [
+           ['$currentOp' => []],
+           ['$match' => ['op' => 'command'],
+       ]
+   );
+
+See Also
+--------
+
+- :phpmethod:`MongoDB\\Collection::aggregate()`
+- :manual:`aggregate </reference/command/aggregate>` command reference in the
+  MongoDB manual
+- :manual:`Aggregation Pipeline </core/aggregation-pipeline>` documentation in
+  the MongoDB Manual
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBDatabase-command.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBDatabase-command.txt
new file mode 100644
index 0000000000000000000000000000000000000000..46b28fbee37255634ac383649a9e67139f384faa
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBDatabase-command.txt	
@@ -0,0 +1,155 @@
+============================
+MongoDB\\Database::command()
+============================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\Database::command()
+
+   Execute a :manual:`command </reference/command>` on the database.
+
+   .. code-block:: php
+
+      function command($command, array $options = []): MongoDB\Driver\Cursor
+
+   This method has the following parameters:
+
+   .. include:: /includes/apiargs/MongoDBDatabase-method-command-param.rst
+
+   The ``$options`` parameter supports the following options:
+
+   .. include:: /includes/apiargs/MongoDBDatabase-method-command-option.rst
+
+Return Values
+-------------
+
+A :php:`MongoDB\\Driver\\Cursor <class.mongodb-driver-cursor>` object.
+
+Errors/Exceptions
+-----------------
+
+.. include:: /includes/extracts/error-invalidargumentexception.rst
+.. include:: /includes/extracts/error-driver-runtimeexception.rst
+
+Example
+-------
+
+The following example executes an :manual:`isMaster
+</reference/command/isMaster>` command, which returns a cursor with a single
+result document:
+
+.. code-block:: php
+
+   <?php
+
+   $database = (new MongoDB\Client)->test;
+
+   $cursor = $database->command(['isMaster' => 1]);
+
+   var_dump($c->toArray()[0]);
+
+The output would resemble::
+
+   object(MongoDB\Model\BSONDocument)#11 (1) {
+     ["storage":"ArrayObject":private]=>
+     array(8) {
+       ["ismaster"]=>
+       bool(true)
+       ["maxBsonObjectSize"]=>
+       int(16777216)
+       ["maxMessageSizeBytes"]=>
+       int(48000000)
+       ["maxWriteBatchSize"]=>
+       int(1000)
+       ["localTime"]=>
+       object(MongoDB\BSON\UTCDateTime)#3 (1) {
+         ["milliseconds"]=>
+         string(13) "1477608046464"
+       }
+       ["maxWireVersion"]=>
+       int(4)
+       ["minWireVersion"]=>
+       int(0)
+       ["ok"]=>
+       float(1)
+     }
+   }
+
+The following example executes a :manual:`listCollections
+</reference/command/listCollections>` command, which returns a cursor with
+multiple result documents:
+
+.. code-block:: php
+
+   <?php
+
+   $database = (new MongoDB\Client)->test;
+
+   $cursor = $database->command(['isMaster' => 1]);
+
+   var_dump($c->toArray());
+
+The output would resemble::
+
+   array(3) {
+     [0]=>
+     object(MongoDB\Model\BSONDocument)#11 (1) {
+       ["storage":"ArrayObject":private]=>
+       array(2) {
+         ["name"]=>
+         string(11) "restaurants"
+         ["options"]=>
+         object(MongoDB\Model\BSONDocument)#3 (1) {
+           ["storage":"ArrayObject":private]=>
+           array(0) {
+           }
+         }
+       }
+     }
+     [1]=>
+     object(MongoDB\Model\BSONDocument)#13 (1) {
+       ["storage":"ArrayObject":private]=>
+       array(2) {
+         ["name"]=>
+         string(5) "users"
+         ["options"]=>
+         object(MongoDB\Model\BSONDocument)#12 (1) {
+           ["storage":"ArrayObject":private]=>
+           array(0) {
+           }
+         }
+       }
+     }
+     [2]=>
+     object(MongoDB\Model\BSONDocument)#15 (1) {
+       ["storage":"ArrayObject":private]=>
+       array(2) {
+         ["name"]=>
+         string(6) "restos"
+         ["options"]=>
+         object(MongoDB\Model\BSONDocument)#14 (1) {
+           ["storage":"ArrayObject":private]=>
+           array(0) {
+           }
+         }
+       }
+     }
+   }
+
+See Also
+--------
+
+- :doc:`/tutorial/commands`
+- :manual:`Database Commands </reference/command>` in the MongoDB manual
+- :php:`MongoDB\\Driver\\Cursor <class.mongodb-driver-cursor>`
+- :php:`MongoDB\\Driver\\Manager::executeCommand()
+  <manual/en/mongodb-driver-manager.executecommand.php>`
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBDatabase-createCollection.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBDatabase-createCollection.txt
new file mode 100644
index 0000000000000000000000000000000000000000..8db6696c40bbba1b0635dd76007309f3121b7463
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBDatabase-createCollection.txt	
@@ -0,0 +1,99 @@
+=====================================
+MongoDB\\Database::createCollection()
+=====================================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\Database::createCollection()
+
+   Explicitly creates a collection.
+
+   .. code-block:: php
+
+      function createCollection($collectionName, array $options = []): array|object
+
+   MongoDB creates collections implicitly when you first reference the
+   collection in a command, such as when inserting a document into a new
+   collection. You may also explicitly create a collection with specific options
+   using the :phpmethod:`MongoDB\\Database::createCollection()` method, or using
+   :manual:`db.createCollection() </reference/method/db.createCollection>` in
+   the :program:`mongo` shell.
+
+   Explicitly creating collections enables you to create
+   :manual:`capped collections </core/capped-collections>`, specify
+   :manual:`document validation criteria </core/document-validation>`,
+   or configure your storage engine or indexing options.
+
+   This method has the following parameters:
+
+   .. include:: /includes/apiargs/MongoDBDatabase-method-createCollection-param.rst
+
+   The ``$options`` parameter supports the following options:
+
+   .. include:: /includes/apiargs/MongoDBDatabase-method-createCollection-option.rst
+
+   Note that not all options are available on all versions of MongoDB. Document
+   validation, for example, was added in MongoDB 3.2; similarly, the WiredTiger
+   storage engine is available only for MongoDB 3.0 and later. Refer to the
+   :manual:`create </reference/command/create>` command reference in the MongoDB
+   manual for compatibility considerations.
+
+Return Values
+-------------
+
+An array or object with the result document of the :manual:`create
+</reference/command/create>` command.
+
+Errors/Exceptions
+-----------------
+
+.. include:: /includes/extracts/error-unsupportedexception.rst
+.. include:: /includes/extracts/error-invalidargumentexception.rst
+.. include:: /includes/extracts/error-driver-runtimeexception.rst
+
+Example
+-------
+
+The following example creates a ``users`` collection in the ``test``
+database with document validation criteria:
+
+.. code-block:: php
+
+   <?php
+
+   $db = (new MongoDB\Client)->test;
+
+   $result = $db->createCollection('users', [
+       'validator' => [
+           'username' => ['$type' => 'string'],
+           'email' => ['$regex' => '@mongodb\.com$'],
+       ],
+   ]);
+
+   var_dump($result);
+
+The output would then resemble::
+
+   object(MongoDB\Model\BSONDocument)#11 (1) {
+     ["storage":"ArrayObject":private]=>
+     array(1) {
+       ["ok"]=>
+       float(1)
+     }
+   }
+
+See Also
+--------
+
+- :manual:`create </reference/command/create>` command reference in the MongoDB
+  manual
+- :manual:`db.createCollection() </reference/method/db.createCollection>`
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBDatabase-drop.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBDatabase-drop.txt
new file mode 100644
index 0000000000000000000000000000000000000000..bcf6ca88a67faa3d808cf2e2f5fb5731f20f97ae
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBDatabase-drop.txt	
@@ -0,0 +1,78 @@
+=========================
+MongoDB\\Database::drop()
+=========================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\Database::drop()
+
+   Drop the database.
+
+   .. code-block:: php
+
+      function drop(array $options = []): array|object
+
+   This method has the following parameters:
+
+   .. include:: /includes/apiargs/MongoDBDatabase-method-drop-param.rst
+
+   The ``$options`` parameter supports the following options:
+
+   .. include:: /includes/apiargs/MongoDBDatabase-method-drop-option.rst
+
+Return Values
+-------------
+
+An array or object with the result document of the :manual:`dropDatabase
+</reference/command/dropDatabase>` command. The return type will depend on the
+``typeMap`` option.
+
+Errors/Exceptions
+-----------------
+
+.. include:: /includes/extracts/error-unsupportedexception.rst
+.. include:: /includes/extracts/error-invalidargumentexception.rst
+.. include:: /includes/extracts/error-driver-runtimeexception.rst
+
+Example
+-------
+
+The following example drops the ``test`` database:
+
+.. code-block:: php
+
+   <?php
+
+   $db = (new MongoDB\Client)->test;
+
+   $result = $db->drop();
+
+   var_dump($result);
+
+The output would then resemble::
+
+   object(MongoDB\Model\BSONDocument)#8 (1) {
+     ["storage":"ArrayObject":private]=>
+     array(2) {
+       ["dropped"]=>
+       string(4) "test"
+       ["ok"]=>
+       float(1)
+     }
+   }
+
+See Also
+--------
+
+- :phpmethod:`MongoDB\\Client::dropDatabase()`
+- :manual:`dropDatabase </reference/command/dropDatabase>` command reference in
+  the MongoDB manual
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBDatabase-dropCollection.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBDatabase-dropCollection.txt
new file mode 100644
index 0000000000000000000000000000000000000000..fbc005b86f865cbac68bcbfe668bad48447ba950
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBDatabase-dropCollection.txt	
@@ -0,0 +1,80 @@
+===================================
+MongoDB\\Database::dropCollection()
+===================================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\Database::dropCollection()
+
+   Drop a collection within the current database.
+
+   .. code-block:: php
+
+      function dropCollection($collectionName, array $options = []): array|object
+
+   This method has the following parameters:
+
+   .. include:: /includes/apiargs/MongoDBDatabase-method-dropCollection-param.rst
+
+   The ``$options`` parameter supports the following options:
+
+   .. include:: /includes/apiargs/MongoDBDatabase-method-dropCollection-option.rst
+
+Return Values
+-------------
+
+An array or object with the result document of the :manual:`drop
+</reference/command/drop>` command. The return type will depend on the
+``typeMap`` option.
+
+Errors/Exceptions
+-----------------
+
+.. include:: /includes/extracts/error-unsupportedexception.rst
+.. include:: /includes/extracts/error-invalidargumentexception.rst
+.. include:: /includes/extracts/error-driver-runtimeexception.rst
+
+Example
+-------
+
+The following example drops the ``users`` collection in the ``test`` database:
+
+.. code-block:: php
+
+   <?php
+
+   $db = (new MongoDB\Client)->test;
+
+   $result = $db->dropCollection('users');
+
+   var_dump($result);
+
+The output would then resemble::
+
+   object(MongoDB\Model\BSONDocument)#8 (1) {
+     ["storage":"ArrayObject":private]=>
+     array(3) {
+       ["ns"]=>
+       string(10) "test.users"
+       ["nIndexesWas"]=>
+       int(1)
+       ["ok"]=>
+       float(1)
+     }
+   }
+
+See Also
+--------
+
+- :phpmethod:`MongoDB\\Collection::drop()`
+- :manual:`drop </reference/command/drop>` command reference in the MongoDB
+  manual
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBDatabase-getDatabaseName.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBDatabase-getDatabaseName.txt
new file mode 100644
index 0000000000000000000000000000000000000000..6ff9dcb9692356c6e44abdc44d69f0e516477df6
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBDatabase-getDatabaseName.txt	
@@ -0,0 +1,44 @@
+====================================
+MongoDB\\Database::getDatabaseName()
+====================================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\Database::getDatabaseName()
+
+   Returns the name of this database.
+
+   .. code-block:: php
+
+      function getDatabaseName(): string
+
+Return Values
+-------------
+
+The name of this database as a string.
+
+Example
+-------
+
+The following example prints the name of a database object:
+
+.. code-block:: php
+
+   <?php
+
+   $db = (new MongoDB\Client)->test;
+
+   echo $db->getDatabaseName();
+
+The output would then resemble::
+
+   test
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBDatabase-getManager.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBDatabase-getManager.txt
new file mode 100644
index 0000000000000000000000000000000000000000..72a2b0570bb808505d4c1bfcc1a09819b6d6ab58
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBDatabase-getManager.txt	
@@ -0,0 +1,35 @@
+===============================
+MongoDB\\Database::getManager()
+===============================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\Database::getManager()
+
+   Accessor for the
+   :php:`MongoDB\\Driver\\Manager <class.mongodb-driver-manager>` used by this
+   :phpclass:`Database <MongoDB\\Database>`.
+
+   .. code-block:: php
+
+      function getManager(): MongoDB\Manager
+
+Return Values
+-------------
+
+A :php:`MongoDB\\Driver\\Manager <class.mongodb-driver-manager>` object.
+
+See Also
+--------
+
+- :phpmethod:`MongoDB\\Client::getManager()`
+- :phpmethod:`MongoDB\\Collection::getManager()`
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBDatabase-getReadConcern.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBDatabase-getReadConcern.txt
new file mode 100644
index 0000000000000000000000000000000000000000..fa277d884a1fee5c8a056fad100542f692362bc7
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBDatabase-getReadConcern.txt	
@@ -0,0 +1,58 @@
+===================================
+MongoDB\\Database::getReadConcern()
+===================================
+
+.. versionadded:: 1.2
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\Database::getReadConcern()
+
+   Returns the read concern for this database.
+
+   .. code-block:: php
+
+      function getReadConcern(): MongoDB\Driver\ReadConcern
+
+Return Values
+-------------
+
+A :php:`MongoDB\\Driver\\ReadConcern <class.mongodb-driver-readconcern>` object.
+
+Example
+-------
+
+.. code-block:: php
+
+   <?php
+
+   $database = (new MongoDB\Client)->selectDatabase('test', [
+      'readConcern' => new MongoDB\Driver\ReadConcern(MongoDB\Driver\ReadConcern::MAJORITY),
+   ]);
+
+   var_dump($database->getReadConcern());
+
+The output would then resemble::
+
+   object(MongoDB\Driver\ReadConcern)#5 (1) {
+     ["level"]=>
+     string(8) "majority"
+   }
+
+See Also
+--------
+
+- :manual:`Read Concern </reference/read-concern>` in the MongoDB manual
+- :php:`MongoDB\\Driver\\ReadConcern::isDefault() <mongodb-driver-readconcern.isdefault>`
+- :phpmethod:`MongoDB\\Client::getReadConcern()`
+- :phpmethod:`MongoDB\\Collection::getReadConcern()`
+- :phpmethod:`MongoDB\\GridFS\\Bucket::getReadConcern()`
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBDatabase-getReadPreference.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBDatabase-getReadPreference.txt
new file mode 100644
index 0000000000000000000000000000000000000000..c70b40268b19c469ae7038d4d69c0055ccc8db8d
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBDatabase-getReadPreference.txt	
@@ -0,0 +1,58 @@
+======================================
+MongoDB\\Database::getReadPreference()
+======================================
+
+.. versionadded:: 1.2
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\Database::getReadPreference()
+
+   Returns the read preference for this database.
+
+   .. code-block:: php
+
+      function getReadPreference(): MongoDB\Driver\ReadPreference
+
+Return Values
+-------------
+
+A :php:`MongoDB\\Driver\\ReadPreference <class.mongodb-driver-readpreference>`
+object.
+
+Example
+-------
+
+.. code-block:: php
+
+   <?php
+
+   $database = (new MongoDB\Client)->selectDatabase('test', [
+       'readPreference' => new MongoDB\Driver\ReadPreference('primaryPreferred'),
+   ]);
+
+   var_dump($database->getReadPreference());
+
+The output would then resemble::
+
+   object(MongoDB\Driver\ReadPreference)#5 (1) {
+     ["mode"]=>
+     string(16) "primaryPreferred"
+   }
+
+See Also
+--------
+
+- :manual:`Read Preference </reference/read-preference>` in the MongoDB manual
+- :phpmethod:`MongoDB\\Client::getReadPreference()`
+- :phpmethod:`MongoDB\\Collection::getReadPreference()`
+- :phpmethod:`MongoDB\\GridFS\\Bucket::getReadPreference()`
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBDatabase-getTypeMap.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBDatabase-getTypeMap.txt
new file mode 100644
index 0000000000000000000000000000000000000000..bc1688d63168db88fb125c12f502bef83ea7a0a1
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBDatabase-getTypeMap.txt	
@@ -0,0 +1,65 @@
+===============================
+MongoDB\\Database::getTypeMap()
+===============================
+
+.. versionadded:: 1.2
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\Database::getTypeMap()
+
+   Returns the type map for this database.
+
+   .. code-block:: php
+
+      function getTypeMap(): array
+
+Return Values
+-------------
+
+A :ref:`type map <php-type-map>` array.
+
+Example
+-------
+
+.. code-block:: php
+
+   <?php
+
+   $database = (new MongoDB\Client)->selectDatabase('test', [
+       'typeMap' => [
+           'root' => 'array',
+           'document' => 'array',
+           'array' => 'array',
+       ],
+   ]);
+
+   var_dump($database->getTypeMap());
+
+The output would then resemble::
+
+   array(3) {
+     ["root"]=>
+     string(5) "array"
+     ["document"]=>
+     string(5) "array"
+     ["array"]=>
+     string(5) "array"
+   }
+
+See Also
+--------
+
+- :doc:`/reference/bson`
+- :phpmethod:`MongoDB\\Client::getTypeMap()`
+- :phpmethod:`MongoDB\\Collection::getTypeMap()`
+- :phpmethod:`MongoDB\\GridFS\\Bucket::getTypeMap()`
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBDatabase-getWriteConcern.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBDatabase-getWriteConcern.txt
new file mode 100644
index 0000000000000000000000000000000000000000..31b0ded51214902de42133fcd9d7a16c53ca75cf
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBDatabase-getWriteConcern.txt	
@@ -0,0 +1,61 @@
+====================================
+MongoDB\\Database::getWriteConcern()
+====================================
+
+.. versionadded:: 1.2
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\Database::getWriteConcern()
+
+   Returns the write concern for this database.
+
+   .. code-block:: php
+
+      function getWriteConcern(): MongoDB\Driver\WriteConcern
+
+Return Values
+-------------
+
+A :php:`MongoDB\\Driver\\WriteConcern <class.mongodb-driver-writeconcern>`
+object.
+
+Example
+-------
+
+.. code-block:: php
+
+   <?php
+
+   $database = (new MongoDB\Client)->selectDatabase('test', [
+      'writeConcern' => new MongoDB\Driver\WriteConcern(1, 0, true),
+   ]);
+
+   var_dump($database->getWriteConcern());
+
+The output would then resemble::
+
+   object(MongoDB\Driver\WriteConcern)#5 (2) {
+     ["w"]=>
+     int(1)
+     ["j"]=>
+     bool(true)
+   }
+
+See Also
+--------
+
+- :manual:`Write Concern </reference/read-concern>` in the MongoDB manual
+- :php:`MongoDB\\Driver\\WriteConcern::isDefault() <mongodb-driver-writeconcern.isdefault>`
+- :phpmethod:`MongoDB\\Client::getWriteConcern()`
+- :phpmethod:`MongoDB\\Collection::getWriteConcern()`
+- :phpmethod:`MongoDB\\GridFS\\Bucket::getWriteConcern()`
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBDatabase-listCollectionNames.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBDatabase-listCollectionNames.txt
new file mode 100644
index 0000000000000000000000000000000000000000..6e973df19d0555b2d3c20fb8a4c976e296a89b80
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBDatabase-listCollectionNames.txt	
@@ -0,0 +1,98 @@
+========================================
+MongoDB\\Database::listCollectionNames()
+========================================
+
+.. versionadded:: 1.7
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\Database::listCollectionNames()
+
+   Returns names for all collections in this database.
+
+   .. code-block:: php
+
+      function listCollectionNames(array $options = []): Iterator
+
+   This method has the following parameters:
+
+   .. include:: /includes/apiargs/MongoDBDatabase-method-listCollections-param.rst
+
+   The ``$options`` parameter supports the following options:
+
+   .. include:: /includes/apiargs/MongoDBDatabase-method-listCollections-option.rst
+
+Return Values
+-------------
+
+An :php:`Iterator <class.iterator.php>`, which provides the name of each
+collection in the database.
+
+Example
+-------
+
+The following example lists all of the collections in the ``test`` database:
+
+.. code-block:: php
+
+   <?php
+
+   $database = (new MongoDB\Client)->test;
+
+   foreach ($database->listCollectionNames() as $collectionName) {
+       var_dump($collectionName);
+   }
+
+The output would then resemble::
+
+   string(11) "restaurants"
+   string(5) "users"
+   string(6) "restos"
+
+The following example lists all collections whose name starts with ``"rest"``
+in the ``test`` database:
+
+.. code-block:: php
+
+   <?php
+
+   $database = (new MongoDB\Client)->test;
+
+   $collections = $database->listCollectionNames([
+       'filter' => [
+           'name' => new MongoDB\BSON\Regex('^rest.*'),
+       ],
+   ]);
+
+   foreach ($collections as $collectionName) {
+       var_dump($collectionName);
+   }
+
+The output would then resemble::
+
+   string(11) "restaurants"
+   string(6) "restos"
+
+.. note::
+
+   When enumerating collection names, a filter expression can only filter based
+   on a collection's name and type. No other fields are available.
+
+See Also
+--------
+
+- :phpmethod:`MongoDB\\Database::listCollections()`
+- :manual:`listCollections </reference/command/listCollections` command
+  reference in the MongoDB manual
+- `Enumerating Collections
+  <https://github.com/mongodb/specifications/blob/master/source/enumerate-collections.rst>`_
+  specification
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBDatabase-listCollections.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBDatabase-listCollections.txt
new file mode 100644
index 0000000000000000000000000000000000000000..eb0c4c921113e0cc6c3d5af69b5772a05ab4ec37
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBDatabase-listCollections.txt	
@@ -0,0 +1,122 @@
+====================================
+MongoDB\\Database::listCollections()
+====================================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\Database::listCollections()
+
+   Returns information for all collections in this database.
+
+   .. code-block:: php
+
+      function listCollections(array $options = []): MongoDB\Model\CollectionInfoIterator
+
+   This method has the following parameters:
+
+   .. include:: /includes/apiargs/MongoDBDatabase-method-listCollections-param.rst
+
+   The ``$options`` parameter supports the following options:
+
+   .. include:: /includes/apiargs/MongoDBDatabase-method-listCollections-option.rst
+
+Return Values
+-------------
+
+A traversable :phpclass:`MongoDB\\Model\\CollectionInfoIterator`, which contains
+a :phpclass:`MongoDB\\Model\\CollectionInfo` object for each collection in the
+database.
+
+Example
+-------
+
+The following example lists all of the collections in the ``test`` database:
+
+.. code-block:: php
+
+   <?php
+
+   $database = (new MongoDB\Client)->test;
+
+   foreach ($database->listCollections() as $collectionInfo) {
+       var_dump($collectionInfo);
+   }
+
+The output would then resemble::
+
+   object(MongoDB\Model\CollectionInfo)#3 (2) {
+     ["name"]=>
+     string(11) "restaurants"
+     ["options"]=>
+     array(0) {
+     }
+   }
+   object(MongoDB\Model\CollectionInfo)#3 (2) {
+     ["name"]=>
+     string(5) "users"
+     ["options"]=>
+     array(0) {
+     }
+   }
+   object(MongoDB\Model\CollectionInfo)#3 (2) {
+     ["name"]=>
+     string(6) "restos"
+     ["options"]=>
+     array(0) {
+     }
+   }
+
+The following example lists all collections whose name starts with ``"rest"``
+in the ``test`` database:
+
+.. code-block:: php
+
+   <?php
+
+   $database = (new MongoDB\Client)->test;
+
+   $collections = $database->listCollections([
+       'filter' => [
+           'name' => new MongoDB\BSON\Regex('^rest.*'),
+       ],
+   ]);
+
+   foreach ($collections as $collectionInfo) {
+       var_dump($collectionInfo);
+   }
+
+The output would then resemble::
+
+   object(MongoDB\Model\CollectionInfo)#3 (2) {
+     ["name"]=>
+     string(11) "restaurants"
+     ["options"]=>
+     array(0) {
+     }
+   }
+   object(MongoDB\Model\CollectionInfo)#3 (2) {
+     ["name"]=>
+     string(6) "restos"
+     ["options"]=>
+     array(0) {
+     }
+   }
+
+See Also
+--------
+
+- :phpmethod:`MongoDB\\Database::listCollectionNames()`
+- :manual:`listCollections </reference/command/listCollections` command
+  reference in the MongoDB manual
+- `Enumerating Collections
+  <https://github.com/mongodb/specifications/blob/master/source/enumerate-collections.rst>`_
+  specification
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBDatabase-modifyCollection.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBDatabase-modifyCollection.txt
new file mode 100644
index 0000000000000000000000000000000000000000..43eb2d259ced01938dc01db2dea4097f60dc990d
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBDatabase-modifyCollection.txt	
@@ -0,0 +1,81 @@
+=====================================
+MongoDB\\Database::modifyCollection()
+=====================================
+
+.. versionadded:: 1.4
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\Database::modifyCollection()
+
+   Modifies a collection or view according to the specified
+   ``$collectionOptions``.
+
+   .. code-block:: php
+
+      function modifyCollection($collectionName, array $collectionOptions, array $options = []): array|object
+
+   This method has the following parameters:
+
+   .. include:: /includes/apiargs/MongoDBDatabase-method-modifyCollection-param.rst
+
+   The ``$options`` parameter supports the following options:
+
+   .. include:: /includes/apiargs/MongoDBDatabase-method-modifyCollection-option.rst
+
+Return Values
+-------------
+
+An array or object with the result document of the :manual:`collMod
+</reference/command/collMod>` command.
+
+Errors/Exceptions
+-----------------
+
+.. include:: /includes/extracts/error-invalidargumentexception.rst
+.. include:: /includes/extracts/error-driver-runtimeexception.rst
+
+Example
+-------
+
+The following example changes the expiration time of a TTL collection in the
+``test`` database:
+
+.. code-block:: php
+
+   <?php
+
+   $db = (new MongoDB\Client)->test;
+
+   $result = $db->modifyCollection('users', [
+       'keyPattern' => ['lastAccess' => 1],
+       'expireAfterSeconds' => 1000
+   ]);
+
+   var_dump($result);
+
+The output would then resemble::
+
+   object(stdClass)#2779 {
+     ["expireAfterSeconds_old"]=>
+     int(3)
+     ["expireAfterSeconds_new"]=>
+     int(1000)
+     ["ok"]=>
+     float(1)
+   }
+
+See Also
+--------
+
+- :manual:`collMod </reference/command/collMod>` command reference in the MongoDB
+  manual
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBDatabase-selectCollection.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBDatabase-selectCollection.txt
new file mode 100644
index 0000000000000000000000000000000000000000..6294e1a75c63abe1c5a10a5aec47118cbb185f32
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBDatabase-selectCollection.txt	
@@ -0,0 +1,83 @@
+=====================================
+MongoDB\\Database::selectCollection()
+=====================================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\Database::selectCollection()
+
+   Selects a collection within the database.
+
+   .. code-block:: php
+
+      function selectCollection($collectionName, array $options = []): MongoDB\Collection
+
+   This method has the following parameters:
+
+   .. include:: /includes/apiargs/MongoDBDatabase-method-selectCollection-param.rst
+
+   The ``$options`` parameter supports the following options:
+
+   .. include:: /includes/apiargs/MongoDBDatabase-method-selectCollection-option.rst
+
+Return Values
+-------------
+
+A :phpclass:`MongoDB\\Collection` object.
+
+Errors/Exceptions
+-----------------
+
+.. include:: /includes/extracts/error-invalidargumentexception.rst
+
+Behavior
+--------
+
+The selected collection inherits options such as read preference and type
+mapping from the :phpclass:`Database <MongoDB\\Database>` object. Options may be
+overridden via the ``$options`` parameter.
+
+Example
+-------
+
+The following example selects the ``users`` collection in the ``test`` database:
+
+.. code-block:: php
+
+   <?php
+
+   $db = (new MongoDB\Client)->test;
+
+   $collection = $db->selectCollection('users');
+
+The following example selects the ``users`` collection in the ``test``
+database with a custom read preference:
+
+.. code-block:: php
+
+   <?php
+
+   $db = (new MongoDB\Client)->test;
+
+   $users = $db->selectCollection(
+       'users',
+       [
+           'readPreference' => new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_SECONDARY),
+       ]
+   );
+
+See Also
+--------
+
+- :phpmethod:`MongoDB\\Database::__get()`
+- :phpmethod:`MongoDB\\Client::selectCollection()`
+- :phpmethod:`MongoDB\\Collection::__construct()`
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBDatabase-selectGridFSBucket.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBDatabase-selectGridFSBucket.txt
new file mode 100644
index 0000000000000000000000000000000000000000..9c63fdf7c3f6fe984ae3fb8a6cf24a080af65a96
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBDatabase-selectGridFSBucket.txt	
@@ -0,0 +1,80 @@
+=======================================
+MongoDB\\Database::selectGridFSBucket()
+=======================================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\Database::selectGridFSBucket()
+
+   Selects a GridFS bucket within the database.
+
+   .. code-block:: php
+
+      function selectGridFSBucket(array $options = []): MongoDB\GridFS\Bucket
+
+   This method has the following parameters:
+
+   .. include:: /includes/apiargs/MongoDBDatabase-method-selectGridFSBucket-param.rst
+
+   The ``$options`` parameter supports the following options:
+
+   .. include:: /includes/apiargs/MongoDBDatabase-method-selectGridFSBucket-option.rst
+
+Return Values
+-------------
+
+A :phpclass:`MongoDB\\GridFS\\Bucket` object.
+
+Errors/Exceptions
+-----------------
+
+.. include:: /includes/extracts/error-invalidargumentexception.rst
+
+Behavior
+--------
+
+The selected bucket inherits options such as read preference and type
+mapping from the :phpclass:`Database <MongoDB\\Database>` object. Options may be
+overridden via the ``$options`` parameter.
+
+Example
+-------
+
+The following example selects the default ``fs.files`` bucket in the ``test``
+database:
+
+.. code-block:: php
+
+   <?php
+
+   $db = (new MongoDB\Client)->test;
+
+   $bucket = $db->selectGridFSBucket();
+
+The following example selects the custom ``images.files`` bucket in the ``test``
+database with a custom read preference:
+
+.. code-block:: php
+
+   <?php
+
+   $db = (new MongoDB\Client)->test;
+
+   $imagesBucket = $db->selectGridFSBucket([
+       'bucketName' => 'images',
+       'readPreference' => new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_SECONDARY),
+   ]);
+
+See Also
+--------
+
+- :phpmethod:`MongoDB\\GridFS\\Bucket::__construct()`
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBDatabase-watch.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBDatabase-watch.txt
new file mode 100644
index 0000000000000000000000000000000000000000..7ff19b73af3de957bc803e7ea4674b3caa7892d4
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBDatabase-watch.txt	
@@ -0,0 +1,122 @@
+==========================
+MongoDB\\Database::watch()
+==========================
+
+.. versionadded:: 1.4
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\Database::watch()
+
+   Executes a :manual:`change stream </changeStreams>` operation on the
+   database. The change stream can be watched for database-level changes.
+
+   .. code-block:: php
+
+      function watch(array $pipeline = [], array $options = []): MongoDB\ChangeStream
+
+   This method has the following parameters:
+
+   .. include:: /includes/apiargs/MongoDBDatabase-method-watch-param.rst
+
+   The ``$options`` parameter supports the following options:
+
+   .. include:: /includes/apiargs/MongoDBDatabase-method-watch-option.rst
+
+Return Values
+-------------
+
+A :phpclass:`MongoDB\\ChangeStream` object, which allows for iteration of
+events in the change stream via the :php:`Iterator <class.iterator>` interface.
+
+Errors/Exceptions
+-----------------
+
+.. include:: /includes/extracts/error-unexpectedvalueexception.rst
+.. include:: /includes/extracts/error-unsupportedexception.rst
+.. include:: /includes/extracts/error-invalidargumentexception.rst
+.. include:: /includes/extracts/error-driver-runtimeexception.rst
+
+Examples
+--------
+
+This example reports events while iterating a change stream.
+
+.. code-block:: php
+
+   <?php
+
+   $uri = 'mongodb://rs1.example.com,rs2.example.com/?replicaSet=myReplicaSet';
+
+   $database = (new MongoDB\Client($uri))->test;
+
+   $changeStream = $database->watch();
+
+   for ($changeStream->rewind(); true; $changeStream->next()) {
+       if ( ! $changeStream->valid()) {
+           continue;
+       }
+
+       $event = $changeStream->current();
+
+       if ($event['operationType'] === 'invalidate') {
+           break;
+       }
+
+       $ns = sprintf('%s.%s', $event['ns']['db'], $event['ns']['coll']);
+       $id = json_encode($event['documentKey']['_id']);
+
+       switch ($event['operationType']) {
+           case 'delete':
+               printf("Deleted document in %s with _id: %s\n\n", $ns, $id);
+               break;
+
+           case 'insert':
+               printf("Inserted new document in %s\n", $ns);
+               echo json_encode($event['fullDocument']), "\n\n";
+               break;
+
+           case 'replace':
+               printf("Replaced new document in %s with _id: %s\n", $ns, $id);
+               echo json_encode($event['fullDocument']), "\n\n";
+               break;
+
+           case 'update':
+               printf("Updated document in %s with _id: %s\n", $ns, $id);
+               echo json_encode($event['updateDescription']), "\n\n";
+               break;
+       }
+   }
+
+Assuming that a document was inserted, updated, and deleted while the above
+script was iterating the change stream, the output would then resemble:
+
+.. code-block:: none
+
+   Inserted new document in test.inventory
+   {"_id":{"$oid":"5a81fc0d6118fd1af1790d32"},"name":"Widget","quantity":5}
+
+   Updated document in test.inventory with _id: {"$oid":"5a81fc0d6118fd1af1790d32"}
+   {"updatedFields":{"quantity":4},"removedFields":[]}
+
+   Deleted document in test.inventory with _id: {"$oid":"5a81fc0d6118fd1af1790d32"}
+
+See Also
+--------
+
+- :phpmethod:`MongoDB\\Collection::watch()`
+- :phpmethod:`MongoDB\\Client::watch()`
+- :manual:`Aggregation Pipeline </core/aggregation-pipeline>` documentation in
+  the MongoDB Manual
+- :manual:`Change Streams </changeStreams>` documentation in the MongoDB manual
+- :manual:`Change Events </reference/change-events/>` documentation in the
+  MongoDB manual
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBDatabase-withOptions.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBDatabase-withOptions.txt
new file mode 100644
index 0000000000000000000000000000000000000000..9bc0a82eac366516ef32d5b5f84c6c95b091efa5
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBDatabase-withOptions.txt	
@@ -0,0 +1,61 @@
+================================
+MongoDB\\Database::withOptions()
+================================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\Database::withOptions()
+
+   Returns a clone of the Database object, but with different options.
+
+   .. code-block:: php
+
+      function withOptions(array $options = []): MongoDB\Database
+
+   This method has the following parameters:
+
+   .. include:: /includes/apiargs/MongoDBDatabase-method-withOptions-param.rst
+
+   The ``$options`` parameter supports the following options:
+
+   .. include:: /includes/apiargs/MongoDBDatabase-method-withOptions-option.rst
+
+Return Values
+-------------
+
+A :phpclass:`MongoDB\\Database` object.
+
+Errors/Exceptions
+-----------------
+
+.. include:: /includes/extracts/error-invalidargumentexception.rst
+
+Example
+-------
+
+The following example clones an existing Database object with a new read
+preference:
+
+.. code-block:: php
+
+   <?php
+
+   $db = (new MongoDB\Client)->test;
+
+   $newDb = $db->withOptions([
+       'readPreference' => new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_SECONDARY),
+   ]);
+
+See Also
+--------
+
+- :phpmethod:`MongoDB\\Database::__construct()`
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBDatabase__construct.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBDatabase__construct.txt
new file mode 100644
index 0000000000000000000000000000000000000000..2d3e7f57b9aefbd15f83acb373f64190a0f43a3a
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBDatabase__construct.txt	
@@ -0,0 +1,50 @@
+================================
+MongoDB\\Database::__construct()
+================================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\Database::__construct()
+
+   Constructs a new :phpclass:`Database <MongoDB\\Database>` instance.
+
+   .. code-block:: php
+
+      function __construct(MongoDB\Driver\Manager $manager, $databaseName, array $options = [])
+
+   This constructor has the following parameters:
+
+   .. include:: /includes/apiargs/MongoDBDatabase-method-construct-param.rst
+
+   The ``$options`` parameter supports the following options:
+
+   .. include:: /includes/apiargs/MongoDBDatabase-method-construct-option.rst
+
+Errors/Exceptions
+-----------------
+
+.. include:: /includes/extracts/error-invalidargumentexception.rst
+
+Behavior
+--------
+
+If you construct a Database explicitly, the Database inherits any options from
+the :php:`MongoDB\\Driver\\Manager <class.mongodb-driver-manager>` object. If
+you select the Database from a :phpclass:`Client <MongoDB\\Client>` object, the
+Database inherits its options from that object.
+
+See Also
+--------
+
+- :phpmethod:`MongoDB\\Database::withOptions()`
+- :phpmethod:`MongoDB\\Client::selectDatabase()`
+- :phpmethod:`MongoDB\\Client::__get()`
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBDatabase__get.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBDatabase__get.txt
new file mode 100644
index 0000000000000000000000000000000000000000..c41e3981d709e14479dcfe752219a107e67a9e1f
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBDatabase__get.txt	
@@ -0,0 +1,69 @@
+==========================
+MongoDB\\Database::__get()
+==========================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\Database::__get()
+
+   Select a collection within the database.
+
+   .. code-block:: php
+
+      function __get($collectionName): MongoDB\Collection
+
+   This method has the following parameters:
+
+   .. include:: /includes/apiargs/MongoDBDatabase-method-get-param.rst
+
+Return Values
+-------------
+
+A :phpclass:`MongoDB\\Collection` object.
+
+Behavior
+--------
+
+The selected collection inherits options such as read preference and type
+mapping from the :phpclass:`Database <MongoDB\\Database>` object. If you wish to
+override any options, use the :phpmethod:`MongoDB\\Database::selectCollection`
+method.
+
+.. note::
+
+   To select collections whose names contain special characters, such as
+   ``.``, use complex syntax, as in ``$database->{'that.database'}``.
+
+   Alternatively, :phpmethod:`MongoDB\\Database::selectCollection` supports
+   selecting collections whose names contain special characters.
+
+Examples
+--------
+
+The following example selects the ``users`` and ``system.profile``
+collections from the ``test`` database:
+
+.. code-block:: php
+
+   <?php
+
+   $db = (new MongoDB\Client)->test;
+
+   $users = $db->users;
+   $systemProfile = $db->{'system.profile'};
+
+See Also
+--------
+
+- :phpmethod:`MongoDB\\Database::selectCollection()`
+- :phpmethod:`MongoDB\\Client::selectCollection()`
+- :php:`Property Overloading <oop5.overloading>` in the PHP Manual
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBDeleteResult-getDeletedCount.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBDeleteResult-getDeletedCount.txt
new file mode 100644
index 0000000000000000000000000000000000000000..dcda25741e5caaa18fac60c03d80c6e71e228bea
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBDeleteResult-getDeletedCount.txt	
@@ -0,0 +1,40 @@
+========================================
+MongoDB\\DeleteResult::getDeletedCount()
+========================================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\DeleteResult::getDeletedCount()
+
+   Return the number of documents that were deleted.
+
+   .. code-block:: php
+
+      function getDeletedCount(): integer
+
+   This method should only be called if the write was acknowledged.
+
+Return Values
+-------------
+
+The number of documents that were deleted.
+
+Errors/Exceptions
+-----------------
+
+.. include:: /includes/extracts/error-badmethodcallexception-write-result.rst
+
+See Also
+--------
+
+- :php:`MongoDB\\Driver\\WriteResult::getDeletedCount()
+  <manual/en/mongodb-driver-writeresult.getdeletedcount.php>`
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBDeleteResult-isAcknowledged.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBDeleteResult-isAcknowledged.txt
new file mode 100644
index 0000000000000000000000000000000000000000..a82fa523880d8ef9697b3db38cc891fc07ffcfee
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBDeleteResult-isAcknowledged.txt	
@@ -0,0 +1,34 @@
+=======================================
+MongoDB\\DeleteResult::isAcknowledged()
+=======================================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\DeleteResult::isAcknowledged()
+
+   Return whether the write was acknowledged.
+
+   .. code-block:: php
+
+      function isAcknowledged(): boolean
+
+Return Values
+-------------
+
+A boolean indicating whether the write was acknowledged.
+
+See Also
+--------
+
+- :php:`MongoDB\\Driver\\WriteResult::isAcknowledged()
+  <manual/en/mongodb-driver-writeresult.isacknowledged.php>`
+- :manual:`Write Concern </reference/write-concern>` in the MongoDB manual
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBGridFSBucket-delete.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBGridFSBucket-delete.txt
new file mode 100644
index 0000000000000000000000000000000000000000..b063337e7769e0925cdf150497969ec29ba0b161
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBGridFSBucket-delete.txt	
@@ -0,0 +1,55 @@
+=================================
+MongoDB\\GridFS\\Bucket::delete()
+=================================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\GridFS\\Bucket::delete()
+
+   Delete a file and its chunks from the GridFS bucket.
+
+   .. code-block:: php
+
+      function delete($id): void
+
+   This method has the following parameters:
+
+   .. include:: /includes/apiargs/MongoDBGridFSBucket-method-delete-param.rst
+
+Errors/Exceptions
+-----------------
+
+.. include:: /includes/extracts/error-gridfs-filenotfoundexception.rst
+.. include:: /includes/extracts/error-driver-runtimeexception.rst
+
+Behavior
+--------
+
+If the files collection document is not found, this method will still attempt to
+delete orphaned chunks.
+
+Examples
+--------
+
+.. code-block:: php
+
+   <?php
+
+   $bucket = (new MongoDB\Client)->test->selectGridFSBucket();
+
+   $stream = fopen('php://temp', 'w+b');
+   fwrite($stream, "foobar");
+   rewind($stream);
+
+   $id = $bucket->uploadFromStream('filename', $stream);
+
+   $bucket->delete($id);
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBGridFSBucket-downloadToStream.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBGridFSBucket-downloadToStream.txt
new file mode 100644
index 0000000000000000000000000000000000000000..3d8e6ebcfdbf41177e798772c353f88bee99f814
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBGridFSBucket-downloadToStream.txt	
@@ -0,0 +1,66 @@
+===========================================
+MongoDB\\GridFS\\Bucket::downloadToStream()
+===========================================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\GridFS\\Bucket::downloadToStream()
+
+   Selects a GridFS file by its ``_id`` and copies its contents to a writable
+   stream.
+
+   .. code-block:: php
+
+      function downloadToStream($id, $destination): void
+
+   This method has the following parameters:
+
+   .. include:: /includes/apiargs/MongoDBGridFSBucket-method-downloadToStream-param.rst
+
+Errors/Exceptions
+-----------------
+
+.. include:: /includes/extracts/error-gridfs-filenotfoundexception.rst
+.. include:: /includes/extracts/error-invalidargumentexception.rst
+.. include:: /includes/extracts/error-driver-runtimeexception.rst
+
+Examples
+--------
+
+.. code-block:: php
+
+   <?php
+
+   $bucket = (new MongoDB\Client)->test->selectGridFSBucket();
+
+   $stream = fopen('php://temp', 'w+b');
+   fwrite($stream, "foobar");
+   rewind($stream);
+
+   $id = $bucket->uploadFromStream('filename', $stream);
+
+   $destination = fopen('php://temp', 'w+b');
+
+   $bucket->downloadToStream($id, $destination);
+
+   var_dump(stream_get_contents($destination, -1, 0));
+
+The output would then resemble::
+
+   string(6) "foobar"
+
+See Also
+--------
+
+- :phpmethod:`MongoDB\\GridFS\\Bucket::downloadToStreamByName()`
+- :phpmethod:`MongoDB\\GridFS\\Bucket::openDownloadStream()`
+- :phpmethod:`MongoDB\\GridFS\\Bucket::openDownloadStreamByName()`
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBGridFSBucket-downloadToStreamByName.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBGridFSBucket-downloadToStreamByName.txt
new file mode 100644
index 0000000000000000000000000000000000000000..002bdc654db31d2f6a4a8b1570ff44bdc382c665
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBGridFSBucket-downloadToStreamByName.txt	
@@ -0,0 +1,70 @@
+=================================================
+MongoDB\\GridFS\\Bucket::downloadToStreamByName()
+=================================================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\GridFS\\Bucket::downloadToStreamByName()
+
+   Selects a GridFS file by its ``filename`` and copies its contents to a
+   writable stream.
+
+   .. code-block:: php
+
+      function downloadToStreamByName($filename, $destination, array $options = []): void
+
+   This method has the following parameters:
+
+   .. include:: /includes/apiargs/MongoDBGridFSBucket-method-downloadToStreamByName-param.rst
+
+   The ``$options`` parameter supports the following options:
+
+   .. include:: /includes/apiargs/MongoDBGridFSBucket-method-downloadToStreamByName-option.rst
+
+Errors/Exceptions
+-----------------
+
+.. include:: /includes/extracts/error-gridfs-filenotfoundexception.rst
+.. include:: /includes/extracts/error-invalidargumentexception.rst
+.. include:: /includes/extracts/error-driver-runtimeexception.rst
+
+Examples
+--------
+
+.. code-block:: php
+
+   <?php
+
+   $bucket = (new MongoDB\Client)->test->selectGridFSBucket();
+
+   $stream = fopen('php://temp', 'w+b');
+   fwrite($stream, "foobar");
+   rewind($stream);
+
+   $bucket->uploadFromStream('filename', $stream);
+
+   $destination = fopen('php://temp', 'w+b');
+
+   $bucket->downloadToStreamByName('filename', $destination);
+
+   var_dump(stream_get_contents($destination, -1, 0));
+
+The output would then resemble::
+
+   string(6) "foobar"
+
+See Also
+--------
+
+- :phpmethod:`MongoDB\\GridFS\\Bucket::downloadToStream()`
+- :phpmethod:`MongoDB\\GridFS\\Bucket::openDownloadStream()`
+- :phpmethod:`MongoDB\\GridFS\\Bucket::openDownloadStreamByName()`
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBGridFSBucket-drop.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBGridFSBucket-drop.txt
new file mode 100644
index 0000000000000000000000000000000000000000..53a10091ad82f483ba3e533460a3d717b6231bc7
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBGridFSBucket-drop.txt	
@@ -0,0 +1,46 @@
+===============================
+MongoDB\\GridFS\\Bucket::drop()
+===============================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\GridFS\\Bucket::drop()
+
+   Drops the files and chunks collections associated with this GridFS bucket.
+
+   .. code-block:: php
+
+      function drop(): void
+
+Errors/Exceptions
+-----------------
+
+.. include:: /includes/extracts/error-driver-runtimeexception.rst
+
+Examples
+--------
+
+.. code-block:: php
+
+   <?php
+
+   $database = (new MongoDB\Client)->test;
+
+   $bucket = $database->selectGridFSBucket();
+
+   $stream = fopen('php://temp', 'w+b');
+   fwrite($stream, "foobar");
+   rewind($stream);
+
+   $bucket->uploadFromStream('filename', $stream);
+
+   $bucket->drop();
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBGridFSBucket-find.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBGridFSBucket-find.txt
new file mode 100644
index 0000000000000000000000000000000000000000..c7418cede12dc8e1ad91dbaa2aa0e8ce7dbf3823
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBGridFSBucket-find.txt	
@@ -0,0 +1,97 @@
+===============================
+MongoDB\\GridFS\\Bucket::find()
+===============================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\GridFS\\Bucket::find()
+
+   Finds documents from the GridFS bucket's files collection matching the query.
+
+   .. code-block:: php
+
+      function find($filter = [], array $options = []): MongoDB\Driver\Cursor
+
+   This method has the following parameters:
+
+   .. include:: /includes/apiargs/MongoDBCollection-method-find-param.rst
+
+   The ``$options`` parameter supports the following options:
+
+   .. include:: /includes/apiargs/MongoDBGridFSBucket-method-find-option.rst
+
+Return Values
+-------------
+
+A :php:`MongoDB\\Driver\\Cursor <class.mongodb-driver-cursor>` object.
+
+Errors/Exceptions
+-----------------
+
+.. include:: /includes/extracts/error-unsupportedexception.rst
+.. include:: /includes/extracts/error-invalidargumentexception.rst
+.. include:: /includes/extracts/error-driver-runtimeexception.rst
+
+Behavior
+--------
+
+.. include:: /includes/extracts/note-bson-comparison.rst
+
+Examples
+--------
+
+.. code-block:: php
+
+   <?php
+
+   $bucket = (new MongoDB\Client)->test->selectGridFSBucket();
+
+   $stream = fopen('php://temp', 'w+b');
+   fwrite($stream, "foobar");
+   rewind($stream);
+
+   $bucket->uploadFromStream('b', $stream);
+
+   $cursor = $bucket->find(
+       ['length' => ['$lte' => 6]],
+       [
+           'projection' => [
+               'filename' => 1,
+               'length' => 1,
+               '_id' => 0,
+            ],
+            'sort' => ['length' => -1],
+        ]
+   );
+
+   var_dump($cursor->toArray());
+
+The output would then resemble::
+
+   array(1) {
+     [0]=>
+     object(MongoDB\Model\BSONDocument)#3015 (1) {
+       ["storage":"ArrayObject":private]=>
+       array(2) {
+         ["filename"]=>
+         string(1) "b"
+         ["length"]=>
+         int(6)
+       }
+     }
+   }
+
+See Also
+--------
+
+- :phpmethod:`MongoDB\\Collection::find()`
+- :phpmethod:`MongoDB\\GridFS\\Bucket::findOne()`
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBGridFSBucket-findOne.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBGridFSBucket-findOne.txt
new file mode 100644
index 0000000000000000000000000000000000000000..7b6fcc8fcb5075725d065e7484d3a8147440a386
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBGridFSBucket-findOne.txt	
@@ -0,0 +1,97 @@
+==================================
+MongoDB\\GridFS\\Bucket::findOne()
+==================================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\GridFS\\Bucket::findOne()
+
+   Finds a single document from the GridFS bucket's files collection matching
+   the query.
+
+   .. code-block:: php
+
+      function findOne($filter = [], array $options = []): array|object|null
+
+   This method has the following parameters:
+
+   .. include:: /includes/apiargs/MongoDBCollection-method-findOne-param.rst
+
+   The ``$options`` parameter supports the following options:
+
+   .. include:: /includes/apiargs/MongoDBGridFSBucket-method-findOne-option.rst
+
+Return Values
+-------------
+
+An array or object for the :term:`first document <natural order>` that matched
+the query, or ``null`` if no document matched the query. The return type will
+depend on the ``typeMap`` option.
+
+Errors/Exceptions
+-----------------
+
+.. include:: /includes/extracts/error-unsupportedexception.rst
+.. include:: /includes/extracts/error-invalidargumentexception.rst
+.. include:: /includes/extracts/error-driver-runtimeexception.rst
+
+Behavior
+--------
+
+.. include:: /includes/extracts/note-bson-comparison.rst
+
+Examples
+--------
+
+.. code-block:: php
+
+   <?php
+
+   $bucket = (new MongoDB\Client)->test->selectGridFSBucket();
+
+   $stream = fopen('php://temp', 'w+b');
+   fwrite($stream, "foobar");
+   rewind($stream);
+
+   $bucket->uploadFromStream('b', $stream);
+
+   $fileDocument = $bucket->findOne(
+       ['length' => ['$lte' => 6]],
+       [
+           'projection' => [
+               'filename' => 1,
+               'length' => 1,
+               '_id' => 0,
+           ],
+           'sort' => ['length' => -1],
+       ]
+   );
+
+   var_dump($fileDocument);
+
+The output would then resemble::
+
+   object(MongoDB\Model\BSONDocument)#3004 (1) {
+     ["storage":"ArrayObject":private]=>
+     array(2) {
+       ["filename"]=>
+       string(1) "b"
+       ["length"]=>
+       int(6)
+     }
+   }
+
+See Also
+--------
+
+- :phpmethod:`MongoDB\\Collection::findOne()`
+- :phpmethod:`MongoDB\\GridFS\\Bucket::find()`
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBGridFSBucket-getBucketName.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBGridFSBucket-getBucketName.txt
new file mode 100644
index 0000000000000000000000000000000000000000..0452de0a732cbfed31b23aab10311097723668cb
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBGridFSBucket-getBucketName.txt	
@@ -0,0 +1,42 @@
+========================================
+MongoDB\\GridFS\\Bucket::getBucketName()
+========================================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\GridFS\\Bucket::getBucketName()
+
+   Returns the name of this bucket.
+
+   .. code-block:: php
+
+      function getBucketName(): string
+
+Return Values
+-------------
+
+The name of this bucket as a string.
+
+Examples
+--------
+
+.. code-block:: php
+
+   <?php
+
+   $bucket = (new MongoDB\Client)->test->selectGridFSBucket();
+
+   var_dump($bucket->getBucketName());
+
+The output would then resemble::
+
+   string(2) "fs"
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBGridFSBucket-getChunkSizeBytes.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBGridFSBucket-getChunkSizeBytes.txt
new file mode 100644
index 0000000000000000000000000000000000000000..f592030a22c655848009eb2c4bd687ec5a679d69
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBGridFSBucket-getChunkSizeBytes.txt	
@@ -0,0 +1,44 @@
+============================================
+MongoDB\\GridFS\\Bucket::getChunkSizeBytes()
+============================================
+
+.. versionchanged:: 1.2
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\GridFS\\Bucket::getChunkSizeBytes()
+
+   Returns the chunk size of this bucket in bytes.
+
+   .. code-block:: php
+
+      function getChunkSizeBytes(): integer
+
+Return Values
+-------------
+
+The chunk size of this bucket in bytes.
+
+Examples
+--------
+
+.. code-block:: php
+
+   <?php
+
+   $bucket = (new MongoDB\Client)->test->selectGridFSBucket();
+
+   var_dump($bucket->getChunkSizeBytes());
+
+The output would then resemble::
+
+   int(261120)
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBGridFSBucket-getChunksCollection.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBGridFSBucket-getChunksCollection.txt
new file mode 100644
index 0000000000000000000000000000000000000000..fa5be832257ff1472ea5f35399c717e79f8e4da9
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBGridFSBucket-getChunksCollection.txt	
@@ -0,0 +1,44 @@
+==============================================
+MongoDB\\GridFS\\Bucket::getChunksCollection()
+==============================================
+
+.. versionadded:: 1.2
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\GridFS\\Bucket::getChunksCollection()
+
+   Returns the chunks collection used by the bucket.
+
+   .. code-block:: php
+
+      function getChunksCollection(): MongoDB\Collection
+
+Return Values
+-------------
+
+A :phpclass:`MongoDB\\Collection` object for the chunks collection.
+
+Examples
+--------
+
+.. code-block:: php
+
+   <?php
+
+   $bucket = (new MongoDB\Client)->test->selectGridFSBucket();
+
+   var_dump((string) $bucket->getChunksCollection());
+
+The output would then resemble::
+
+   string(14) "test.fs.chunks"
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBGridFSBucket-getDatabaseName.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBGridFSBucket-getDatabaseName.txt
new file mode 100644
index 0000000000000000000000000000000000000000..b270b7b57b0250aaa93174e90aa86e4505e6318d
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBGridFSBucket-getDatabaseName.txt	
@@ -0,0 +1,43 @@
+==========================================
+MongoDB\\GridFS\\Bucket::getDatabaseName()
+==========================================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\GridFS\\Bucket::getDatabaseName()
+
+   Returns the name of the database containing this bucket.
+
+   .. code-block:: php
+
+      function getDatabaseName(): string
+
+Return Values
+-------------
+
+The name of the database containing this bucket as a string.
+
+Examples
+--------
+
+.. code-block:: php
+
+   <?php
+
+   $bucket = (new MongoDB\Client)->test->selectGridFSBucket();
+
+   var_dump($bucket->getDatabaseName());
+
+The output would then resemble::
+
+   string(4) "test"
+
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBGridFSBucket-getFileDocumentForStream.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBGridFSBucket-getFileDocumentForStream.txt
new file mode 100644
index 0000000000000000000000000000000000000000..052bc79c9a80f4568e8e5937eb94bbe4aba5f7df
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBGridFSBucket-getFileDocumentForStream.txt	
@@ -0,0 +1,77 @@
+===================================================
+MongoDB\\GridFS\\Bucket::getFileDocumentForStream()
+===================================================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\GridFS\\Bucket::getFileDocumentForStream()
+
+   Gets the file document of the GridFS file associated with a stream.
+
+   .. code-block:: php
+
+      function getFileDocumentForStream($stream): array|object
+
+   This method has the following parameters:
+
+   .. include:: /includes/apiargs/MongoDBGridFSBucket-method-getFileDocumentForStream-param.rst
+
+Return Values
+-------------
+
+The metadata document associated with the GridFS stream. The return type will
+depend on the bucket's ``typeMap`` option.
+
+Errors/Exceptions
+-----------------
+
+.. include:: /includes/extracts/error-invalidargumentexception.rst
+.. include:: /includes/extracts/error-driver-runtimeexception.rst
+
+Examples
+--------
+
+.. code-block:: php
+
+   <?php
+
+   $bucket = (new MongoDB\Client)->test->selectGridFSBucket();
+
+   $stream = $bucket->openUploadStream('filename');
+
+   $fileDocument = $bucket->getFileDocumentForStream($stream);
+
+   var_dump($fileDocument);
+
+   fclose($stream);
+
+The output would then resemble::
+
+   object(MongoDB\Model\BSONDocument)#4956 (1) {
+     ["storage":"ArrayObject":private]=>
+     array(3) {
+       ["_id"]=>
+       object(MongoDB\BSON\ObjectId)#4955 (1) {
+         ["oid"]=>
+         string(24) "5acfb05b7e21e83b5a29037c"
+       }
+       ["chunkSize"]=>
+       int(261120)
+       ["filename"]=>
+       string(8) "filename"
+     }
+   }
+
+See Also
+--------
+
+- :phpmethod:`MongoDB\\GridFS\\Bucket::getFileIdForStream()`
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBGridFSBucket-getFileIdForStream.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBGridFSBucket-getFileIdForStream.txt
new file mode 100644
index 0000000000000000000000000000000000000000..976843b4de325836cb90a9b91fdc84583e5e356b
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBGridFSBucket-getFileIdForStream.txt	
@@ -0,0 +1,68 @@
+=============================================
+MongoDB\\GridFS\\Bucket::getFileIdForStream()
+=============================================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\GridFS\\Bucket::getFileIdForStream()
+
+   Gets the file document's ID of the GridFS file associated with a stream.
+
+   .. code-block:: php
+
+      function getFileIdForStream($stream): mixed
+
+   This method has the following parameters:
+
+   .. include:: /includes/apiargs/MongoDBGridFSBucket-method-getFileIdForStream-param.rst
+
+Return Values
+-------------
+
+The ``_id`` field of the metadata document associated with the GridFS stream.
+The return type will depend on the bucket's ``typeMap`` option.
+
+Errors/Exceptions
+-----------------
+
+.. include:: /includes/extracts/error-gridfs-corruptfileexception.rst
+.. include:: /includes/extracts/error-invalidargumentexception.rst
+.. include:: /includes/extracts/error-driver-runtimeexception.rst
+
+Examples
+--------
+
+.. code-block:: php
+
+   <?php
+
+   $bucket = (new MongoDB\Client)->test->selectGridFSBucket();
+
+   $stream = $bucket->openUploadStream('filename');
+
+   $id = $bucket->getFileIdForStream($stream);
+
+   var_dump($id);
+
+   fclose($stream);
+
+The output would then resemble::
+
+   object(MongoDB\BSON\ObjectId)#3005 (1) {
+     ["oid"]=>
+     string(24) "5acfb37d7e21e83cdb3e1583"
+   }
+
+See Also
+--------
+
+- :phpmethod:`MongoDB\\GridFS\\Bucket::getFileDocumentForStream()`
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBGridFSBucket-getFilesCollection.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBGridFSBucket-getFilesCollection.txt
new file mode 100644
index 0000000000000000000000000000000000000000..de4196b2f141359b7dc913adfc027fb7bbab91cd
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBGridFSBucket-getFilesCollection.txt	
@@ -0,0 +1,47 @@
+=============================================
+MongoDB\\GridFS\\Bucket::getFilesCollection()
+=============================================
+
+.. versionadded:: 1.2
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\GridFS\\Bucket::getFilesCollection()
+
+   Returns the files collection used by the bucket.
+
+   .. code-block:: php
+
+      function getFilesCollection(): MongoDB\Collection
+
+Return Values
+-------------
+
+A :phpclass:`MongoDB\\Collection` object for the files collection.
+
+Examples
+--------
+
+.. code-block:: php
+
+   <?php
+
+   $bucket = (new MongoDB\Client)->test->selectGridFSBucket();
+
+   $filesCollection = $bucket->getFilesCollection();
+
+   var_dump($filesCollection->getCollectionName());
+
+The output would then resemble::
+
+   string(8) "fs.files"
+
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBGridFSBucket-getReadConcern.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBGridFSBucket-getReadConcern.txt
new file mode 100644
index 0000000000000000000000000000000000000000..00517d22070e6cd0a3d73e938d1aa93f1c725a5f
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBGridFSBucket-getReadConcern.txt	
@@ -0,0 +1,59 @@
+=========================================
+MongoDB\\GridFS\\Bucket::getReadConcern()
+=========================================
+
+.. versionadded:: 1.2
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\GridFS\\Bucket::getReadConcern()
+
+   Returns the read concern for this GridFS bucket.
+
+   .. code-block:: php
+
+      function getReadConcern(): MongoDB\Driver\ReadConcern
+
+Return Values
+-------------
+
+A :php:`MongoDB\\Driver\\ReadConcern <class.mongodb-driver-readconcern>` object.
+
+Example
+-------
+
+.. code-block:: php
+
+   <?php
+
+   $database = (new MongoDB\Client)->selectDatabase('test');
+   $bucket = $database->selectGridFSBucket([
+      'readConcern' => new MongoDB\Driver\ReadConcern(MongoDB\Driver\ReadConcern::MAJORITY),
+   ]);
+
+   var_dump($bucket->getReadConcern());
+
+The output would then resemble::
+
+   object(MongoDB\Driver\ReadConcern)#3 (1) {
+     ["level"]=>
+     string(8) "majority"
+   }
+
+See Also
+--------
+
+- :manual:`Read Concern </reference/read-concern>` in the MongoDB manual
+- :php:`MongoDB\\Driver\\ReadConcern::isDefault() <mongodb-driver-readconcern.isdefault>`
+- :phpmethod:`MongoDB\\Client::getReadConcern()`
+- :phpmethod:`MongoDB\\Collection::getReadConcern()`
+- :phpmethod:`MongoDB\\Database::getReadConcern()`
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBGridFSBucket-getReadPreference.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBGridFSBucket-getReadPreference.txt
new file mode 100644
index 0000000000000000000000000000000000000000..94003eea70e842e6a3eab2cc85977a903e0f2725
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBGridFSBucket-getReadPreference.txt	
@@ -0,0 +1,59 @@
+============================================
+MongoDB\\GridFS\\Bucket::getReadPreference()
+============================================
+
+.. versionadded:: 1.2
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\GridFS\\Bucket::getReadPreference()
+
+   Returns the read preference for this GridFS bucket.
+
+   .. code-block:: php
+
+      function getReadPreference(): MongoDB\Driver\ReadPreference
+
+Return Values
+-------------
+
+A :php:`MongoDB\\Driver\\ReadPreference <class.mongodb-driver-readpreference>`
+object.
+
+Example
+-------
+
+.. code-block:: php
+
+   <?php
+
+   $database = (new MongoDB\Client)->selectDatabase('test');
+   $bucket = $database->selectGridFSBucket([
+      'readPreference' => new MongoDB\Driver\ReadPreference('primaryPreferred'),
+   ]);
+
+   var_dump($bucket->getReadPreference());
+
+The output would then resemble::
+
+   object(MongoDB\Driver\ReadPreference)#3 (1) {
+     ["mode"]=>
+     string(16) "primaryPreferred"
+   }
+
+See Also
+--------
+
+- :manual:`Read Preference </reference/read-preference>` in the MongoDB manual
+- :phpmethod:`MongoDB\\Client::getReadPreference()`
+- :phpmethod:`MongoDB\\Collection::getReadPreference()`
+- :phpmethod:`MongoDB\\Database::getReadPreference()`
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBGridFSBucket-getTypeMap.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBGridFSBucket-getTypeMap.txt
new file mode 100644
index 0000000000000000000000000000000000000000..cd9c4a1be35554822a4baf86e4feed17f6b91d46
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBGridFSBucket-getTypeMap.txt	
@@ -0,0 +1,66 @@
+=====================================
+MongoDB\\GridFS\\Bucket::getTypeMap()
+=====================================
+
+.. versionadded:: 1.2
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\GridFS\\Bucket::getTypeMap()
+
+   Returns the type map for this GridFS bucket.
+
+   .. code-block:: php
+
+      function getTypeMap(): array
+
+Return Values
+-------------
+
+A :ref:`type map <php-type-map>` array.
+
+Example
+-------
+
+.. code-block:: php
+
+   <?php
+
+   $database = (new MongoDB\Client)->selectDatabase('test');
+   $bucket = $database->selectGridFSBucket([
+       'typeMap' => [
+           'root' => 'array',
+           'document' => 'array',
+           'array' => 'array',
+       ],
+   ]);
+
+   var_dump($bucket->getTypeMap());
+
+The output would then resemble::
+
+   array(3) {
+     ["root"]=>
+     string(5) "array"
+     ["document"]=>
+     string(5) "array"
+     ["array"]=>
+     string(5) "array"
+   }
+
+See Also
+--------
+
+- :doc:`/reference/bson`
+- :phpmethod:`MongoDB\\Client::getTypeMap()`
+- :phpmethod:`MongoDB\\Collection::getTypeMap()`
+- :phpmethod:`MongoDB\\Database::getTypeMap()`
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBGridFSBucket-getWriteConcern.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBGridFSBucket-getWriteConcern.txt
new file mode 100644
index 0000000000000000000000000000000000000000..1b5577e6cc1993e42a67c0cd08ef54912c24fdeb
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBGridFSBucket-getWriteConcern.txt	
@@ -0,0 +1,62 @@
+=========================================
+MongoDB\\GridFS\Bucket::getWriteConcern()
+=========================================
+
+.. versionadded:: 1.2
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\GridFS\\Bucket::getWriteConcern()
+
+   Returns the write concern for this GridFS bucket.
+
+   .. code-block:: php
+
+      function getWriteConcern(): MongoDB\Driver\WriteConcern
+
+Return Values
+-------------
+
+A :php:`MongoDB\\Driver\\WriteConcern <class.mongodb-driver-writeconcern>`
+object.
+
+Example
+-------
+
+.. code-block:: php
+
+   <?php
+
+   $database = (new MongoDB\Client)->selectDatabase('test');
+   $bucket = $database->selectGridFSBucket([
+      'writeConcern' => new MongoDB\Driver\WriteConcern(1, 0, true),
+   ]);
+
+   var_dump($bucket->getWriteConcern());
+
+The output would then resemble::
+
+   object(MongoDB\Driver\WriteConcern)#3 (2) {
+     ["w"]=>
+     int(1)
+     ["j"]=>
+     bool(true)
+   }
+
+See Also
+--------
+
+- :manual:`Write Concern </reference/read-concern>` in the MongoDB manual
+- :php:`MongoDB\\Driver\\WriteConcern::isDefault() <mongodb-driver-writeconcern.isdefault>`
+- :phpmethod:`MongoDB\\Client::getWriteConcern()`
+- :phpmethod:`MongoDB\\Collection::getWriteConcern()`
+- :phpmethod:`MongoDB\\Database::getWriteConcern()`
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBGridFSBucket-openDownloadStream.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBGridFSBucket-openDownloadStream.txt
new file mode 100644
index 0000000000000000000000000000000000000000..663a69c9510347cbde47814777d6e46a87c78680
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBGridFSBucket-openDownloadStream.txt	
@@ -0,0 +1,67 @@
+=============================================
+MongoDB\\GridFS\\Bucket::openDownloadStream()
+=============================================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\GridFS\\Bucket::openDownloadStream()
+
+   Selects a GridFS file by its ``_id`` and opens it as a readable stream.
+
+   .. code-block:: php
+
+      function openDownloadStream($id): resource
+
+   This method has the following parameters:
+
+   .. include:: /includes/apiargs/MongoDBGridFSBucket-method-openDownloadStream-param.rst
+
+Return Values
+-------------
+
+A readable stream resource.
+
+Errors/Exceptions
+-----------------
+
+.. include:: /includes/extracts/error-gridfs-filenotfoundexception.rst
+.. include:: /includes/extracts/error-driver-runtimeexception.rst
+
+Examples
+--------
+
+.. code-block:: php
+
+   <?php
+
+   $bucket = (new MongoDB\Client)->test->selectGridFSBucket();
+
+   $uploadStream = fopen('php://temp', 'w+b');
+   fwrite($uploadStream, "foobar");
+   rewind($uploadStream);
+
+   $id = $bucket->uploadFromStream('filename', $uploadStream);
+
+   $downloadStream = $bucket->openDownloadStream($id);
+
+   var_dump(stream_get_contents($downloadStream));
+
+The output would then resemble::
+
+   string(6) "foobar"
+
+See Also
+--------
+
+- :phpmethod:`MongoDB\\GridFS\\Bucket::downloadToStream()`
+- :phpmethod:`MongoDB\\GridFS\\Bucket::downloadToStreamByName()`
+- :phpmethod:`MongoDB\\GridFS\\Bucket::openDownloadStreamByName()`
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBGridFSBucket-openDownloadStreamByName.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBGridFSBucket-openDownloadStreamByName.txt
new file mode 100644
index 0000000000000000000000000000000000000000..d9f7b5b441d5fa1ec49a48b28749caf026879242
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBGridFSBucket-openDownloadStreamByName.txt	
@@ -0,0 +1,69 @@
+===================================================
+MongoDB\\GridFS\\Bucket::openDownloadStreamByName()
+===================================================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\GridFS\\Bucket::openDownloadStreamByName()
+
+   Selects a GridFS file by its ``filename`` and opens it as a readable stream.
+
+   .. code-block:: php
+
+      function openDownloadStreamByName($filename, array $options = []): resource
+
+   This method has the following parameters:
+
+   .. include:: /includes/apiargs/MongoDBGridFSBucket-method-openDownloadStreamByName-param.rst
+
+   The ``$options`` parameter supports the following options:
+
+   .. include:: /includes/apiargs/MongoDBGridFSBucket-method-openDownloadStreamByName-option.rst
+
+Return Values
+-------------
+
+A readable stream resource.
+
+Errors/Exceptions
+-----------------
+
+.. include:: /includes/extracts/error-gridfs-filenotfoundexception.rst
+.. include:: /includes/extracts/error-driver-runtimeexception.rst
+
+Examples
+--------
+
+.. code-block:: php
+
+   <?php
+
+   $bucket = (new MongoDB\Client)->test->selectGridFSBucket();
+
+   $stream = fopen('php://temp', 'w+b');
+   fwrite($stream, "foobar");
+   rewind($stream);
+
+   $bucket->uploadFromStream('filename', $stream);
+
+   var_dump(stream_get_contents($bucket->openDownloadStreamByName('filename')));
+
+The output would then resemble::
+
+   string(6) "foobar"
+
+See Also
+--------
+
+- :phpmethod:`MongoDB\\GridFS\\Bucket::downloadToStream()`
+- :phpmethod:`MongoDB\\GridFS\\Bucket::downloadToStreamByName()`
+- :phpmethod:`MongoDB\\GridFS\\Bucket::openDownloadStream()`
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBGridFSBucket-openUploadStream.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBGridFSBucket-openUploadStream.txt
new file mode 100644
index 0000000000000000000000000000000000000000..806ad6b8bddf696a24ee5528c2f76c5d0a3308fc
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBGridFSBucket-openUploadStream.txt	
@@ -0,0 +1,66 @@
+===========================================
+MongoDB\\GridFS\\Bucket::openUploadStream()
+===========================================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\GridFS\\Bucket::openUploadStream()
+
+   Opens a writable stream for a new GridFS file.
+
+   .. code-block:: php
+
+      function openUploadStream($filename, array $options = []): resource
+
+   This method has the following parameters:
+
+   .. include:: /includes/apiargs/MongoDBGridFSBucket-method-openUploadStream-param.rst
+
+   The ``$options`` parameter supports the following options:
+
+   .. include:: /includes/apiargs/MongoDBGridFSBucket-method-openUploadStream-option.rst
+
+Return Values
+-------------
+
+A writable stream resource.
+
+Behavior
+--------
+
+Chunk documents will be created as data is written to the writable stream. The
+metadata document will be created when the writable stream is closed.
+
+Examples
+--------
+
+.. code-block:: php
+
+   <?php
+
+   $bucket = (new MongoDB\Client)->test->selectGridFSBucket();
+
+   $uploadStream = $bucket->openUploadStream('filename');
+   fwrite($uploadStream, 'foobar');
+   fclose($uploadStream);
+
+   $downloadStream = $bucket->openDownloadStreamByName('filename');
+   var_dump(stream_get_contents($downloadStream));
+
+The output would then resemble::
+
+   string(6) "foobar"
+
+See Also
+--------
+
+- :phpmethod:`MongoDB\\GridFS\\Bucket::uploadFromStream()`
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBGridFSBucket-rename.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBGridFSBucket-rename.txt
new file mode 100644
index 0000000000000000000000000000000000000000..346ffd81f9d3c43d8561cce0aee9ccf97e0cf91c
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBGridFSBucket-rename.txt	
@@ -0,0 +1,55 @@
+=================================
+MongoDB\\GridFS\\Bucket::rename()
+=================================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\GridFS\\Bucket::rename()
+
+   Selects a GridFS file by its ``_id`` and alters its ``filename``.
+
+   .. code-block:: php
+
+      function rename($id, $newFilename): void
+
+   This method has the following parameters:
+
+   .. include:: /includes/apiargs/MongoDBGridFSBucket-method-rename-param.rst
+
+Errors/Exceptions
+-----------------
+
+.. include:: /includes/extracts/error-gridfs-filenotfoundexception.rst
+.. include:: /includes/extracts/error-driver-runtimeexception.rst
+
+Examples
+--------
+
+.. code-block:: php
+
+   <?php
+
+   $bucket = (new MongoDB\Client)->test->selectGridFSBucket();
+
+   $stream = fopen('php://temp', 'w+b');
+   fwrite($stream, "foobar");
+   rewind($stream);
+
+   $id = $bucket->uploadFromStream('a', $stream);
+
+   $bucket->rename($id, 'b');
+
+   var_dump(stream_get_contents($bucket->openDownloadStreamByName('b')));
+
+The output would then resemble::
+
+   string(6) "foobar"
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBGridFSBucket-uploadFromStream.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBGridFSBucket-uploadFromStream.txt
new file mode 100644
index 0000000000000000000000000000000000000000..b5d5abefcd6a0a37dc65be6cd5c6b9457a2dcfe7
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBGridFSBucket-uploadFromStream.txt	
@@ -0,0 +1,73 @@
+===========================================
+MongoDB\\GridFS\\Bucket::uploadFromStream()
+===========================================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\GridFS\\Bucket::uploadFromStream()
+
+   Creates a new GridFS file and copies the contents of a readable stream to it.
+
+   .. code-block:: php
+
+      function uploadFromStream($filename, $source, array $options = []): mixed
+
+   This method has the following parameters:
+
+   .. include:: /includes/apiargs/MongoDBGridFSBucket-method-uploadFromStream-param.rst
+
+   The ``$options`` parameter supports the following options:
+
+   .. include:: /includes/apiargs/MongoDBGridFSBucket-method-uploadFromStream-option.rst
+
+Return Values
+-------------
+
+The ``_id`` field of the metadata document associated with the newly created
+GridFS file. If the ``_id`` option is not specified, a new
+:php:`MongoDB\\BSON\\ObjectId <class.mongodb-bson-objectid>` object will be used
+by default.
+
+Errors/Exceptions
+-----------------
+
+.. include:: /includes/extracts/error-invalidargumentexception.rst
+.. include:: /includes/extracts/error-driver-runtimeexception.rst
+
+Examples
+--------
+
+.. code-block:: php
+
+   <?php
+
+   $bucket = (new MongoDB\Client)->test->selectGridFSBucket();
+
+   $stream = fopen('php://temp', 'w+b');
+   fwrite($stream, "foobar");
+   rewind($stream);
+
+   $id = $bucket->uploadFromStream('filename', $stream);
+
+   var_dump($id);
+
+The output would then resemble::
+
+   object(MongoDB\BSON\ObjectId)#3009 (1) {
+     ["oid"]=>
+     string(24) "5acf81017e21e816e538d883"
+   }
+
+See Also
+--------
+
+- :phpmethod:`MongoDB\\GridFS\\Bucket::openUploadStream()`
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBGridFSBucket__construct.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBGridFSBucket__construct.txt
new file mode 100644
index 0000000000000000000000000000000000000000..49211fba720b8323d685fd54e84d71e1c900581a
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBGridFSBucket__construct.txt	
@@ -0,0 +1,68 @@
+======================================
+MongoDB\\GridFS\\Bucket::__construct()
+======================================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\GridFS\\Bucket::__construct()
+
+   Constructs a new :phpclass:`Bucket <MongoDB\\GridFS\\Bucket>` instance.
+
+   .. code-block:: php
+
+      function __construct(MongoDB\Driver\Manager $manager, $databaseName, array $options = [])
+
+   This constructor has the following parameters:
+
+   .. include:: /includes/apiargs/MongoDBGridFSBucket-method-construct-param.rst
+
+   The ``$options`` parameter supports the following options:
+
+   .. include:: /includes/apiargs/MongoDBGridFSBucket-method-construct-option.rst
+
+Errors/Exceptions
+-----------------
+
+.. include:: /includes/extracts/error-invalidargumentexception.rst
+
+Behavior
+--------
+
+If you construct a Bucket explicitly, the Bucket inherits any options
+from the :php:`MongoDB\\Driver\\Manager <class.mongodb-driver-manager>` object.
+If you select the Bucket from a :phpclass:`Database <MongoDB\\Database>` object,
+the Bucket inherits its options from that object.
+
+Examples
+--------
+
+.. code-block:: php
+
+   <?php
+
+   $bucket = (new MongoDB\Client)->test->selectGridFSBucket();
+
+   var_dump($bucket);
+
+The output would then resemble::
+
+   object(MongoDB\GridFS\Bucket)#3053 (2) {
+     ["bucketName"]=>
+     string(4) "test"
+     ["databaseName"]=>
+     string(11) "phplib_test"
+   }
+
+See Also
+--------
+
+- :phpmethod:`MongoDB\\Database::selectGridFSBucket()`
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBInsertManyResult-getInsertedCount.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBInsertManyResult-getInsertedCount.txt
new file mode 100644
index 0000000000000000000000000000000000000000..9297008bf886458f6dd98275834847d34087f9bc
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBInsertManyResult-getInsertedCount.txt	
@@ -0,0 +1,40 @@
+=============================================
+MongoDB\\InsertManyResult::getInsertedCount()
+=============================================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\InsertManyResult::getInsertedCount()
+
+   Return the number of documents that were inserted.
+
+   .. code-block:: php
+
+      function getInsertedCount(): integer
+
+   This method should only be called if the write was acknowledged.
+
+Return Values
+-------------
+
+The number of documents that were inserted.
+
+Errors/Exceptions
+-----------------
+
+.. include:: /includes/extracts/error-badmethodcallexception-write-result.rst
+
+See Also
+--------
+
+- :php:`MongoDB\\Driver\\WriteResult::getInsertedCount()
+  <manual/en/mongodb-driver-writeresult.getinsertedcount.php>`
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBInsertManyResult-getInsertedIds.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBInsertManyResult-getInsertedIds.txt
new file mode 100644
index 0000000000000000000000000000000000000000..75c6387032c918604c677f30da6df2d2270d129d
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBInsertManyResult-getInsertedIds.txt	
@@ -0,0 +1,36 @@
+===========================================
+MongoDB\\InsertManyResult::getInsertedIds()
+===========================================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\InsertManyResult::getInsertedIds()
+
+   Return a map of IDs (i.e. ``_id`` field values) for the inserted documents.
+
+   .. code-block:: php
+
+      function getInsertedIds(): array
+
+   Since IDs are created by the driver, this method may be called irrespective
+   of whether the write was acknowledged.
+
+Return Values
+-------------
+
+A map of IDs (i.e. ``_id`` field values) for the inserted documents.
+
+The index of each ID in the map corresponds to each document's position in the
+bulk operation. If a document had an ID prior to inserting (i.e. the driver did
+not generate an ID), the index will contain its ``_id`` field value. Any
+driver-generated ID will be a :php:`MongoDB\\BSON\\ObjectId
+<class.mongodb-bson-objectid>` instance.
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBInsertManyResult-isAcknowledged.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBInsertManyResult-isAcknowledged.txt
new file mode 100644
index 0000000000000000000000000000000000000000..db376e5facb752b86fad2b66dad80629645be9b1
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBInsertManyResult-isAcknowledged.txt	
@@ -0,0 +1,34 @@
+===========================================
+MongoDB\\InsertManyResult::isAcknowledged()
+===========================================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\InsertManyResult::isAcknowledged()
+
+   Return whether the write was acknowledged.
+
+   .. code-block:: php
+
+      function isAcknowledged(): boolean
+
+Return Values
+-------------
+
+A boolean indicating whether the write was acknowledged.
+
+See Also
+--------
+
+- :php:`MongoDB\\Driver\\WriteResult::isAcknowledged()
+  <manual/en/mongodb-driver-writeresult.isacknowledged.php>`
+- :manual:`Write Concern </reference/write-concern>` in the MongoDB manual
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBInsertOneResult-getInsertedCount.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBInsertOneResult-getInsertedCount.txt
new file mode 100644
index 0000000000000000000000000000000000000000..3550801507b9359db55a09470ce503d52172636a
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBInsertOneResult-getInsertedCount.txt	
@@ -0,0 +1,41 @@
+============================================
+MongoDB\\InsertOneResult::getInsertedCount()
+============================================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\InsertOneResult::getInsertedCount()
+
+   Return the number of documents that were inserted.
+
+   .. code-block:: php
+
+      function getInsertedCount(): integer
+
+   This method should only be called if the write was acknowledged.
+
+Return Values
+-------------
+
+The number of documents that were inserted. This should be ``1`` for an
+acknowledged insert operation.
+
+Errors/Exceptions
+-----------------
+
+.. include:: /includes/extracts/error-badmethodcallexception-write-result.rst
+
+See Also
+--------
+
+- :php:`MongoDB\\Driver\\WriteResult::getInsertedCount()
+  <manual/en/mongodb-driver-writeresult.getinsertedcount.php>`
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBInsertOneResult-getInsertedId.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBInsertOneResult-getInsertedId.txt
new file mode 100644
index 0000000000000000000000000000000000000000..8d4a01ddf625d423e29bda279c7944f50b7cbbfd
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBInsertOneResult-getInsertedId.txt	
@@ -0,0 +1,35 @@
+=========================================
+MongoDB\\InsertOneResult::getInsertedId()
+=========================================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\InsertOneResult::getInsertedId()
+
+   Return the ID (i.e. ``_id`` field value) for the inserted document.
+
+   .. code-block:: php
+
+      function getInsertedId(): mixed
+
+   Since IDs are created by the driver, this method may be called irrespective
+   of whether the write was acknowledged.
+
+Return Values
+-------------
+
+The ID (i.e. ``_id`` field value) of the inserted document.
+
+If the document had an ID prior to inserting (i.e. the driver did not need to
+generate an ID), this will contain its ``_id`` field value. Any driver-generated
+ID will be a :php:`MongoDB\\BSON\\ObjectId <class.mongodb-bson-objectid>`
+instance.
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBInsertOneResult-isAcknowledged.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBInsertOneResult-isAcknowledged.txt
new file mode 100644
index 0000000000000000000000000000000000000000..921e3a6115f6b51ac598e2887a971b913420f3aa
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBInsertOneResult-isAcknowledged.txt	
@@ -0,0 +1,34 @@
+==========================================
+MongoDB\\InsertOneResult::isAcknowledged()
+==========================================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\InsertOneResult::isAcknowledged()
+
+   Return whether the write was acknowledged.
+
+   .. code-block:: php
+
+      function isAcknowledged(): boolean
+
+Return Values
+-------------
+
+A boolean indicating whether the write was acknowledged.
+
+See Also
+--------
+
+- :php:`MongoDB\\Driver\\WriteResult::isAcknowledged()
+  <manual/en/mongodb-driver-writeresult.isacknowledged.php>`
+- :manual:`Write Concern </reference/write-concern>` in the MongoDB manual
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBMapReduceResult-getCounts.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBMapReduceResult-getCounts.txt
new file mode 100644
index 0000000000000000000000000000000000000000..c2feab0ca780e2f923a6563e44aae46d71881136
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBMapReduceResult-getCounts.txt	
@@ -0,0 +1,66 @@
+=====================================
+MongoDB\\MapReduceResult::getCounts()
+=====================================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\MapReduceResult::getCounts()
+
+   Returns count statistics for the map-reduce operation.
+
+   .. code-block:: php
+
+      function getCounts(): array
+
+Return Values
+-------------
+
+An array of count statistics for the map-reduce operation.
+
+Examples
+--------
+
+This example reports the count statistics for a map-reduce operation.
+
+.. code-block:: php
+
+   <?php
+
+   $collection = (new MongoDB\Client)->test->zips;
+
+   $map = new MongoDB\BSON\Javascript('function() { emit(this.state, this.pop); }');
+   $reduce = new MongoDB\BSON\Javascript('function(key, values) { return Array.sum(values) }');
+   $out = ['inline' => 1];
+
+   $result = $collection->mapReduce($map, $reduce, $out);
+
+   var_dump($result->getCounts());
+
+The output would then resemble::
+
+   array(4) {
+     ["input"]=>
+     int(29353)
+     ["emit"]=>
+     int(29353)
+     ["reduce"]=>
+     int(180)
+     ["output"]=>
+     int(51)
+   }
+
+See Also
+--------
+
+- :phpmethod:`MongoDB\\Collection::mapReduce()`
+- :manual:`mapReduce </reference/command/mapReduce>` command reference in the
+  MongoDB manual
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBMapReduceResult-getExecutionTimeMS.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBMapReduceResult-getExecutionTimeMS.txt
new file mode 100644
index 0000000000000000000000000000000000000000..06c5b012bc3dded91d397b5cec86886732abdae5
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBMapReduceResult-getExecutionTimeMS.txt	
@@ -0,0 +1,58 @@
+==============================================
+MongoDB\\MapReduceResult::getExecutionTimeMS()
+==============================================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\MapReduceResult::getExecutionTimeMS()
+
+   Returns the execution time in milliseconds of the map-reduce operation.
+
+   .. code-block:: php
+
+      function getExecutionTimeMS(): integer
+
+Return Values
+-------------
+
+An integer denoting the execution time in milliseconds for the map-reduce
+operation.
+
+Examples
+--------
+
+This example reports the execution time for a map-reduce operation.
+
+.. code-block:: php
+
+   <?php
+
+   $collection = (new MongoDB\Client)->test->zips;
+
+   $map = new MongoDB\BSON\Javascript('function() { emit(this.state, this.pop); }');
+   $reduce = new MongoDB\BSON\Javascript('function(key, values) { return Array.sum(values) }');
+   $out = ['inline' => 1];
+
+   $result = $collection->mapReduce($map, $reduce, $out);
+
+   var_dump($result->getExecutionTimeMS());
+
+The output would then resemble::
+
+   int(244)
+
+See Also
+--------
+
+- :phpmethod:`MongoDB\\Collection::mapReduce()`
+- :manual:`mapReduce </reference/command/mapReduce>` command reference in the
+  MongoDB manual
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBMapReduceResult-getIterator.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBMapReduceResult-getIterator.txt
new file mode 100644
index 0000000000000000000000000000000000000000..b58040288168e00c83baac9cf96bc070dbcfdd3f
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBMapReduceResult-getIterator.txt	
@@ -0,0 +1,83 @@
+=======================================
+MongoDB\\MapReduceResult::getIterator()
+=======================================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\MapReduceResult::getIterator()
+
+   Returns a php:`Traversable <traversable>`, which may be used to iterate
+   through the results of the map-reduce operation.
+
+   .. code-block:: php
+
+      function getIterator(): Traversable
+
+Return Values
+-------------
+
+A :php:`Traversable <traversable>`, which may be used to iterate through the
+results of the map-reduce operation.
+
+Example
+-------
+
+This example iterates through the results of a map-reduce operation.
+
+.. code-block:: php
+
+   <?php
+
+   $collection = (new MongoDB\Client)->test->zips;
+
+   $map = new MongoDB\BSON\Javascript('function() { emit(this.state, this.pop); }');
+   $reduce = new MongoDB\BSON\Javascript('function(key, values) { return Array.sum(values) }');
+   $out = ['inline' => 1];
+
+   $result = $collection->mapReduce($map, $reduce, $out);
+
+   foreach ($result as $population) {
+      var_dump($population);
+   };
+
+The output would then resemble::
+
+   object(stdClass)#2293 (2) {
+      ["_id"]=>
+      string(2) "AK"
+      ["value"]=>
+      float(544698)
+   }
+   object(stdClass)#2300 (2) {
+      ["_id"]=>
+      string(2) "AL"
+      ["value"]=>
+      float(4040587)
+   }
+   object(stdClass)#2293 (2) {
+      ["_id"]=>
+      string(2) "AR"
+      ["value"]=>
+      float(2350725)
+   }
+   object(stdClass)#2300 (2) {
+      ["_id"]=>
+      string(2) "AZ"
+      ["value"]=>
+      float(3665228)
+   }
+
+See Also
+--------
+
+- :phpmethod:`MongoDB\\Collection::mapReduce()`
+- :php:`IteratorAggregate::getIterator() <manual/en/iteratoraggregate.getiterator.php>`
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBMapReduceResult-getTiming.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBMapReduceResult-getTiming.txt
new file mode 100644
index 0000000000000000000000000000000000000000..75ab53939f7ea07b0cea63507c7e952cabde81b5
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBMapReduceResult-getTiming.txt	
@@ -0,0 +1,74 @@
+=====================================
+MongoDB\\MapReduceResult::getTiming()
+=====================================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\MapReduceResult::getTiming()
+
+   Returns timing statistics for the map-reduce operation.
+
+   .. code-block:: php
+
+      function getTiming(): array
+
+   Timing statistics will only be available if the ``verbose`` option was
+   specified for :phpmethod:`MongoDB\\Collection::mapReduce()`.
+
+Return Values
+-------------
+
+An array of timing statistics for the map-reduce operation. If no timing
+statistics are available, the array will be empty.
+
+Examples
+--------
+
+This example specifies the ``verbose`` option for
+:phpmethod:`MongoDB\\Collection::mapReduce()` and reports the timing statistics
+for a map-reduce operation.
+
+.. code-block:: php
+
+   <?php
+
+   $collection = (new MongoDB\Client)->test->zips;
+
+   $map = new MongoDB\BSON\Javascript('function() { emit(this.state, this.pop); }');
+   $reduce = new MongoDB\BSON\Javascript('function(key, values) { return Array.sum(values) }');
+   $out = ['inline' => 1];
+
+   $result = $collection->mapReduce($map, $reduce, $out, ['verbose' => true]);
+
+   var_dump($result->getTiming());
+
+The output would then resemble::
+
+   array(5) {
+     ["mapTime"]=>
+     int(163)
+     ["emitLoop"]=>
+     int(233)
+     ["reduceTime"]=>
+     int(9)
+     ["mode"]=>
+     string(5) "mixed"
+     ["total"]=>
+     int(233)
+   }
+
+See Also
+--------
+
+- :phpmethod:`MongoDB\\Collection::mapReduce()`
+- :manual:`mapReduce </reference/command/mapReduce>` command reference in the
+  MongoDB manual
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBModelCollectionInfo-getCappedMax.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBModelCollectionInfo-getCappedMax.txt
new file mode 100644
index 0000000000000000000000000000000000000000..fb86ee19a83d7c98fd9978fcb4c1d0e0800fa8fc
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBModelCollectionInfo-getCappedMax.txt	
@@ -0,0 +1,61 @@
+==============================================
+MongoDB\\Model\\CollectionInfo::getCappedMax()
+==============================================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\Model\\CollectionInfo::getCappedMax()
+
+   Return the document limit for the capped collection. This correlates with the
+   ``max`` option for :phpmethod:`MongoDB\\Database::createCollection()`.
+
+   .. code-block:: php
+
+      function getCappedMax(): integer|null
+
+Return Values
+-------------
+
+The document limit for the capped collection. If the collection is not capped,
+``null`` will be returned.
+
+Examples
+--------
+
+.. code-block:: php
+
+   <?php
+
+   $info = new CollectionInfo([
+       'name' => 'foo',
+       'options' => [
+           'capped' => true,
+           'size' => 1048576,
+           'max' => 100,
+       ]
+   ]);
+
+   var_dump($info->getCappedMax());
+
+The output would then resemble::
+
+   int(100)
+
+See Also
+--------
+
+- :phpmethod:`MongoDB\\Model\\CollectionInfo::getCappedSize()`
+- :phpmethod:`MongoDB\\Model\\CollectionInfo::isCapped()`
+- :phpmethod:`MongoDB\\Database::createCollection()`
+- :manual:`Capped Collections </core/capped-collections>` in the MongoDB manual
+- :manual:`listCollections </reference/command/listCollections>` command
+  reference in the MongoDB manual
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBModelCollectionInfo-getCappedSize.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBModelCollectionInfo-getCappedSize.txt
new file mode 100644
index 0000000000000000000000000000000000000000..a3b1ce48fc7b2ea848756c6a015a9ff4fdae262c
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBModelCollectionInfo-getCappedSize.txt	
@@ -0,0 +1,61 @@
+===============================================
+MongoDB\\Model\\CollectionInfo::getCappedSize()
+===============================================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\Model\\CollectionInfo::getCappedSize()
+
+   Return the size limit for the capped collection in bytes. This correlates
+   with the ``size`` option for
+   :phpmethod:`MongoDB\\Database::createCollection()`.
+
+   .. code-block:: php
+
+      function getCappedSize(): integer|null
+
+Return Values
+-------------
+
+The size limit for the capped collection in bytes. If the collection is not
+capped, ``null`` will be returned.
+
+Examples
+--------
+
+.. code-block:: php
+
+   <?php
+
+   $info = new CollectionInfo([
+       'name' => 'foo',
+       'options' => [
+           'capped' => true,
+           'size' => 1048576,
+       ]
+   ]);
+
+   var_dump($info->getCappedSize());
+
+The output would then resemble::
+
+   int(1048576)
+
+See Also
+--------
+
+- :phpmethod:`MongoDB\\Model\\CollectionInfo::getCappedMax()`
+- :phpmethod:`MongoDB\\Model\\CollectionInfo::isCapped()`
+- :phpmethod:`MongoDB\\Database::createCollection()`
+- :manual:`Capped Collections </core/capped-collections>` in the MongoDB manual
+- :manual:`listCollections </reference/command/listCollections>` command
+  reference in the MongoDB manual
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBModelCollectionInfo-getName.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBModelCollectionInfo-getName.txt
new file mode 100644
index 0000000000000000000000000000000000000000..42226c203664659a3829071a97914b5e75f3458f
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBModelCollectionInfo-getName.txt	
@@ -0,0 +1,49 @@
+=========================================
+MongoDB\\Model\\CollectionInfo::getName()
+=========================================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\Model\\CollectionInfo::getName()
+
+   Return the collection name.
+
+   .. code-block:: php
+
+      function getName(): string
+
+Return Values
+-------------
+
+The collection name.
+
+Examples
+--------
+
+.. code-block:: php
+
+   <?php
+
+   $info = new CollectionInfo(['name' => 'foo']);
+
+   echo $info->getName();
+
+The output would then resemble::
+
+   foo
+
+See Also
+--------
+
+- :phpmethod:`MongoDB\\Collection::getCollectionName()`
+- :manual:`listCollections </reference/command/listCollections>` command
+  reference in the MongoDB manual
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBModelCollectionInfo-getOptions.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBModelCollectionInfo-getOptions.txt
new file mode 100644
index 0000000000000000000000000000000000000000..8450681631ba09785be486d23bd125c487446df4
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBModelCollectionInfo-getOptions.txt	
@@ -0,0 +1,62 @@
+============================================
+MongoDB\\Model\\CollectionInfo::getOptions()
+============================================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\Model\\CollectionInfo::getOptions()
+
+   Return the collection options. This correlates with the options for
+   :phpmethod:`MongoDB\\Database::createCollection()`, but may include
+   additional fields set by the server.
+
+   .. code-block:: php
+
+      function getOptions(): array
+
+Return Values
+-------------
+
+The collection options.
+
+Examples
+--------
+
+.. code-block:: php
+
+   <?php
+
+   $info = new CollectionInfo([
+       'name' => 'foo',
+       'options' => [
+           'capped' => true,
+           'size' => 1048576,
+       ]
+   ]);
+
+   var_dump($info->getOptions());
+
+The output would then resemble::
+
+   array(2) {
+     ["capped"]=>
+     bool(true)
+     ["size"]=>
+     int(1048576)
+   }
+
+See Also
+--------
+
+- :phpmethod:`MongoDB\\Database::createCollection()`
+- :manual:`listCollections </reference/command/listCollections>` command
+  reference in the MongoDB manual
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBModelCollectionInfo-isCapped.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBModelCollectionInfo-isCapped.txt
new file mode 100644
index 0000000000000000000000000000000000000000..a583a83fc132a6b9a702233b8476b27fccac9a94
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBModelCollectionInfo-isCapped.txt	
@@ -0,0 +1,58 @@
+==========================================
+MongoDB\\Model\\CollectionInfo::isCapped()
+==========================================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\Model\\CollectionInfo::isCapped()
+
+   Return whether the collection is a :manual:`capped collection
+   </core/capped-collections>`.
+
+   .. code-block:: php
+
+      function isCapped(): boolean
+
+Return Values
+-------------
+
+A boolean indicating whether the collection is a capped collection.
+
+Examples
+--------
+
+.. code-block:: php
+
+   <?php
+
+   $info = new CollectionInfo([
+       'name' => 'foo',
+       'options' => [
+           'capped' => true,
+           'size' => 1048576,
+      ]
+   ]);
+
+   var_dump($info->isCapped());
+
+The output would then resemble::
+
+   bool(true)
+
+See Also
+--------
+
+- :phpmethod:`MongoDB\\Model\\CollectionInfo::getCappedMax()`
+- :phpmethod:`MongoDB\\Model\\CollectionInfo::getCappedSize()`
+- :manual:`Capped Collections </core/capped-collections>` in the MongoDB manual
+- :manual:`listCollections </reference/command/listCollections>` command
+  reference in the MongoDB manual
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBModelDatabaseInfo-getName.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBModelDatabaseInfo-getName.txt
new file mode 100644
index 0000000000000000000000000000000000000000..a2524a4b1e3f0a2c3f1d259c2f9221c7ec2afe58
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBModelDatabaseInfo-getName.txt	
@@ -0,0 +1,49 @@
+=======================================
+MongoDB\\Model\\DatabaseInfo::getName()
+=======================================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\Model\\DatabaseInfo::getName()
+
+   Return the database name.
+
+   .. code-block:: php
+
+      function getName(): string
+
+Return Values
+-------------
+
+The database name.
+
+Examples
+--------
+
+.. code-block:: php
+
+   <?php
+
+   $info = new DatabaseInfo(['name' => 'foo']);
+
+   echo $info->getName();
+
+The output would then resemble::
+
+   foo
+
+See Also
+--------
+
+- :phpmethod:`MongoDB\\Database::getDatabaseName()`
+- :manual:`listDatabases </reference/command/listDatabases>` command reference
+  in the MongoDB manual
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBModelDatabaseInfo-getSizeOnDisk.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBModelDatabaseInfo-getSizeOnDisk.txt
new file mode 100644
index 0000000000000000000000000000000000000000..d42f23ff55d9e59d9906c55a358d4641edf02b30
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBModelDatabaseInfo-getSizeOnDisk.txt	
@@ -0,0 +1,48 @@
+=============================================
+MongoDB\\Model\\DatabaseInfo::getSizeOnDisk()
+=============================================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\Model\\DatabaseInfo::getSizeOnDisk()
+
+   Return the total size of the database file on disk in bytes.
+
+   .. code-block:: php
+
+      function getSizeOnDisk(): integer
+
+Return Values
+-------------
+
+The total size of the database file on disk in bytes.
+
+Examples
+--------
+
+.. code-block:: php
+
+   <?php
+
+   $info = new DatabaseInfo(['sizeOnDisk' => 1048576]);
+
+   var_dump($info->getSizeOnDisk());
+
+The output would then resemble::
+
+   int(1048576)
+
+See Also
+--------
+
+- :manual:`listDatabases </reference/command/listDatabases>` command reference
+  in the MongoDB manual
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBModelDatabaseInfo-isEmpty.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBModelDatabaseInfo-isEmpty.txt
new file mode 100644
index 0000000000000000000000000000000000000000..ae25e67f264c8d3c584f433a9460d84abf751dcd
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBModelDatabaseInfo-isEmpty.txt	
@@ -0,0 +1,48 @@
+=======================================
+MongoDB\\Model\\DatabaseInfo::isEmpty()
+=======================================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\Model\\DatabaseInfo::isEmpty()
+
+   Return whether the database has any data.
+
+   .. code-block:: php
+
+      function isEmpty(): boolean
+
+Return Values
+-------------
+
+A boolean indicating whether the database has any data.
+
+Examples
+--------
+
+.. code-block:: php
+
+   <?php
+
+   $info = new DatabaseInfo(['empty' => true]);
+
+   var_dump($info->isEmpty());
+
+The output would then resemble::
+
+   bool(true)
+
+See Also
+--------
+
+- :manual:`listDatabases </reference/command/listDatabases>` command reference
+  in the MongoDB manual
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBModelIndexInfo-getKey.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBModelIndexInfo-getKey.txt
new file mode 100644
index 0000000000000000000000000000000000000000..1a115f9ccfbc110d11572f79d603deaa0d8127fe
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBModelIndexInfo-getKey.txt	
@@ -0,0 +1,56 @@
+===================================
+MongoDB\\Model\\IndexInfo::getKey()
+===================================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\Model\\IndexInfo::getKey()
+
+   Return the index specification (i.e. indexed field(s) and order). This
+   correlates with the ``$key`` parameter for
+   :phpmethod:`MongoDB\\Collection::createIndex()`.
+
+   .. code-block:: php
+
+      function getKey(): array
+
+Return Values
+-------------
+
+The index specification as an associative array.
+
+Examples
+--------
+
+.. code-block:: php
+
+   <?php
+
+   $info = new IndexInfo([
+       'key' => ['x' => 1],
+   ]);
+
+   var_dump($info->getKey());
+
+The output would then resemble::
+
+   array(1) {
+     ["x"]=>
+     int(1)
+   }
+
+See Also
+--------
+
+- :phpmethod:`MongoDB\\Collection::createIndex()`
+- :manual:`listIndexes </reference/command/listIndexes>` command reference in
+  the MongoDB manual
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBModelIndexInfo-getName.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBModelIndexInfo-getName.txt
new file mode 100644
index 0000000000000000000000000000000000000000..97ad45faebb4224796f9d54acbc47bc4302540a1
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBModelIndexInfo-getName.txt	
@@ -0,0 +1,54 @@
+====================================
+MongoDB\\Model\\IndexInfo::getName()
+====================================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\Model\\IndexInfo::getName()
+
+   Return the index name. This correlates with the return value of
+   :phpmethod:`MongoDB\\Collection::createIndex()`. An index name may be derived
+   from the ``$key`` parameter or or explicitly specified via the ``name``
+   option.
+
+   .. code-block:: php
+
+      function getName(): string
+
+Return Values
+-------------
+
+The index name.
+
+Examples
+--------
+
+.. code-block:: php
+
+   <?php
+
+   $info = new IndexInfo([
+       'name' => 'x_1',
+   ]);
+
+   echo $info->getName();
+
+The output would then resemble::
+
+   x_1
+
+See Also
+--------
+
+- :phpmethod:`MongoDB\\Collection::createIndex()`
+- :manual:`listIndexes </reference/command/listIndexes>` command reference in
+  the MongoDB manual
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBModelIndexInfo-getNamespace.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBModelIndexInfo-getNamespace.txt
new file mode 100644
index 0000000000000000000000000000000000000000..f4a64bb6688b8a320526fd41a853a117c8fa59a3
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBModelIndexInfo-getNamespace.txt	
@@ -0,0 +1,53 @@
+=========================================
+MongoDB\\Model\\IndexInfo::getNamespace()
+=========================================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\Model\\IndexInfo::getNamespace()
+
+   Return the index namespace, which is the namespace of the collection
+   containing the index.
+
+   .. code-block:: php
+
+      function getNamespace(): string
+
+Return Values
+-------------
+
+The index namespace.
+
+Examples
+--------
+
+.. code-block:: php
+
+   <?php
+
+   $info = new IndexInfo([
+       'ns' => 'foo.bar',
+   ]);
+
+   echo $info->getNamespace();
+
+The output would then resemble::
+
+   foo.bar
+
+See Also
+--------
+
+- :phpmethod:`MongoDB\\Collection::createIndex()`
+- :phpmethod:`MongoDB\\Collection::getNamespace()`
+- :manual:`listIndexes </reference/command/listIndexes>` command reference in
+  the MongoDB manual
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBModelIndexInfo-getVersion.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBModelIndexInfo-getVersion.txt
new file mode 100644
index 0000000000000000000000000000000000000000..728f38858b3e6d25e9f503fb5e38640ff8ef5fe9
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBModelIndexInfo-getVersion.txt	
@@ -0,0 +1,51 @@
+=======================================
+MongoDB\\Model\\IndexInfo::getVersion()
+=======================================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\Model\\IndexInfo::getVersion()
+
+   Return the index version.
+
+   .. code-block:: php
+
+      function getVersion(): integer
+
+Return Values
+-------------
+
+The index version.
+
+Examples
+--------
+
+.. code-block:: php
+
+   <?php
+
+   $info = new IndexInfo([
+       'v' => 1,
+   ]);
+
+   var_dump($info->getVersion());
+
+The output would then resemble::
+
+   int(1)
+
+See Also
+--------
+
+- :phpmethod:`MongoDB\\Collection::createIndex()`
+- :manual:`listIndexes </reference/command/listIndexes>` command reference in
+  the MongoDB manual
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBModelIndexInfo-is2dSphere.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBModelIndexInfo-is2dSphere.txt
new file mode 100644
index 0000000000000000000000000000000000000000..a6bb398be7338d80391752dca3d0428a2a779158
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBModelIndexInfo-is2dSphere.txt	
@@ -0,0 +1,59 @@
+=======================================
+MongoDB\\Model\\IndexInfo::is2dSphere()
+=======================================
+
+.. versionadded:: 1.4
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\Model\\IndexInfo::is2dSphere()
+
+   Return whether the index is a :manual:`2dsphere </core/2dsphere>`
+   index.
+
+   .. code-block:: php
+
+      function is2dSphere(): boolean
+
+Return Values
+-------------
+
+A boolean indicating whether the index is a 2dsphere index.
+
+Examples
+--------
+
+.. code-block:: php
+
+   <?php
+
+   $collection = (new MongoDB\Client)->selectCollection('test', 'places');
+
+   $collection->createIndex(['pos' => '2dsphere']);
+
+   foreach ($collection->listIndexes() as $index) {
+       if ($index->is2dSphere()) {
+           printf("%s has 2dsphereIndexVersion: %d\n", $index->getName(), $index['2dsphereIndexVersion']);
+       }
+   }
+
+The output would then resemble::
+
+   pos_2dsphere has 2dsphereIndexVersion: 3
+
+See Also
+--------
+
+- :phpmethod:`MongoDB\\Collection::createIndex()`
+- :phpmethod:`MongoDB\\Collection::listIndexes()`
+- :manual:`2dsphere Indexes </core/2dsphere>` reference in the MongoDB
+  manual
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBModelIndexInfo-isGeoHaystack.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBModelIndexInfo-isGeoHaystack.txt
new file mode 100644
index 0000000000000000000000000000000000000000..a2d9a028b5245e856accb147b595289d4d02ba38
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBModelIndexInfo-isGeoHaystack.txt	
@@ -0,0 +1,59 @@
+==========================================
+MongoDB\\Model\\IndexInfo::isGeoHaystack()
+==========================================
+
+.. versionadded:: 1.4
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\Model\\IndexInfo::isGeoHaystack()
+
+   Return whether the index is a :manual:`geoHaystack
+   </core/geohaystack>` index.
+
+   .. code-block:: php
+
+      function isGeoHaystack(): boolean
+
+Return Values
+-------------
+
+A boolean indicating whether the index is a geoHaystack index.
+
+Examples
+--------
+
+.. code-block:: php
+
+   <?php
+
+   $collection = (new MongoDB\Client)->selectCollection('test', 'places');
+
+   $collection->createIndex(['pos' => 'geoHaystack', 'x' => 1], ['bucketSize' => 5]);
+
+   foreach ($collection->listIndexes() as $index) {
+       if ($index->isGeoHaystack()) {
+           printf("%s has bucketSize: %d\n", $index->getName(), $index['bucketSize']);
+       }
+   }
+
+The output would then resemble::
+
+   pos_geoHaystack_x_1 has bucketSize: 5
+
+See Also
+--------
+
+- :phpmethod:`MongoDB\\Collection::createIndex()`
+- :phpmethod:`MongoDB\\Collection::listIndexes()`
+- :manual:`geoHaystack Indexes </core/geohaystack>` reference in the MongoDB
+  manual
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBModelIndexInfo-isSparse.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBModelIndexInfo-isSparse.txt
new file mode 100644
index 0000000000000000000000000000000000000000..5bbe4dea4cc0adab4d38ec0de92149790e878fee
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBModelIndexInfo-isSparse.txt	
@@ -0,0 +1,54 @@
+=====================================
+MongoDB\\Model\\IndexInfo::isSparse()
+=====================================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\Model\\IndexInfo::isSparse()
+
+   Return whether the index is a :manual:`sparse index </core/index-sparse>`.
+   This correlates with the ``sparse`` option for
+   :phpmethod:`MongoDB\\Collection::createIndex()`.
+
+   .. code-block:: php
+
+      function isSparse(): boolean
+
+Return Values
+-------------
+
+A boolean indicating whether the index is a sparse index.
+
+Examples
+--------
+
+.. code-block:: php
+
+   <?php
+
+   $info = new IndexInfo([
+       'sparse' => true,
+   ]);
+
+   var_dump($info->isSparse());
+
+The output would then resemble::
+
+   bool(true)
+
+See Also
+--------
+
+- :phpmethod:`MongoDB\\Collection::createIndex()`
+- :manual:`listIndexes </reference/command/listIndexes>` command reference in
+  the MongoDB manual
+- :manual:`Sparse Indexes </core/index-sparse>` in the MongoDB manual
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBModelIndexInfo-isText.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBModelIndexInfo-isText.txt
new file mode 100644
index 0000000000000000000000000000000000000000..0833359689f8e712affbc8daf48938bbe9a415ba
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBModelIndexInfo-isText.txt	
@@ -0,0 +1,58 @@
+===================================
+MongoDB\\Model\\IndexInfo::isText()
+===================================
+
+.. versionadded:: 1.4
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\Model\\IndexInfo::isText()
+
+   Return whether the index is a :manual:`text </core/index-text>` index.
+
+   .. code-block:: php
+
+      function isText(): boolean
+
+Return Values
+-------------
+
+A boolean indicating whether the index is a text index.
+
+Examples
+--------
+
+.. code-block:: php
+
+   <?php
+
+   $collection = (new MongoDB\Client)->selectCollection('test', 'restaurants');
+
+   $collection->createIndex(['name' => 'text']);
+
+   foreach ($collection->listIndexes() as $index) {
+       if ($index->isText()) {
+           printf("%s has default language: %d\n", $index->getName(), $index['default_language']);
+       }
+   }
+
+The output would then resemble::
+
+   name_text has default language: english
+
+See Also
+--------
+
+- :phpmethod:`MongoDB\\Collection::createIndex()`
+- :phpmethod:`MongoDB\\Collection::listIndexes()`
+- :manual:`Text Indexes </core/index-text>` reference in the MongoDB
+  manual
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBModelIndexInfo-isTtl.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBModelIndexInfo-isTtl.txt
new file mode 100644
index 0000000000000000000000000000000000000000..a3e70d036ece4a4a4640241c10b532791054c21c
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBModelIndexInfo-isTtl.txt	
@@ -0,0 +1,54 @@
+==================================
+MongoDB\\Model\\IndexInfo::isTtl()
+==================================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\Model\\IndexInfo::isTtl()
+
+   Return whether the index is a :manual:`TTL index </core/index-ttl>`. This
+   correlates with the ``expireAfterSeconds`` option for
+   :phpmethod:`MongoDB\\Collection::createIndex()`.
+
+   .. code-block:: php
+
+      function isTtl(): boolean
+
+Return Values
+-------------
+
+A boolean indicating whether the index is a TTL index.
+
+Examples
+--------
+
+.. code-block:: php
+
+   <?php
+
+   $info = new IndexInfo([
+       'expireAfterSeconds' => 100,
+   ]);
+
+   var_dump($info->isTtl());
+
+The output would then resemble::
+
+   bool(true)
+
+See Also
+--------
+
+- :phpmethod:`MongoDB\\Collection::createIndex()`
+- :manual:`listIndexes </reference/command/listIndexes>` command reference in
+  the MongoDB manual
+- :manual:`TTL Indexes </core/index-ttl>` in the MongoDB manual
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBModelIndexInfo-isUnique.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBModelIndexInfo-isUnique.txt
new file mode 100644
index 0000000000000000000000000000000000000000..30cf1ece5e9e2a7c1d5642f856f0b4892ccd9ffa
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBModelIndexInfo-isUnique.txt	
@@ -0,0 +1,54 @@
+=====================================
+MongoDB\\Model\\IndexInfo::isUnique()
+=====================================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\Model\\IndexInfo::isUnique()
+
+   Return whether the index is a :manual:`unique index </core/index-unique>`.
+   This correlates with the ``unique`` option for
+   :phpmethod:`MongoDB\\Collection::createIndex()`.
+
+   .. code-block:: php
+
+      function isUnique(): boolean
+
+Return Values
+-------------
+
+A boolean indicating whether the index is a unique index.
+
+Examples
+--------
+
+.. code-block:: php
+
+   <?php
+
+   $info = new IndexInfo([
+       'unique' => true,
+   ]);
+
+   var_dump($info->isUnique());
+
+The output would then resemble::
+
+   bool(true)
+
+See Also
+--------
+
+- :phpmethod:`MongoDB\\Collection::createIndex()`
+- :manual:`listIndexes </reference/command/listIndexes>` command reference in
+  the MongoDB manual
+- :manual:`Unique Indexes </core/index-unique>` in the MongoDB manual
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBUpdateResult-getMatchedCount.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBUpdateResult-getMatchedCount.txt
new file mode 100644
index 0000000000000000000000000000000000000000..f347a8cf0c40b5824dfe550953d8f01af5454aeb
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBUpdateResult-getMatchedCount.txt	
@@ -0,0 +1,49 @@
+========================================
+MongoDB\\UpdateResult::getMatchedCount()
+========================================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\UpdateResult::getMatchedCount()
+
+   Return the number of documents that were matched.
+
+   .. code-block:: php
+
+      function getMatchedCount(): integer
+
+   This method should only be called if the write was acknowledged.
+
+   .. note::
+
+      If an update/replace operation results in no change to the document
+      (e.g. setting the value of a field to its current value), the matched
+      count may be greater than the value returned by
+      :phpmethod:`getModifiedCount()
+      <MongoDB\\UpdateResult::getModifiedCount()>`.
+
+Return Values
+-------------
+
+The number of documents that were matched.
+
+Errors/Exceptions
+-----------------
+
+.. include:: /includes/extracts/error-badmethodcallexception-write-result.rst
+
+See Also
+--------
+
+- :phpmethod:`MongoDB\\UpdateResult::getModifiedCount()`
+- :php:`MongoDB\\Driver\\WriteResult::getMatchedCount()
+  <manual/en/mongodb-driver-writeresult.getmatchedcount.php>`
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBUpdateResult-getModifiedCount.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBUpdateResult-getModifiedCount.txt
new file mode 100644
index 0000000000000000000000000000000000000000..3e2a7a6ed7a4c18b8dcd8c4aeb894709657ffe9d
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBUpdateResult-getModifiedCount.txt	
@@ -0,0 +1,48 @@
+=========================================
+MongoDB\\UpdateResult::getModifiedCount()
+=========================================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\UpdateResult::getModifiedCount()
+
+   Return the number of documents that were modified.
+
+   .. code-block:: php
+
+      function getModifiedCount(): integer|null
+
+   This method should only be called if the write was acknowledged.
+
+   .. note::
+
+      If an update/replace operation results in no change to the document
+      (e.g. setting the value of a field to its current value), the modified
+      count may be less than the value returned by :phpmethod:`getMatchedCount()
+      <MongoDB\\UpdateResult::getMatchedCount()>`.
+
+Return Values
+-------------
+
+The number of documents that were modified.
+
+Errors/Exceptions
+-----------------
+
+.. include:: /includes/extracts/error-badmethodcallexception-write-result.rst
+
+See Also
+--------
+
+- :phpmethod:`MongoDB\\UpdateResult::getMatchedCount()`
+- :php:`MongoDB\\Driver\\WriteResult::getModifiedCount()
+  <manual/en/mongodb-driver-writeresult.getmodifiedcount.php>`
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBUpdateResult-getUpsertedCount.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBUpdateResult-getUpsertedCount.txt
new file mode 100644
index 0000000000000000000000000000000000000000..0bbb39fbcaf414f9356335051203da89fdb61aa9
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBUpdateResult-getUpsertedCount.txt	
@@ -0,0 +1,42 @@
+=========================================
+MongoDB\\UpdateResult::getUpsertedCount()
+=========================================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\UpdateResult::getUpsertedCount()
+
+   Return the number of documents that were upserted.
+
+   .. code-block:: php
+
+      function getUpsertedCount(): integer
+
+   This method should only be called if the write was acknowledged.
+
+Return Values
+-------------
+
+The total number of documents that were upserted. This should be either ``0`` or
+``1`` for an acknowledged update or replace operation, depending on whether an
+upsert occurred.
+
+Errors/Exceptions
+-----------------
+
+.. include:: /includes/extracts/error-badmethodcallexception-write-result.rst
+
+See Also
+--------
+
+- :php:`MongoDB\\Driver\\WriteResult::getUpsertedCount()
+  <manual/en/mongodb-driver-writeresult.getupsertedcount.php>`
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBUpdateResult-getUpsertedId.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBUpdateResult-getUpsertedId.txt
new file mode 100644
index 0000000000000000000000000000000000000000..52498708de839522f4a9e4ae60ea866310f10edc
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBUpdateResult-getUpsertedId.txt	
@@ -0,0 +1,44 @@
+======================================
+MongoDB\\UpdateResult::getUpsertedId()
+======================================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\UpdateResult::getUpsertedId()
+
+   Return the ID (i.e. ``_id`` field value) of the upserted document.
+
+   .. code-block:: php
+
+      function getUpsertedId(): mixed|null
+
+Return Values
+-------------
+
+The ID (i.e. ``_id`` field value) of the upserted document. If no document was
+upserted, ``null`` will be returned.
+
+If the document had an ID prior to upserting (i.e. the server did not need to
+generate an ID), this will contain its ``_id`` field value. Any server-generated
+ID will be a :php:`MongoDB\\BSON\\ObjectId <class.mongodb-bson-objectid>`
+instance.
+
+Errors/Exceptions
+-----------------
+
+.. include:: /includes/extracts/error-badmethodcallexception-write-result.rst
+
+See Also
+--------
+
+- :php:`MongoDB\\Driver\\WriteResult::getUpsertedIds()
+  <manual/en/mongodb-driver-writeresult.getupsertedids.php>`
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBUpdateResult-isAcknowledged.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBUpdateResult-isAcknowledged.txt
new file mode 100644
index 0000000000000000000000000000000000000000..af15d1f11195c0e20c8a3deaa89a21691c772f49
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/method/MongoDBUpdateResult-isAcknowledged.txt	
@@ -0,0 +1,34 @@
+=======================================
+MongoDB\\UpdateResult::isAcknowledged()
+=======================================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Definition
+----------
+
+.. phpmethod:: MongoDB\\UpdateResult::isAcknowledged()
+
+   Return whether the write was acknowledged.
+
+   .. code-block:: php
+
+      function isAcknowledged(): boolean
+
+Return Values
+-------------
+
+A boolean indicating whether the write was acknowledged.
+
+See Also
+--------
+
+- :php:`MongoDB\\Driver\\WriteResult::isAcknowledged()
+  <manual/en/mongodb-driver-writeresult.isacknowledged.php>`
+- :manual:`Write Concern </reference/write-concern>` in the MongoDB manual
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/result-classes.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/result-classes.txt
new file mode 100644
index 0000000000000000000000000000000000000000..3371c137ee6c64d40ac44f9fe75f59581032b6a2
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/result-classes.txt	
@@ -0,0 +1,76 @@
+==============
+Result Classes
+==============
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+MongoDB\\ChangeStream
+---------------------
+
+.. versionadded:: 1.3
+
+Definition
+~~~~~~~~~~
+
+.. phpclass:: MongoDB\\ChangeStream
+
+   This class extends PHP's :php:`Iterator <manual/en/class.iterator.php>`
+   interface. An instance of this class is returned by
+   :phpmethod:`MongoDB\\Client::watch()`,
+   :phpmethod:`MongoDB\\Database::watch()`, and
+   :phpmethod:`MongoDB\\Collection::watch()`.
+
+   This class allows for iteration of events in a change stream. It also allows
+   iteration to automatically resume after certain errors, such as a replica set
+   failover.
+
+Methods
+~~~~~~~
+
+.. toctree::
+   :titlesonly:
+
+   /reference/method/MongoDBChangeStream-current
+   /reference/method/MongoDBChangeStream-getCursorId
+   /reference/method/MongoDBChangeStream-getResumeToken
+   /reference/method/MongoDBChangeStream-key
+   /reference/method/MongoDBChangeStream-next
+   /reference/method/MongoDBChangeStream-rewind
+   /reference/method/MongoDBChangeStream-valid
+
+----
+
+MongoDB\\MapReduceResult
+------------------------
+
+.. versionadded:: 1.2
+
+Definition
+~~~~~~~~~~
+
+.. phpclass:: MongoDB\\MapReduceResult
+
+   This class extends PHP's :php:`IteratorAggregate <iteratoraggregate>`
+   interface. An instance of this class is returned by
+   :phpmethod:`MongoDB\\Collection::mapReduce()`.
+
+   This class allows for iteration of map-reduce results irrespective of the
+   output method (e.g. inline, collection). It also provides access to command
+   statistics.
+
+Methods
+~~~~~~~
+
+.. toctree::
+   :titlesonly:
+
+   /reference/method/MongoDBMapReduceResult-getCounts
+   /reference/method/MongoDBMapReduceResult-getExecutionTimeMS
+   /reference/method/MongoDBMapReduceResult-getIterator
+   /reference/method/MongoDBMapReduceResult-getTiming
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/write-result-classes.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/write-result-classes.txt
new file mode 100644
index 0000000000000000000000000000000000000000..f410c0834098d029f2b271cfa380ba6dd574e2b7
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/reference/write-result-classes.txt	
@@ -0,0 +1,143 @@
+====================
+Write Result Classes
+====================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+MongoDB\\BulkWriteResult
+------------------------
+
+Definition
+~~~~~~~~~~
+
+.. phpclass:: MongoDB\\BulkWriteResult
+
+   This class contains information about an executed bulk write operation. It
+   encapsulates a :php:`MongoDB\\Driver\\WriteResult
+   <class.mongodb-driver-writeresult>` object and is returned from
+   :phpmethod:`MongoDB\\Collection::bulkWrite()`.
+
+Methods
+~~~~~~~
+
+.. toctree::
+   :titlesonly:
+
+   /reference/method/MongoDBBulkWriteResult-getDeletedCount
+   /reference/method/MongoDBBulkWriteResult-getInsertedCount
+   /reference/method/MongoDBBulkWriteResult-getInsertedIds
+   /reference/method/MongoDBBulkWriteResult-getMatchedCount
+   /reference/method/MongoDBBulkWriteResult-getModifiedCount
+   /reference/method/MongoDBBulkWriteResult-getUpsertedCount
+   /reference/method/MongoDBBulkWriteResult-getUpsertedIds
+   /reference/method/MongoDBBulkWriteResult-isAcknowledged
+
+----
+
+MongoDB\\DeleteResult
+---------------------
+
+Definition
+~~~~~~~~~~
+
+.. phpclass:: MongoDB\\DeleteResult
+
+   This class contains information about an executed delete operation. It
+   encapsulates a :php:`MongoDB\\Driver\\WriteResult
+   <class.mongodb-driver-writeresult>` object and is returned from
+   :phpmethod:`MongoDB\\Collection::deleteMany()` or
+   :phpmethod:`MongoDB\\Collection::deleteOne()`.
+
+Methods
+~~~~~~~
+
+.. toctree::
+   :titlesonly:
+
+   /reference/method/MongoDBDeleteResult-getDeletedCount
+   /reference/method/MongoDBDeleteResult-isAcknowledged
+
+----
+
+MongoDB\\InsertManyResult
+-------------------------
+
+Definition
+~~~~~~~~~~
+
+.. phpclass:: MongoDB\\InsertManyResult
+
+   This class contains information about an executed bulk insert operation. It
+   encapsulates a :php:`MongoDB\\Driver\\WriteResult
+   <class.mongodb-driver-writeresult>` object and is returned from
+   :phpmethod:`MongoDB\\Collection::insertMany()`.
+
+Methods
+~~~~~~~
+
+.. toctree::
+   :titlesonly:
+
+   /reference/method/MongoDBInsertManyResult-getInsertedCount
+   /reference/method/MongoDBInsertManyResult-getInsertedIds
+   /reference/method/MongoDBInsertManyResult-isAcknowledged
+
+----
+
+MongoDB\\InsertOneResult
+------------------------
+
+Definition
+~~~~~~~~~~
+
+.. phpclass:: MongoDB\\InsertOneResult
+
+   This class contains information about an executed insert operation. It
+   encapsulates a :php:`MongoDB\\Driver\\WriteResult
+   <class.mongodb-driver-writeresult>` object and is returned from
+   :phpmethod:`MongoDB\\Collection::insertOne()`.
+
+Methods
+~~~~~~~
+
+.. toctree::
+   :titlesonly:
+
+   /reference/method/MongoDBInsertOneResult-getInsertedCount
+   /reference/method/MongoDBInsertOneResult-getInsertedId
+   /reference/method/MongoDBInsertOneResult-isAcknowledged
+
+----
+
+MongoDB\\UpdateResult
+---------------------
+
+Definition
+~~~~~~~~~~
+
+.. phpclass:: MongoDB\\UpdateResult
+
+   This class contains information about an executed update or replace
+   operation. It encapsulates a :php:`MongoDB\\Driver\\WriteResult
+   <class.mongodb-driver-writeresult>` object and is returned from
+   :phpmethod:`MongoDB\\Collection::replaceOne()`,
+   :phpmethod:`MongoDB\\Collection::updateMany()`, or
+   :phpmethod:`MongoDB\\Collection::updateOne()`.
+
+Methods
+~~~~~~~
+
+.. toctree::
+   :titlesonly:
+
+   /reference/method/MongoDBUpdateResult-getMatchedCount
+   /reference/method/MongoDBUpdateResult-getModifiedCount
+   /reference/method/MongoDBUpdateResult-getUpsertedCount
+   /reference/method/MongoDBUpdateResult-getUpsertedId
+   /reference/method/MongoDBUpdateResult-isAcknowledged
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/tutorial.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/tutorial.txt
new file mode 100644
index 0000000000000000000000000000000000000000..7735508e612c2517f396ff807a32223e14bdb4eb
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/tutorial.txt	
@@ -0,0 +1,17 @@
+Tutorials
+=========
+
+.. default-domain:: mongodb
+
+.. toctree::
+
+   /tutorial/crud
+   /tutorial/collation
+   /tutorial/commands
+   /tutorial/custom-types
+   /tutorial/decimal128
+   /tutorial/client-side-encryption
+   /tutorial/gridfs
+   /tutorial/indexes
+   /tutorial/tailable-cursor
+   /tutorial/example-data
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/tutorial/client-side-encryption.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/tutorial/client-side-encryption.txt
new file mode 100644
index 0000000000000000000000000000000000000000..cc77b07b17593d993e6c17ab79afe8eb6a9b436d
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/tutorial/client-side-encryption.txt	
@@ -0,0 +1,241 @@
+======================
+Client-Side Encryption
+======================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+Client-Side Field Level Encryption allows administrators and developers to
+encrypt specific data fields in addition to other MongoDB encryption features.
+
+
+Automatic Encryption and Decryption
+-----------------------------------
+
+.. note::
+
+   Auto encryption is an enterprise only feature.
+
+The following example uses a local key, however using AWS Key Management Service
+is also an option. The data in the ``encryptedField`` field is automatically
+encrypted on insertion and decrypted when querying on the client side.
+
+.. code-block:: php
+
+   <?php
+
+   use MongoDB\BSON\Binary;
+   use MongoDB\Client;
+
+   $localKey = new Binary('<binary key data (96 bytes)>', Binary::TYPE_GENERIC);
+
+   $encryptionOpts = [
+       'keyVaultNamespace' => 'admin.datakeys',
+       'kmsProviders' => [
+           'local' => ['key' => $localKey],
+       ],
+   ];
+
+   $client = new Client('mongodb://127.0.0.1');
+   $clientEncryption = $client->createClientEncryption($encryptionOpts);
+
+   $database = $client->selectDatabase('test');
+   $database->dropCollection('coll'); // remove old data
+
+   // Create new key in the key vault and store its ID for later use
+   $keyId = $clientEncryption->createDataKey('local');
+
+   $database->createCollection('coll', [
+       'validator' => [
+           '$jsonSchema' => [
+               'bsonType' => 'object',
+               'properties' => [
+                   'encryptedField' => [
+                       'encrypt' => [
+                           'keyId' => [$keyId],
+                           'bsonType' => 'string',
+                           'algorithm' => ClientEncryption::AEAD_AES_256_CBC_HMAC_SHA_512_DETERMINISTIC,
+                       ],
+                   ],
+               ],
+           ],
+       ],
+   ]);
+
+   $encryptedClient = new Client('mongodb://127.0.0.1', [], ['autoEncryption' => $encryptionOpts]);
+
+   $collection = $encryptedClient->selectCollection('test', 'coll');
+
+   $collection->insertOne(['encryptedField' => '123456789']);
+
+   var_dump($collection->findOne([]));
+
+
+Specifying an Explicit Schema for Encryption
+--------------------------------------------
+
+The following example shows how to create a new key and store it in the key
+vault collection. The encrypted client configures an explicit schema for
+encryption using the newly created key.
+
+.. note::
+
+   Supplying a ``schemaMap`` provides more security than relying on JSON schemas
+   obtained from the server. It protects against a malicious server advertising
+   a false JSON schema, which could trick the client into sending unencrypted
+   data that should be encrypted.
+
+.. code-block:: php
+
+   <?php
+
+   use MongoDB\BSON\Binary;
+   use MongoDB\Client;
+   use MongoDB\Driver\ClientEncryption;
+
+   $localKey = new Binary('<binary key data (96 bytes)>', Binary::TYPE_GENERIC);
+
+   $clientEncryptionOpts = [
+       'keyVaultNamespace' => 'admin.datakeys',
+       'kmsProviders' => [
+           'local' => ['key' => $localKey],
+       ],
+   ];
+
+   $client = new Client();
+   $clientEncryption = $client->createClientEncryption($clientEncryptionOpts);
+
+   // Create new key in the key vault and store its ID for later use
+   $keyId = $clientEncryption->createDataKey('local');
+
+   $autoEncryptionOpts = [
+       'keyVaultNamespace' => 'admin.datakeys',
+       'kmsProviders' => [
+           'local' => ['key' => $localKey],
+       ],
+       'schemaMap' => [
+           'test.coll' => [
+               'bsonType' => 'object',
+               'properties' => [
+                   'encryptedField' => [
+                       'encrypt' => [
+                           'keyId' => [$keyId],
+                           'bsonType' => 'string',
+                           'algorithm' => ClientEncryption::AEAD_AES_256_CBC_HMAC_SHA_512_DETERMINISTIC,
+                       ],
+                   ],
+               ],
+           ],
+       ],
+   ];
+
+   $encryptedClient = new Client('mongodb://127.0.0.1', [], ['autoEncryption' => $autoEncryptionOpts]);
+
+   $collection = $encryptedClient->selectCollection('test', 'coll');
+   $collection->drop(); // clear old data
+
+   $collection->insertOne(['encryptedField' => '123456789']);
+
+   var_dump($collection->findOne([]));
+
+
+Manually Encrypting and Decrypting Values
+-----------------------------------------
+
+In the MongoDB Community Edition, you will have to manually encrypt and decrypt
+values before storing them in the database. The following example assumes that
+you have already created an encryption key in the key vault collection and
+explicitly encrypts and decrypts values in the document.
+
+.. code-block:: php
+
+   <?php
+
+   use MongoDB\BSON\Binary;
+   use MongoDB\Client;
+   use MongoDB\Driver\ClientEncryption;
+
+   $localKey = new Binary('<binary key data (96 bytes)>', Binary::TYPE_GENERIC);
+
+   $clientEncryptionOpts = [
+       'keyVaultNamespace' => 'admin.datakeys',
+       'kmsProviders' => [
+           'local' => ['key' => $localKey],
+       ],
+   ];
+
+   $client = new Client();
+   $clientEncryption = $client->createClientEncryption($clientEncryptionOpts);
+
+   // Create new key in the key vault and store its ID for later use
+   $keyId = $clientEncryption->createDataKey('local');
+
+   $collection = $client->selectCollection('test', 'coll');
+   $collection->drop(); // clear old data
+
+   $encryptionOpts = [
+       'keyId' => $keyId,
+       'algorithm' => ClientEncryption::AEAD_AES_256_CBC_HMAC_SHA_512_DETERMINISTIC,
+   ];
+   $encryptedValue = $clientEncryption->encrypt('123456789', $encryptionOpts);
+
+   $collection->insertOne(['encryptedField' => $encryptedValue]);
+
+   $document = $collection->findOne();
+   var_dump($clientEncryption->decrypt($document->encryptedField));
+
+
+Referencing Encryption Keys by an Alternative Name
+--------------------------------------------------
+
+While it is possible to create an encryption key every time data is encrypted,
+this is not the recommended approach. Instead, you should create your encryption
+keys depending on your use-case, e.g. by creating a user-specific encryption
+key. To reference keys in your software, you can use the keyAltName attribute
+specified when creating the key. The following example creates an encryption key
+with an alternative name, which could be done when deploying the application.
+The software then encrypts data by referencing the key by its alternative name.
+
+.. code-block:: php
+
+   <?php
+
+   use MongoDB\BSON\Binary;
+   use MongoDB\Client;
+   use MongoDB\Driver\ClientEncryption;
+
+   $localKey = new Binary('<binary key data (96 bytes)>', Binary::TYPE_GENERIC);
+
+   $clientEncryptionOpts = [
+       'keyVaultNamespace' => 'admin.datakeys',
+       'kmsProviders' => [
+           'local' => ['key' => $localKey],
+       ],
+   ];
+
+   $client = new Client();
+   $clientEncryption = $client->createClientEncryption($clientEncryptionOpts);
+
+   // Create an encryption key with an alternative name. This could be done when
+   // deploying the application
+   $keyId = $clientEncryption->createDataKey('local', ['keyAltNames' => ['altname']]);
+
+   $collection = $client->selectCollection('test', 'coll');
+   $collection->drop(); // clear old data
+
+   // Reference the encryption key we created earlier by its alternative name
+   $encryptionOpts = [
+       'keyAltName' => 'altname',
+       'algorithm' => ClientEncryption::AEAD_AES_256_CBC_HMAC_SHA_512_DETERMINISTIC,
+   ];
+   $encryptedValue = $clientEncryption->encrypt('123456789', $encryptionOpts);
+
+   $collection->insertOne(['encryptedField' => $encryptedValue]);
+
+   $document = $collection->findOne();
+   var_dump($clientEncryption->decrypt($document->encryptedField));
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/tutorial/collation.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/tutorial/collation.txt
new file mode 100644
index 0000000000000000000000000000000000000000..0b1bfabd9fd6602f3823184c5789b7fae5b414d4
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/tutorial/collation.txt	
@@ -0,0 +1,373 @@
+=========
+Collation
+=========
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 2
+   :class: singlecol
+
+.. versionadded:: 1.1
+
+Overview
+--------
+
+MongoDB 3.4 introduced support for :manual:`collations
+</manual/reference/collation/>`, which provide a set of rules to comply with the
+conventions of a particular language when comparing strings.
+
+For example, in Canadian French, the last accent in a given word determines the
+sorting order. Consider the following French words:
+
+.. code-block:: none
+
+   cote < coté < côte < côté
+
+The sort order using the Canadian French collation would result in the
+following:
+
+.. code-block:: none
+
+   cote < côte < coté < côté
+
+If collation is unspecified, MongoDB uses simple binary comparison for strings.
+As such, the sort order of the words would be:
+
+.. code-block:: none
+
+    cote < coté < côte < côté
+
+Usage
+-----
+
+You can specify a default collation for collections and indexes when they are
+created, or specify a collation for CRUD operations and aggregations. For
+operations that support collation, MongoDB uses the collection's default
+collation unless the operation specifies a different collation.
+
+Collation Parameters
+~~~~~~~~~~~~~~~~~~~~
+
+.. code-block:: php
+
+   'collation' => [
+       'locale' => <string>,
+       'caseLevel' => <boolean>,
+       'caseFirst' => <string>,
+       'strength' => <integer>,
+       'numericOrdering' => <boolean>,
+       'alternate' => <string>,
+       'maxVariable' => <string>,
+       'normalization' => <boolean>,
+       'backwards' => <boolean>,
+   ]
+
+The only required parameter is ``locale``, which the server parses as an `ICU
+format locale ID <http://userguide.icu-project.org/locale>`_. For example, set
+``locale`` to ``en_US`` to represent US English or ``fr_CA`` to represent
+Canadian French.
+
+For a complete description of the available parameters, see :manual:`Collation
+Document </reference/collation/#collation-document>` in the MongoDB manual.
+
+Assign a Default Collation to a Collection
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The following example creates a new collection called ``contacts`` on the
+``test`` database and assigns a default collation with the ``fr_CA`` locale.
+Specifying a collation when you create the collection ensures that all
+operations involving a query that are run against the ``contacts`` collection
+use the ``fr_CA`` collation, unless the query specifies another collation. Any
+indexes on the new collection also inherit the default collation, unless the
+creation command specifies another collation.
+
+.. code-block:: php
+
+   <?php
+
+   $database = (new MongoDB\Client)->test;
+
+   $database->createCollection('contacts', [
+       'collation' => ['locale' => 'fr_CA'],
+   ]);
+
+Assign a Collation to an Index
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+To specify a collation for an index, use the ``collation`` option when you
+create the index.
+
+The following example creates an index on the ``name`` field of the
+``address_book`` collection, with the ``unique`` parameter enabled and a default
+collation with ``locale`` set to ``en_US``.
+
+.. code-block:: php
+
+   <?php
+
+   $collection = (new MongoDB\Client)->test->address_book;
+
+   $collection->createIndex(
+       ['first_name' => 1],
+       [
+           'collation' => ['locale' => 'en_US'],
+           'unique' => true,
+       ]
+   );
+
+To use this index, make sure your queries also specify the same collation. The
+following query uses the above index:
+
+.. code-block:: php
+
+   <?php
+
+   $collection = (new MongoDB\Client)->test->address_book;
+
+   $cursor = $collection->find(
+       ['first_name' => 'Adam'],
+       [
+           'collation' => ['locale' => 'en_US'],
+       ]
+   );
+
+The following queries do **NOT** use the index. The first query uses no
+collation, and the second uses a collation with a different ``strength`` value
+than the collation on the index.
+
+.. code-block:: php
+
+   <?php
+
+   $collection = (new MongoDB\Client)->test->address_book;
+
+   $cursor1 = $collection->find(['first_name' => 'Adam']);
+
+   $cursor2 = $collection->find(
+       ['first_name' => 'Adam'],
+       [
+           'collation' => [
+               'locale' => 'en_US',
+               'strength' => 2,
+           ],
+       ]
+   );
+
+Operations that Support Collation
+---------------------------------
+
+All reading, updating, and deleting methods support collation. Some examples are
+listed below.
+
+``find()`` with ``sort``
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+Individual queries can specify a collation to use when matching and sorting
+results. The following query and sort operation uses a German collation with the
+``locale`` parameter set to ``de``.
+
+.. code-block:: php
+
+   <?php
+
+   $collection = (new MongoDB\Client)->test->contacts;
+
+   $cursor = $collection->find(
+       ['city' => 'New York'],
+       [
+           'collation' => ['locale' => 'de'],
+           'sort' => ['name' => 1],
+       ]
+   );
+
+``findOneAndUpdate()``
+~~~~~~~~~~~~~~~~~~~~~~
+
+A collection called ``names`` contains the following documents:
+
+.. code-block:: javascript
+
+   { "_id" : 1, "first_name" : "Hans" }
+   { "_id" : 2, "first_name" : "Gunter" }
+   { "_id" : 3, "first_name" : "Günter" }
+   { "_id" : 4, "first_name" : "Jürgen" }
+
+The following :phpmethod:`findOneAndUpdate()
+<MongoDB\\Collection::findOneAndUpdate>` operation on the collection does not
+specify a collation.
+
+.. code-block:: php
+
+   <?php
+
+   $collection = (new MongoDB\Client)->test->names;
+
+   $document = $collection->findOneAndUpdate(
+       ['first_name' => ['$lt' =-> 'Gunter']],
+       ['$set' => ['verified' => true]]
+   );
+
+Because ``Gunter`` is lexically first in the collection, the above operation
+returns no results and updates no documents.
+
+Consider the same :phpmethod:`findOneAndUpdate()
+<MongoDB\\Collection::findOneAndUpdate>` operation but with a collation
+specified, which uses the locale ``de@collation=phonebook``.
+
+.. note::
+
+   Some locales have a ``collation=phonebook`` option available for use with
+   languages which sort proper nouns differently from other words. According to
+   the ``de@collation=phonebook`` collation, characters with umlauts come before
+   the same characters without umlauts.
+
+.. code-block:: php
+
+   <?php
+
+   $collection = (new MongoDB\Client)->test->names;
+
+   $document = $collection->findOneAndUpdate(
+       ['first_name' => ['$lt' =-> 'Gunter']],
+       ['$set' => ['verified' => true]],
+       [
+           'collation' => ['locale' => 'de@collation=phonebook'],
+           'returnDocument' => MongoDB\Operation\FindOneAndUpdate::RETURN_DOCUMENT_AFTER,
+       ]
+   );
+
+The operation returns the following updated document:
+
+.. code-block:: javascript
+
+   { "_id" => 3, "first_name" => "Günter", "verified" => true }
+
+``findOneAndDelete()``
+~~~~~~~~~~~~~~~~~~~~~~
+
+Set the ``numericOrdering`` collation parameter to ``true`` to compare numeric
+strings by their numeric values.
+
+The collection ``numbers`` contains the following documents:
+
+.. code-block:: javascript
+
+   { "_id" : 1, "a" : "16" }
+   { "_id" : 2, "a" : "84" }
+   { "_id" : 3, "a" : "179" }
+
+The following example matches the first document in which field ``a`` has a
+numeric value greater than 100 and deletes it.
+
+.. code-block:: php
+
+   <?php
+
+   $collection = (new MongoDB\Client)->test->numbers;
+
+   $document = $collection->findOneAndDelete(
+       ['a' => ['$gt' =-> '100']],
+       [
+           'collation' => [
+               'locale' => 'en',
+               'numericOrdering' => true,
+           ],
+       ]
+   );
+
+After the above operation, the following documents remain in the collection:
+
+.. code-block:: javascript
+
+   { "_id" : 1, "a" : "16" }
+   { "_id" : 2, "a" : "84" }
+
+If you perform the same operation without collation, the server deletes the
+first document it finds in which the lexical value of ``a`` is greater than
+``"100"``.
+
+.. code-block:: php
+
+   <?php
+
+   $collection = (new MongoDB\Client)->test->numbers;
+
+   $document = $collection->findOneAndDelete(['a' => ['$gt' =-> '100']]);
+
+After the above operation is executed, the document in which ``a`` was equal to
+``"16"`` has been deleted, and the following documents remain in the collection:
+
+.. code-block:: javascript
+
+   { "_id" : 2, "a" : "84" }
+   { "_id" : 3, "a" : "179" }
+
+``deleteMany()``
+~~~~~~~~~~~~~~~~
+
+You can use collations with all the various CRUD operations which exist in the
+|php-library|.
+
+The collection ``recipes`` contains the following documents:
+
+.. code-block:: javascript
+
+   { "_id" : 1, "dish" : "veggie empanadas", "cuisine" : "Spanish" }
+   { "_id" : 2, "dish" : "beef bourgignon", "cuisine" : "French" }
+   { "_id" : 3, "dish" : "chicken molé", "cuisine" : "Mexican" }
+   { "_id" : 4, "dish" : "chicken paillard", "cuisine" : "french" }
+   { "_id" : 5, "dish" : "pozole verde", "cuisine" : "Mexican" }
+
+Setting the ``strength`` parameter of the collation document to ``1`` or ``2``
+causes the server to disregard case in the query filter. The following example
+uses a case-insensitive query filter to delete all records in which the
+``cuisine`` field matches ``French``.
+
+.. code-block:: php
+
+   <?php
+
+   $collection = (new MongoDB\Client)->test->recipes;
+
+   $collection->deleteMany(
+       ['cuisine' => 'French'],
+       [
+           'collation' => [
+               'locale' => 'en_US',
+               'strength' => 1,
+           ],
+       ]
+   );
+
+After the above operation runs, the documents with ``_id`` values of ``2`` and
+``4`` are deleted from the collection.
+
+Aggregation
+~~~~~~~~~~~
+
+To use collation with an :phpmethod:`aggregate()
+<MongoDB\\Collection::aggregate>` operation, specify a collation in the
+aggregation options.
+
+The following aggregation example uses a collection called ``names`` and groups
+the ``first_name`` field together, counts the total number of results in each
+group, and sorts the results by German phonebook order.
+
+.. code-block:: php
+
+   <?php
+
+   $collection = (new MongoDB\Client)->test->names;
+
+   $cursor = $collection->aggregate(
+       [
+           ['$group' => ['_id' => '$first_name', 'name_count' => ['$sum' => 1]]],
+           ['$sort' => ['_id' => 1]],
+       ],
+       [
+           'collation' => ['locale' => 'de@collation=phonebook'],
+       ]
+   );
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/tutorial/commands.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/tutorial/commands.txt
new file mode 100644
index 0000000000000000000000000000000000000000..88ce5ec9a5a8cb98198e02c98460a14ea4aa90fb
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/tutorial/commands.txt	
@@ -0,0 +1,325 @@
+=========================
+Execute Database Commands
+=========================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 2
+   :class: singlecol
+
+Overview
+--------
+
+The |php-library| provides helper methods across the :phpclass:`Client
+<MongoDB\\Client>`, :phpclass:`Database <MongoDB\\Database>`, and
+:phpclass:`Collection <MongoDB\\Collection>` classes for common
+:manual:`database commands </reference/command>`. In addition, the
+:phpmethod:`MongoDB\\Database::command()` method may be used to run database
+commands that do not have a helper method.
+
+Execute Database Commands
+-------------------------
+
+Basic Command
+~~~~~~~~~~~~~
+
+To execute a command on a :program:`mongod` instance, use the
+:phpmethod:`MongoDB\\Database::command()` method. For instance, the following
+operation uses the :manual:`geoNear </reference/command/geoNear>` command to
+search for the three closest documents to longitude ``-74`` and latitude ``40``
+in the ``restos`` collection in the ``test`` database:
+
+.. code-block:: php
+
+   <?php
+
+   $database = (new MongoDB\Client)->test;
+
+   $cursor = $database->command([
+       'geoNear' => 'restos',
+       'near' => [
+           'type' => 'Point',
+           'coordinates' => [-74.0, 40.0],
+       ],
+       'spherical' => 'true',
+       'num' => 3,
+   ]);
+
+   $results = $cursor->toArray()[0];
+
+   var_dump($results);
+
+The output would then resemble::
+
+   object(MongoDB\Model\BSONDocument)#27 (1) {
+     ["storage":"ArrayObject":private]=>
+     array(4) {
+       ["waitedMS"]=>
+       int(0)
+       ["results"]=>
+       object(MongoDB\Model\BSONArray)#25 (1) {
+         ["storage":"ArrayObject":private]=>
+         array(3) {
+           [0]=>
+           object(MongoDB\Model\BSONDocument)#14 (1) {
+             ["storage":"ArrayObject":private]=>
+             array(2) {
+               ["dis"]=>
+               float(39463.618389163)
+               ["obj"]=>
+               object(MongoDB\Model\BSONDocument)#13 (1) {
+                 ["storage":"ArrayObject":private]=>
+                 array(3) {
+                   ["_id"]=>
+                   object(MongoDB\BSON\ObjectId)#3 (1) {
+                     ["oid"]=>
+                     string(24) "55cba2486c522cafdb059bed"
+                   }
+                   ["location"]=>
+                   object(MongoDB\Model\BSONDocument)#12 (1) {
+                     ["storage":"ArrayObject":private]=>
+                     array(2) {
+                       ["coordinates"]=>
+                       object(MongoDB\Model\BSONArray)#11 (1) {
+                         ["storage":"ArrayObject":private]=>
+                         array(2) {
+                           [0]=>
+                           float(-74.1641319)
+                           [1]=>
+                           float(39.6686512)
+                         }
+                       }
+                       ["type"]=>
+                       string(5) "Point"
+                     }
+                   }
+                   ["name"]=>
+                   string(32) "Soul Food Kitchen Seafood Heaven"
+                 }
+               }
+             }
+           }
+           [1]=>
+           object(MongoDB\Model\BSONDocument)#19 (1) {
+             ["storage":"ArrayObject":private]=>
+             array(2) {
+               ["dis"]=>
+               float(50686.851650416)
+               ["obj"]=>
+               object(MongoDB\Model\BSONDocument)#18 (1) {
+                 ["storage":"ArrayObject":private]=>
+                 array(3) {
+                   ["_id"]=>
+                   object(MongoDB\BSON\ObjectId)#15 (1) {
+                     ["oid"]=>
+                     string(24) "55cba2476c522cafdb0544df"
+                   }
+                   ["location"]=>
+                   object(MongoDB\Model\BSONDocument)#17 (1) {
+                     ["storage":"ArrayObject":private]=>
+                     array(2) {
+                       ["coordinates"]=>
+                       object(MongoDB\Model\BSONArray)#16 (1) {
+                         ["storage":"ArrayObject":private]=>
+                         array(2) {
+                           [0]=>
+                           float(-74.2566332)
+                           [1]=>
+                           float(40.4109872)
+                         }
+                       }
+                       ["type"]=>
+                       string(5) "Point"
+                     }
+                   }
+                   ["name"]=>
+                   string(20) "Seguine Bagel Bakery"
+                 }
+               }
+             }
+           }
+           [2]=>
+           object(MongoDB\Model\BSONDocument)#24 (1) {
+             ["storage":"ArrayObject":private]=>
+             array(2) {
+               ["dis"]=>
+               float(58398.379630263)
+               ["obj"]=>
+               object(MongoDB\Model\BSONDocument)#23 (1) {
+                 ["storage":"ArrayObject":private]=>
+                 array(3) {
+                   ["_id"]=>
+                   object(MongoDB\BSON\ObjectId)#20 (1) {
+                     ["oid"]=>
+                     string(24) "55cba2476c522cafdb053c92"
+                   }
+                   ["location"]=>
+                   object(MongoDB\Model\BSONDocument)#22 (1) {
+                     ["storage":"ArrayObject":private]=>
+                     array(2) {
+                       ["coordinates"]=>
+                       object(MongoDB\Model\BSONArray)#21 (1) {
+                         ["storage":"ArrayObject":private]=>
+                         array(2) {
+                           [0]=>
+                           float(-74.3731727)
+                           [1]=>
+                           float(40.4404759)
+                         }
+                       }
+                       ["type"]=>
+                       string(5) "Point"
+                     }
+                   }
+                   ["name"]=>
+                   string(17) "Water'S Edge Club"
+                 }
+               }
+             }
+           }
+         }
+       }
+       ["stats"]=>
+       object(MongoDB\Model\BSONDocument)#26 (1) {
+         ["storage":"ArrayObject":private]=>
+         array(5) {
+           ["nscanned"]=>
+           int(25139)
+           ["objectsLoaded"]=>
+           int(25134)
+           ["avgDistance"]=>
+           float(49516.283223281)
+           ["maxDistance"]=>
+           float(58398.379630263)
+           ["time"]=>
+           int(126)
+         }
+       }
+       ["ok"]=>
+       float(1)
+     }
+   }
+
+Commands with Custom Read Preference
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Some commands, such as :manual:`createUser </reference/command/createUser>`, may
+only be executed on a :term:`primary` replica set member or a
+:term:`standalone`.
+
+The command helper methods in the |php-library|, such as
+:phpmethod:`MongoDB\\Database::drop()`, know to apply their own :term:`read
+preference` if necessary. However, the :phpmethod:`MongoDB\\Database::command()`
+method is a generic method and defaults to the read preference of the Database
+object on which it is invoked. To execute commands that require a specific read
+preference, specify the read preference in the ``$options`` parameter of the
+method.
+
+The following example adds a user to the ``test`` database and specifies a
+custom read preference:
+
+.. code-block:: php
+
+   <?php
+
+   $db = (new MongoDB\Client)->test;
+
+   $cursor = $db->command(
+       [
+           'createUser' => 'username',
+           'pwd' => 'password',
+           'roles' => ['readWrite'],
+       ],
+       [
+           'readPreference' => new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_PRIMARY),
+       ]
+   );
+
+   var_dump($cursor->toArray()[0]);
+
+The output would then resemble::
+
+   object(MongoDB\Model\BSONDocument)#8 (1) {
+     ["storage":"ArrayObject":private]=>
+     array(1) {
+       ["ok"]=>
+       float(1)
+     }
+   }
+
+View Command Results
+--------------------
+
+View Single Result Documents
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The :phpmethod:`MongoDB\\Database::command()` method returns a
+:php:`MongoDB\\Driver\\Cursor <mongodb-driver-cursor>` object.
+
+Many MongoDB commands return their responses as a single document. To read the
+command response, you may either iterate on the cursor and access the first
+document, or access the first result in the array, as in the following:
+
+.. code-block:: php
+
+   <?php
+
+   $database = (new MongoDB\Client)->test;
+
+   $cursor = $database->command(['ping' => 1]);
+
+   var_dump($cursor->toArray()[0]);
+
+The output would then resemble::
+
+   object(MongoDB\Model\BSONDocument)#2 (1) {
+     ["storage":"ArrayObject":private]=>
+     array(1) {
+       ["ok"]=>
+       float(1)
+     }
+   }
+
+Iterate Results from a Cursor
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Some commands, such as :manual:`listCollections
+</reference/command/listCollections>`, return their results via an iterable
+cursor. To view the results, iterate through the cursor.
+
+The following example lists the collections in the ``test`` database by
+iterating through the cursor returned by the ``listCollections`` command using a
+``foreach`` loop:
+
+.. code-block:: php
+
+   <?php
+
+   $database = (new MongoDB\Client)->test;
+
+   $cursor = $database->command(['listCollections' => 1]);
+
+   foreach ($cursor as $collection) {
+       echo $collection['name'], "\n";
+   }
+
+The output would then be a list of the values for the ``name`` key, for
+instance::
+
+   persons
+   posts
+   zips
+
+.. note::
+
+   At the *protocol* level, commands that support a cursor return a single
+   result document with the essential ingredients for constructing the command
+   cursor (i.e. the cursor's ID, namespace, and the first batch of results). In
+   the PHP driver implementation, the
+   :php:`MongoDB\Driver\Manager::executeCommand()
+   <mongodb-driver-manager.executecommand>` method detects such a result and
+   constructs the iterable command cursor, which is returned rather than the
+   base result document.
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/tutorial/crud.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/tutorial/crud.txt
new file mode 100644
index 0000000000000000000000000000000000000000..1e9f95e2e69b4130ebaa6b6180f5cc6abe0c7880
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/tutorial/crud.txt	
@@ -0,0 +1,746 @@
+===============
+CRUD Operations
+===============
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 2
+   :class: singlecol
+
+
+CRUD operations *create*, *read*, *update*, and *delete* documents. The
+|php-library|'s :phpclass:`MongoDB\\Collection` class implements MongoDB's
+cross-driver `CRUD specification
+<https://github.com/mongodb/specifications/blob/master/source/crud/crud.rst>`_,
+providing access to methods for inserting, finding, updating, and deleting
+documents in MongoDB.
+
+This document provides a general introduction to inserting, querying, updating,
+and deleting documents using the |php-library|. The MongoDB Manual's
+:manual:`CRUD Section </crud>` provides a more thorough introduction to CRUD
+operations with MongoDB.
+
+Insert Documents
+----------------
+
+Insert One Document
+~~~~~~~~~~~~~~~~~~~
+
+The :phpmethod:`MongoDB\\Collection::insertOne()` method inserts a single
+document into MongoDB and returns an instance of
+:phpclass:`MongoDB\\InsertOneResult`, which you can use to access the ID of the
+inserted document.
+
+.. this uses the insertOne example from the method reference:
+
+.. include:: /reference/method/MongoDBCollection-insertOne.txt
+   :start-after: start-crud-include
+   :end-before: end-crud-include
+
+The output includes the ID of the inserted document.
+
+If you include an ``_id`` value when inserting a document, MongoDB checks to
+ensure that the ``_id`` value is unique for the collection. If the ``_id`` value
+is not unique, the insert operation fails due to a duplicate key error.
+
+The following example inserts a document while specifying the value for the
+``_id``:
+
+.. code-block:: php
+
+   <?php
+
+   $collection = (new MongoDB\Client)->test->users;
+
+   $insertOneResult = $collection->insertOne(['_id' => 1, 'name' => 'Alice']);
+
+   printf("Inserted %d document(s)\n", $insertOneResult->getInsertedCount());
+
+   var_dump($insertOneResult->getInsertedId());
+
+The output would then resemble::
+
+   Inserted 1 document(s)
+   int(1)
+
+.. seealso:: :phpmethod:`MongoDB\\Collection::insertOne()`
+
+Insert Many Documents
+~~~~~~~~~~~~~~~~~~~~~
+
+The :phpmethod:`MongoDB\\Collection::insertMany()` method allows you to insert
+multiple documents in one write operation and returns an instance of
+:phpclass:`MongoDB\\InsertManyResult`, which you can use to access the IDs of
+the inserted documents.
+
+.. this uses the insertMany example from the method reference:
+
+.. include:: /reference/method/MongoDBCollection-insertMany.txt
+   :start-after: start-crud-include
+   :end-before: end-crud-include
+
+.. seealso:: :phpmethod:`MongoDB\\Collection::insertMany()`
+
+Query Documents
+---------------
+
+The |php-library| provides the :phpmethod:`MongoDB\\Collection::findOne()` and
+:phpmethod:`MongoDB\\Collection::find()` methods for querying documents and the
+:phpmethod:`MongoDB\\Collection::aggregate()` method for performing
+:manual:`aggregation operations </core/aggregation-pipeline>`.
+
+.. include:: /includes/extracts/note-bson-comparison.rst
+
+Find One Document
+~~~~~~~~~~~~~~~~~
+
+:phpmethod:`MongoDB\\Collection::findOne()` returns the :term:`first document
+<natural order>` that matches the query or ``null`` if no document matches the
+query.
+
+The following example searches for the document with ``_id`` of ``"94301"``:
+
+.. code-block:: php
+
+   <?php
+
+   $collection = (new MongoDB\Client)->test->zips;
+
+   $document = $collection->findOne(['_id' => '94301']);
+
+   var_dump($document);
+
+The output would then resemble::
+
+   object(MongoDB\Model\BSONDocument)#13 (1) {
+     ["storage":"ArrayObject":private]=>
+     array(5) {
+       ["_id"]=>
+       string(5) "94301"
+       ["city"]=>
+       string(9) "PALO ALTO"
+       ["loc"]=>
+       object(MongoDB\Model\BSONArray)#12 (1) {
+         ["storage":"ArrayObject":private]=>
+         array(2) {
+           [0]=>
+           float(-122.149685)
+           [1]=>
+           float(37.444324)
+         }
+       }
+       ["pop"]=>
+       int(15965)
+       ["state"]=>
+       string(2) "CA"
+     }
+   }
+
+.. note::
+
+   The criteria in this example matched an ``_id`` with a string value of
+   ``"94301"``. The same criteria would not have matched a document with an
+   integer value of ``94301`` due to MongoDB's :manual:`comparison rules for
+   BSON types </reference/bson-type-comparison-order>`. Similarly, users should
+   use a :php:`MongoDB\\BSON\\ObjectId <class.mongodb-bson-objectid>` object
+   when matching an ``_id`` with an :manual:`ObjectId </reference/object-id/>`
+   value, as strings and ObjectIds are not directly comparable.
+
+.. seealso:: :phpmethod:`MongoDB\\Collection::findOne()`
+
+.. _php-find-many-documents:
+
+Find Many Documents
+~~~~~~~~~~~~~~~~~~~
+
+:phpmethod:`MongoDB\\Collection::find()` returns a
+:php:`MongoDB\\Driver\\Cursor <mongodb-driver-cursor>` object, which you can
+iterate upon to access all matched documents.
+
+The following example lists the documents in the ``zips`` collection with the
+specified city and state values:
+
+.. code-block:: php
+
+   <?php
+
+   $collection = (new MongoDB\Client)->test->zips;
+
+   $cursor = $collection->find(['city' => 'JERSEY CITY', 'state' => 'NJ']);
+
+   foreach ($cursor as $document) {
+       echo $document['_id'], "\n";
+   }
+
+The output would resemble::
+
+   07302
+   07304
+   07305
+   07306
+   07307
+   07310
+
+.. seealso:: :phpmethod:`MongoDB\\Collection::find()`
+
+.. _php-query-projection:
+
+Query Projection
+~~~~~~~~~~~~~~~~
+
+By default, queries in MongoDB return all fields in matching documents. To limit
+the amount of data that MongoDB sends to applications, you can include a
+:manual:`projection document </tutorial/project-fields-from-query-results>` in
+the query operation.
+
+.. note::
+
+   MongoDB includes the ``_id`` field by default unless you explicitly exclude
+   it in a projection document.
+
+The following example finds restaurants based on the ``cuisine`` and ``borough``
+fields and uses a :manual:`projection
+</tutorial/project-fields-from-query-results>` to limit the fields that are
+returned. It also limits the results to 5 documents.
+
+.. code-block:: php
+
+   <?php
+
+   $collection = (new MongoDB\Client)->test->restaurants;
+
+   $cursor = $collection->find(
+       [
+           'cuisine' => 'Italian',
+           'borough' => 'Manhattan',
+       ],
+       [
+           'projection' => [
+               'name' => 1,
+               'borough' => 1,
+               'cuisine' => 1,
+           ],
+           'limit' => 4,
+       ]
+   );
+
+   foreach($cursor as $restaurant) {
+      var_dump($restaurant);
+   };
+
+The output would then resemble::
+
+   object(MongoDB\Model\BSONDocument)#10 (1) {
+     ["storage":"ArrayObject":private]=>
+     array(4) {
+       ["_id"]=>
+       object(MongoDB\BSON\ObjectId)#8 (1) {
+         ["oid"]=>
+         string(24) "576023c6b02fa9281da3f983"
+       }
+       ["borough"]=>
+       string(9) "Manhattan"
+       ["cuisine"]=>
+       string(7) "Italian"
+       ["name"]=>
+       string(23) "Isle Of Capri Resturant"
+     }
+   }
+   object(MongoDB\Model\BSONDocument)#13 (1) {
+     ["storage":"ArrayObject":private]=>
+     array(4) {
+       ["_id"]=>
+       object(MongoDB\BSON\ObjectId)#12 (1) {
+         ["oid"]=>
+         string(24) "576023c6b02fa9281da3f98d"
+       }
+       ["borough"]=>
+       string(9) "Manhattan"
+       ["cuisine"]=>
+       string(7) "Italian"
+       ["name"]=>
+       string(18) "Marchis Restaurant"
+     }
+   }
+   object(MongoDB\Model\BSONDocument)#8 (1) {
+     ["storage":"ArrayObject":private]=>
+     array(4) {
+       ["_id"]=>
+       object(MongoDB\BSON\ObjectId)#10 (1) {
+         ["oid"]=>
+         string(24) "576023c6b02fa9281da3f99b"
+       }
+       ["borough"]=>
+       string(9) "Manhattan"
+       ["cuisine"]=>
+       string(7) "Italian"
+       ["name"]=>
+       string(19) "Forlinis Restaurant"
+     }
+   }
+   object(MongoDB\Model\BSONDocument)#12 (1) {
+     ["storage":"ArrayObject":private]=>
+     array(4) {
+       ["_id"]=>
+       object(MongoDB\BSON\ObjectId)#13 (1) {
+         ["oid"]=>
+         string(24) "576023c6b02fa9281da3f9a8"
+       }
+       ["borough"]=>
+       string(9) "Manhattan"
+       ["cuisine"]=>
+       string(7) "Italian"
+       ["name"]=>
+       string(22) "Angelo Of Mulberry St."
+     }
+   }
+
+Limit, Sort, and Skip Options
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+In addition to :ref:`projection criteria <php-query-projection>`, you can
+specify options to limit, sort, and skip documents during queries.
+
+The following example uses the ``limit`` and ``sort`` options to query for the
+five most populous zip codes in the United States:
+
+.. code-block:: php
+
+   <?php
+
+   $collection = (new MongoDB\Client)->test->zips;
+
+   $cursor = $collection->find(
+       [],
+       [
+           'limit' => 5,
+           'sort' => ['pop' => -1],
+       ]
+   );
+
+   foreach ($cursor as $document) {
+       printf("%s: %s, %s\n", $document['_id'], $document['city'], $document['state']);
+   }
+
+The output would then resemble::
+
+   60623: CHICAGO, IL
+   11226: BROOKLYN, NY
+   10021: NEW YORK, NY
+   10025: NEW YORK, NY
+   90201: BELL GARDENS, CA
+
+Regular Expressions
+~~~~~~~~~~~~~~~~~~~
+
+Filter criteria may include regular expressions, either by using the
+:php:`MongoDB\\BSON\\Regex <mongodb-bson-regex>` class directory or the
+:query:`$regex` operator.
+
+The following example lists documents in the ``zips`` collection where the city
+name starts with "garden" and the state is Texas:
+
+.. code-block:: php
+
+   <?php
+
+   $collection = (new MongoDB\Client)->test->zips;
+
+   $cursor = $collection->find([
+       'city' => new MongoDB\BSON\Regex('^garden', 'i'),
+       'state' => 'TX',
+   ]);
+
+   foreach ($cursor as $document) {
+      printf("%s: %s, %s\n", $document['_id'], $document['city'], $document['state']);
+   }
+
+The output would then resemble::
+
+   78266: GARDEN RIDGE, TX
+   79739: GARDEN CITY, TX
+   79758: GARDENDALE, TX
+
+An equivalent filter could be constructed using the :query:`$regex` operator:
+
+.. code-block:: php
+
+   [
+       'city' => ['$regex' => '^garden', '$options' => 'i'],
+       'state' => 'TX',
+   ]
+
+.. seealso:: :manual:`$regex </reference/operator/query/regex>` in the MongoDB manual
+
+Although MongoDB's regular expression syntax is not exactly the same as PHP's
+:php:`PCRE <manual/en/book.pcre.php>` syntax, :php:`preg_quote() <preg_quote>`
+may be used to escape special characters that should be matched as-is. The
+following example finds restaurants whose name starts with "(Library)":
+
+.. code-block:: php
+
+   <?php
+
+   $collection = (new MongoDB\Client)->test->restaurants;
+
+   $cursor = $collection->find([
+       'name' => new MongoDB\BSON\Regex('^' . preg_quote('(Library)')),
+   ]);
+
+.. _php-aggregation:
+
+Complex Queries with Aggregation
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+MongoDB's :manual:`Aggregation Framework </core/aggregation-pipeline>` allows
+you to issue complex queries that filter, transform, and group collection data.
+The |php-library|\'s :phpmethod:`MongoDB\\Collection::aggregate()` method
+returns a :php:`Traversable <traversable>` object, which you can iterate upon to
+access the results of the aggregation operation. Refer to the
+:phpmethod:`MongoDB\\Collection::aggregate()` method's :ref:`behavior
+reference <php-coll-agg-method-behavior>` for more about the method's output.
+
+The following example lists the 5 US states with the most zip codes associated
+with them:
+
+.. code-block:: php
+
+   <?php
+
+   $collection = (new MongoDB\Client)->test->zips;
+
+   $cursor = $collection->aggregate([
+       ['$group' => ['_id' => '$state', 'count' => ['$sum' => 1]]],
+       ['$sort' => ['count' => -1]],
+       ['$limit' => 5],
+   ]);
+
+   foreach ($cursor as $state) {
+       printf("%s has %d zip codes\n", $state['_id'], $state['count']);
+   }
+
+The output would then resemble::
+
+   TX has 1671 zip codes
+   NY has 1595 zip codes
+   CA has 1516 zip codes
+   PA has 1458 zip codes
+   IL has 1237 zip codes
+
+.. seealso:: :phpmethod:`MongoDB\\Collection::aggregate()`
+
+Update Documents
+----------------
+
+Update One Document
+~~~~~~~~~~~~~~~~~~~
+
+Use the :phpmethod:`MongoDB\\Collection::updateOne()` method to update a single
+document matching a filter. :phpmethod:`MongoDB\\Collection::updateOne()`
+returns a :phpclass:`MongoDB\\UpdateResult` object, which you can use to access
+statistics about the update operation.
+
+Update methods have two required parameters: the query filter that identifies
+the document or documents to update, and an update document that specifies what
+updates to perform. The :phpmethod:`MongoDB\\Collection::updateOne()` reference
+describes each parameter in detail.
+
+The following example inserts two documents into an empty ``users`` collection
+in the ``test`` database using the :phpmethod:`MongoDB\\Collection::insertOne()`
+method, and then updates the documents where the value for the ``state`` field
+is ``"ny"`` to include a ``country`` field set to ``"us"``:
+
+.. code-block:: php
+
+   <?php
+
+   $collection = (new MongoDB\Client)->test->users;
+   $collection->drop();
+
+   $collection->insertOne(['name' => 'Bob', 'state' => 'ny']);
+   $collection->insertOne(['name' => 'Alice', 'state' => 'ny']);
+   $updateResult = $collection->updateOne(
+       ['state' => 'ny'],
+       ['$set' => ['country' => 'us']]
+   );
+
+   printf("Matched %d document(s)\n", $updateResult->getMatchedCount());
+   printf("Modified %d document(s)\n", $updateResult->getModifiedCount());
+
+Since the update operation uses the
+:phpmethod:`MongoDB\\Collection::updateOne()` method, which updates the first
+document to match the filter criteria, the results would then resemble::
+
+   Matched 1 document(s)
+   Modified 1 document(s)
+
+It is possible for a document to match the filter but *not be modified* by an
+update, as is the case where the update sets a field's value to its existing
+value, as in this example:
+
+.. code-block:: php
+
+   <?php
+
+   $collection = (new MongoDB\Client)->test->users;
+   $collection->drop();
+
+   $collection->insertOne(['name' => 'Bob', 'state' => 'ny']);
+   $updateResult = $collection->updateOne(
+       ['name' => 'Bob'],
+       ['$set' => ['state' => 'ny']]
+   );
+
+   printf("Matched %d document(s)\n", $updateResult->getMatchedCount());
+   printf("Modified %d document(s)\n", $updateResult->getModifiedCount());
+
+The number of matched documents and the number of *modified* documents would
+therefore not be equal, and the output from the operation would resemble::
+
+   Matched 1 document(s)
+   Modified 0 document(s)
+
+.. seealso::
+
+   - :phpmethod:`MongoDB\\Collection::updateOne()`
+   - :phpmethod:`MongoDB\\Collection::findOneAndUpdate()`
+
+Update Many Documents
+~~~~~~~~~~~~~~~~~~~~~
+
+:phpmethod:`MongoDB\\Collection::updateMany()` updates one or more documents
+matching the filter criteria and returns a :phpclass:`MongoDB\\UpdateResult`
+object, which you can use to access statistics about the update operation.
+
+Update methods have two required parameters: the query filter that identifies
+the document or documents to update, and an update document that specifies what
+updates to perform. The :phpmethod:`MongoDB\\Collection::updateMany()` reference
+describes each parameter in detail.
+
+The following example inserts three documents into an empty ``users`` collection
+in the ``test`` database and then uses the :query:`$set` operator to update the
+documents matching the filter criteria to include the ``country`` field with
+value ``"us"``:
+
+.. code-block:: php
+
+   <?php
+
+   $collection = (new MongoDB\Client)->test->users;
+   $collection->drop();
+
+   $collection->insertOne(['name' => 'Bob', 'state' => 'ny', 'country' => 'us']);
+   $collection->insertOne(['name' => 'Alice', 'state' => 'ny']);
+   $collection->insertOne(['name' => 'Sam', 'state' => 'ny']);
+   $updateResult = $collection->updateMany(
+       ['state' => 'ny'],
+       ['$set' => ['country' => 'us']]
+   );
+
+   printf("Matched %d document(s)\n", $updateResult->getMatchedCount());
+   printf("Modified %d document(s)\n", $updateResult->getModifiedCount());
+
+If an update operation results in no change to a document, such as setting the
+value of the field to its current value, the number of modified documents can be
+less than the number of *matched* documents. Since the update document with
+``name`` of ``"Bob"`` results in no changes to the document, the output of the
+operation therefore resembles::
+
+   Matched 3 document(s)
+   Modified 2 document(s)
+
+.. seealso:: :phpmethod:`MongoDB\\Collection::updateMany()`
+
+Replace Documents
+~~~~~~~~~~~~~~~~~
+
+Replacement operations are similar to update operations, but instead of updating
+a document to include new fields or new field values, a replacement operation
+replaces the entire document with a new document, but retains the original
+document's ``_id`` value.
+
+The :phpmethod:`MongoDB\\Collection::replaceOne()` method replaces a single
+document that matches the filter criteria and returns an instance of
+:phpclass:`MongoDB\\UpdateResult`, which you can use to access statistics about
+the replacement operation.
+
+:phpmethod:`MongoDB\\Collection::replaceOne()` has two required parameters: the
+query filter that identifies the document or documents to replace, and a
+replacement document that will replace the original document in MongoDB. The
+:phpmethod:`MongoDB\\Collection::replaceOne()` reference describes each
+parameter in detail.
+
+.. important:: 
+
+   Replacement operations replace all of the fields in a document except the
+   ``_id`` value. To avoid accidentally overwriting or deleting desired fields,
+   use the :phpmethod:`MongoDB\\Collection::updateOne()` or
+   :phpmethod:`MongoDB\\Collection::updateMany()` methods to update individual
+   fields in a document rather than replacing the entire document.
+
+The following example inserts one document into an empty ``users`` collection in
+the ``test`` database, and then replaces that document with a new one:
+
+.. code-block:: php
+
+   <?php
+
+   $collection = (new MongoDB\Client)->test->users;
+   $collection->drop();
+
+   $collection->insertOne(['name' => 'Bob', 'state' => 'ny']);
+   $updateResult = $collection->replaceOne(
+       ['name' => 'Bob'],
+       ['name' => 'Robert', 'state' => 'ca']
+   );
+
+   printf("Matched %d document(s)\n", $updateResult->getMatchedCount());
+   printf("Modified %d document(s)\n", $updateResult->getModifiedCount());
+
+The output would then resemble::
+
+   Matched 1 document(s)
+   Modified 1 document(s)
+
+.. seealso:: 
+
+   - :phpmethod:`MongoDB\\Collection::replaceOne()`
+   - :phpmethod:`MongoDB\\Collection::findOneAndReplace()`
+
+Upsert
+~~~~~~
+
+Update and replace operations support an :manual:`upsert
+</tutorial/update-documents/#upsert-option>` option. When ``upsert`` is ``true``
+*and* no documents match the specified filter, the operation creates a new
+document and inserts it. If there *are* matching documents, then the operation
+modifies or replaces the matching document or documents.
+
+When a document is upserted, the ID is accessible via
+:phpmethod:`MongoDB\\UpdateResult::getUpsertedId()`.
+
+The following example uses :phpmethod:`MongoDB\\Collection::updateOne()` with
+the ``upsert`` option set to ``true`` and an empty ``users`` collection in the
+``test`` database, therefore inserting the document into the database:
+
+.. code-block:: php
+
+   <?php
+
+   $collection = (new MongoDB\Client)->test->users;
+   $collection->drop();
+
+   $updateResult = $collection->updateOne(
+       ['name' => 'Bob'],
+       ['$set' => ['state' => 'ny']],
+       ['upsert' => true]
+   );
+
+   printf("Matched %d document(s)\n", $updateResult->getMatchedCount());
+   printf("Modified %d document(s)\n", $updateResult->getModifiedCount());
+   printf("Upserted %d document(s)\n", $updateResult->getUpsertedCount());
+
+   $upsertedDocument = $collection->findOne([
+       '_id' => $updateResult->getUpsertedId(),
+   ]);
+
+   var_dump($upsertedDocument);
+
+The output would then resemble::
+
+   Matched 0 document(s)
+   Modified 0 document(s)
+   Upserted 1 document(s)
+   object(MongoDB\Model\BSONDocument)#16 (1) {
+     ["storage":"ArrayObject":private]=>
+     array(3) {
+       ["_id"]=>
+       object(MongoDB\BSON\ObjectId)#15 (1) {
+         ["oid"]=>
+         string(24) "57509c4406d7241dad86e7c3"
+       }
+       ["name"]=>
+       string(3) "Bob"
+       ["state"]=>
+       string(2) "ny"
+     }
+   }
+
+Delete Documents
+----------------
+
+Delete One Document
+~~~~~~~~~~~~~~~~~~~
+
+The :phpmethod:`MongoDB\\Collection::deleteOne()` method deletes a single
+document that matches the filter criteria and returns a
+:phpclass:`MongoDB\\DeleteResult`, which you can use to access statistics about
+the delete operation.
+
+If multiple documents match the filter criteria,
+:phpmethod:`MongoDB\\Collection::deleteOne()` deletes the :term:`first
+<natural order>` matching document.
+
+:phpmethod:`MongoDB\\Collection::deleteOne()` has one required parameter: a
+query filter that specifies the document to delete. Refer to the
+:phpmethod:`MongoDB\\Collection::deleteOne()` reference for full method
+documentation.
+
+The following operation deletes the first document where the ``state`` field's
+value is ``"ny"``:
+
+.. code-block:: php
+
+   <?php
+
+   $collection = (new MongoDB\Client)->test->users;
+   $collection->drop();
+
+   $collection->insertOne(['name' => 'Bob', 'state' => 'ny']);
+   $collection->insertOne(['name' => 'Alice', 'state' => 'ny']);
+   $deleteResult = $collection->deleteOne(['state' => 'ny']);
+
+   printf("Deleted %d document(s)\n", $deleteResult->getDeletedCount());
+
+The output would then resemble::
+
+   Deleted 1 document(s)
+
+.. seealso:: :phpmethod:`MongoDB\\Collection::deleteOne()`
+
+Delete Many Documents
+~~~~~~~~~~~~~~~~~~~~~
+
+:phpmethod:`MongoDB\\Collection::deleteMany()` deletes all of the documents that
+match the filter criteria and returns a :phpclass:`MongoDB\\DeleteResult`, which
+you can use to access statistics about the delete operation.
+
+:phpmethod:`MongoDB\\Collection::deleteMany()` has one required parameter: a
+query filter that specifies the document to delete. Refer to the
+:phpmethod:`MongoDB\\Collection::deleteMany()` reference for full method
+documentation.
+
+The following operation deletes all of the documents where the ``state`` field's
+value is ``"ny"``:
+
+.. code-block:: php
+
+   <?php
+
+   $collection = (new MongoDB\Client)->test->users;
+   $collection->drop();
+
+   $collection->insertOne(['name' => 'Bob', 'state' => 'ny']);
+   $collection->insertOne(['name' => 'Alice', 'state' => 'ny']);
+   $deleteResult = $collection->deleteMany(['state' => 'ny']);
+
+   printf("Deleted %d document(s)\n", $deleteResult->getDeletedCount());
+
+The output would then resemble::
+
+   Deleted 2 document(s)
+
+.. seealso:: :phpmethod:`MongoDB\\Collection::deleteMany()`
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/tutorial/custom-types.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/tutorial/custom-types.txt
new file mode 100644
index 0000000000000000000000000000000000000000..574604302b154628948ab16c89cf3edf2d17de91
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/tutorial/custom-types.txt	
@@ -0,0 +1,187 @@
+=================
+Custom Data-Types
+=================
+
+.. default-domain:: mongodb
+
+The MongoDB PHP extension and library support custom classes while
+serializing and deserializing. An example of where this might be useful is
+if you want to store date/time information retaining the time zone
+information that PHP's :php:`DateTimeImmutable <class.datetimeimmutable>`
+class stores with a point in time.
+
+The driver serializes PHP variables, including objects, into BSON when it
+communicates to the server, and deserializes BSON back into PHP variables when
+it receives data from the server.
+
+It is possible to influence the behaviour by implementing the
+:php:`MongoDB\\BSON\\Persistable <class.mongodb-bson-persistable>` interface.
+If a class implements this interface, then upon serialization the
+:php:`bsonSerialize <mongodb-bson-serializable.bsonserialize>` method is
+called. This method is responsible for returning an array or stdClass object
+to convert to BSON and store in the database. That data will later be used to
+reconstruct the object upon reading from the database.
+
+As an example we present the ``LocalDateTime`` class. This class wraps around
+the :php:`MongoDB\\BSON\\UTCDateTime <class.mongodb-bson-utcdatetime>` data
+type and a time zone.
+
+.. code-block:: php
+
+    <?php
+    /* Custom document class that stores a UTCDateTime and time zone and also
+     * implements the UTCDateTime interface for portability. */
+    class LocalDateTime implements \MongoDB\BSON\Persistable, \MongoDB\BSON\UTCDateTimeInterface
+    {
+        private $utc;
+        private $tz;
+        public function __construct($milliseconds = null, \DateTimeZone $timezone = null)
+        {
+            $this->utc = new \MongoDB\BSON\UTCDateTime($milliseconds);
+            if ($timezone === null) {
+                $timezone = new \DateTimeZone(date_default_timezone_get());
+            }
+            $this->tz = $timezone;
+        }
+    ?>
+
+As it implements the :php:`MongoDB\\BSON\\Persistable
+<class.mongodb-bson-persistable>` interface, the
+class is required to implement the :php:`bsonSerialize
+<mongodb-bson-serializable.bsonserialize>` and :php:`bsonUnserialize
+<mongodb-bson-unserializable.bsonunserialize>` methods. In the
+:php:`bsonSerialize <mongodb-bson-serializable.bsonserialize>` method, we
+return an array with the two values that we need to persist: the point in time
+in milliseconds since the Epoch, represented by a
+:php:`MongoDB\\BSON\\UTCDateTime <class.mongodb-bson-utcdatetime>` object, and
+a string containing the Olson time zone identifier:
+
+.. code-block:: php
+
+    <?php
+        public function bsonSerialize()
+        {
+            return [
+                'utc' => $this->utc,
+                'tz' => $this->tz->getName(),
+            ];
+        }
+    ?>
+
+The driver will additionally add a ``__pclass`` field to the document, and
+store that in the database, too. This field contains the PHP class name so that
+upon deserialization the driver knows which class to use for recreating the
+stored object.
+
+When the document is read from the database, the driver detects whether a
+``__pclass`` field is present and then executes
+:php:`MongoDB\\BSON\\Persistable::bsonUnserialize
+<mongodb-bson-unserializable.bsonunserialize>` method which is
+responsible for restoring the object's original state.
+
+In the code below, we make sure that the data in the ``utc`` and ``tz`` fields
+are of the right time, and then assign their values to the two private
+properties.
+
+.. code-block:: php
+
+    <?php
+        public function bsonUnserialize(array $data)
+        {
+            if ( ! isset($data['utc']) || ! $data['utc'] instanceof \MongoDB\BSON\UTCDateTime) {
+                throw new Exception('Expected "utc" field to be a UTCDateTime');
+            }
+
+            if ( ! isset($data['tz']) || ! is_string($data['tz'])) {
+                throw new Exception('Expected "tz" field to be a string');
+            }
+
+            $this->utc = $data['utc'];
+            $this->tz = new \DateTimeZone($data['tz']);
+        }
+    ?>
+
+You may have noticed that the class also implements the
+:php:`MongoDB\\BSON\\UTCDateTimeInterface
+<class.mongodb-bson-utcdatetimeinterface>` interface. This interface defines
+the two non-constructor methods of the :php:`MongoDB\\BSON\\UTCDateTime
+<class.mongodb-bson-utcdatetime>` class.
+
+It is recommended that wrappers around existing BSON classes implement their
+respective interface (i.e. :php:`MongoDB\\BSON\\UTCDateTimeInterface
+<class.mongodb-bson-utcdatetimeinterface>`) so that the wrapper objects can be
+used in the same context as their original unwrapped version. It is also
+recommended that you always type-hint against the interface (i.e.
+:php:`MongoDB\\BSON\\UTCDateTimeInterface
+<class.mongodb-bson-utcdatetimeinterface>`) and never against the concrete
+class (i.e. :php:`MongoDB\\BSON\\UTCDateTime
+<class.mongodb-bson-utcdatetime>`), as this would prevent wrapped objects from
+being accepted into methods.
+
+In our new ``toDateTime`` method we return a :php:`DateTime <class.datetime>`
+object with the local time zone set, instead of the UTC time zone that
+:php:`MongoDB\\BSON\\UTCDateTime <class.mongodb-bson-utcdatetime>` normally uses
+in its return value.
+
+.. code-block:: php
+
+    <?php
+        public function toDateTime()
+        {
+            return $this->utc->toDateTime()->setTimezone($this->tz);
+        }
+
+        public function __toString()
+        {
+            return (string) $this->utc;
+        }
+    }
+    ?>
+
+With the class defined, we can now use it in our documents. The snippet below
+demonstrates the round tripping from the ``LocalDateTime`` object to BSON, and
+back to ``LocalDateTime``.
+
+.. code-block:: php
+
+    <?php
+    $bson = MongoDB\BSON\fromPHP(['date' => new LocalDateTime]);
+    $document = MongoDB\BSON\toPHP($bson);
+
+    var_dump($document);
+    var_dump($document->date->toDateTime());
+    ?>
+
+Which outputs::
+
+    object(stdClass)#1 (1) {
+      ["date"]=>
+      object(LocalDateTime)#2 (2) {
+        ["utc":"LocalDateTime":private]=>
+        object(MongoDB\BSON\UTCDateTime)#3 (1) {
+          ["milliseconds"]=>
+          string(13) "1533042443716"
+        }
+        ["tz":"LocalDateTime":private]=>
+        object(DateTimeZone)#4 (2) {
+          ["timezone_type"]=>
+          int(3)
+          ["timezone"]=>
+          string(13) "Europe/London"
+        }
+      }
+    }
+    object(DateTime)#5 (3) {
+      ["date"]=>
+      string(26) "2018-07-31 14:07:23.716000"
+      ["timezone_type"]=>
+      int(3)
+      ["timezone"]=>
+      string(13) "Europe/London"
+    }
+
+Storing the Olson time zone identifier in a separate field also works well
+with MongoDB's :manual:`Aggregation Framework </aggregation>`, which allows
+date manipulation, :manual:`formatting
+</reference/operator/aggregation/dateToString>`, and querying depending on a
+specific time zone.
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/tutorial/decimal128.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/tutorial/decimal128.txt
new file mode 100644
index 0000000000000000000000000000000000000000..a94d0ea5ef31cf8c0c7d8fe2a650737fb77f6878
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/tutorial/decimal128.txt	
@@ -0,0 +1,124 @@
+==========
+Decimal128
+==========
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 2
+   :class: singlecol
+
+Overview
+--------
+
+MongoDB 3.4 introduced support for a :manual:`Decimal128 BSON type
+</manual/release-notes/3.4/#decimal-type>`, which is a 128-bit decimal-based
+floating-point value capable of emulating decimal rounding with exact precision.
+This functionality is intended for applications that handle :manual:`monetary
+data </tutorial/model-monetary-data>`, such as financial and tax computations.
+
+The :php:`MongoDB\BSON\Decimal128 <mongodb-bson-decimal128>` class, which was
+introduced in :php:`PHP driver <mongodb>` 1.2.0, may be used to work with this
+type in PHP.
+
+Working with Decimal128 Values
+------------------------------
+
+Inserting a Decimal128
+~~~~~~~~~~~~~~~~~~~~~~
+
+The following example inserts a value of type ``Decimal128`` into the ``price``
+field of a collection named ``inventory``:
+
+.. code-block:: php
+
+   <?php
+
+   $collection = (new MongoDB\Client)->test->inventory;
+
+   $collection->insertOne([
+       '_id' => 1,
+       'item' => '26-inch monitor',
+       'price' => new MongoDB\BSON\Decimal128('428.79'),
+   ]);
+
+   $item = $collection->findOne(['_id' => 1]);
+
+   var_dump($item);
+
+The output would then resemble::
+
+   object(MongoDB\Model\BSONDocument)#9 (1) {
+     ["storage":"ArrayObject":private]=>
+     array(3) {
+       ["_id"]=>
+       int(1)
+       ["item"]=>
+       string(15) "26-inch monitor"
+       ["price"]=>
+       object(MongoDB\BSON\Decimal128)#13 (1) {
+         ["dec"]=>
+         string(6) "428.79"
+       }
+     }
+   }
+
+Mathematical Operations with BCMath
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The :php:`PHP driver <mongodb>` does not provide any functionality for working
+with ``Decimal128`` values; however, the string representation of a
+:php:`MongoDB\BSON\Decimal128 <mongodb-bson-decimal128>` object may be used
+with PHP's :php:`BCMath <bcmath>` extension.
+
+The following example adds two ``Decimal128`` values and creates a new
+``Decimal128`` value with the result from :php:`bcadd() <bcadd>`:
+
+.. code-block:: php
+
+   <?php
+
+   $lhs = new MongoDB\BSON\Decimal128('1.234');
+   $rhs = new MongoDB\BSON\Decimal128('5.678');
+   $sum = new MongoDB\BSON\Decimal128(bcadd($lhs, $rhs));
+
+   var_dump($sum);
+
+The output would then resemble::
+
+   object(MongoDB\BSON\Decimal128)#4 (1) {
+     ["dec"]=>
+     string(1) "6"
+   }
+
+This does not match the expected result of "6.912". Each operation in the BCMath
+API uses a scale to determine the number of decimal digits in the result. The
+default scale is zero, which is why the above example produces a result with no
+decimal precision.
+
+In the following example, we use a scale of three for :php:`bcadd() <bcadd>` to
+obtain the expected result:
+
+.. code-block:: php
+
+   <?php
+
+   $lhs = new MongoDB\BSON\Decimal128('1.234');
+   $rhs = new MongoDB\BSON\Decimal128('5.678');
+   $sum = new MongoDB\BSON\Decimal128(bcadd($lhs, $rhs, 3));
+
+   var_dump($sum);
+
+The output would then resemble::
+
+   object(MongoDB\BSON\Decimal128)#4 (1) {
+     ["dec"]=>
+     string(5) "6.912"
+   }
+
+In lieu of specifying a scale for each operation, a default scale may be set via
+:php:`bcscale() <bcscale>` or the :php:`bcmath.scale INI setting
+<manual/en/bc.configuration.php#ini.bcmath.scale>`. The ``Decimal128`` type
+supports up to 34 decimal digits (i.e. significant digits).
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/tutorial/example-data.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/tutorial/example-data.txt
new file mode 100644
index 0000000000000000000000000000000000000000..cf3230952ee6b5cf4ab035f018a1c7171e5bc5f2
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/tutorial/example-data.txt	
@@ -0,0 +1,45 @@
+============
+Example Data
+============
+
+.. default-domain:: mongodb
+
+Some examples in this documentation use example data fixtures from
+`zips.json <https://media.mongodb.org/zips.json>`_ and
+`primer-dataset.json <https://raw.githubusercontent.com/mongodb/docs-assets/primer-dataset/primer-dataset.json>`_.
+
+Importing the dataset into MongoDB can be done in several ways. The following
+example imports the `zips.json` file into a `test.zips` collection:
+:php:`driver <mongodb>` directly:
+
+.. code-block:: php
+
+   <?php
+
+   $filename = 'https://media.mongodb.org/zips.json';
+   $lines = file($filename, FILE_IGNORE_NEW_LINES);
+
+   $bulk = new MongoDB\Driver\BulkWrite;
+
+   foreach ($lines as $line) {
+       $bson = MongoDB\BSON\fromJSON($line);
+       $document = MongoDB\BSON\toPHP($bson);
+       $bulk->insert($document);
+   }
+
+   $manager = new MongoDB\Driver\Manager('mongodb://127.0.0.1/');
+
+   $result = $manager->executeBulkWrite('test.zips', $bulk);
+   printf("Inserted %d documents\n", $result->getInsertedCount());
+
+The output would then resemble::
+
+   Inserted 29353 documents
+
+You may also import the datasets using :manual:`mongoimport
+</reference/program/mongoimport>`, which is included with MongoDB:
+
+.. code-block:: sh
+
+   mongoimport --db test --collection zips --file zips.json --drop
+   mongoimport --db test --collection restaurants --file primer-dataset.json --drop
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/tutorial/gridfs.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/tutorial/gridfs.txt
new file mode 100644
index 0000000000000000000000000000000000000000..ba9b83681ddb296c5c36216e96ee931ce11a4556
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/tutorial/gridfs.txt	
@@ -0,0 +1,214 @@
+======
+GridFS
+======
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 1
+   :class: singlecol
+
+:manual:`GridFS </core/gridfs>` is a specification for storing and retrieving
+files in MongoDB. GridFS uses two collections to store files. One collection
+stores the file chunks (e.g. ``fs.chunks``), and the other stores file metadata
+(e.g. ``fs.files``). The :phpclass:`MongoDB\\GridFS\\Bucket` class provides an
+interface around these collections for working with the files as PHP
+:php:`Streams <stream>`.
+
+Creating a GridFS Bucket
+------------------------
+
+You can construct a GridFS bucket using the PHP extension's
+:php:`MongoDB\\Driver\\Manager <class.mongodb-driver-manager>` class, or select
+a bucket from the |php-library|'s :phpclass:`MongoDB\\Database` class via the
+:phpmethod:`selectGridFSBucket() <MongoDB\\Database::selectGridFSBucket>`
+method.
+
+The bucket can be constructed with various options:
+
+ - ``bucketName`` determines the prefix for the bucket's metadata and chunk
+   collections. The default value is ``"fs"``.
+ - ``chunkSizeBytes`` determines the size of each chunk. GridFS divides the
+   file into chunks of this length, except for the last, which is only as large
+   as needed. The default size is ``261120`` (i.e. 255 KiB).
+ - ``readConcern``, ``readPreference`` and ``writeConcern`` options can be used
+   to specify defaults for read and write operations, much like the
+   :phpclass:`MongoDB\\GridFS\\Collection` options.
+
+Uploading Files with Writable Streams
+-------------------------------------
+
+To upload a file to GridFS using a writable stream, you can either open a stream
+and write to it directly or write the entire contents of another readable stream
+to GridFS all at once.
+
+To open an upload stream and write to it:
+
+.. code-block:: php
+
+   <?php
+
+   $bucket = (new MongoDB\Client)->test->selectGridFSBucket();
+
+   $stream = $bucket->openUploadStream('my-file.txt');
+
+   $contents = file_get_contents('/path/to/my-file.txt');
+   fwrite($stream, $contents);
+   fclose($stream);
+
+To upload the entire contents of a readable stream in one call:
+
+.. code-block:: php
+
+   <?php
+
+   $bucket = (new MongoDB\Client)->test->selectGridFSBucket();
+
+   $file = fopen('/path/to/my-file.txt', 'rb');
+   $bucket->uploadFromStream('my-file.txt', $file);
+
+Downloading Files with Readable Streams
+---------------------------------------
+
+To download a file from GridFS using a readable stream, you can either open a
+stream and read from it directly or download the entire file all at once.
+
+To open a download stream and read from it:
+
+.. code-block:: php
+
+   <?php
+
+   // In practice, $fileId denotes the _id of an existing file in GridFS
+   $fileId = new MongoDB\BSON\ObjectId;
+
+   $bucket = (new MongoDB\Client)->test->selectGridFSBucket();
+
+   $stream = $bucket->openDownloadStream($fileId);
+   $contents = stream_get_contents($stream);
+
+To download the file all at once and write it to a writable stream:
+
+.. code-block:: php
+
+   <?php
+
+   // In practice, $fileId denotes the _id of an existing file in GridFS
+   $fileId = new MongoDB\BSON\ObjectId;
+
+   $bucket = (new MongoDB\Client)->test->selectGridFSBucket();
+
+   $file = fopen('/path/to/my-output-file.txt', 'wb');
+
+   $bucket->downloadToStream($fileId, $file);
+
+Selecting Files by Filename and Revision
+----------------------------------------
+
+You can also download a file specified by filename and (optionally) revision
+number. Revision numbers are used to distinguish between files sharing the same
+``filename`` metadata field, ordered by date of upload (i.e. the ``uploadDate``
+metadata field). The ``revision`` option accepted by
+:phpmethod:`openDownloadStreamByName()
+<MongoDB\\GridFS\\Bucket::openDownloadStreamByName>` and
+:phpmethod:`downloadToStreamByName()
+<MongoDB\\GridFS\\Bucket::downloadToStreamByName>` can be positive or negative.
+
+A positive ``revision`` number may be used to select files in order of the
+oldest upload date. A revision of ``0`` would denote the file with the oldest
+upload date, a revision of ``1`` would denote the second oldest upload, and so
+on.
+
+A negative revision may be used to select files in order of the most recent
+upload date. A revision of ``-1`` would denote a file with the most recent
+upload date, a revision of ``-2`` would denote the second most recent upload,
+and so on. The ``revision`` option defaults to ``-1`` if not specified.
+
+The following example downloads the contents of the oldest version of a
+particular file:
+
+.. code-block:: php
+
+   <?php
+
+   $bucket = (new MongoDB\Client)->test->selectGridFSBucket();
+
+   $stream = $bucket->openDownloadStreamByName('my-file.txt', ['revision' => 0]);
+   $contents = stream_get_contents($stream);
+
+Deleting Files
+--------------
+
+You can delete a GridFS file by its ``_id``.
+
+.. code-block:: php
+
+   <?php
+
+   // In practice, $fileId denotes the _id of an existing file in GridFS
+   $fileId = new MongoDB\BSON\ObjectId;
+
+   $bucket = (new MongoDB\Client)->test->selectGridFSBucket();
+
+   $bucket->delete($fileId);
+
+Finding File Metadata
+---------------------
+
+The :phpmethod:`find() <MongoDB\\GridFS\\Bucket::find>` method allows you to
+retrieve documents from the GridFS files collection, which contain metadata
+about the GridFS files.
+
+.. code-block:: php
+
+   <?php
+
+   $bucket = (new MongoDB\Client)->test->selectGridFSBucket();
+
+   $cursor = $bucket->find(['filename' => 'my-file.txt']);
+
+Accessing File Metadata for an Existing Stream
+----------------------------------------------
+
+The :phpmethod:`getFileDocumentForStream()
+<MongoDB\\GridFS\\Bucket::getFileDocumentForStream>` method may be used to get
+the file document for an existing readable or writable GridFS stream.
+
+.. code-block:: php
+
+   <?php
+
+   // In practice, $fileId denotes the _id of an existing file in GridFS
+   $fileId = new MongoDB\BSON\ObjectId;
+
+   $bucket = (new MongoDB\Client)->test->selectGridFSBucket();
+
+   $stream = $bucket->openDownloadStream($fileId);
+   $metadata = $bucket->getFileDocumentForStream($stream);
+
+.. note::
+
+   Since the file document for a writable stream is not committed to MongoDB
+   until the stream is closed,
+   :phpmethod:`getFileDocumentForStream()
+   <MongoDB\\GridFS\\Bucket::getFileDocumentForStream>` can only return an
+   in-memory document, which will be missing some fields (e.g. ``length``,
+   ``md5``).
+
+The :phpmethod:`getFileIdForStream()
+<MongoDB\\GridFS\\Bucket::getFileIdForStream>` method may be used to get the
+``_id`` for an existing readable or writable GridFS stream. This is a
+convenience for accessing the ``_id`` property of the object returned by
+:phpmethod:`getFileDocumentForStream()
+<MongoDB\\GridFS\\Bucket::getFileDocumentForStream>`.
+
+.. code-block:: php
+
+   <?php
+
+   $bucket = (new MongoDB\Client)->test->selectGridFSBucket();
+
+   $stream = $bucket->openDownloadStreamByName('my-file.txt');
+   $fileId = $bucket->getFileIdForStream($stream);
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/tutorial/indexes.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/tutorial/indexes.txt
new file mode 100644
index 0000000000000000000000000000000000000000..0ffe7bdb988a81558a764eb5e4d54713bb0df63b
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/tutorial/indexes.txt	
@@ -0,0 +1,133 @@
+=======
+Indexes
+=======
+
+.. default-domain:: mongodb
+
+Indexes support the efficient execution of queries in MongoDB. Without indexes,
+MongoDB must perform a *collection scan*, i.e. scan every document in a
+collection, to select those documents that match the query statement. If an
+appropriate index exists for a query, MongoDB can use the index to limit the
+number of documents it must inspect.
+
+The PHP driver supports managing indexes through the
+:phpclass:`MongoDB\\Collection` class, which implements MongoDB's
+cross-driver `Index Management
+<https://github.com/mongodb/specifications/blob/master/source/index-management.rst>`_
+and `Enumerating Indexes
+<https://github.com/mongodb/specifications/blob/master/source/enumerate-indexes.rst>`_
+specifications.
+
+This document provides an introduction to creating, listing, and dropping
+indexes using the |php-library|. The MongoDB Manual's :manual:`Indexes
+</indexes>` reference provides more thorough information about indexing in
+MongoDB.
+
+Create Indexes
+--------------
+
+Create indexes with the :phpmethod:`MongoDB\\Collection::createIndex()` or
+:phpmethod:`MongoDB\\Collection::createIndexes()` methods. Refer to the method
+reference for more details about each method.
+
+The following example creates an ascending index on the ``state`` field using
+the :phpmethod:`createIndex() <MongoDB\\Collection::createIndex>` method:
+
+.. code-block:: php
+
+   <?php
+
+   $collection = (new MongoDB\Client)->test->zips;
+
+   $result = $collection->createIndex(['state' => 1]);
+
+   var_dump($result);
+
+When you create an index, the method returns its name, which is automatically
+generated from its specification. The above example would output something
+similar to::
+
+   string(7) "state_1"
+
+List Indexes
+------------
+
+The :phpmethod:`MongoDB\\Collection::listIndexes()` method provides information
+about the indexes in a collection. The
+:phpmethod:`MongoDB\\Collection::listIndexes()` method returns an iterator of
+:phpclass:`MongoDB\\Model\\IndexInfo` objects, which you can use to view
+information about each index. Refer to the method reference for more details.
+
+The following example lists all indexes in the ``zips`` collection in the
+``test`` database:
+
+.. code-block:: php
+
+   <?php
+
+   $collection = (new MongoDB\Client)->test->zips;
+
+   foreach ($collection->listIndexes() as $indexInfo) {
+       var_dump($indexInfo);
+   }
+
+The output would resemble::
+
+   object(MongoDB\Model\IndexInfo)#10 (4) {
+     ["v"]=>
+     int(1)
+     ["key"]=>
+     array(1) {
+       ["_id"]=>
+       int(1)
+     }
+     ["name"]=>
+     string(4) "_id_"
+     ["ns"]=>
+     string(9) "test.zips"
+   }
+   object(MongoDB\Model\IndexInfo)#13 (4) {
+     ["v"]=>
+     int(1)
+     ["key"]=>
+     array(1) {
+       ["state"]=>
+       int(1)
+     }
+     ["name"]=>
+     string(7) "state_1"
+     ["ns"]=>
+     string(9) "test.zips"
+   }
+
+Drop Indexes
+------------
+
+The :phpmethod:`MongoDB\\Collection::dropIndex()` method lets you drop a single
+index while :phpmethod:`MongoDB\\Collection::dropIndexes()` drops all of the
+indexes on a collection. Refer to the method reference for more details about
+each method.
+
+The following example drops a single index by its name, ``state_1``:
+
+.. code-block:: php
+
+   <?php
+
+   $collection = (new MongoDB\Client)->test->zips;
+
+   $result = $collection->dropIndex('state_1');
+
+   var_dump($result);
+
+The operation's output would resemble::
+
+   object(MongoDB\Model\BSONDocument)#11 (1) {
+     ["storage":"ArrayObject":private]=>
+     array(2) {
+       ["nIndexesWas"]=>
+       int(2)
+       ["ok"]=>
+       float(1)
+     }
+   }
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/tutorial/install-php-library.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/tutorial/install-php-library.txt
new file mode 100644
index 0000000000000000000000000000000000000000..acaa8ed10958786ff1dbd1b9e31ba04e788239ee
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/tutorial/install-php-library.txt	
@@ -0,0 +1,106 @@
+=========================
+Install the |php-library|
+=========================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 2
+   :class: singlecol
+
+The |php-library| is a high-level abstraction for the
+`PHP driver <https://php.net/mongodb>`_ (i.e. ``mongodb`` extension). This page
+will briefly explain how to install both the ``mongodb`` extension and the
+|php-library|.
+
+Installing the Extension
+------------------------
+
+Linux, Unix, and macOS users can either
+:php:`install the extension with PECL <manual/en/mongodb.installation.pecl.php>`
+(recommended) or
+:php:`manually compile from source <manual/en/mongodb.installation.manual.php>`.
+The following command may be used to install the extension with PECL:
+
+.. code-block:: sh
+
+   sudo pecl install mongodb
+
+.. note::
+
+   If the build process for either installation method fails to find a TLS
+   library, check that the development packages (e.g. ``libssl-dev``) and
+   `pkg-config <https://en.wikipedia.org/wiki/Pkg-config>`_ are both installed.
+
+Once the extension is installed, add the following line to your ``php.ini``
+file:
+
+.. code-block:: ini
+
+   extension=mongodb.so
+
+Windows users can download precompiled binaries of the extension from
+`PECL <https://pecl.php.net/package/mongodb>`_. After extracting the
+``php_mongodb.dll`` file to PHP's extension directory, add the following line to
+your ``php.ini`` file:
+
+.. code-block:: ini
+
+   extension=php_mongodb.dll
+
+Windows binaries are available for various combinations of PHP version,
+thread-safety, and architecture. Failure to select the correct binary will
+result in an error attempting to load the extension DLL at runtime. Additional
+considerations for Windows are discussed in the
+:php:`Windows installation documentation <manual/en/mongodb.installation.windows.php>`.
+
+.. note::
+
+   If your system has multiple versions of PHP installed, each version will have
+   its own ``pecl`` command and ``php.ini`` file. Additionally, PHP may also use
+   separate ``php.ini`` files for its web and CLI environments. If the extension
+   has been installed but is not available at runtime, double-check that you
+   have used the correct ``pecl`` command (or binary in the case of Windows) and
+   have modified the appropriate ``php.ini`` file(s).
+
+Installing the Library
+----------------------
+
+The preferred method of installing the |php-library| is with
+`Composer <https://getcomposer.org/>`_ by running the following command from
+your project root:
+
+.. code-block:: sh
+
+   composer require mongodb/mongodb
+
+While not recommended, you may also manually install the library using a source
+archive attached to the
+`GitHub releases <https://github.com/mongodb/mongo-php-library/releases>`_.
+
+Configure Autoloading
+~~~~~~~~~~~~~~~~~~~~~
+
+Once you have installed the library, ensure that your application includes
+Composer's autoloader as in the following example:
+
+.. code-block:: php
+
+   <?php
+
+   require_once __DIR__ . '/vendor/autoload.php';
+
+Refer to Composer's `autoloading documentation
+<https://getcomposer.org/doc/01-basic-usage.md#autoloading>`_ for more
+information about setting up autoloading.
+
+If you installed the library manually from a source archive, you will need to
+manually configure autoloading:
+
+#. Map the top-level ``MongoDB\`` namespace to the ``src/`` directory
+   using your preferred autoloader implementation.
+
+#. Manually require the ``src/functions.php`` file. This is necessary because
+   PHP does not support autoloading for functions.
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/tutorial/tailable-cursor.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/tutorial/tailable-cursor.txt
new file mode 100644
index 0000000000000000000000000000000000000000..c4ff3b0eb52eb16afc344c7b78d8c0908a773f7e
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/tutorial/tailable-cursor.txt	
@@ -0,0 +1,193 @@
+.. _php-tailable-cursor:
+
+=========================
+Tailable Cursor Iteration
+=========================
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 2
+   :class: singlecol
+
+Overview
+--------
+
+When the driver executes a query or command (e.g.
+:manual:`aggregate </reference/command/aggregate>`), results from the operation
+are returned via a :php:`MongoDB\\Driver\\Cursor <class.mongodb-driver-cursor>`
+object. The Cursor class implements PHP's :php:`Traversable <traversable>`
+interface, which allows it to be iterated with ``foreach`` and interface with
+any PHP functions that work with :php:`iterables <types.iterable>`. Similar to
+result objects in other database drivers, cursors in MongoDB only support
+forward iteration, which means they cannot be rewound or used with ``foreach``
+multiple times.
+
+:manual:`Tailable cursors </core/tailable-cursors>` are a special type of
+MongoDB cursor that allows the client to read some results and then wait until
+more documents become available. These cursors are primarily used with
+:manual:`Capped Collections </core/capped-collections>` and
+:manual:`Change Streams </changeStreams>`.
+
+While normal cursors can be iterated once with ``foreach``, that approach will
+not work with tailable cursors. When ``foreach`` is used with a tailable cursor,
+the loop will stop upon reaching the end of the initial result set. Attempting
+to continue iteration on the cursor with a second ``foreach`` would throw an
+exception, since PHP attempts to rewind the cursor.
+
+In order to continuously read from a tailable cursor, we will need to wrap the
+Cursor object with an :php:`IteratorIterator <iteratoriterator>`. This will
+allow us to directly control the cursor's iteration (e.g. call ``next()``),
+avoid inadvertently rewinding the cursor, and decide when to wait for new
+results or stop iteration entirely.
+
+Wrapping a Normal Cursor
+------------------------
+
+Before looking at how a tailable cursor can be wrapped with
+:php:`IteratorIterator <iteratoriterator>`, we'll start by examining how the
+class interacts with a normal cursor.
+
+The following example finds five restaurants and uses ``foreach`` to view the
+results:
+
+.. code-block:: php
+
+   <?php
+
+   $collection = (new MongoDB\Client)->test->restaurants;
+
+   $cursor = $collection->find([], ['limit' => 5]);
+
+   foreach ($cursor as $document) {
+      var_dump($document);
+   }
+
+While this example is quite concise, there is actually quite a bit going on. The
+``foreach`` construct begins by rewinding the iterable (``$cursor`` in this
+case). It then checks if the current position is valid. If the position is not
+valid, the loop ends. Otherwise, the current key and value are accessed
+accordingly and the loop body is executed. Assuming a :php:`break <break>` has
+not occurred, the iterator then advances to the next position, control jumps
+back to the validity check, and the loop continues.
+
+With the inner workings of ``foreach`` under our belt, we can now translate the
+preceding example to use IteratorIterator:
+
+.. code-block:: php
+
+   <?php
+
+   $collection = (new MongoDB\Client)->test->restaurants;
+
+   $cursor = $collection->find([], ['limit' => 5]);
+
+   $iterator = new IteratorIterator($cursor);
+
+   $iterator->rewind();
+
+   while ($iterator->valid()) {
+      $document = $iterator->current();
+      var_dump($document);
+      $iterator->next();
+   }
+
+.. note::
+
+   Calling ``$iterator->next()`` after the ``while`` loop naturally ends would
+   throw an exception, since all results on the cursor have been exhausted.
+
+The purpose of this example is simply to demonstrate the functional equivalence
+between ``foreach`` and manual iteration with PHP's :php:`Iterator <iterator>`
+API. For normal cursors, there is little reason to use IteratorIterator instead
+of a concise ``foreach`` loop.
+
+Wrapping a Tailable Cursor
+--------------------------
+
+In order to demonstrate a tailable cursor in action, we'll need two scripts: a
+"producer" and a "consumer". The producer script will create a new capped
+collection using :phpmethod:`MongoDB\\Database::createCollection()` and proceed
+to insert a new document into that collection each second.
+
+.. code-block:: php
+
+   <?php
+
+   $database = (new MongoDB\Client)->test;
+
+   $database->createCollection('capped', [
+       'capped' => true,
+       'size' => 16777216,
+   ]);
+
+   $collection = $database->selectCollection('capped');
+
+   while (true) {
+       $collection->insertOne(['createdAt' => new MongoDB\BSON\UTCDateTime()]);
+       sleep(1);
+   }
+
+With the producer script still running, we will now execute a consumer script to
+read the inserted documents using a tailable cursor, indicated by the
+``cursorType`` option to :phpmethod:`MongoDB\\Collection::find()`. We'll start
+by using ``foreach`` to illustrate its shortcomings:
+
+.. code-block:: php
+
+   <?php
+
+   $collection = (new MongoDB\Client)->test->capped;
+
+   $cursor = $collection->find([], [
+       'cursorType' => MongoDB\Operation\Find::TAILABLE_AWAIT,
+       'maxAwaitTimeMS' => 100,
+   ]);
+
+   foreach ($cursor as $document) {
+       printf("Consumed document created at: %s\n", $document->createdAt);
+   }
+
+If you execute this consumer script, you'll notice that it quickly exhausts all
+results in the capped collection and then terminates. We cannot add a second
+``foreach``, as that would throw an exception when attempting to rewind the
+cursor. This is a ripe use case for directly controlling the iteration process
+using :php:`IteratorIterator <iteratoriterator>`.
+
+.. code-block:: php
+
+   <?php
+
+   $collection = (new MongoDB\Client)->test->capped;
+
+   $cursor = $collection->find([], [
+       'cursorType' => MongoDB\Operation\Find::TAILABLE_AWAIT,
+       'maxAwaitTimeMS' => 100,
+   ]);
+
+   $iterator = new IteratorIterator($cursor);
+
+   $iterator->rewind();
+
+   while (true) {
+      if ($iterator->valid()) {
+         $document = $iterator->current();
+         printf("Consumed document created at: %s\n", $document->createdAt);
+      }
+
+      $iterator->next();
+   }
+
+Much like the ``foreach`` example, this version on the consumer script will
+start by quickly printing all results in the capped collection; however, it will
+not terminate upon reaching the end of the initial result set. Since we're
+working with a tailable cursor, calling ``next()`` will block and wait for
+additional results rather than throw an exception. We will also use ``valid()``
+to check if there is actually data available to read at each step.
+
+Since we've elected to use a ``TAILABLE_AWAIT`` cursor, the server will delay
+its response to the driver for a set amount of time. In this example, we've
+requested that the server block for approximately 100 milliseconds by specifying
+the ``maxAwaitTimeMS`` option to :phpmethod:`MongoDB\\Collection::find()`.
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/upgrade.txt b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/upgrade.txt
new file mode 100644
index 0000000000000000000000000000000000000000..d783f13ae565c858cc359ad5b33cfc3e6646e143
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/docs/upgrade.txt	
@@ -0,0 +1,310 @@
+=============
+Upgrade Guide
+=============
+
+.. default-domain:: mongodb
+
+.. contents:: On this page
+   :local:
+   :backlinks: none
+   :depth: 2
+   :class: singlecol
+
+Overview
+--------
+
+The |php-library| and underlying :php:`mongodb extension <mongodb>` have notable
+API differences from the legacy :php:`mongo extension <mongo>`. This page will
+summarize those differences for the benefit of those upgrading from the legacy
+driver.
+
+Additionally, a community-developed `mongo-php-adapter
+<https://github.com/alcaeus/mongo-php-adapter>`_ library exists, which
+implements the `mongo extension <http://php.net/mongo>`_ API using this library
+and the new driver. While this adapter library is not officially supported by
+MongoDB, it does bear mentioning.
+
+BSON Type Classes
+-----------------
+
+When upgrading from the legacy driver,
+`type classes <https://www.php.net/manual/en/mongo.types.php>`_ such as
+:php:`MongoId <mongoid>` must be replaced with classes in the
+`MongoDB\\BSON namespace <https://www.php.net/manual/en/book.bson.php>`_. The
+new driver also introduces interfaces for its BSON types, which should be
+preferred if applications need to type hint against BSON values.
+
+The following table lists all legacy classes alongside the equivalent class in
+the new driver.
+
+.. list-table::
+   :header-rows: 1
+
+   * - Legacy class
+     - BSON type class
+     - BSON type interface
+
+   * - :php:`MongoId <mongoid>`
+     - :php:`MongoDB\\BSON\\ObjectId <mongodb_bson_objectid>`
+     - :php:`MongoDB\\BSON\\ObjectIdInterface <mongodb_bson_objectidinterface>`
+
+   * - :php:`MongoCode <mongocode>`
+     - :php:`MongoDB\\BSON\\Javascript <mongodb_bson_javascript>`
+     - :php:`MongoDB\\BSON\\JavascriptInterface <mongodb_bson_javascriptinterface>`
+
+   * - :php:`MongoDate <mongodate>`
+     - :php:`MongoDB\\BSON\\UTCDateTime <mongodb_bson_utcdatetime>`
+     - :php:`MongoDB\\BSON\\UTCDateTimeInterface <mongodb_bson_utcdatetimeinterface>`
+
+   * - :php:`MongoRegex <mongoregex>`
+     - :php:`MongoDB\\BSON\\Regex <mongodb_bson_regex>`
+     - :php:`MongoDB\\BSON\\RegexInterface <mongodb_bson_regexinterface>`
+
+   * - :php:`MongoBinData <mongobindata>`
+     - :php:`MongoDB\\BSON\\Binary <mongodb_bson_binary>`
+     - :php:`MongoDB\\BSON\\BinaryInterface <mongodb_bson_binaryinterface>`
+
+   * - :php:`MongoInt32 <mongoint32>`
+     - Not implemented. [1]_
+     -
+
+   * - :php:`MongoInt64 <mongoint64>`
+     - :php:`MongoDB\\BSON\\Int64 <mongodb_bson_int64>`
+     - Not implemented. [2]_
+
+   * - :php:`MongoDBRef <mongodbref>`
+     - Not implemented. [3]_
+     -
+
+   * - :php:`MongoMinKey <mongominkey>`
+     - :php:`MongoDB\\BSON\\MinKey <mongodb_bson_minkey>`
+     - :php:`MongoDB\\BSON\\MinKeyInterface <mongodb_bson_minkeyinterface>`
+
+   * - :php:`MongoMaxKey <mongomaxkey>`
+     - :php:`MongoDB\\BSON\\MaxKey <mongodb_bson_maxkey>`
+     - :php:`MongoDB\\BSON\\MaxKeyInterface <mongodb_bson_maxkeyinterface>`
+
+   * - :php:`MongoTimestamp <mongotimestamp>`
+     - :php:`MongoDB\\BSON\\Timestamp <mongodb_bson_timestamp>`
+     - :php:`MongoDB\\BSON\\TimestampInterface <mongodb_bson_timestampinterface>`
+
+.. [1] The new driver does not implement an equivalent class for
+   :php:`MongoInt32 <mongoint32>`. When decoding BSON, 32-bit integers will
+   always be represented as a PHP integer. When encoding BSON, PHP integers will
+   encode as either a 32-bit or 64-bit integer depending on their value.
+
+.. [2] :php:`MongoDB\\BSON\\Int64 <mongodb_bson_int64>` does not have an
+   interface defined. The new driver does not allow applications to instantiate
+   this type (i.e. its constructor is private) and it is only created during
+   BSON decoding when a 64-bit integer cannot be represented as a PHP integer on
+   a 32-bit platform.
+
+.. [3] The new driver does not implement an equivalent class for
+   :php:`MongoDBRef <mongodbref>` since
+   :manual:`DBRefs </reference/database-references>` are merely a BSON document
+   with a particular structure and not a proper BSON type. The new driver also
+   does not provide any helpers for working with DBRef objects, since their use
+   is not encouraged.
+
+Collection API
+--------------
+
+This library's :phpclass:`MongoDB\\Collection` class implements MongoDB's
+cross-driver `CRUD
+<https://github.com/mongodb/specifications/blob/master/source/crud/crud.rst>`_
+and `Index Management
+<https://github.com/mongodb/specifications/blob/master/source/index-management.rst>`_
+specifications. Although some method names have changed in accordance with the
+new specifications, the new class provides the same functionality as the legacy
+driver's :php:`MongoCollection <mongocollection>` class with some notable
+exceptions.
+
+A guiding principle in designing the new APIs was that explicit method names are
+preferable to overloaded terms found in the old API. For instance,
+:php:`MongoCollection::save() <mongocollection.save>` and
+:php:`MongoCollection::findAndModify() <mongocollection.findandmodify>`
+have different modes of operation, depending on their arguments. Methods were
+also split to distinguish between :manual:`updating specific fields
+</tutorial/modify-documents>` and :manual:`full-document replacement
+</tutorial/modify-documents/#replace-the-document>`.
+
+The following table lists all legacy methods alongside the
+equivalent method(s) in the new driver.
+
+.. list-table::
+   :header-rows: 1
+
+   * - :php:`MongoCollection <mongocollection>` method
+     - :phpclass:`MongoDB\\Collection` method(s)
+
+   * - :php:`MongoCollection::aggregate() <mongocollection.aggregate>`
+     - :phpmethod:`MongoDB\\Collection::aggregate()`
+
+   * - :php:`MongoCollection::aggregateCursor() <mongocollection.aggregatecursor>`
+     - :phpmethod:`MongoDB\\Collection::aggregate()`
+
+   * - :php:`MongoCollection::batchInsert() <mongocollection.batchinsert>`
+     - :phpmethod:`MongoDB\\Collection::insertMany()`
+
+   * - :php:`MongoCollection::count() <mongocollection.count>`
+     - :phpmethod:`MongoDB\\Collection::count()`
+
+   * - :php:`MongoCollection::createDBRef() <mongocollection.createdbref>`
+     - Not yet implemented. [3]_
+
+   * - :php:`MongoCollection::createIndex() <mongocollection.createindex>`
+     - :phpmethod:`MongoDB\\Collection::createIndex()`
+
+   * - :php:`MongoCollection::deleteIndex() <mongocollection.deleteindex>`
+     - :phpmethod:`MongoDB\\Collection::dropIndex()`
+
+   * - :php:`MongoCollection::deleteIndexes() <mongocollection.deleteindexes>`
+     - :phpmethod:`MongoDB\\Collection::dropIndexes()`
+
+   * - :php:`MongoCollection::drop() <mongocollection.drop>`
+     - :phpmethod:`MongoDB\\Collection::drop()`
+
+   * - :php:`MongoCollection::distinct() <mongocollection.distinct>`
+     - :phpmethod:`MongoDB\\Collection::distinct()`
+
+   * - :php:`MongoCollection::ensureIndex() <mongocollection.ensureindex>`
+     - :phpmethod:`MongoDB\\Collection::createIndex()`
+
+   * - :php:`MongoCollection::find() <mongocollection.find>`
+     - :phpmethod:`MongoDB\\Collection::find()`
+
+   * - :php:`MongoCollection::findAndModify() <mongocollection.findandmodify>`
+     - :phpmethod:`MongoDB\\Collection::findOneAndDelete()`,
+       :phpmethod:`MongoDB\\Collection::findOneAndReplace()`, and
+       :phpmethod:`MongoDB\\Collection::findOneAndUpdate()`
+
+   * - :php:`MongoCollection::findOne() <mongocollection.findone>`
+     - :phpmethod:`MongoDB\\Collection::findOne()`
+
+   * - :php:`MongoCollection::getDBRef() <mongocollection.getdbref>`
+     - Not implemented. [3]_
+
+   * - :php:`MongoCollection::getIndexInfo() <mongocollection.getindexinfo>`
+     - :phpmethod:`MongoDB\\Collection::listIndexes()`
+
+   * - :php:`MongoCollection::getName() <mongocollection.getname>`
+     - :phpmethod:`MongoDB\\Collection::getCollectionName()`
+
+   * - :php:`MongoCollection::getReadPreference() <mongocollection.getreadpreference>`
+     - Not implemented.
+
+   * - :php:`MongoCollection::getSlaveOkay() <mongocollection.getslaveokay>`
+     - Not implemented.
+
+   * - :php:`MongoCollection::getWriteConcern() <mongocollection.getwriteconcern>`
+     - Not implemented.
+
+   * - :php:`MongoCollection::group() <mongocollection.group>`
+     - Not implemented. Use :phpmethod:`MongoDB\\Database::command()`. See
+       `Group Command Helper`_ for an example.
+
+   * - :php:`MongoCollection::insert() <mongocollection.insert>`
+     - :phpmethod:`MongoDB\\Collection::insertOne()`
+
+   * - :php:`MongoCollection::parallelCollectionScan() <mongocollection.parallelcollectionscan>`
+     - Not implemented.
+
+   * - :php:`MongoCollection::remove() <mongocollection.remove>`
+     - :phpmethod:`MongoDB\\Collection::deleteMany()` and
+       :phpmethod:`MongoDB\\Collection::deleteOne()`
+
+   * - :php:`MongoCollection::save() <mongocollection.save>`
+     - :phpmethod:`MongoDB\\Collection::insertOne()` or
+       :phpmethod:`MongoDB\\Collection::replaceOne()` with the ``upsert``
+       option.
+
+   * - :php:`MongoCollection::setReadPreference() <mongocollection.setreadpreference>`
+     - Not implemented. Use :phpmethod:`MongoDB\\Collection::withOptions()`.
+
+   * - :php:`MongoCollection::setSlaveOkay() <mongocollection.getslaveokay>`
+     - Not implemented.
+
+   * - :php:`MongoCollection::setWriteConcern() <mongocollection.setwriteconcern>`
+     - Not implemented. Use :phpmethod:`MongoDB\\Collection::withOptions()`.
+
+   * - :php:`MongoCollection::update() <mongocollection.update>`
+     - :phpmethod:`MongoDB\\Collection::replaceOne()`,
+       :phpmethod:`MongoDB\\Collection::updateMany()`, and
+       :phpmethod:`MongoDB\\Collection::updateOne()`.
+
+   * - :php:`MongoCollection::validate() <mongocollection.validate>`
+     - Not implemented.
+
+Accessing IDs of Inserted Documents
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+In the legacy driver, :php:`MongoCollection::insert() <mongocollection.insert>`,
+:php:`MongoCollection::batchInsert() <mongocollection.batchinsert>`, and
+:php:`MongoCollection::save() <mongocollection.save>` (when inserting) would
+modify their input argument by injecting an ``_id`` key with a generated
+ObjectId (i.e. :php:`MongoId <class.mongoid>` object). This behavior was a bit
+of a hack, as it did not rely on the argument being :php:`passed by reference
+<language.references.pass>`; instead, it directly modified memory through the
+extension API and could not be implemented in PHP userland. As such, it is no
+longer done in the new driver and library.
+
+IDs of inserted documents (whether generated or not) may be accessed through the
+following methods on the write result objects:
+
+- :phpmethod:`MongoDB\\InsertOneResult::getInsertedId()` for
+  :phpmethod:`MongoDB\\Collection::insertOne()`
+- :phpmethod:`MongoDB\\InsertManyResult::getInsertedIds()` for
+  :phpmethod:`MongoDB\\Collection::insertMany()`
+- :phpmethod:`MongoDB\\BulkWriteResult::getInsertedIds()` for
+  :phpmethod:`MongoDB\\Collection::bulkWrite()`
+
+Bulk Write Operations
+~~~~~~~~~~~~~~~~~~~~~
+
+The legacy driver's :php:`MongoWriteBatch <class.mongowritebatch>` classes have
+been replaced with a general-purpose
+:phpmethod:`MongoDB\\Collection::bulkWrite()` method. Whereas the legacy driver
+only allowed bulk operations of the same type, the new method allows operations
+to be mixed (e.g. inserts, updates, and deletes).
+
+MongoCollection::save() Removed
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+:php:`MongoCollection::save() <mongocollection.save>`, which was syntactic sugar
+for an insert or upsert operation, has been removed in favor of explicitly using
+:phpmethod:`MongoDB\\Collection::insertOne` or
+:phpmethod:`MongoDB\\Collection::replaceOne` (with the ``upsert`` option).
+
+While the ``save`` method does have its uses for interactive environments, such
+as the ``mongo`` shell, it was intentionally excluded from the
+`CRUD specification <https://github.com/mongodb/specifications/blob/master/source/crud/crud.rst>`_
+for language drivers. Generally, application code should know if the document
+has an identifier and be able to explicitly insert or replace the document and
+handle the returned :phpclass:`MongoDB\\InsertOneResult` or
+:phpclass:`MongoDB\\UpdateResult`, respectively. This also helps avoid
+inadvertent and potentially dangerous :manual:`full-document replacements
+</tutorial/modify-documents>`.
+
+Group Command Helper
+~~~~~~~~~~~~~~~~~~~~
+
+:phpclass:`MongoDB\\Collection` does have a helper method for the
+:manual:`group </reference/command/group>` command. The following example
+demonstrates how to execute a group command using the
+:phpmethod:`MongoDB\\Database::command()` method:
+
+.. code-block:: php
+
+   <?php
+
+   $database = (new MongoDB\Client)->selectDatabase('db_name');
+   $cursor = $database->command([
+       'group' => [
+           'ns' => 'collection_name',
+           'key' => ['field_name' => 1],
+           'initial' => ['total' => 0],
+           '$reduce' => new MongoDB\BSON\Javascript('...'),
+       ],
+   ]);
+
+   $resultDocument = $cursor->toArray()[0];
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/mongo-orchestration/replica_sets/replicaset-old.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/mongo-orchestration/replica_sets/replicaset-old.json
new file mode 100644
index 0000000000000000000000000000000000000000..87c81637cdf86072fa12cb63259ea4fb6719e46b
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/mongo-orchestration/replica_sets/replicaset-old.json	
@@ -0,0 +1,64 @@
+{
+    "id": "REPLICASET_OLD",
+    "name": "mongod",
+    "members": [
+        {
+            "procParams": {
+                "dbpath": "/tmp/REPLICASET/3500/",
+                "ipv6": true,
+                "logappend": true,
+                "logpath": "/tmp/REPLICASET/3500/mongod.log",
+                "journal": true,
+                "nssize": 1,
+                "port": 3500,
+                "bind_ip": "::,0.0.0.0",
+                "smallfiles": true
+            },
+            "rsParams": {
+                "tags": {
+                    "ordinal": "one",
+                    "dc": "pa"
+                }
+            },
+            "server_id": "RS-OLD-one"
+        },
+        {
+            "procParams": {
+                "dbpath": "/tmp/REPLICASET/3501/",
+                "ipv6": true,
+                "logappend": true,
+                "logpath": "/tmp/REPLICASET/3501/mongod.log",
+                "journal": true,
+                "nssize": 1,
+                "port": 3501,
+                "bind_ip": "::,0.0.0.0",
+                "smallfiles": true
+            },
+            "rsParams": {
+                "tags": {
+                    "ordinal": "two",
+                    "dc": "nyc"
+                }
+            },
+            "server_id": "RS-OLD-two"
+        },
+        {
+            "procParams": {
+                "dbpath": "/tmp/REPLICASET/3502/",
+                "ipv6": true,
+                "logappend": true,
+                "logpath": "/tmp/REPLICASET/3502/mongod.log",
+                "journal": true,
+                "nssize": 1,
+                "port": 3502,
+                "bind_ip": "::,0.0.0.0",
+                "smallfiles": true
+            },
+            "rsParams": {
+                "arbiterOnly": true
+
+            },
+            "server_id": "RS-OLD-arbiter"
+        }
+    ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/mongo-orchestration/replica_sets/replicaset-one-node.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/mongo-orchestration/replica_sets/replicaset-one-node.json
new file mode 100644
index 0000000000000000000000000000000000000000..8b5bbd045a82a6de9fcb0ed0edd3f12ec0ef2d10
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/mongo-orchestration/replica_sets/replicaset-one-node.json	
@@ -0,0 +1,24 @@
+{
+    "id": "REPLICASET_SINGLE",
+    "name": "mongod",
+    "members": [
+        {
+            "procParams": {
+                "dbpath": "/tmp/REPLICASET/3020/",
+                "ipv6": true,
+                "logappend": true,
+                "logpath": "/tmp/REPLICASET/3020/mongod.log",
+                "journal": true,
+                "port": 3020,
+                "bind_ip_all": true
+            },
+            "rsParams": {
+                "tags": {
+                    "ordinal": "one",
+                    "dc": "pa"
+                }
+            },
+            "server_id": "RS-alone"
+        }
+    ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/mongo-orchestration/replica_sets/replicaset.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/mongo-orchestration/replica_sets/replicaset.json
new file mode 100644
index 0000000000000000000000000000000000000000..a80de8bbb463f56ca092d6c4c2750ed0fd5456e0
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/mongo-orchestration/replica_sets/replicaset.json	
@@ -0,0 +1,58 @@
+{
+    "id": "REPLICASET",
+    "name": "mongod",
+    "members": [
+        {
+            "procParams": {
+                "dbpath": "/tmp/REPLICASET/3000/",
+                "ipv6": true,
+                "logappend": true,
+                "logpath": "/tmp/REPLICASET/3000/mongod.log",
+                "journal": true,
+                "port": 3000,
+                "bind_ip_all": true
+            },
+            "rsParams": {
+                "tags": {
+                    "ordinal": "one",
+                    "dc": "pa"
+                }
+            },
+            "server_id": "RS-one"
+        },
+        {
+            "procParams": {
+                "dbpath": "/tmp/REPLICASET/3001/",
+                "ipv6": true,
+                "logappend": true,
+                "logpath": "/tmp/REPLICASET/3001/mongod.log",
+                "journal": true,
+                "port": 3001,
+                "bind_ip_all": true
+            },
+            "rsParams": {
+                "tags": {
+                    "ordinal": "two",
+                    "dc": "nyc"
+                }
+            },
+            "server_id": "RS-two"
+        },
+        {
+            "procParams": {
+                "dbpath": "/tmp/REPLICASET/3002/",
+                "ipv6": true,
+                "logappend": true,
+                "logpath": "/tmp/REPLICASET/3002/mongod.log",
+                "journal": true,
+                "port": 3002,
+                "bind_ip_all": true
+            },
+            "rsParams": {
+                "arbiterOnly": true
+
+            },
+            "server_id": "RS-arbiter"
+        }
+    ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/mongo-orchestration/sharded_clusters/cluster.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/mongo-orchestration/sharded_clusters/cluster.json
new file mode 100644
index 0000000000000000000000000000000000000000..094785a7eeac8fd7f88850ea986301a069bb76c7
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/mongo-orchestration/sharded_clusters/cluster.json	
@@ -0,0 +1,86 @@
+{
+    "configsvrs": [ {
+        "members" : [
+            {
+                "procParams": {
+                    "dbpath": "/tmp/SHARDED/CFG/4000",
+                    "logpath": "/tmp/SHARDED/CFG/4000/mongod.log",
+                    "ipv6": true,
+                    "journal": true,
+                    "logappend": true,
+                    "port": 4000,
+                    "bind_ip_all": true
+                }
+            },
+            {
+                "procParams": {
+                    "dbpath": "/tmp/SHARDED/CFG/4001",
+                    "logpath": "/tmp/SHARDED/CFG/4001/mongod.log",
+                    "ipv6": true,
+                    "journal": true,
+                    "logappend": true,
+                    "port": 4001,
+                    "bind_ip_all": true
+                }
+            },
+            {
+                "procParams": {
+                    "dbpath": "/tmp/SHARDED/CFG/4002",
+                    "logpath": "/tmp/SHARDED/CFG/4002/mongod.log",
+                    "ipv6": true,
+                    "journal": true,
+                    "logappend": true,
+                    "port": 4002,
+                    "bind_ip_all": true
+                }
+            }
+        ]
+    } ],
+    "id": "cluster_1", 
+    "shards": [
+        {
+            "id": "sh01", 
+            "shardParams": {
+                "procParams": {
+                    "dbpath": "/tmp/SHARDED/SHARD1/4100",
+                    "logpath": "/tmp/SHARDED/SHARD1/4100/mongod.log",
+                    "ipv6": true,
+                    "journal": true,
+                    "logappend": true,
+                    "port": 4100,
+                    "bind_ip_all": true
+                }
+            }
+        }, 
+        {
+            "id": "sh02", 
+            "shardParams": {
+                "procParams": {
+                    "dbpath": "/tmp/SHARDED/SHARD2/4200",
+                    "logpath": "/tmp/SHARDED/SHARD2/4200/mongod.log",
+                    "ipv6": true,
+                    "journal": true,
+                    "logappend": true,
+                    "port": 4200,
+                    "bind_ip_all": true
+                }
+            }
+        }
+    ], 
+    "routers": [
+        {
+            "logpath": "/tmp/SHARDED/ROUTER/4300/mongod.log",
+            "ipv6": true,
+            "logappend": true,
+            "port": 4300,
+            "bind_ip_all": true
+        },
+        {
+            "logpath": "/tmp/SHARDED/ROUTER/4301/mongod.log",
+            "ipv6": true,
+            "logappend": true,
+            "port": 4301,
+            "bind_ip_all": true
+        }
+    ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/mongo-orchestration/sharded_clusters/cluster_replset.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/mongo-orchestration/sharded_clusters/cluster_replset.json
new file mode 100644
index 0000000000000000000000000000000000000000..80cd4c2bd705ab7a3c01aab5499fd5f34ca4ce16
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/mongo-orchestration/sharded_clusters/cluster_replset.json	
@@ -0,0 +1,126 @@
+{
+    "configsvrs": [ {
+        "members" : [
+            {
+                "procParams": {
+                    "dbpath": "/tmp/SHARDED-RS/CFG/4490",
+                    "logpath": "/tmp/SHARDED-RS/CFG/4490/mongod.log",
+                    "ipv6": true,
+                    "journal": true,
+                    "logappend": true,
+                    "port": 4490,
+                    "bind_ip_all": true
+                }
+            },
+            {
+                "procParams": {
+                    "dbpath": "/tmp/SHARDED-RS/CFG/4491",
+                    "logpath": "/tmp/SHARDED-RS/CFG/4491/mongod.log",
+                    "ipv6": true,
+                    "journal": true,
+                    "logappend": true,
+                    "port": 4491,
+                    "bind_ip_all": true
+                }
+            },
+            {
+                "procParams": {
+                    "dbpath": "/tmp/SHARDED-RS/CFG/4492",
+                    "logpath": "/tmp/SHARDED-RS/CFG/4492/mongod.log",
+                    "ipv6": true,
+                    "journal": true,
+                    "logappend": true,
+                    "port": 4492,
+                    "bind_ip_all": true
+                }
+            }
+        ]
+    } ],
+    "id": "cluster_rs",
+    "shards": [
+        {
+            "id": "cluster-rs-sh01", 
+            "shardParams": {
+                "id": "sh01-rs",
+                "members": [
+                    { "procParams": {
+                        "dbpath": "/tmp/SHARDED-RS/SHARD1/4400",
+                        "logpath": "/tmp/SHARDED-RS/SHARD1/4400/mongod.log",
+                        "ipv6": true,
+                        "journal": true,
+                        "logappend": true,
+                        "port": 4400,
+                        "bind_ip_all": true,
+                        "setParameter":  {
+                            "periodicNoopIntervalSecs":  1,
+                            "writePeriodicNoops":  true
+                        }
+                    } },
+                    { "procParams": {
+                        "dbpath": "/tmp/SHARDED-RS/SHARD1/4401",
+                        "logpath": "/tmp/SHARDED-RS/SHARD1/4401/mongod.log",
+                        "ipv6": true,
+                        "journal": true,
+                        "logappend": true,
+                        "port": 4401,
+                        "bind_ip_all": true,
+                        "setParameter":  {
+                            "periodicNoopIntervalSecs":  1,
+                            "writePeriodicNoops":  true
+                        }
+                    } }
+                ]
+            }
+        }, 
+        {
+            "id": "cluster-rs-sh02", 
+            "shardParams": {
+                "id": "sh02-rs",
+                "members": [
+                    { "procParams": {
+                        "dbpath": "/tmp/SHARDED-RS/SHARD2/4410",
+                        "logpath": "/tmp/SHARDED-RS/SHARD2/4410/mongod.log",
+                        "ipv6": true,
+                        "journal": true,
+                        "logappend": true,
+                        "port": 4410,
+                        "bind_ip_all": true,
+                        "setParameter":  {
+                            "periodicNoopIntervalSecs":  1,
+                            "writePeriodicNoops":  true
+                        }
+                    } },
+                    { "procParams": {
+                        "dbpath": "/tmp/SHARDED-RS/SHARD2/4411",
+                        "logpath": "/tmp/SHARDED-RS/SHARD2/4411/mongod.log",
+                        "ipv6": true,
+                        "journal": true,
+                        "logappend": true,
+                        "port": 4411,
+                        "bind_ip_all": true,
+                        "setParameter":  {
+                            "periodicNoopIntervalSecs":  1,
+                            "writePeriodicNoops":  true
+                        }
+                    } }
+                ]
+            }
+        }
+    ], 
+    "routers": [
+        {
+            "logpath": "/tmp/SHARDED-RS/ROUTER/4430/mongod.log",
+            "ipv6": true,
+            "logappend": true,
+            "port": 4430,
+            "bind_ip_all": true
+        },
+        {
+            "logpath": "/tmp/SHARDED-RS/ROUTER/4431/mongod.log",
+            "ipv6": true,
+            "logappend": true,
+            "port": 4431,
+            "bind_ip_all": true
+        }
+    ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/mongo-orchestration/ssl/ca.pem b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/mongo-orchestration/ssl/ca.pem
new file mode 100644
index 0000000000000000000000000000000000000000..6ac86cfcc1ee3129aab684f1093e204190aee7e5
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/mongo-orchestration/ssl/ca.pem	
@@ -0,0 +1,21 @@
+-----BEGIN CERTIFICATE-----
+MIIDfzCCAmegAwIBAgIDB1MGMA0GCSqGSIb3DQEBCwUAMHkxGzAZBgNVBAMTEkRy
+aXZlcnMgVGVzdGluZyBDQTEQMA4GA1UECxMHRHJpdmVyczEQMA4GA1UEChMHTW9u
+Z29EQjEWMBQGA1UEBxMNTmV3IFlvcmsgQ2l0eTERMA8GA1UECBMITmV3IFlvcmsx
+CzAJBgNVBAYTAlVTMB4XDTE5MDUyMjIwMjMxMVoXDTM5MDUyMjIwMjMxMVoweTEb
+MBkGA1UEAxMSRHJpdmVycyBUZXN0aW5nIENBMRAwDgYDVQQLEwdEcml2ZXJzMRAw
+DgYDVQQKEwdNb25nb0RCMRYwFAYDVQQHEw1OZXcgWW9yayBDaXR5MREwDwYDVQQI
+EwhOZXcgWW9yazELMAkGA1UEBhMCVVMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
+ggEKAoIBAQCl7VN+WsQfHlwapcOpTLZVoeMAl1LTbWTFuXSAavIyy0W1Ytky1UP/
+bxCSW0mSWwCgqoJ5aXbAvrNRp6ArWu3LsTQIEcD3pEdrFIVQhYzWUs9fXqPyI9k+
+QNNQ+MRFKeGteTPYwF2eVEtPzUHU5ws3+OKp1m6MCLkwAG3RBFUAfddUnLvGoZiT
+pd8/eNabhgHvdrCw+tYFCWvSjz7SluEVievpQehrSEPKe8DxJq/IM3tSl3tdylzT
+zeiKNO7c7LuQrgjAfrZl7n2SriHIlNmqiDR/kdd8+TxBuxjFlcf2WyHCO3lIcIgH
+KXTlhUCg50KfHaxHu05Qw0x8869yIzqbAgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8w
+DQYJKoZIhvcNAQELBQADggEBAEHuhTL8KQZcKCTSJbYA9MgZj7U32arMGBbc1hiq
+VBREwvdVz4+9tIyWMzN9R/YCKmUTnCq8z3wTlC8kBtxYn/l4Tj8nJYcgLJjQ0Fwe
+gT564CmvkUat8uXPz6olOCdwkMpJ9Sj62i0mpgXJdBfxKQ6TZ9yGz6m3jannjZpN
+LchB7xSAEWtqUgvNusq0dApJsf4n7jZ+oBZVaQw2+tzaMfaLqHgMwcu1FzA8UKCD
+sxCgIsZUs8DdxaD418Ot6nPfheOTqe24n+TTa+Z6O0W0QtnofJBx7tmAo1aEc57i
+77s89pfwIJetpIlhzNSMKurCAocFCJMJLAASJFuu6dyDvPo=
+-----END CERTIFICATE-----
\ No newline at end of file
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/mongo-orchestration/ssl/client.pem b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/mongo-orchestration/ssl/client.pem
new file mode 100644
index 0000000000000000000000000000000000000000..5b070010920d3159a2b4eb1bed834508fb799fde
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/mongo-orchestration/ssl/client.pem	
@@ -0,0 +1,48 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpAIBAAKCAQEAsNS8UEuin7/K29jXfIOLpIoh1jEyWVqxiie2Onx7uJJKcoKo
+khA3XeUnVN0k6X5MwYWcN52xcns7LYtyt06nRpTG2/emoV44w9uKTuHsvUbiOwSV
+m/ToKQQ4FUFZoqorXH+ZmJuIpJNfoW+3CkE1vEDCIecIq6BNg5ySsPtvSuSJHGjp
+mc7/5ZUDvFE2aJ8QbJU3Ws0HXiEb6ymi048LlzEL2VKX3w6mqqh+7dcZGAy7qYk2
+5FZ9ktKvCeQau7mTyU1hsPrKFiKtMN8Q2ZAItX13asw5/IeSTq2LgLFHlbj5Kpq4
+GmLdNCshzH5X7Ew3IYM8EHmsX8dmD6mhv7vpVwIDAQABAoIBABOdpb4qhcG+3twA
+c/cGCKmaASLnljQ/UU6IFTjrsjXJVKTbRaPeVKX/05sgZQXZ0t3s2mV5AsQ2U1w8
+Cd+3w+qaemzQThW8hAOGCROzEDX29QWi/o2sX0ydgTMqaq0Wv3SlWv6I0mGfT45y
+/BURIsrdTCvCmz2erLqa1dL4MWJXRFjT9UTs5twlecIOM2IHKoGGagFhymRK4kDe
+wTRC9fpfoAgyfus3pCO/wi/F8yKGPDEwY+zgkhrJQ+kSeki7oKdGD1H540vB8gRt
+EIqssE0Y6rEYf97WssQlxJgvoJBDSftOijS6mwvoasDUwfFqyyPiirawXWWhHXkc
+DjIi/XECgYEA5xfjilw9YyM2UGQNESbNNunPcj7gDZbN347xJwmYmi9AUdPLt9xN
+3XaMqqR22k1DUOxC/5hH0uiXir7mDfqmC+XS/ic/VOsa3CDWejkEnyGLiwSHY502
+wD/xWgHwUiGVAG9HY64vnDGm6L3KGXA2oqxanL4V0+0+Ht49pZ16i8sCgYEAw+Ox
+CHGtpkzjCP/z8xr+1VTSdpc/4CP2HONnYopcn48KfQnf7Nale69/1kZpypJlvQSG
+eeA3jMGigNJEkb8/kaVoRLCisXcwLc0XIfCTeiK6FS0Ka30D/84Qm8UsHxRdpGkM
+kYITAa2r64tgRL8as4/ukeXBKE+oOhX43LeEfyUCgYBkf7IX2Ndlhsm3GlvIarxy
+NipeP9PGdR/hKlPbq0OvQf9R1q7QrcE7H7Q6/b0mYNV2mtjkOQB7S2WkFDMOP0P5
+BqDEoKLdNkV/F9TOYH+PCNKbyYNrodJOt0Ap6Y/u1+Xpw3sjcXwJDFrO+sKqX2+T
+PStG4S+y84jBedsLbDoAEwKBgQCTz7/KC11o2yOFqv09N+WKvBKDgeWlD/2qFr3w
+UU9K5viXGVhqshz0k5z25vL09Drowf1nAZVpFMO2SPOMtq8VC6b+Dfr1xmYIaXVH
+Gu1tf77CM9Zk/VSDNc66e7GrUgbHBK2DLo+A+Ld9aRIfTcSsMbNnS+LQtCrQibvb
+cG7+MQKBgQCY11oMT2dUekoZEyW4no7W5D74lR8ztMjp/fWWTDo/AZGPBY6cZoZF
+IICrzYtDT/5BzB0Jh1f4O9ZQkm5+OvlFbmoZoSbMzHL3oJCBOY5K0/kdGXL46WWh
+IRJSYakNU6VIS7SjDpKgm9D8befQqZeoSggSjIIULIiAtYgS80vmGA==
+-----END RSA PRIVATE KEY-----
+-----BEGIN CERTIFICATE-----
+MIIDgzCCAmugAwIBAgIDAxOUMA0GCSqGSIb3DQEBCwUAMHkxGzAZBgNVBAMTEkRy
+aXZlcnMgVGVzdGluZyBDQTEQMA4GA1UECxMHRHJpdmVyczEQMA4GA1UEChMHTW9u
+Z29EQjEWMBQGA1UEBxMNTmV3IFlvcmsgQ2l0eTERMA8GA1UECBMITmV3IFlvcmsx
+CzAJBgNVBAYTAlVTMB4XDTE5MDUyMjIzNTU1NFoXDTM5MDUyMjIzNTU1NFowaTEP
+MA0GA1UEAxMGY2xpZW50MRAwDgYDVQQLEwdEcml2ZXJzMQwwCgYDVQQKEwNNREIx
+FjAUBgNVBAcTDU5ldyBZb3JrIENpdHkxETAPBgNVBAgTCE5ldyBZb3JrMQswCQYD
+VQQGEwJVUzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALDUvFBLop+/
+ytvY13yDi6SKIdYxMllasYontjp8e7iSSnKCqJIQN13lJ1TdJOl+TMGFnDedsXJ7
+Oy2LcrdOp0aUxtv3pqFeOMPbik7h7L1G4jsElZv06CkEOBVBWaKqK1x/mZibiKST
+X6FvtwpBNbxAwiHnCKugTYOckrD7b0rkiRxo6ZnO/+WVA7xRNmifEGyVN1rNB14h
+G+spotOPC5cxC9lSl98Opqqofu3XGRgMu6mJNuRWfZLSrwnkGru5k8lNYbD6yhYi
+rTDfENmQCLV9d2rMOfyHkk6ti4CxR5W4+SqauBpi3TQrIcx+V+xMNyGDPBB5rF/H
+Zg+pob+76VcCAwEAAaMkMCIwCwYDVR0PBAQDAgeAMBMGA1UdJQQMMAoGCCsGAQUF
+BwMCMA0GCSqGSIb3DQEBCwUAA4IBAQAqRcLAGvYMaGYOV4HJTzNotT2qE0I9THNQ
+wOV1fBg69x6SrUQTQLjJEptpOA288Wue6Jt3H+p5qAGV5GbXjzN/yjCoItggSKxG
+Xg7279nz6/C5faoIKRjpS9R+MsJGlttP9nUzdSxrHvvqm62OuSVFjjETxD39DupE
+YPFQoHOxdFTtBQlc/zIKxVdd20rs1xJeeU2/L7jtRBSPuR/Sk8zot7G2/dQHX49y
+kHrq8qz12kj1T6XDXf8KZawFywXaz0/Ur+fUYKmkVk1T0JZaNtF4sKqDeNE4zcns
+p3xLVDSl1Q5Gwj7bgph9o4Hxs9izPwiqjmNaSjPimGYZ399zcurY
+-----END CERTIFICATE-----
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/mongo-orchestration/ssl/crl.pem b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/mongo-orchestration/ssl/crl.pem
new file mode 100644
index 0000000000000000000000000000000000000000..733a0acdc0760a1bbc5ad3dcf93620aad97ffa1e
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/mongo-orchestration/ssl/crl.pem	
@@ -0,0 +1,13 @@
+-----BEGIN X509 CRL-----
+MIIB6jCB0wIBATANBgkqhkiG9w0BAQsFADB5MRswGQYDVQQDExJEcml2ZXJzIFRl
+c3RpbmcgQ0ExEDAOBgNVBAsTB0RyaXZlcnMxEDAOBgNVBAoTB01vbmdvREIxFjAU
+BgNVBAcTDU5ldyBZb3JrIENpdHkxETAPBgNVBAgTCE5ldyBZb3JrMQswCQYDVQQG
+EwJVUxcNMTkwNTIyMjI0NTUzWhcNMTkwNjIxMjI0NTUzWjAVMBMCAncVFw0xOTA1
+MjIyMjQ1MzJaoA8wDTALBgNVHRQEBAICEAAwDQYJKoZIhvcNAQELBQADggEBACwQ
+W9OF6ExJSzzYbpCRroznkfdLG7ghNSxIpBQUGtcnYbkP4em6TdtAj5K3yBjcKn4a
+hnUoa5EJGr2Xgg0QascV/1GuWEJC9rsYYB9boVi95l1CrkS0pseaunM086iItZ4a
+hRVza8qEMBc3rdsracA7hElYMKdFTRLpIGciJehXzv40yT5XFBHGy/HIT0CD50O7
+BDOHzA+rCFCvxX8UY9myDfb1r1zUW7Gzjn241VT7bcIJmhFE9oV0popzDyqr6GvP
+qB2t5VmFpbnSwkuc4ie8Jizip1P8Hg73lut3oVAHACFGPpfaNIAp4GcSH61zJmff
+9UBe3CJ1INwqyiuqGeA=
+-----END X509 CRL-----
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/mongo-orchestration/ssl/server.pem b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/mongo-orchestration/ssl/server.pem
new file mode 100644
index 0000000000000000000000000000000000000000..7480f9644763eff444e0490bf78bdc342213c7b8
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/mongo-orchestration/ssl/server.pem	
@@ -0,0 +1,49 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEogIBAAKCAQEAhNrB0E6GY/kFSd8/vNpu/t952tbnOsD5drV0XPvmuy7SgKDY
+a/S+xb/jPnlZKKehdBnH7qP/gYbv34ZykzcDFZscjPLiGc2cRGP+NQCSFK0d2/7d
+y15zSD3zhj14G8+MkpAejTU+0/qFNZMc5neDvGanTe0+8aWa0DXssM0MuTxIv7j6
+CtsMWeqLLofN7a1Kw2UvmieCHfHMuA/08pJwRnV/+5T9WONBPJja2ZQRrG1BjpI4
+81zSPUZesIqi8yDlExdvgNaRZIEHi/njREqwVgJOZomUY57zmKypiMzbz48dDTsV
+gUStxrEqbaP+BEjQYPX5+QQk4GdMjkLf52LR6QIDAQABAoIBAHSs+hHLJNOf2zkp
+S3y8CUblVMsQeTpsR6otaehPgi9Zy50TpX4KD5D0GMrBH8BIl86y5Zd7h+VlcDzK
+gs0vPxI2izhuBovKuzaE6rf5rFFkSBjxGDCG3o/PeJOoYFdsS3RcBbjVzju0hFCs
+xnDQ/Wz0anJRrTnjyraY5SnQqx/xuhLXkj/lwWoWjP2bUqDprnuLOj16soNu60Um
+JziWbmWx9ty0wohkI/8DPBl9FjSniEEUi9pnZXPElFN6kwPkgdfT5rY/TkMH4lsu
+ozOUc5xgwlkT6kVjXHcs3fleuT/mOfVXLPgNms85JKLucfd6KiV7jYZkT/bXIjQ+
+7CZEn0ECgYEA5QiKZgsfJjWvZpt21V/i7dPje2xdwHtZ8F9NjX7ZUFA7mUPxUlwe
+GiXxmy6RGzNdnLOto4SF0/7ebuF3koO77oLup5a2etL+y/AnNAufbu4S5D72sbiz
+wdLzr3d5JQ12xeaEH6kQNk2SD5/ShctdS6GmTgQPiJIgH0MIdi9F3v0CgYEAlH84
+hMWcC+5b4hHUEexeNkT8kCXwHVcUjGRaYFdSHgovvWllApZDHSWZ+vRcMBdlhNPu
+09Btxo99cjOZwGYJyt20QQLGc/ZyiOF4ximQzabTeFgLkTH3Ox6Mh2Rx9yIruYoX
+nE3UfMDkYELanEJUv0zenKpZHw7tTt5yXXSlEF0CgYBSsEOvVcKYO/eoluZPYQAA
+F2jgzZ4HeUFebDoGpM52lZD+463Dq2hezmYtPaG77U6V3bUJ/TWH9VN/Or290vvN
+v83ECcC2FWlSXdD5lFyqYx/E8gqE3YdgqfW62uqM+xBvoKsA9zvYLydVpsEN9v8m
+6CSvs/2btA4O21e5u5WBTQKBgGtAb6vFpe0gHRDs24SOeYUs0lWycPhf+qFjobrP
+lqnHpa9iPeheat7UV6BfeW3qmBIVl/s4IPE2ld4z0qqZiB0Tf6ssu/TpXNPsNXS6
+dLFz+myC+ufFdNEoQUtQitd5wKbjTCZCOGRaVRgJcSdG6Tq55Fa22mOKPm+mTmed
+ZdKpAoGAFsTYBAHPxs8nzkCJCl7KLa4/zgbgywO6EcQgA7tfelB8bc8vcAMG5o+8
+YqAfwxrzhVSVbJx0fibTARXROmbh2pn010l2wj3+qUajM8NiskCPFbSjGy7HSUze
+P8Kt1uMDJdj55gATzn44au31QBioZY2zXleorxF21cr+BZCJgfA=
+-----END RSA PRIVATE KEY-----
+-----BEGIN CERTIFICATE-----
+MIIDlTCCAn2gAwIBAgICdxUwDQYJKoZIhvcNAQELBQAweTEbMBkGA1UEAxMSRHJp
+dmVycyBUZXN0aW5nIENBMRAwDgYDVQQLEwdEcml2ZXJzMRAwDgYDVQQKEwdNb25n
+b0RCMRYwFAYDVQQHEw1OZXcgWW9yayBDaXR5MREwDwYDVQQIEwhOZXcgWW9yazEL
+MAkGA1UEBhMCVVMwHhcNMTkwNTIyMjIzMjU2WhcNMzkwNTIyMjIzMjU2WjBwMRIw
+EAYDVQQDEwlsb2NhbGhvc3QxEDAOBgNVBAsTB0RyaXZlcnMxEDAOBgNVBAoTB01v
+bmdvREIxFjAUBgNVBAcTDU5ldyBZb3JrIENpdHkxETAPBgNVBAgTCE5ldyBZb3Jr
+MQswCQYDVQQGEwJVUzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAITa
+wdBOhmP5BUnfP7zabv7fedrW5zrA+Xa1dFz75rsu0oCg2Gv0vsW/4z55WSinoXQZ
+x+6j/4GG79+GcpM3AxWbHIzy4hnNnERj/jUAkhStHdv+3ctec0g984Y9eBvPjJKQ
+Ho01PtP6hTWTHOZ3g7xmp03tPvGlmtA17LDNDLk8SL+4+grbDFnqiy6Hze2tSsNl
+L5ongh3xzLgP9PKScEZ1f/uU/VjjQTyY2tmUEaxtQY6SOPNc0j1GXrCKovMg5RMX
+b4DWkWSBB4v540RKsFYCTmaJlGOe85isqYjM28+PHQ07FYFErcaxKm2j/gRI0GD1
++fkEJOBnTI5C3+di0ekCAwEAAaMwMC4wLAYDVR0RBCUwI4IJbG9jYWxob3N0hwR/
+AAABhxAAAAAAAAAAAAAAAAAAAAABMA0GCSqGSIb3DQEBCwUAA4IBAQBol8+YH7MA
+HwnIh7KcJ8h87GkCWsjOJCDJWiYBJArQ0MmgDO0qdx+QEtvLMn3XNtP05ZfK0WyX
+or4cWllAkMFYaFbyB2hYazlD1UAAG+22Rku0UP6pJMLbWe6pnqzx+RL68FYdbZhN
+fCW2xiiKsdPoo2VEY7eeZKrNr/0RFE5EKXgzmobpTBQT1Dl3Ve4aWLoTy9INlQ/g
+z40qS7oq1PjjPLgxINhf4ncJqfmRXugYTOnyFiVXLZTys5Pb9SMKdToGl3NTYWLL
+2AZdjr6bKtT+WtXyHqO0cQ8CkAW0M6VOlMluACllcJxfrtdlQS2S4lUIj76QKBdZ
+khBHXq/b8MFX
+-----END CERTIFICATE-----
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/mongo-orchestration/standalone/standalone-auth.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/mongo-orchestration/standalone/standalone-auth.json
new file mode 100644
index 0000000000000000000000000000000000000000..b15a68566f65f2ec41be83f3a0e663af02250724
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/mongo-orchestration/standalone/standalone-auth.json	
@@ -0,0 +1,17 @@
+{
+    "name": "mongod",
+    "id" : "STANDALONE_AUTH",
+    "auth_key": "secret",
+    "login": "root",
+    "password": "toor",
+    "procParams": {
+        "dbpath": "/tmp/standalone-auth/",
+        "ipv6": true,
+        "logappend": true,
+        "logpath": "/tmp/standalone-auth/m.log",
+        "journal": true,
+        "port": 2200,
+        "bind_ip_all": true,
+        "setParameter": {"enableTestCommands": 1}
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/mongo-orchestration/standalone/standalone-old.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/mongo-orchestration/standalone/standalone-old.json
new file mode 100644
index 0000000000000000000000000000000000000000..e89f013b8355dd828dd04e8f8ac3df569035ce75
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/mongo-orchestration/standalone/standalone-old.json	
@@ -0,0 +1,16 @@
+{
+    "name": "mongod",
+    "id" : "STANDALONE",
+    "procParams": {
+        "dbpath": "/tmp/standalone/",
+        "ipv6": true,
+        "logappend": true,
+        "logpath": "/tmp/standalone/mongod.log",
+        "journal": true,
+        "nssize": 1,
+        "port": 2700,
+        "bind_ip": "::,0.0.0.0",
+        "smallfiles": true,
+        "setParameter": {"enableTestCommands": 1}
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/mongo-orchestration/standalone/standalone-ssl.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/mongo-orchestration/standalone/standalone-ssl.json
new file mode 100644
index 0000000000000000000000000000000000000000..f843589e6c7f33ef2cec4524f167a3602d9c2f03
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/mongo-orchestration/standalone/standalone-ssl.json	
@@ -0,0 +1,21 @@
+{
+    "name": "mongod",
+    "id" : "STANDALONE_SSL",
+    "procParams": {
+        "dbpath": "/tmp/standalone-ssl/",
+        "ipv6": true,
+        "logappend": true,
+        "logpath": "/tmp/standalone-ssl/m.log",
+        "journal": true,
+        "port": 2100,
+        "bind_ip_all": true,
+        "setParameter": {"enableTestCommands": 1}
+    },
+    "sslParams": {
+        "sslMode": "requireSSL",
+        "sslCAFile": "$TRAVIS_BUILD_DIR/mongo-orchestration/ssl/ca.pem",
+        "sslPEMKeyFile": "$TRAVIS_BUILD_DIR/mongo-orchestration/ssl/server.pem",
+        "sslWeakCertificateValidation": true,
+        "sslAllowInvalidHostnames": true
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/mongo-orchestration/standalone/standalone.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/mongo-orchestration/standalone/standalone.json
new file mode 100644
index 0000000000000000000000000000000000000000..4cb451114068603ee700d0c6c4373ee2f8f991e7
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/mongo-orchestration/standalone/standalone.json	
@@ -0,0 +1,14 @@
+{
+    "name": "mongod",
+    "id" : "STANDALONE",
+    "procParams": {
+        "dbpath": "/tmp/standalone/",
+        "ipv6": true,
+        "logappend": true,
+        "logpath": "/tmp/standalone/mongod.log",
+        "journal": true,
+        "port": 2000,
+        "bind_ip_all": true,
+        "setParameter": {"enableTestCommands": 1}
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/phpcs.xml.dist b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/phpcs.xml.dist
new file mode 100644
index 0000000000000000000000000000000000000000..5fffede511b7bea7908d2d975f8ea1ff9223c48a
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/phpcs.xml.dist	
@@ -0,0 +1,118 @@
+<?xml version="1.0"?>
+<ruleset>
+    <arg name="basepath" value="."/>
+    <arg name="extensions" value="php"/>
+    <arg name="parallel" value="80"/>
+    <arg name="cache" value=".phpcs-cache"/>
+    <arg name="colors" />
+
+    <!-- Ignore warnings, show progress of the run, and show sniff names -->
+    <arg value="nps"/>
+
+    <autoload>.phpcs/autoload.php</autoload>
+
+    <file>.phpcs</file>
+    <file>src</file>
+    <file>tests</file>
+
+    <rule ref="Doctrine">
+        <!-- Exclude sniffs that require newer PHP versions -->
+        <!-- Available with PHP 7.1 -->
+        <exclude name="SlevomatCodingStandard.Classes.ClassConstantVisibility" />
+        <exclude name="SlevomatCodingStandard.PHP.ShortList.LongListUsed" />
+        <exclude name="SlevomatCodingStandard.TypeHints.NullableTypeForNullDefaultValue" />
+
+        <!-- Can cause subtle BC breaks, disabled for now -->
+        <exclude name="SlevomatCodingStandard.TypeHints.DeclareStrictTypes" />
+
+        <!-- No statement alignment so far -->
+        <exclude name="Generic.Formatting.MultipleStatementAlignment" />
+
+        <!-- Class naming sniffs are excluded to preserve BC -->
+        <exclude name="SlevomatCodingStandard.Classes.SuperfluousAbstractClassNaming" />
+        <exclude name="SlevomatCodingStandard.Classes.SuperfluousExceptionNaming" />
+        <exclude name="SlevomatCodingStandard.Classes.SuperfluousInterfaceNaming" />
+        <exclude name="SlevomatCodingStandard.Classes.SuperfluousTraitNaming" />
+
+        <!-- Forbid useless annotations - Git and LICENCE file provide more accurate information -->
+        <!-- Disable forbidden annotation sniff as excluding @api from the list doesn't work -->
+        <exclude name="SlevomatCodingStandard.Commenting.ForbiddenAnnotations.AnnotationForbidden" />
+
+        <!-- Keep long typehints (for now) -->
+        <exclude name="SlevomatCodingStandard.PHP.TypeCast.InvalidCastUsed" />
+        <exclude name="SlevomatCodingStandard.TypeHints.LongTypeHints" />
+
+        <!-- Don't require a full stop after @throws tags -->
+        <exclude name="Squiz.Commenting.FunctionComment.ThrowsNoFullStop" />
+
+        <!-- Disable some sniffs as they can cause functional changes. These will be enabled later -->
+        <exclude name="Generic.PHP.ForbiddenFunctions.FoundWithAlternative" />
+        <exclude name="SlevomatCodingStandard.Classes.UnusedPrivateElements" />
+        <exclude name="SlevomatCodingStandard.ControlStructures.DisallowYodaComparison" />
+        <exclude name="SlevomatCodingStandard.ControlStructures.EarlyExit" />
+        <exclude name="SlevomatCodingStandard.ControlStructures.UselessIfConditionWithReturn" />
+        <exclude name="SlevomatCodingStandard.Functions.StaticClosure" />
+        <exclude name="SlevomatCodingStandard.Functions.UnusedInheritedVariablePassedToClosure" />
+        <exclude name="SlevomatCodingStandard.Operators.DisallowEqualOperators" />
+
+        <!-- These sniffs cause a large diff, so enable them in separate steps -->
+        <exclude name="SlevomatCodingStandard.Commenting.DocCommentSpacing.IncorrectAnnotationsGroup" />
+        <exclude name="Squiz.Strings.DoubleQuoteUsage" />
+
+        <!-- Sniff currently breaks, see https://github.com/slevomat/coding-standard/issues/727 -->
+        <exclude name="SlevomatCodingStandard.Namespaces.NamespaceSpacing" />
+
+        <!-- Sniff currently broken when casting arrays, see https://github.com/squizlabs/PHP_CodeSniffer/issues/2937#issuecomment-615498860 -->
+        <exclude name="Squiz.Arrays.ArrayDeclaration.ValueNoNewline" />
+    </rule>
+
+    <!-- Change use statement sorting to be compatible with PSR-12 -->
+    <rule ref="SlevomatCodingStandard.Namespaces.AlphabeticallySortedUses">
+        <properties>
+            <property name="psr12Compatible" value="true"/>
+        </properties>
+    </rule>
+
+    <!-- Forbid fully qualified names even for colliding names -->
+    <rule ref="SlevomatCodingStandard.Namespaces.ReferenceUsedNamesOnly">
+        <properties>
+            <property name="allowFallbackGlobalConstants" value="false"/>
+            <property name="allowFallbackGlobalFunctions" value="false"/>
+            <property name="allowFullyQualifiedGlobalClasses" value="false"/>
+            <property name="allowFullyQualifiedGlobalConstants" value="false"/>
+            <property name="allowFullyQualifiedGlobalFunctions" value="false"/>
+            <property phpcs-only="true" name="allowFullyQualifiedNameForCollidingClasses" value="false"/>
+            <property phpcs-only="true" name="allowFullyQualifiedNameForCollidingConstants" value="false"/>
+            <property phpcs-only="true" name="allowFullyQualifiedNameForCollidingFunctions" value="false"/>
+            <property name="searchAnnotations" value="true"/>
+        </properties>
+    </rule>
+
+    <!-- Only enable some checks regarding type hints -->
+    <!-- In addition to requiring PHP 7.0, this sniff will cause a significant amount of BC breaks. Proceed with caution! -->
+    <rule ref="SlevomatCodingStandard.TypeHints.TypeHintDeclaration">
+        <!-- Traversable type hints often end up as mixed[], so we skip them for now -->
+        <exclude name="SlevomatCodingStandard.TypeHints.TypeHintDeclaration.MissingTraversablePropertyTypeHintSpecification" />
+        <exclude name="SlevomatCodingStandard.TypeHints.TypeHintDeclaration.MissingTraversableParameterTypeHintSpecification" />
+        <exclude name="SlevomatCodingStandard.TypeHints.TypeHintDeclaration.MissingTraversableReturnTypeHintSpecification" />
+
+        <!-- Will cause BC breaks to method signatures - disabled for now -->
+        <exclude name="SlevomatCodingStandard.TypeHints.TypeHintDeclaration.MissingParameterTypeHint" />
+        <exclude name="SlevomatCodingStandard.TypeHints.TypeHintDeclaration.MissingReturnTypeHint" />
+
+        <properties>
+            <property name="enableObjectTypeHint" value="true" />
+            <property name="enableEachParameterAndReturnInspection" value="false" />
+        </properties>
+    </rule>
+
+    <rule ref="PSR1.Methods.CamelCapsMethodName.NotCamelCaps">
+        <exclude-pattern>/src/GridFS/StreamWrapper</exclude-pattern>
+        <exclude-pattern>/tests/DocumentationExamplesTest.php</exclude-pattern>
+        <exclude-pattern>/tests/GridFS/UnusableStream.php</exclude-pattern>
+    </rule>
+
+    <rule ref="PSR1.Classes.ClassDeclaration.MultipleClasses">
+        <exclude-pattern>/tests/PHPUnit/ConstraintTrait.php</exclude-pattern>
+    </rule>
+</ruleset>
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/phpunit.evergreen.xml b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/phpunit.evergreen.xml
new file mode 100644
index 0000000000000000000000000000000000000000..fae1bdf0e6bbd0459d276a691bcd7701c70ab58b
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/phpunit.evergreen.xml	
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<phpunit
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/8.3/phpunit.xsd"
+         beStrictAboutOutputDuringTests="true"
+         beStrictAboutChangesToGlobalState="true"
+         colors="true"
+         bootstrap="tests/bootstrap.php"
+         defaultTestSuite="Default Test Suite"
+>
+
+    <php>
+        <ini name="error_reporting" value="-1"/>
+        <env name="MONGODB_URI" value="mongodb://127.0.0.1:27017/?serverSelectionTimeoutMS=100"/>
+        <env name="MONGODB_DATABASE" value="phplib_test"/>
+    </php>
+
+    <testsuites>
+        <testsuite name="Default Test Suite">
+            <directory>./tests/</directory>
+        </testsuite>
+
+        <testsuite name="Atlas Data Lake Test Suite">
+            <file>tests/SpecTests/AtlasDataLakeSpecTest.php</file>
+        </testsuite>
+    </testsuites>
+
+    <logging>
+        <log type="junit" target="test-results.xml" />
+    </logging>
+</phpunit>
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/phpunit.xml.dist b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/phpunit.xml.dist
new file mode 100644
index 0000000000000000000000000000000000000000..13d1fdd4139ce2458d2b44b059d79728d60682e1
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/phpunit.xml.dist	
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<phpunit
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/8.3/phpunit.xsd"
+         beStrictAboutOutputDuringTests="true"
+         beStrictAboutChangesToGlobalState="true"
+         colors="true"
+         bootstrap="tests/bootstrap.php"
+         defaultTestSuite="Default Test Suite"
+>
+
+    <php>
+        <ini name="error_reporting" value="-1"/>
+        <env name="MONGODB_URI" value="mongodb://127.0.0.1:27017/?serverSelectionTimeoutMS=100"/>
+        <env name="MONGODB_DATABASE" value="phplib_test"/>
+    </php>
+
+    <testsuites>
+        <testsuite name="Default Test Suite">
+            <directory>./tests/</directory>
+        </testsuite>
+
+        <testsuite name="Atlas Data Lake Test Suite">
+            <file>tests/SpecTests/AtlasDataLakeSpecTest.php</file>
+        </testsuite>
+    </testsuites>
+</phpunit>
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/BulkWriteResult.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/BulkWriteResult.php
new file mode 100644
index 0000000000000000000000000000000000000000..68af2cd751e283a9bbc505067ca2e833ee3dd9ac
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/BulkWriteResult.php	
@@ -0,0 +1,192 @@
+<?php
+/*
+ * Copyright 2015-2017 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace MongoDB;
+
+use MongoDB\Driver\WriteResult;
+use MongoDB\Exception\BadMethodCallException;
+
+/**
+ * Result class for a bulk write operation.
+ */
+class BulkWriteResult
+{
+    /** @var WriteResult */
+    private $writeResult;
+
+    /** @var mixed[] */
+    private $insertedIds;
+
+    /** @var boolean */
+    private $isAcknowledged;
+
+    /**
+     * @param WriteResult $writeResult
+     * @param mixed[]     $insertedIds
+     */
+    public function __construct(WriteResult $writeResult, array $insertedIds)
+    {
+        $this->writeResult = $writeResult;
+        $this->insertedIds = $insertedIds;
+        $this->isAcknowledged = $writeResult->isAcknowledged();
+    }
+
+    /**
+     * Return the number of documents that were deleted.
+     *
+     * This method should only be called if the write was acknowledged.
+     *
+     * @see BulkWriteResult::isAcknowledged()
+     * @return integer
+     * @throws BadMethodCallException is the write result is unacknowledged
+     */
+    public function getDeletedCount()
+    {
+        if ($this->isAcknowledged) {
+            return $this->writeResult->getDeletedCount();
+        }
+
+        throw BadMethodCallException::unacknowledgedWriteResultAccess(__METHOD__);
+    }
+
+    /**
+     * Return the number of documents that were inserted.
+     *
+     * This method should only be called if the write was acknowledged.
+     *
+     * @see BulkWriteResult::isAcknowledged()
+     * @return integer
+     * @throws BadMethodCallException is the write result is unacknowledged
+     */
+    public function getInsertedCount()
+    {
+        if ($this->isAcknowledged) {
+            return $this->writeResult->getInsertedCount();
+        }
+
+        throw BadMethodCallException::unacknowledgedWriteResultAccess(__METHOD__);
+    }
+
+    /**
+     * Return a map of the inserted documents' IDs.
+     *
+     * The index of each ID in the map corresponds to each document's position
+     * in the bulk operation. If a document had an ID prior to inserting (i.e.
+     * the driver did not generate an ID), the index will contain its "_id"
+     * field value. Any driver-generated ID will be a MongoDB\BSON\ObjectId
+     * instance.
+     *
+     * @return mixed[]
+     */
+    public function getInsertedIds()
+    {
+        return $this->insertedIds;
+    }
+
+    /**
+     * Return the number of documents that were matched by the filter.
+     *
+     * This method should only be called if the write was acknowledged.
+     *
+     * @see BulkWriteResult::isAcknowledged()
+     * @return integer
+     * @throws BadMethodCallException is the write result is unacknowledged
+     */
+    public function getMatchedCount()
+    {
+        if ($this->isAcknowledged) {
+            return $this->writeResult->getMatchedCount();
+        }
+
+        throw BadMethodCallException::unacknowledgedWriteResultAccess(__METHOD__);
+    }
+
+    /**
+     * Return the number of documents that were modified.
+     *
+     * This value is undefined (i.e. null) if the write executed as a legacy
+     * operation instead of command.
+     *
+     * This method should only be called if the write was acknowledged.
+     *
+     * @see BulkWriteResult::isAcknowledged()
+     * @return integer|null
+     * @throws BadMethodCallException is the write result is unacknowledged
+     */
+    public function getModifiedCount()
+    {
+        if ($this->isAcknowledged) {
+            return $this->writeResult->getModifiedCount();
+        }
+
+        throw BadMethodCallException::unacknowledgedWriteResultAccess(__METHOD__);
+    }
+
+    /**
+     * Return the number of documents that were upserted.
+     *
+     * This method should only be called if the write was acknowledged.
+     *
+     * @see BulkWriteResult::isAcknowledged()
+     * @return integer
+     * @throws BadMethodCallException is the write result is unacknowledged
+     */
+    public function getUpsertedCount()
+    {
+        if ($this->isAcknowledged) {
+            return $this->writeResult->getUpsertedCount();
+        }
+
+        throw BadMethodCallException::unacknowledgedWriteResultAccess(__METHOD__);
+    }
+
+    /**
+     * Return a map of the upserted documents' IDs.
+     *
+     * The index of each ID in the map corresponds to each document's position
+     * in bulk operation. If a document had an ID prior to upserting (i.e. the
+     * server did not need to generate an ID), this will contain its "_id". Any
+     * server-generated ID will be a MongoDB\BSON\ObjectId instance.
+     *
+     * This method should only be called if the write was acknowledged.
+     *
+     * @see BulkWriteResult::isAcknowledged()
+     * @return mixed[]
+     * @throws BadMethodCallException is the write result is unacknowledged
+     */
+    public function getUpsertedIds()
+    {
+        if ($this->isAcknowledged) {
+            return $this->writeResult->getUpsertedIds();
+        }
+
+        throw BadMethodCallException::unacknowledgedWriteResultAccess(__METHOD__);
+    }
+
+    /**
+     * Return whether this update was acknowledged by the server.
+     *
+     * If the update was not acknowledged, other fields from the WriteResult
+     * (e.g. matchedCount) will be undefined.
+     *
+     * @return boolean
+     */
+    public function isAcknowledged()
+    {
+        return $this->isAcknowledged;
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/ChangeStream.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/ChangeStream.php
new file mode 100644
index 0000000000000000000000000000000000000000..fcf16dde86662cbac07f641f2811c5b0f38d071f
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/ChangeStream.php	
@@ -0,0 +1,274 @@
+<?php
+/*
+ * Copyright 2017 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace MongoDB;
+
+use Iterator;
+use MongoDB\Driver\CursorId;
+use MongoDB\Driver\Exception\ConnectionException;
+use MongoDB\Driver\Exception\RuntimeException;
+use MongoDB\Driver\Exception\ServerException;
+use MongoDB\Exception\ResumeTokenException;
+use MongoDB\Model\ChangeStreamIterator;
+use function call_user_func;
+use function in_array;
+
+/**
+ * Iterator for a change stream.
+ *
+ * @api
+ * @see \MongoDB\Collection::watch()
+ * @see http://docs.mongodb.org/manual/reference/command/changeStream/
+ */
+class ChangeStream implements Iterator
+{
+    /**
+     * @deprecated 1.4
+     * @todo Remove this in 2.0 (see: PHPLIB-360)
+     */
+    const CURSOR_NOT_FOUND = 43;
+
+    /** @var int */
+    private static $cursorNotFound = 43;
+
+    /** @var int[] */
+    private static $resumableErrorCodes = [
+        6, // HostUnreachable
+        7, // HostNotFound
+        89, // NetworkTimeout
+        91, // ShutdownInProgress
+        189, // PrimarySteppedDown
+        262, // ExceededTimeLimit
+        9001, // SocketException
+        10107, // NotMaster
+        11600, // InterruptedAtShutdown
+        11602, // InterruptedDueToReplStateChange
+        13435, // NotMasterNoSlaveOk
+        13436, // NotMasterOrSecondary
+        63, // StaleShardVersion
+        150, // StaleEpoch
+        13388, // StaleConfig
+        234, // RetryChangeStream
+        133, // FailedToSatisfyReadPreference
+    ];
+
+    /** @var int */
+    private static $wireVersionForResumableChangeStreamError = 9;
+
+    /** @var callable */
+    private $resumeCallable;
+
+    /** @var ChangeStreamIterator */
+    private $iterator;
+
+    /** @var integer */
+    private $key = 0;
+
+    /**
+     * Whether the change stream has advanced to its first result. This is used
+     * to determine whether $key should be incremented after an iteration event.
+     *
+     * @var boolean
+     */
+    private $hasAdvanced = false;
+
+    /**
+     * @internal
+     * @param ChangeStreamIterator $iterator
+     * @param callable             $resumeCallable
+     */
+    public function __construct(ChangeStreamIterator $iterator, callable $resumeCallable)
+    {
+        $this->iterator = $iterator;
+        $this->resumeCallable = $resumeCallable;
+    }
+
+    /**
+     * @see http://php.net/iterator.current
+     * @return mixed
+     */
+    public function current()
+    {
+        return $this->iterator->current();
+    }
+
+    /**
+     * @return CursorId
+     */
+    public function getCursorId()
+    {
+        return $this->iterator->getInnerIterator()->getId();
+    }
+
+    /**
+     * Returns the resume token for the iterator's current position.
+     *
+     * Null may be returned if no change documents have been iterated and the
+     * server did not include a postBatchResumeToken in its aggregate or getMore
+     * command response.
+     *
+     * @return array|object|null
+     */
+    public function getResumeToken()
+    {
+        return $this->iterator->getResumeToken();
+    }
+
+    /**
+     * @see http://php.net/iterator.key
+     * @return mixed
+     */
+    public function key()
+    {
+        if ($this->valid()) {
+            return $this->key;
+        }
+
+        return null;
+    }
+
+    /**
+     * @see http://php.net/iterator.next
+     * @return void
+     * @throws ResumeTokenException
+     */
+    public function next()
+    {
+        try {
+            $this->iterator->next();
+            $this->onIteration($this->hasAdvanced);
+        } catch (RuntimeException $e) {
+            $this->resumeOrThrow($e);
+        }
+    }
+
+    /**
+     * @see http://php.net/iterator.rewind
+     * @return void
+     * @throws ResumeTokenException
+     */
+    public function rewind()
+    {
+        try {
+            $this->iterator->rewind();
+            /* Unlike next() and resume(), the decision to increment the key
+             * does not depend on whether the change stream has advanced. This
+             * ensures that multiple calls to rewind() do not alter state. */
+            $this->onIteration(false);
+        } catch (RuntimeException $e) {
+            $this->resumeOrThrow($e);
+        }
+    }
+
+    /**
+     * @see http://php.net/iterator.valid
+     * @return boolean
+     */
+    public function valid()
+    {
+        return $this->iterator->valid();
+    }
+
+    /**
+     * Determines if an exception is a resumable error.
+     *
+     * @see https://github.com/mongodb/specifications/blob/master/source/change-streams/change-streams.rst#resumable-error
+     * @param RuntimeException $exception
+     * @return boolean
+     */
+    private function isResumableError(RuntimeException $exception)
+    {
+        if ($exception instanceof ConnectionException) {
+            return true;
+        }
+
+        if (! $exception instanceof ServerException) {
+            return false;
+        }
+
+        if ($exception->getCode() === self::$cursorNotFound) {
+            return true;
+        }
+
+        if (server_supports_feature($this->iterator->getServer(), self::$wireVersionForResumableChangeStreamError)) {
+            return $exception->hasErrorLabel('ResumableChangeStreamError');
+        }
+
+        return in_array($exception->getCode(), self::$resumableErrorCodes);
+    }
+
+    /**
+     * Perform housekeeping after an iteration event.
+     *
+     * @param boolean $incrementKey Increment $key if there is a current result
+     * @throws ResumeTokenException
+     */
+    private function onIteration($incrementKey)
+    {
+        /* If the cursorId is 0, the server has invalidated the cursor and we
+         * will never perform another getMore nor need to resume since any
+         * remaining results (up to and including the invalidate event) will
+         * have been received in the last response. Therefore, we can unset the
+         * resumeCallable. This will free any reference to Watch as well as the
+         * only reference to any implicit session created therein. */
+        if ((string) $this->getCursorId() === '0') {
+            $this->resumeCallable = null;
+        }
+
+        /* Return early if there is not a current result. Avoid any attempt to
+         * increment the iterator's key. */
+        if (! $this->valid()) {
+            return;
+        }
+
+        if ($incrementKey) {
+            $this->key++;
+        }
+
+        $this->hasAdvanced = true;
+    }
+
+    /**
+     * Recreates the ChangeStreamIterator after a resumable server error.
+     *
+     * @return void
+     */
+    private function resume()
+    {
+        $this->iterator = call_user_func($this->resumeCallable, $this->getResumeToken(), $this->hasAdvanced);
+        $this->iterator->rewind();
+
+        $this->onIteration($this->hasAdvanced);
+    }
+
+    /**
+     * Either resumes after a resumable error or re-throws the exception.
+     *
+     * @param RuntimeException $exception
+     * @throws RuntimeException
+     */
+    private function resumeOrThrow(RuntimeException $exception)
+    {
+        if ($this->isResumableError($exception)) {
+            $this->resume();
+
+            return;
+        }
+
+        throw $exception;
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Client.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Client.php
new file mode 100644
index 0000000000000000000000000000000000000000..f3215d34952caf6c3e4ea620b463f4a25abe6bff
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Client.php	
@@ -0,0 +1,429 @@
+<?php
+/*
+ * Copyright 2015-2017 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace MongoDB;
+
+use Iterator;
+use Jean85\PrettyVersions;
+use MongoDB\Driver\ClientEncryption;
+use MongoDB\Driver\Exception\InvalidArgumentException as DriverInvalidArgumentException;
+use MongoDB\Driver\Exception\RuntimeException as DriverRuntimeException;
+use MongoDB\Driver\Manager;
+use MongoDB\Driver\ReadConcern;
+use MongoDB\Driver\ReadPreference;
+use MongoDB\Driver\Session;
+use MongoDB\Driver\WriteConcern;
+use MongoDB\Exception\InvalidArgumentException;
+use MongoDB\Exception\UnexpectedValueException;
+use MongoDB\Exception\UnsupportedException;
+use MongoDB\Model\BSONArray;
+use MongoDB\Model\BSONDocument;
+use MongoDB\Model\DatabaseInfoIterator;
+use MongoDB\Operation\DropDatabase;
+use MongoDB\Operation\ListDatabaseNames;
+use MongoDB\Operation\ListDatabases;
+use MongoDB\Operation\Watch;
+use Throwable;
+use function is_array;
+use function is_string;
+
+class Client
+{
+    /** @var array */
+    private static $defaultTypeMap = [
+        'array' => BSONArray::class,
+        'document' => BSONDocument::class,
+        'root' => BSONDocument::class,
+    ];
+
+    /** @var integer */
+    private static $wireVersionForReadConcern = 4;
+
+    /** @var integer */
+    private static $wireVersionForWritableCommandWriteConcern = 5;
+
+    /** @var string */
+    private static $handshakeSeparator = ' / ';
+
+    /** @var string|null */
+    private static $version;
+
+    /** @var Manager */
+    private $manager;
+
+    /** @var ReadConcern */
+    private $readConcern;
+
+    /** @var ReadPreference */
+    private $readPreference;
+
+    /** @var string */
+    private $uri;
+
+    /** @var array */
+    private $typeMap;
+
+    /** @var WriteConcern */
+    private $writeConcern;
+
+    /**
+     * Constructs a new Client instance.
+     *
+     * This is the preferred class for connecting to a MongoDB server or
+     * cluster of servers. It serves as a gateway for accessing individual
+     * databases and collections.
+     *
+     * Supported driver-specific options:
+     *
+     *  * typeMap (array): Default type map for cursors and BSON documents.
+     *
+     * Other options are documented in MongoDB\Driver\Manager::__construct().
+     *
+     * @see http://docs.mongodb.org/manual/reference/connection-string/
+     * @see http://php.net/manual/en/mongodb-driver-manager.construct.php
+     * @see http://php.net/manual/en/mongodb.persistence.php#mongodb.persistence.typemaps
+     * @param string $uri           MongoDB connection string
+     * @param array  $uriOptions    Additional connection string options
+     * @param array  $driverOptions Driver-specific options
+     * @throws InvalidArgumentException for parameter/option parsing errors
+     * @throws DriverInvalidArgumentException for parameter/option parsing errors in the driver
+     * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
+     */
+    public function __construct($uri = 'mongodb://127.0.0.1/', array $uriOptions = [], array $driverOptions = [])
+    {
+        $driverOptions += ['typeMap' => self::$defaultTypeMap];
+
+        if (! is_array($driverOptions['typeMap'])) {
+            throw InvalidArgumentException::invalidType('"typeMap" driver option', $driverOptions['typeMap'], 'array');
+        }
+
+        if (isset($driverOptions['autoEncryption']['keyVaultClient'])) {
+            if ($driverOptions['autoEncryption']['keyVaultClient'] instanceof self) {
+                $driverOptions['autoEncryption']['keyVaultClient'] = $driverOptions['autoEncryption']['keyVaultClient']->manager;
+            } elseif (! $driverOptions['autoEncryption']['keyVaultClient'] instanceof Manager) {
+                throw InvalidArgumentException::invalidType('"keyVaultClient" autoEncryption option', $driverOptions['autoEncryption']['keyVaultClient'], [self::class, Manager::class]);
+            }
+        }
+
+        $driverOptions['driver'] = $this->mergeDriverInfo($driverOptions['driver'] ?? []);
+
+        $this->uri = (string) $uri;
+        $this->typeMap = $driverOptions['typeMap'] ?? null;
+
+        unset($driverOptions['typeMap']);
+
+        $this->manager = new Manager($uri, $uriOptions, $driverOptions);
+        $this->readConcern = $this->manager->getReadConcern();
+        $this->readPreference = $this->manager->getReadPreference();
+        $this->writeConcern = $this->manager->getWriteConcern();
+    }
+
+    /**
+     * Return internal properties for debugging purposes.
+     *
+     * @see http://php.net/manual/en/language.oop5.magic.php#language.oop5.magic.debuginfo
+     * @return array
+     */
+    public function __debugInfo()
+    {
+        return [
+            'manager' => $this->manager,
+            'uri' => $this->uri,
+            'typeMap' => $this->typeMap,
+            'writeConcern' => $this->writeConcern,
+        ];
+    }
+
+    /**
+     * Select a database.
+     *
+     * Note: databases whose names contain special characters (e.g. "-") may
+     * be selected with complex syntax (e.g. $client->{"that-database"}) or
+     * {@link selectDatabase()}.
+     *
+     * @see http://php.net/oop5.overloading#object.get
+     * @see http://php.net/types.string#language.types.string.parsing.complex
+     * @param string $databaseName Name of the database to select
+     * @return Database
+     */
+    public function __get($databaseName)
+    {
+        return $this->selectDatabase($databaseName);
+    }
+
+    /**
+     * Return the connection string (i.e. URI).
+     *
+     * @return string
+     */
+    public function __toString()
+    {
+        return $this->uri;
+    }
+
+    /**
+     * Returns a ClientEncryption instance for explicit encryption and decryption
+     *
+     * @param array $options Encryption options
+     *
+     * @return ClientEncryption
+     */
+    public function createClientEncryption(array $options)
+    {
+        if (isset($options['keyVaultClient'])) {
+            if ($options['keyVaultClient'] instanceof self) {
+                $options['keyVaultClient'] = $options['keyVaultClient']->manager;
+            } elseif (! $options['keyVaultClient'] instanceof Manager) {
+                throw InvalidArgumentException::invalidType('"keyVaultClient" option', $options['keyVaultClient'], [self::class, Manager::class]);
+            }
+        }
+
+        return $this->manager->createClientEncryption($options);
+    }
+
+    /**
+     * Drop a database.
+     *
+     * @see DropDatabase::__construct() for supported options
+     * @param string $databaseName Database name
+     * @param array  $options      Additional options
+     * @return array|object Command result document
+     * @throws UnsupportedException if options are unsupported on the selected server
+     * @throws InvalidArgumentException for parameter/option parsing errors
+     * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
+     */
+    public function dropDatabase($databaseName, array $options = [])
+    {
+        if (! isset($options['typeMap'])) {
+            $options['typeMap'] = $this->typeMap;
+        }
+
+        $server = select_server($this->manager, $options);
+
+        if (! isset($options['writeConcern']) && server_supports_feature($server, self::$wireVersionForWritableCommandWriteConcern) && ! is_in_transaction($options)) {
+            $options['writeConcern'] = $this->writeConcern;
+        }
+
+        $operation = new DropDatabase($databaseName, $options);
+
+        return $operation->execute($server);
+    }
+
+    /**
+     * Return the Manager.
+     *
+     * @return Manager
+     */
+    public function getManager()
+    {
+        return $this->manager;
+    }
+
+    /**
+     * Return the read concern for this client.
+     *
+     * @see http://php.net/manual/en/mongodb-driver-readconcern.isdefault.php
+     * @return ReadConcern
+     */
+    public function getReadConcern()
+    {
+        return $this->readConcern;
+    }
+
+    /**
+     * Return the read preference for this client.
+     *
+     * @return ReadPreference
+     */
+    public function getReadPreference()
+    {
+        return $this->readPreference;
+    }
+
+    /**
+     * Return the type map for this client.
+     *
+     * @return array
+     */
+    public function getTypeMap()
+    {
+        return $this->typeMap;
+    }
+
+    /**
+     * Return the write concern for this client.
+     *
+     * @see http://php.net/manual/en/mongodb-driver-writeconcern.isdefault.php
+     * @return WriteConcern
+     */
+    public function getWriteConcern()
+    {
+        return $this->writeConcern;
+    }
+
+    /**
+     * List database names.
+     *
+     * @see ListDatabaseNames::__construct() for supported options
+     * @throws UnexpectedValueException if the command response was malformed
+     * @throws InvalidArgumentException for parameter/option parsing errors
+     * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
+     */
+    public function listDatabaseNames(array $options = []) : Iterator
+    {
+        $operation = new ListDatabaseNames($options);
+        $server = select_server($this->manager, $options);
+
+        return $operation->execute($server);
+    }
+
+    /**
+     * List databases.
+     *
+     * @see ListDatabases::__construct() for supported options
+     * @param array $options
+     * @return DatabaseInfoIterator
+     * @throws UnexpectedValueException if the command response was malformed
+     * @throws InvalidArgumentException for parameter/option parsing errors
+     * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
+     */
+    public function listDatabases(array $options = [])
+    {
+        $operation = new ListDatabases($options);
+        $server = select_server($this->manager, $options);
+
+        return $operation->execute($server);
+    }
+
+    /**
+     * Select a collection.
+     *
+     * @see Collection::__construct() for supported options
+     * @param string $databaseName   Name of the database containing the collection
+     * @param string $collectionName Name of the collection to select
+     * @param array  $options        Collection constructor options
+     * @return Collection
+     * @throws InvalidArgumentException for parameter/option parsing errors
+     */
+    public function selectCollection($databaseName, $collectionName, array $options = [])
+    {
+        $options += ['typeMap' => $this->typeMap];
+
+        return new Collection($this->manager, $databaseName, $collectionName, $options);
+    }
+
+    /**
+     * Select a database.
+     *
+     * @see Database::__construct() for supported options
+     * @param string $databaseName Name of the database to select
+     * @param array  $options      Database constructor options
+     * @return Database
+     * @throws InvalidArgumentException for parameter/option parsing errors
+     */
+    public function selectDatabase($databaseName, array $options = [])
+    {
+        $options += ['typeMap' => $this->typeMap];
+
+        return new Database($this->manager, $databaseName, $options);
+    }
+
+    /**
+     * Start a new client session.
+     *
+     * @see http://php.net/manual/en/mongodb-driver-manager.startsession.php
+     * @param array $options Session options
+     * @return Session
+     */
+    public function startSession(array $options = [])
+    {
+        return $this->manager->startSession($options);
+    }
+
+    /**
+     * Create a change stream for watching changes to the cluster.
+     *
+     * @see Watch::__construct() for supported options
+     * @param array $pipeline List of pipeline operations
+     * @param array $options  Command options
+     * @return ChangeStream
+     * @throws InvalidArgumentException for parameter/option parsing errors
+     */
+    public function watch(array $pipeline = [], array $options = [])
+    {
+        if (! isset($options['readPreference']) && ! is_in_transaction($options)) {
+            $options['readPreference'] = $this->readPreference;
+        }
+
+        $server = select_server($this->manager, $options);
+
+        if (! isset($options['readConcern']) && server_supports_feature($server, self::$wireVersionForReadConcern) && ! is_in_transaction($options)) {
+            $options['readConcern'] = $this->readConcern;
+        }
+
+        if (! isset($options['typeMap'])) {
+            $options['typeMap'] = $this->typeMap;
+        }
+
+        $operation = new Watch($this->manager, null, null, $pipeline, $options);
+
+        return $operation->execute($server);
+    }
+
+    private static function getVersion() : string
+    {
+        if (self::$version === null) {
+            try {
+                self::$version = PrettyVersions::getVersion('mongodb/mongodb')->getPrettyVersion();
+            } catch (Throwable $t) {
+                return 'unknown';
+            }
+        }
+
+        return self::$version;
+    }
+
+    private function mergeDriverInfo(array $driver) : array
+    {
+        $mergedDriver = [
+            'name' => 'PHPLIB',
+            'version' => self::getVersion(),
+        ];
+
+        if (isset($driver['name'])) {
+            if (! is_string($driver['name'])) {
+                throw InvalidArgumentException::invalidType('"name" handshake option', $driver['name'], 'string');
+            }
+
+            $mergedDriver['name'] .= self::$handshakeSeparator . $driver['name'];
+        }
+
+        if (isset($driver['version'])) {
+            if (! is_string($driver['version'])) {
+                throw InvalidArgumentException::invalidType('"version" handshake option', $driver['version'], 'string');
+            }
+
+            $mergedDriver['version'] .= self::$handshakeSeparator . $driver['version'];
+        }
+
+        if (isset($driver['platform'])) {
+            $mergedDriver['platform'] = $driver['platform'];
+        }
+
+        return $mergedDriver;
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Collection.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Collection.php
new file mode 100644
index 0000000000000000000000000000000000000000..a449c7edc55ed189d9305ceccd1dff44753be41a
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Collection.php	
@@ -0,0 +1,1134 @@
+<?php
+/*
+ * Copyright 2015-2017 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace MongoDB;
+
+use MongoDB\BSON\JavascriptInterface;
+use MongoDB\Driver\Cursor;
+use MongoDB\Driver\Exception\RuntimeException as DriverRuntimeException;
+use MongoDB\Driver\Manager;
+use MongoDB\Driver\ReadConcern;
+use MongoDB\Driver\ReadPreference;
+use MongoDB\Driver\WriteConcern;
+use MongoDB\Exception\InvalidArgumentException;
+use MongoDB\Exception\UnexpectedValueException;
+use MongoDB\Exception\UnsupportedException;
+use MongoDB\Model\BSONArray;
+use MongoDB\Model\BSONDocument;
+use MongoDB\Model\IndexInfo;
+use MongoDB\Model\IndexInfoIterator;
+use MongoDB\Operation\Aggregate;
+use MongoDB\Operation\BulkWrite;
+use MongoDB\Operation\Count;
+use MongoDB\Operation\CountDocuments;
+use MongoDB\Operation\CreateIndexes;
+use MongoDB\Operation\DeleteMany;
+use MongoDB\Operation\DeleteOne;
+use MongoDB\Operation\Distinct;
+use MongoDB\Operation\DropCollection;
+use MongoDB\Operation\DropIndexes;
+use MongoDB\Operation\EstimatedDocumentCount;
+use MongoDB\Operation\Explain;
+use MongoDB\Operation\Explainable;
+use MongoDB\Operation\Find;
+use MongoDB\Operation\FindOne;
+use MongoDB\Operation\FindOneAndDelete;
+use MongoDB\Operation\FindOneAndReplace;
+use MongoDB\Operation\FindOneAndUpdate;
+use MongoDB\Operation\InsertMany;
+use MongoDB\Operation\InsertOne;
+use MongoDB\Operation\ListIndexes;
+use MongoDB\Operation\MapReduce;
+use MongoDB\Operation\ReplaceOne;
+use MongoDB\Operation\UpdateMany;
+use MongoDB\Operation\UpdateOne;
+use MongoDB\Operation\Watch;
+use Traversable;
+use function array_diff_key;
+use function array_intersect_key;
+use function current;
+use function is_array;
+use function strlen;
+
+class Collection
+{
+    /** @var array */
+    private static $defaultTypeMap = [
+        'array' => BSONArray::class,
+        'document' => BSONDocument::class,
+        'root' => BSONDocument::class,
+    ];
+
+    /** @var integer */
+    private static $wireVersionForFindAndModifyWriteConcern = 4;
+
+    /** @var integer */
+    private static $wireVersionForReadConcern = 4;
+
+    /** @var integer */
+    private static $wireVersionForWritableCommandWriteConcern = 5;
+
+    /** @var integer */
+    private static $wireVersionForReadConcernWithWriteStage = 8;
+
+    /** @var string */
+    private $collectionName;
+
+    /** @var string */
+    private $databaseName;
+
+    /** @var Manager */
+    private $manager;
+
+    /** @var ReadConcern */
+    private $readConcern;
+
+    /** @var ReadPreference */
+    private $readPreference;
+
+    /** @var array */
+    private $typeMap;
+
+    /** @var WriteConcern */
+    private $writeConcern;
+
+    /**
+     * Constructs new Collection instance.
+     *
+     * This class provides methods for collection-specific operations, such as
+     * CRUD (i.e. create, read, update, and delete) and index management.
+     *
+     * Supported options:
+     *
+     *  * readConcern (MongoDB\Driver\ReadConcern): The default read concern to
+     *    use for collection operations. Defaults to the Manager's read concern.
+     *
+     *  * readPreference (MongoDB\Driver\ReadPreference): The default read
+     *    preference to use for collection operations. Defaults to the Manager's
+     *    read preference.
+     *
+     *  * typeMap (array): Default type map for cursors and BSON documents.
+     *
+     *  * writeConcern (MongoDB\Driver\WriteConcern): The default write concern
+     *    to use for collection operations. Defaults to the Manager's write
+     *    concern.
+     *
+     * @param Manager $manager        Manager instance from the driver
+     * @param string  $databaseName   Database name
+     * @param string  $collectionName Collection name
+     * @param array   $options        Collection options
+     * @throws InvalidArgumentException for parameter/option parsing errors
+     */
+    public function __construct(Manager $manager, $databaseName, $collectionName, array $options = [])
+    {
+        if (strlen($databaseName) < 1) {
+            throw new InvalidArgumentException('$databaseName is invalid: ' . $databaseName);
+        }
+
+        if (strlen($collectionName) < 1) {
+            throw new InvalidArgumentException('$collectionName is invalid: ' . $collectionName);
+        }
+
+        if (isset($options['readConcern']) && ! $options['readConcern'] instanceof ReadConcern) {
+            throw InvalidArgumentException::invalidType('"readConcern" option', $options['readConcern'], ReadConcern::class);
+        }
+
+        if (isset($options['readPreference']) && ! $options['readPreference'] instanceof ReadPreference) {
+            throw InvalidArgumentException::invalidType('"readPreference" option', $options['readPreference'], ReadPreference::class);
+        }
+
+        if (isset($options['typeMap']) && ! is_array($options['typeMap'])) {
+            throw InvalidArgumentException::invalidType('"typeMap" option', $options['typeMap'], 'array');
+        }
+
+        if (isset($options['writeConcern']) && ! $options['writeConcern'] instanceof WriteConcern) {
+            throw InvalidArgumentException::invalidType('"writeConcern" option', $options['writeConcern'], WriteConcern::class);
+        }
+
+        $this->manager = $manager;
+        $this->databaseName = (string) $databaseName;
+        $this->collectionName = (string) $collectionName;
+        $this->readConcern = $options['readConcern'] ?? $this->manager->getReadConcern();
+        $this->readPreference = $options['readPreference'] ?? $this->manager->getReadPreference();
+        $this->typeMap = $options['typeMap'] ?? self::$defaultTypeMap;
+        $this->writeConcern = $options['writeConcern'] ?? $this->manager->getWriteConcern();
+    }
+
+    /**
+     * Return internal properties for debugging purposes.
+     *
+     * @see http://php.net/manual/en/language.oop5.magic.php#language.oop5.magic.debuginfo
+     * @return array
+     */
+    public function __debugInfo()
+    {
+        return [
+            'collectionName' => $this->collectionName,
+            'databaseName' => $this->databaseName,
+            'manager' => $this->manager,
+            'readConcern' => $this->readConcern,
+            'readPreference' => $this->readPreference,
+            'typeMap' => $this->typeMap,
+            'writeConcern' => $this->writeConcern,
+        ];
+    }
+
+    /**
+     * Return the collection namespace (e.g. "db.collection").
+     *
+     * @see https://docs.mongodb.org/manual/faq/developers/#faq-dev-namespace
+     * @return string
+     */
+    public function __toString()
+    {
+        return $this->databaseName . '.' . $this->collectionName;
+    }
+
+    /**
+     * Executes an aggregation framework pipeline on the collection.
+     *
+     * Note: this method's return value depends on the MongoDB server version
+     * and the "useCursor" option. If "useCursor" is true, a Cursor will be
+     * returned; otherwise, an ArrayIterator is returned, which wraps the
+     * "result" array from the command response document.
+     *
+     * @see Aggregate::__construct() for supported options
+     * @param array $pipeline List of pipeline operations
+     * @param array $options  Command options
+     * @return Traversable
+     * @throws UnexpectedValueException if the command response was malformed
+     * @throws UnsupportedException if options are not supported by the selected server
+     * @throws InvalidArgumentException for parameter/option parsing errors
+     * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
+     */
+    public function aggregate(array $pipeline, array $options = [])
+    {
+        $hasWriteStage = is_last_pipeline_operator_write($pipeline);
+
+        if (! isset($options['readPreference']) && ! is_in_transaction($options)) {
+            $options['readPreference'] = $this->readPreference;
+        }
+
+        if ($hasWriteStage) {
+            $options['readPreference'] = new ReadPreference(ReadPreference::RP_PRIMARY);
+        }
+
+        $server = select_server($this->manager, $options);
+
+        /* MongoDB 4.2 and later supports a read concern when an $out stage is
+         * being used, but earlier versions do not.
+         *
+         * A read concern is also not compatible with transactions.
+         */
+        if (! isset($options['readConcern']) &&
+            server_supports_feature($server, self::$wireVersionForReadConcern) &&
+            ! is_in_transaction($options) &&
+            ( ! $hasWriteStage || server_supports_feature($server, self::$wireVersionForReadConcernWithWriteStage))
+        ) {
+            $options['readConcern'] = $this->readConcern;
+        }
+
+        if (! isset($options['typeMap'])) {
+            $options['typeMap'] = $this->typeMap;
+        }
+
+        if ($hasWriteStage &&
+            ! isset($options['writeConcern']) &&
+            server_supports_feature($server, self::$wireVersionForWritableCommandWriteConcern) &&
+            ! is_in_transaction($options)) {
+            $options['writeConcern'] = $this->writeConcern;
+        }
+
+        $operation = new Aggregate($this->databaseName, $this->collectionName, $pipeline, $options);
+
+        return $operation->execute($server);
+    }
+
+    /**
+     * Executes multiple write operations.
+     *
+     * @see BulkWrite::__construct() for supported options
+     * @param array[] $operations List of write operations
+     * @param array   $options    Command options
+     * @return BulkWriteResult
+     * @throws UnsupportedException if options are not supported by the selected server
+     * @throws InvalidArgumentException for parameter/option parsing errors
+     * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
+     */
+    public function bulkWrite(array $operations, array $options = [])
+    {
+        if (! isset($options['writeConcern']) && ! is_in_transaction($options)) {
+            $options['writeConcern'] = $this->writeConcern;
+        }
+
+        $operation = new BulkWrite($this->databaseName, $this->collectionName, $operations, $options);
+        $server = select_server($this->manager, $options);
+
+        return $operation->execute($server);
+    }
+
+    /**
+     * Gets the number of documents matching the filter.
+     *
+     * @see Count::__construct() for supported options
+     * @param array|object $filter  Query by which to filter documents
+     * @param array        $options Command options
+     * @return integer
+     * @throws UnexpectedValueException if the command response was malformed
+     * @throws UnsupportedException if options are not supported by the selected server
+     * @throws InvalidArgumentException for parameter/option parsing errors
+     * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
+     *
+     * @deprecated 1.4
+     */
+    public function count($filter = [], array $options = [])
+    {
+        if (! isset($options['readPreference']) && ! is_in_transaction($options)) {
+            $options['readPreference'] = $this->readPreference;
+        }
+
+        $server = select_server($this->manager, $options);
+
+        if (! isset($options['readConcern']) && server_supports_feature($server, self::$wireVersionForReadConcern) && ! is_in_transaction($options)) {
+            $options['readConcern'] = $this->readConcern;
+        }
+
+        $operation = new Count($this->databaseName, $this->collectionName, $filter, $options);
+
+        return $operation->execute($server);
+    }
+
+    /**
+     * Gets the number of documents matching the filter.
+     *
+     * @see CountDocuments::__construct() for supported options
+     * @param array|object $filter  Query by which to filter documents
+     * @param array        $options Command options
+     * @return integer
+     * @throws UnexpectedValueException if the command response was malformed
+     * @throws UnsupportedException if options are not supported by the selected server
+     * @throws InvalidArgumentException for parameter/option parsing errors
+     * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
+     */
+    public function countDocuments($filter = [], array $options = [])
+    {
+        if (! isset($options['readPreference']) && ! is_in_transaction($options)) {
+            $options['readPreference'] = $this->readPreference;
+        }
+
+        $server = select_server($this->manager, $options);
+
+        if (! isset($options['readConcern']) && server_supports_feature($server, self::$wireVersionForReadConcern) && ! is_in_transaction($options)) {
+            $options['readConcern'] = $this->readConcern;
+        }
+
+        $operation = new CountDocuments($this->databaseName, $this->collectionName, $filter, $options);
+
+        return $operation->execute($server);
+    }
+
+    /**
+     * Create a single index for the collection.
+     *
+     * @see Collection::createIndexes()
+     * @see CreateIndexes::__construct() for supported command options
+     * @param array|object $key     Document containing fields mapped to values,
+     *                              which denote order or an index type
+     * @param array        $options Index and command options
+     * @return string The name of the created index
+     * @throws UnsupportedException if options are not supported by the selected server
+     * @throws InvalidArgumentException for parameter/option parsing errors
+     * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
+     */
+    public function createIndex($key, array $options = [])
+    {
+        $commandOptionKeys = ['commitQuorum' => 1, 'maxTimeMS' => 1, 'session' => 1, 'writeConcern' => 1];
+        $indexOptions = array_diff_key($options, $commandOptionKeys);
+        $commandOptions = array_intersect_key($options, $commandOptionKeys);
+
+        return current($this->createIndexes([['key' => $key] + $indexOptions], $commandOptions));
+    }
+
+    /**
+     * Create one or more indexes for the collection.
+     *
+     * Each element in the $indexes array must have a "key" document, which
+     * contains fields mapped to an order or type. Other options may follow.
+     * For example:
+     *
+     *     $indexes = [
+     *         // Create a unique index on the "username" field
+     *         [ 'key' => [ 'username' => 1 ], 'unique' => true ],
+     *         // Create a 2dsphere index on the "loc" field with a custom name
+     *         [ 'key' => [ 'loc' => '2dsphere' ], 'name' => 'geo' ],
+     *     ];
+     *
+     * If the "name" option is unspecified, a name will be generated from the
+     * "key" document.
+     *
+     * @see http://docs.mongodb.org/manual/reference/command/createIndexes/
+     * @see http://docs.mongodb.org/manual/reference/method/db.collection.createIndex/
+     * @see CreateIndexes::__construct() for supported command options
+     * @param array[] $indexes List of index specifications
+     * @param array   $options Command options
+     * @return string[] The names of the created indexes
+     * @throws UnsupportedException if options are not supported by the selected server
+     * @throws InvalidArgumentException for parameter/option parsing errors
+     * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
+     */
+    public function createIndexes(array $indexes, array $options = [])
+    {
+        $server = select_server($this->manager, $options);
+
+        if (! isset($options['writeConcern']) && server_supports_feature($server, self::$wireVersionForWritableCommandWriteConcern) && ! is_in_transaction($options)) {
+            $options['writeConcern'] = $this->writeConcern;
+        }
+
+        $operation = new CreateIndexes($this->databaseName, $this->collectionName, $indexes, $options);
+
+        return $operation->execute($server);
+    }
+
+    /**
+     * Deletes all documents matching the filter.
+     *
+     * @see DeleteMany::__construct() for supported options
+     * @see http://docs.mongodb.org/manual/reference/command/delete/
+     * @param array|object $filter  Query by which to delete documents
+     * @param array        $options Command options
+     * @return DeleteResult
+     * @throws UnsupportedException if options are not supported by the selected server
+     * @throws InvalidArgumentException for parameter/option parsing errors
+     * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
+     */
+    public function deleteMany($filter, array $options = [])
+    {
+        if (! isset($options['writeConcern']) && ! is_in_transaction($options)) {
+            $options['writeConcern'] = $this->writeConcern;
+        }
+
+        $operation = new DeleteMany($this->databaseName, $this->collectionName, $filter, $options);
+        $server = select_server($this->manager, $options);
+
+        return $operation->execute($server);
+    }
+
+    /**
+     * Deletes at most one document matching the filter.
+     *
+     * @see DeleteOne::__construct() for supported options
+     * @see http://docs.mongodb.org/manual/reference/command/delete/
+     * @param array|object $filter  Query by which to delete documents
+     * @param array        $options Command options
+     * @return DeleteResult
+     * @throws UnsupportedException if options are not supported by the selected server
+     * @throws InvalidArgumentException for parameter/option parsing errors
+     * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
+     */
+    public function deleteOne($filter, array $options = [])
+    {
+        if (! isset($options['writeConcern']) && ! is_in_transaction($options)) {
+            $options['writeConcern'] = $this->writeConcern;
+        }
+
+        $operation = new DeleteOne($this->databaseName, $this->collectionName, $filter, $options);
+        $server = select_server($this->manager, $options);
+
+        return $operation->execute($server);
+    }
+
+    /**
+     * Finds the distinct values for a specified field across the collection.
+     *
+     * @see Distinct::__construct() for supported options
+     * @param string       $fieldName Field for which to return distinct values
+     * @param array|object $filter    Query by which to filter documents
+     * @param array        $options   Command options
+     * @return mixed[]
+     * @throws UnexpectedValueException if the command response was malformed
+     * @throws UnsupportedException if options are not supported by the selected server
+     * @throws InvalidArgumentException for parameter/option parsing errors
+     * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
+     */
+    public function distinct($fieldName, $filter = [], array $options = [])
+    {
+        if (! isset($options['readPreference']) && ! is_in_transaction($options)) {
+            $options['readPreference'] = $this->readPreference;
+        }
+
+        if (! isset($options['typeMap'])) {
+            $options['typeMap'] = $this->typeMap;
+        }
+
+        $server = select_server($this->manager, $options);
+
+        if (! isset($options['readConcern']) && server_supports_feature($server, self::$wireVersionForReadConcern) && ! is_in_transaction($options)) {
+            $options['readConcern'] = $this->readConcern;
+        }
+
+        $operation = new Distinct($this->databaseName, $this->collectionName, $fieldName, $filter, $options);
+
+        return $operation->execute($server);
+    }
+
+    /**
+     * Drop this collection.
+     *
+     * @see DropCollection::__construct() for supported options
+     * @param array $options Additional options
+     * @return array|object Command result document
+     * @throws UnsupportedException if options are not supported by the selected server
+     * @throws InvalidArgumentException for parameter/option parsing errors
+     * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
+     */
+    public function drop(array $options = [])
+    {
+        if (! isset($options['typeMap'])) {
+            $options['typeMap'] = $this->typeMap;
+        }
+
+        $server = select_server($this->manager, $options);
+
+        if (! isset($options['writeConcern']) && server_supports_feature($server, self::$wireVersionForWritableCommandWriteConcern) && ! is_in_transaction($options)) {
+            $options['writeConcern'] = $this->writeConcern;
+        }
+
+        $operation = new DropCollection($this->databaseName, $this->collectionName, $options);
+
+        return $operation->execute($server);
+    }
+
+    /**
+     * Drop a single index in the collection.
+     *
+     * @see DropIndexes::__construct() for supported options
+     * @param string|IndexInfo $indexName Index name or model object
+     * @param array            $options   Additional options
+     * @return array|object Command result document
+     * @throws UnsupportedException if options are not supported by the selected server
+     * @throws InvalidArgumentException for parameter/option parsing errors
+     * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
+     */
+    public function dropIndex($indexName, array $options = [])
+    {
+        $indexName = (string) $indexName;
+
+        if ($indexName === '*') {
+            throw new InvalidArgumentException('dropIndexes() must be used to drop multiple indexes');
+        }
+
+        if (! isset($options['typeMap'])) {
+            $options['typeMap'] = $this->typeMap;
+        }
+
+        $server = select_server($this->manager, $options);
+
+        if (! isset($options['writeConcern']) && server_supports_feature($server, self::$wireVersionForWritableCommandWriteConcern) && ! is_in_transaction($options)) {
+            $options['writeConcern'] = $this->writeConcern;
+        }
+
+        $operation = new DropIndexes($this->databaseName, $this->collectionName, $indexName, $options);
+
+        return $operation->execute($server);
+    }
+
+    /**
+     * Drop all indexes in the collection.
+     *
+     * @see DropIndexes::__construct() for supported options
+     * @param array $options Additional options
+     * @return array|object Command result document
+     * @throws UnsupportedException if options are not supported by the selected server
+     * @throws InvalidArgumentException for parameter/option parsing errors
+     * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
+     */
+    public function dropIndexes(array $options = [])
+    {
+        if (! isset($options['typeMap'])) {
+            $options['typeMap'] = $this->typeMap;
+        }
+
+        $server = select_server($this->manager, $options);
+
+        if (! isset($options['writeConcern']) && server_supports_feature($server, self::$wireVersionForWritableCommandWriteConcern) && ! is_in_transaction($options)) {
+            $options['writeConcern'] = $this->writeConcern;
+        }
+
+        $operation = new DropIndexes($this->databaseName, $this->collectionName, '*', $options);
+
+        return $operation->execute($server);
+    }
+
+    /**
+     * Gets an estimated number of documents in the collection using the collection metadata.
+     *
+     * @see EstimatedDocumentCount::__construct() for supported options
+     * @param array $options Command options
+     * @return integer
+     * @throws UnexpectedValueException if the command response was malformed
+     * @throws UnsupportedException if options are not supported by the selected server
+     * @throws InvalidArgumentException for parameter/option parsing errors
+     * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
+     */
+    public function estimatedDocumentCount(array $options = [])
+    {
+        if (! isset($options['readPreference']) && ! is_in_transaction($options)) {
+            $options['readPreference'] = $this->readPreference;
+        }
+
+        $server = select_server($this->manager, $options);
+
+        if (! isset($options['readConcern']) && server_supports_feature($server, self::$wireVersionForReadConcern) && ! is_in_transaction($options)) {
+            $options['readConcern'] = $this->readConcern;
+        }
+
+        $operation = new EstimatedDocumentCount($this->databaseName, $this->collectionName, $options);
+
+        return $operation->execute($server);
+    }
+
+    /**
+     * Explains explainable commands.
+     *
+     * @see Explain::__construct() for supported options
+     * @see http://docs.mongodb.org/manual/reference/command/explain/
+     * @param Explainable $explainable Command on which to run explain
+     * @param array       $options     Additional options
+     * @return array|object
+     * @throws UnsupportedException if explainable or options are not supported by the selected server
+     * @throws InvalidArgumentException for parameter/option parsing errors
+     * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
+     */
+    public function explain(Explainable $explainable, array $options = [])
+    {
+        if (! isset($options['readPreference']) && ! is_in_transaction($options)) {
+            $options['readPreference'] = $this->readPreference;
+        }
+
+        if (! isset($options['typeMap'])) {
+            $options['typeMap'] = $this->typeMap;
+        }
+
+        $server = select_server($this->manager, $options);
+
+        $operation = new Explain($this->databaseName, $explainable, $options);
+
+        return $operation->execute($server);
+    }
+
+    /**
+     * Finds documents matching the query.
+     *
+     * @see Find::__construct() for supported options
+     * @see http://docs.mongodb.org/manual/core/read-operations-introduction/
+     * @param array|object $filter  Query by which to filter documents
+     * @param array        $options Additional options
+     * @return Cursor
+     * @throws UnsupportedException if options are not supported by the selected server
+     * @throws InvalidArgumentException for parameter/option parsing errors
+     * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
+     */
+    public function find($filter = [], array $options = [])
+    {
+        if (! isset($options['readPreference']) && ! is_in_transaction($options)) {
+            $options['readPreference'] = $this->readPreference;
+        }
+
+        $server = select_server($this->manager, $options);
+
+        if (! isset($options['readConcern']) && server_supports_feature($server, self::$wireVersionForReadConcern) && ! is_in_transaction($options)) {
+            $options['readConcern'] = $this->readConcern;
+        }
+
+        if (! isset($options['typeMap'])) {
+            $options['typeMap'] = $this->typeMap;
+        }
+
+        $operation = new Find($this->databaseName, $this->collectionName, $filter, $options);
+
+        return $operation->execute($server);
+    }
+
+    /**
+     * Finds a single document matching the query.
+     *
+     * @see FindOne::__construct() for supported options
+     * @see http://docs.mongodb.org/manual/core/read-operations-introduction/
+     * @param array|object $filter  Query by which to filter documents
+     * @param array        $options Additional options
+     * @return array|object|null
+     * @throws UnsupportedException if options are not supported by the selected server
+     * @throws InvalidArgumentException for parameter/option parsing errors
+     * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
+     */
+    public function findOne($filter = [], array $options = [])
+    {
+        if (! isset($options['readPreference']) && ! is_in_transaction($options)) {
+            $options['readPreference'] = $this->readPreference;
+        }
+
+        $server = select_server($this->manager, $options);
+
+        if (! isset($options['readConcern']) && server_supports_feature($server, self::$wireVersionForReadConcern) && ! is_in_transaction($options)) {
+            $options['readConcern'] = $this->readConcern;
+        }
+
+        if (! isset($options['typeMap'])) {
+            $options['typeMap'] = $this->typeMap;
+        }
+
+        $operation = new FindOne($this->databaseName, $this->collectionName, $filter, $options);
+
+        return $operation->execute($server);
+    }
+
+    /**
+     * Finds a single document and deletes it, returning the original.
+     *
+     * The document to return may be null if no document matched the filter.
+     *
+     * @see FindOneAndDelete::__construct() for supported options
+     * @see http://docs.mongodb.org/manual/reference/command/findAndModify/
+     * @param array|object $filter  Query by which to filter documents
+     * @param array        $options Command options
+     * @return array|object|null
+     * @throws UnexpectedValueException if the command response was malformed
+     * @throws UnsupportedException if options are not supported by the selected server
+     * @throws InvalidArgumentException for parameter/option parsing errors
+     * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
+     */
+    public function findOneAndDelete($filter, array $options = [])
+    {
+        $server = select_server($this->manager, $options);
+
+        if (! isset($options['writeConcern']) && server_supports_feature($server, self::$wireVersionForFindAndModifyWriteConcern) && ! is_in_transaction($options)) {
+            $options['writeConcern'] = $this->writeConcern;
+        }
+
+        if (! isset($options['typeMap'])) {
+            $options['typeMap'] = $this->typeMap;
+        }
+
+        $operation = new FindOneAndDelete($this->databaseName, $this->collectionName, $filter, $options);
+
+        return $operation->execute($server);
+    }
+
+    /**
+     * Finds a single document and replaces it, returning either the original or
+     * the replaced document.
+     *
+     * The document to return may be null if no document matched the filter. By
+     * default, the original document is returned. Specify
+     * FindOneAndReplace::RETURN_DOCUMENT_AFTER for the "returnDocument" option
+     * to return the updated document.
+     *
+     * @see FindOneAndReplace::__construct() for supported options
+     * @see http://docs.mongodb.org/manual/reference/command/findAndModify/
+     * @param array|object $filter      Query by which to filter documents
+     * @param array|object $replacement Replacement document
+     * @param array        $options     Command options
+     * @return array|object|null
+     * @throws UnexpectedValueException if the command response was malformed
+     * @throws UnsupportedException if options are not supported by the selected server
+     * @throws InvalidArgumentException for parameter/option parsing errors
+     * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
+     */
+    public function findOneAndReplace($filter, $replacement, array $options = [])
+    {
+        $server = select_server($this->manager, $options);
+
+        if (! isset($options['writeConcern']) && server_supports_feature($server, self::$wireVersionForFindAndModifyWriteConcern) && ! is_in_transaction($options)) {
+            $options['writeConcern'] = $this->writeConcern;
+        }
+
+        if (! isset($options['typeMap'])) {
+            $options['typeMap'] = $this->typeMap;
+        }
+
+        $operation = new FindOneAndReplace($this->databaseName, $this->collectionName, $filter, $replacement, $options);
+
+        return $operation->execute($server);
+    }
+
+    /**
+     * Finds a single document and updates it, returning either the original or
+     * the updated document.
+     *
+     * The document to return may be null if no document matched the filter. By
+     * default, the original document is returned. Specify
+     * FindOneAndUpdate::RETURN_DOCUMENT_AFTER for the "returnDocument" option
+     * to return the updated document.
+     *
+     * @see FindOneAndReplace::__construct() for supported options
+     * @see http://docs.mongodb.org/manual/reference/command/findAndModify/
+     * @param array|object $filter  Query by which to filter documents
+     * @param array|object $update  Update to apply to the matched document
+     * @param array        $options Command options
+     * @return array|object|null
+     * @throws UnexpectedValueException if the command response was malformed
+     * @throws UnsupportedException if options are not supported by the selected server
+     * @throws InvalidArgumentException for parameter/option parsing errors
+     * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
+     */
+    public function findOneAndUpdate($filter, $update, array $options = [])
+    {
+        $server = select_server($this->manager, $options);
+
+        if (! isset($options['writeConcern']) && server_supports_feature($server, self::$wireVersionForFindAndModifyWriteConcern) && ! is_in_transaction($options)) {
+            $options['writeConcern'] = $this->writeConcern;
+        }
+
+        if (! isset($options['typeMap'])) {
+            $options['typeMap'] = $this->typeMap;
+        }
+
+        $operation = new FindOneAndUpdate($this->databaseName, $this->collectionName, $filter, $update, $options);
+
+        return $operation->execute($server);
+    }
+
+    /**
+     * Return the collection name.
+     *
+     * @return string
+     */
+    public function getCollectionName()
+    {
+        return $this->collectionName;
+    }
+
+    /**
+     * Return the database name.
+     *
+     * @return string
+     */
+    public function getDatabaseName()
+    {
+        return $this->databaseName;
+    }
+
+    /**
+     * Return the Manager.
+     *
+     * @return Manager
+     */
+    public function getManager()
+    {
+        return $this->manager;
+    }
+
+    /**
+     * Return the collection namespace.
+     *
+     * @see https://docs.mongodb.org/manual/reference/glossary/#term-namespace
+     * @return string
+     */
+    public function getNamespace()
+    {
+        return $this->databaseName . '.' . $this->collectionName;
+    }
+
+    /**
+     * Return the read concern for this collection.
+     *
+     * @see http://php.net/manual/en/mongodb-driver-readconcern.isdefault.php
+     * @return ReadConcern
+     */
+    public function getReadConcern()
+    {
+        return $this->readConcern;
+    }
+
+    /**
+     * Return the read preference for this collection.
+     *
+     * @return ReadPreference
+     */
+    public function getReadPreference()
+    {
+        return $this->readPreference;
+    }
+
+    /**
+     * Return the type map for this collection.
+     *
+     * @return array
+     */
+    public function getTypeMap()
+    {
+        return $this->typeMap;
+    }
+
+    /**
+     * Return the write concern for this collection.
+     *
+     * @see http://php.net/manual/en/mongodb-driver-writeconcern.isdefault.php
+     * @return WriteConcern
+     */
+    public function getWriteConcern()
+    {
+        return $this->writeConcern;
+    }
+
+    /**
+     * Inserts multiple documents.
+     *
+     * @see InsertMany::__construct() for supported options
+     * @see http://docs.mongodb.org/manual/reference/command/insert/
+     * @param array[]|object[] $documents The documents to insert
+     * @param array            $options   Command options
+     * @return InsertManyResult
+     * @throws InvalidArgumentException for parameter/option parsing errors
+     * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
+     */
+    public function insertMany(array $documents, array $options = [])
+    {
+        if (! isset($options['writeConcern']) && ! is_in_transaction($options)) {
+            $options['writeConcern'] = $this->writeConcern;
+        }
+
+        $operation = new InsertMany($this->databaseName, $this->collectionName, $documents, $options);
+        $server = select_server($this->manager, $options);
+
+        return $operation->execute($server);
+    }
+
+    /**
+     * Inserts one document.
+     *
+     * @see InsertOne::__construct() for supported options
+     * @see http://docs.mongodb.org/manual/reference/command/insert/
+     * @param array|object $document The document to insert
+     * @param array        $options  Command options
+     * @return InsertOneResult
+     * @throws InvalidArgumentException for parameter/option parsing errors
+     * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
+     */
+    public function insertOne($document, array $options = [])
+    {
+        if (! isset($options['writeConcern']) && ! is_in_transaction($options)) {
+            $options['writeConcern'] = $this->writeConcern;
+        }
+
+        $operation = new InsertOne($this->databaseName, $this->collectionName, $document, $options);
+        $server = select_server($this->manager, $options);
+
+        return $operation->execute($server);
+    }
+
+    /**
+     * Returns information for all indexes for the collection.
+     *
+     * @see ListIndexes::__construct() for supported options
+     * @param array $options
+     * @return IndexInfoIterator
+     * @throws InvalidArgumentException for parameter/option parsing errors
+     * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
+     */
+    public function listIndexes(array $options = [])
+    {
+        $operation = new ListIndexes($this->databaseName, $this->collectionName, $options);
+        $server = select_server($this->manager, $options);
+
+        return $operation->execute($server);
+    }
+
+    /**
+     * Executes a map-reduce aggregation on the collection.
+     *
+     * @see MapReduce::__construct() for supported options
+     * @see http://docs.mongodb.org/manual/reference/command/mapReduce/
+     * @param JavascriptInterface $map     Map function
+     * @param JavascriptInterface $reduce  Reduce function
+     * @param string|array|object $out     Output specification
+     * @param array               $options Command options
+     * @return MapReduceResult
+     * @throws UnsupportedException if options are not supported by the selected server
+     * @throws InvalidArgumentException for parameter/option parsing errors
+     * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
+     * @throws UnexpectedValueException if the command response was malformed
+     */
+    public function mapReduce(JavascriptInterface $map, JavascriptInterface $reduce, $out, array $options = [])
+    {
+        $hasOutputCollection = ! is_mapreduce_output_inline($out);
+
+        if (! isset($options['readPreference']) && ! is_in_transaction($options)) {
+            $options['readPreference'] = $this->readPreference;
+        }
+
+        // Check if the out option is inline because we will want to coerce a primary read preference if not
+        if ($hasOutputCollection) {
+            $options['readPreference'] = new ReadPreference(ReadPreference::RP_PRIMARY);
+        }
+
+        $server = select_server($this->manager, $options);
+
+        /* A "majority" read concern is not compatible with inline output, so
+         * avoid providing the Collection's read concern if it would conflict.
+         *
+         * A read concern is also not compatible with transactions.
+         */
+        if (! isset($options['readConcern']) && ! ($hasOutputCollection && $this->readConcern->getLevel() === ReadConcern::MAJORITY) && server_supports_feature($server, self::$wireVersionForReadConcern) && ! is_in_transaction($options)) {
+            $options['readConcern'] = $this->readConcern;
+        }
+
+        if (! isset($options['typeMap'])) {
+            $options['typeMap'] = $this->typeMap;
+        }
+
+        if (! isset($options['writeConcern']) && server_supports_feature($server, self::$wireVersionForWritableCommandWriteConcern) && ! is_in_transaction($options)) {
+            $options['writeConcern'] = $this->writeConcern;
+        }
+
+        $operation = new MapReduce($this->databaseName, $this->collectionName, $map, $reduce, $out, $options);
+
+        return $operation->execute($server);
+    }
+
+    /**
+     * Replaces at most one document matching the filter.
+     *
+     * @see ReplaceOne::__construct() for supported options
+     * @see http://docs.mongodb.org/manual/reference/command/update/
+     * @param array|object $filter      Query by which to filter documents
+     * @param array|object $replacement Replacement document
+     * @param array        $options     Command options
+     * @return UpdateResult
+     * @throws UnsupportedException if options are not supported by the selected server
+     * @throws InvalidArgumentException for parameter/option parsing errors
+     * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
+     */
+    public function replaceOne($filter, $replacement, array $options = [])
+    {
+        if (! isset($options['writeConcern']) && ! is_in_transaction($options)) {
+            $options['writeConcern'] = $this->writeConcern;
+        }
+
+        $operation = new ReplaceOne($this->databaseName, $this->collectionName, $filter, $replacement, $options);
+        $server = select_server($this->manager, $options);
+
+        return $operation->execute($server);
+    }
+
+    /**
+     * Updates all documents matching the filter.
+     *
+     * @see UpdateMany::__construct() for supported options
+     * @see http://docs.mongodb.org/manual/reference/command/update/
+     * @param array|object $filter  Query by which to filter documents
+     * @param array|object $update  Update to apply to the matched documents
+     * @param array        $options Command options
+     * @return UpdateResult
+     * @throws UnsupportedException if options are not supported by the selected server
+     * @throws InvalidArgumentException for parameter/option parsing errors
+     * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
+     */
+    public function updateMany($filter, $update, array $options = [])
+    {
+        if (! isset($options['writeConcern']) && ! is_in_transaction($options)) {
+            $options['writeConcern'] = $this->writeConcern;
+        }
+
+        $operation = new UpdateMany($this->databaseName, $this->collectionName, $filter, $update, $options);
+        $server = select_server($this->manager, $options);
+
+        return $operation->execute($server);
+    }
+
+    /**
+     * Updates at most one document matching the filter.
+     *
+     * @see UpdateOne::__construct() for supported options
+     * @see http://docs.mongodb.org/manual/reference/command/update/
+     * @param array|object $filter  Query by which to filter documents
+     * @param array|object $update  Update to apply to the matched document
+     * @param array        $options Command options
+     * @return UpdateResult
+     * @throws UnsupportedException if options are not supported by the selected server
+     * @throws InvalidArgumentException for parameter/option parsing errors
+     * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
+     */
+    public function updateOne($filter, $update, array $options = [])
+    {
+        if (! isset($options['writeConcern']) && ! is_in_transaction($options)) {
+            $options['writeConcern'] = $this->writeConcern;
+        }
+
+        $operation = new UpdateOne($this->databaseName, $this->collectionName, $filter, $update, $options);
+        $server = select_server($this->manager, $options);
+
+        return $operation->execute($server);
+    }
+
+    /**
+     * Create a change stream for watching changes to the collection.
+     *
+     * @see Watch::__construct() for supported options
+     * @param array $pipeline List of pipeline operations
+     * @param array $options  Command options
+     * @return ChangeStream
+     * @throws InvalidArgumentException for parameter/option parsing errors
+     */
+    public function watch(array $pipeline = [], array $options = [])
+    {
+        if (! isset($options['readPreference']) && ! is_in_transaction($options)) {
+            $options['readPreference'] = $this->readPreference;
+        }
+
+        $server = select_server($this->manager, $options);
+
+        /* Although change streams require a newer version of the server than
+         * read concerns, perform the usual wire version check before inheriting
+         * the collection's read concern. In the event that the server is too
+         * old, this makes it more likely that users will encounter an error
+         * related to change streams being unsupported instead of an
+         * UnsupportedException regarding use of the "readConcern" option from
+         * the Aggregate operation class. */
+        if (! isset($options['readConcern']) && server_supports_feature($server, self::$wireVersionForReadConcern) && ! is_in_transaction($options)) {
+            $options['readConcern'] = $this->readConcern;
+        }
+
+        if (! isset($options['typeMap'])) {
+            $options['typeMap'] = $this->typeMap;
+        }
+
+        $operation = new Watch($this->manager, $this->databaseName, $this->collectionName, $pipeline, $options);
+
+        return $operation->execute($server);
+    }
+
+    /**
+     * Get a clone of this collection with different options.
+     *
+     * @see Collection::__construct() for supported options
+     * @param array $options Collection constructor options
+     * @return Collection
+     * @throws InvalidArgumentException for parameter/option parsing errors
+     */
+    public function withOptions(array $options = [])
+    {
+        $options += [
+            'readConcern' => $this->readConcern,
+            'readPreference' => $this->readPreference,
+            'typeMap' => $this->typeMap,
+            'writeConcern' => $this->writeConcern,
+        ];
+
+        return new Collection($this->manager, $this->databaseName, $this->collectionName, $options);
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Command/ListCollections.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Command/ListCollections.php
new file mode 100644
index 0000000000000000000000000000000000000000..4f85f13712c183b8f376ffac93ae6a3fe90766ec
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Command/ListCollections.php	
@@ -0,0 +1,139 @@
+<?php
+/*
+ * Copyright 2020-present MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace MongoDB\Command;
+
+use MongoDB\Driver\Command;
+use MongoDB\Driver\Exception\RuntimeException as DriverRuntimeException;
+use MongoDB\Driver\Server;
+use MongoDB\Driver\Session;
+use MongoDB\Exception\InvalidArgumentException;
+use MongoDB\Model\CachingIterator;
+use MongoDB\Operation\Executable;
+use function is_array;
+use function is_bool;
+use function is_integer;
+use function is_object;
+
+/**
+ * Wrapper for the listCollections command.
+ *
+ * @internal
+ * @see http://docs.mongodb.org/manual/reference/command/listCollections/
+ */
+class ListCollections implements Executable
+{
+    /** @var string */
+    private $databaseName;
+
+    /** @var array */
+    private $options;
+
+    /**
+     * Constructs a listCollections command.
+     *
+     * Supported options:
+     *
+     *  * filter (document): Query by which to filter collections.
+     *
+     *  * maxTimeMS (integer): The maximum amount of time to allow the query to
+     *    run.
+     *
+     *  * nameOnly (boolean): A flag to indicate whether the command should
+     *    return just the collection/view names and type or return both the name
+     *    and other information.
+     *
+     *  * session (MongoDB\Driver\Session): Client session.
+     *
+     *    Sessions are not supported for server versions < 3.6.
+     *
+     * @param string $databaseName Database name
+     * @param array  $options      Command options
+     * @throws InvalidArgumentException for parameter/option parsing errors
+     */
+    public function __construct($databaseName, array $options = [])
+    {
+        if (isset($options['filter']) && ! is_array($options['filter']) && ! is_object($options['filter'])) {
+            throw InvalidArgumentException::invalidType('"filter" option', $options['filter'], 'array or object');
+        }
+
+        if (isset($options['maxTimeMS']) && ! is_integer($options['maxTimeMS'])) {
+            throw InvalidArgumentException::invalidType('"maxTimeMS" option', $options['maxTimeMS'], 'integer');
+        }
+
+        if (isset($options['nameOnly']) && ! is_bool($options['nameOnly'])) {
+            throw InvalidArgumentException::invalidType('"nameOnly" option', $options['nameOnly'], 'boolean');
+        }
+
+        if (isset($options['session']) && ! $options['session'] instanceof Session) {
+            throw InvalidArgumentException::invalidType('"session" option', $options['session'], Session::class);
+        }
+
+        $this->databaseName = (string) $databaseName;
+        $this->options = $options;
+    }
+
+    /**
+     * Execute the operation.
+     *
+     * @see Executable::execute()
+     * @param Server $server
+     * @return CachingIterator
+     * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
+     */
+    public function execute(Server $server)
+    {
+        $cmd = ['listCollections' => 1];
+
+        if (! empty($this->options['filter'])) {
+            $cmd['filter'] = (object) $this->options['filter'];
+        }
+
+        if (isset($this->options['maxTimeMS'])) {
+            $cmd['maxTimeMS'] = $this->options['maxTimeMS'];
+        }
+
+        if (isset($this->options['nameOnly'])) {
+            $cmd['nameOnly'] = $this->options['nameOnly'];
+        }
+
+        $cursor = $server->executeReadCommand($this->databaseName, new Command($cmd), $this->createOptions());
+        $cursor->setTypeMap(['root' => 'array', 'document' => 'array']);
+
+        return new CachingIterator($cursor);
+    }
+
+    /**
+     * Create options for executing the command.
+     *
+     * Note: read preference is intentionally omitted, as the spec requires that
+     * the command be executed on the primary.
+     *
+     * @see http://php.net/manual/en/mongodb-driver-server.executecommand.php
+     * @return array
+     */
+    private function createOptions()
+    {
+        $options = [];
+
+        if (isset($this->options['session'])) {
+            $options['session'] = $this->options['session'];
+        }
+
+        return $options;
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Command/ListDatabases.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Command/ListDatabases.php
new file mode 100644
index 0000000000000000000000000000000000000000..c9fa58fc869071feea25f1879cc7d006edc969ad
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Command/ListDatabases.php	
@@ -0,0 +1,156 @@
+<?php
+/*
+ * Copyright 2020-present MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace MongoDB\Command;
+
+use MongoDB\Driver\Command;
+use MongoDB\Driver\Exception\RuntimeException as DriverRuntimeException;
+use MongoDB\Driver\Server;
+use MongoDB\Driver\Session;
+use MongoDB\Exception\InvalidArgumentException;
+use MongoDB\Exception\UnexpectedValueException;
+use MongoDB\Operation\Executable;
+use function current;
+use function is_array;
+use function is_bool;
+use function is_integer;
+use function is_object;
+
+/**
+ * Wrapper for the ListDatabases command.
+ *
+ * @internal
+ * @see http://docs.mongodb.org/manual/reference/command/listDatabases/
+ */
+class ListDatabases implements Executable
+{
+    /** @var array */
+    private $options;
+
+    /**
+     * Constructs a listDatabases command.
+     *
+     * Supported options:
+     *
+     *  * authorizedDatabases (boolean): Determines which databases are returned
+     *    based on the user privileges.
+     *
+     *    For servers < 4.0.5, this option is ignored.
+     *
+     *  * filter (document): Query by which to filter databases.
+     *
+     *    For servers < 3.6, this option is ignored.
+     *
+     *  * maxTimeMS (integer): The maximum amount of time to allow the query to
+     *    run.
+     *
+     *  * nameOnly (boolean): A flag to indicate whether the command should
+     *    return just the database names, or return both database names and size
+     *    information.
+     *
+     *  * session (MongoDB\Driver\Session): Client session.
+     *
+     *    Sessions are not supported for server versions < 3.6.
+     *
+     * @param array $options Command options
+     * @throws InvalidArgumentException for parameter/option parsing errors
+     */
+    public function __construct(array $options = [])
+    {
+        if (isset($options['authorizedDatabases']) && ! is_bool($options['authorizedDatabases'])) {
+            throw InvalidArgumentException::invalidType('"authorizedDatabases" option', $options['authorizedDatabases'], 'boolean');
+        }
+
+        if (isset($options['filter']) && ! is_array($options['filter']) && ! is_object($options['filter'])) {
+            throw InvalidArgumentException::invalidType('"filter" option', $options['filter'], ['array', 'object']);
+        }
+
+        if (isset($options['maxTimeMS']) && ! is_integer($options['maxTimeMS'])) {
+            throw InvalidArgumentException::invalidType('"maxTimeMS" option', $options['maxTimeMS'], 'integer');
+        }
+
+        if (isset($options['nameOnly']) && ! is_bool($options['nameOnly'])) {
+            throw InvalidArgumentException::invalidType('"nameOnly" option', $options['nameOnly'], 'boolean');
+        }
+
+        if (isset($options['session']) && ! $options['session'] instanceof Session) {
+            throw InvalidArgumentException::invalidType('"session" option', $options['session'], Session::class);
+        }
+
+        $this->options = $options;
+    }
+
+    /**
+     * Execute the operation.
+     *
+     * @see Executable::execute()
+     * @param Server $server
+     * @return array An array of database info structures
+     * @throws UnexpectedValueException if the command response was malformed
+     * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
+     */
+    public function execute(Server $server)
+    {
+        $cmd = ['listDatabases' => 1];
+
+        if (isset($this->options['authorizedDatabases'])) {
+            $cmd['authorizedDatabases'] = $this->options['authorizedDatabases'];
+        }
+
+        if (! empty($this->options['filter'])) {
+            $cmd['filter'] = (object) $this->options['filter'];
+        }
+
+        if (isset($this->options['maxTimeMS'])) {
+            $cmd['maxTimeMS'] = $this->options['maxTimeMS'];
+        }
+
+        if (isset($this->options['nameOnly'])) {
+            $cmd['nameOnly'] = $this->options['nameOnly'];
+        }
+
+        $cursor = $server->executeReadCommand('admin', new Command($cmd), $this->createOptions());
+        $cursor->setTypeMap(['root' => 'array', 'document' => 'array']);
+        $result = current($cursor->toArray());
+
+        if (! isset($result['databases']) || ! is_array($result['databases'])) {
+            throw new UnexpectedValueException('listDatabases command did not return a "databases" array');
+        }
+
+        return $result['databases'];
+    }
+
+    /**
+     * Create options for executing the command.
+     *
+     * Note: read preference is intentionally omitted, as the spec requires that
+     * the command be executed on the primary.
+     *
+     * @see http://php.net/manual/en/mongodb-driver-server.executecommand.php
+     * @return array
+     */
+    private function createOptions()
+    {
+        $options = [];
+
+        if (isset($this->options['session'])) {
+            $options['session'] = $this->options['session'];
+        }
+
+        return $options;
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Database.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Database.php
new file mode 100644
index 0000000000000000000000000000000000000000..fadc64be57e48c7fcb4b70c2095251a380ff0720
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Database.php	
@@ -0,0 +1,559 @@
+<?php
+/*
+ * Copyright 2015-2017 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace MongoDB;
+
+use Iterator;
+use MongoDB\Driver\Cursor;
+use MongoDB\Driver\Exception\RuntimeException as DriverRuntimeException;
+use MongoDB\Driver\Manager;
+use MongoDB\Driver\ReadConcern;
+use MongoDB\Driver\ReadPreference;
+use MongoDB\Driver\WriteConcern;
+use MongoDB\Exception\InvalidArgumentException;
+use MongoDB\Exception\UnexpectedValueException;
+use MongoDB\Exception\UnsupportedException;
+use MongoDB\GridFS\Bucket;
+use MongoDB\Model\BSONArray;
+use MongoDB\Model\BSONDocument;
+use MongoDB\Model\CollectionInfoIterator;
+use MongoDB\Operation\Aggregate;
+use MongoDB\Operation\CreateCollection;
+use MongoDB\Operation\DatabaseCommand;
+use MongoDB\Operation\DropCollection;
+use MongoDB\Operation\DropDatabase;
+use MongoDB\Operation\ListCollectionNames;
+use MongoDB\Operation\ListCollections;
+use MongoDB\Operation\ModifyCollection;
+use MongoDB\Operation\Watch;
+use Traversable;
+use function is_array;
+use function strlen;
+
+class Database
+{
+    /** @var array */
+    private static $defaultTypeMap = [
+        'array' => BSONArray::class,
+        'document' => BSONDocument::class,
+        'root' => BSONDocument::class,
+    ];
+
+    /** @var integer */
+    private static $wireVersionForReadConcern = 4;
+
+    /** @var integer */
+    private static $wireVersionForWritableCommandWriteConcern = 5;
+
+    /** @var integer */
+    private static $wireVersionForReadConcernWithWriteStage = 8;
+
+    /** @var string */
+    private $databaseName;
+
+    /** @var Manager */
+    private $manager;
+
+    /** @var ReadConcern */
+    private $readConcern;
+
+    /** @var ReadPreference */
+    private $readPreference;
+
+    /** @var array */
+    private $typeMap;
+
+    /** @var WriteConcern */
+    private $writeConcern;
+
+    /**
+     * Constructs new Database instance.
+     *
+     * This class provides methods for database-specific operations and serves
+     * as a gateway for accessing collections.
+     *
+     * Supported options:
+     *
+     *  * readConcern (MongoDB\Driver\ReadConcern): The default read concern to
+     *    use for database operations and selected collections. Defaults to the
+     *    Manager's read concern.
+     *
+     *  * readPreference (MongoDB\Driver\ReadPreference): The default read
+     *    preference to use for database operations and selected collections.
+     *    Defaults to the Manager's read preference.
+     *
+     *  * typeMap (array): Default type map for cursors and BSON documents.
+     *
+     *  * writeConcern (MongoDB\Driver\WriteConcern): The default write concern
+     *    to use for database operations and selected collections. Defaults to
+     *    the Manager's write concern.
+     *
+     * @param Manager $manager      Manager instance from the driver
+     * @param string  $databaseName Database name
+     * @param array   $options      Database options
+     * @throws InvalidArgumentException for parameter/option parsing errors
+     */
+    public function __construct(Manager $manager, $databaseName, array $options = [])
+    {
+        if (strlen($databaseName) < 1) {
+            throw new InvalidArgumentException('$databaseName is invalid: ' . $databaseName);
+        }
+
+        if (isset($options['readConcern']) && ! $options['readConcern'] instanceof ReadConcern) {
+            throw InvalidArgumentException::invalidType('"readConcern" option', $options['readConcern'], ReadConcern::class);
+        }
+
+        if (isset($options['readPreference']) && ! $options['readPreference'] instanceof ReadPreference) {
+            throw InvalidArgumentException::invalidType('"readPreference" option', $options['readPreference'], ReadPreference::class);
+        }
+
+        if (isset($options['typeMap']) && ! is_array($options['typeMap'])) {
+            throw InvalidArgumentException::invalidType('"typeMap" option', $options['typeMap'], 'array');
+        }
+
+        if (isset($options['writeConcern']) && ! $options['writeConcern'] instanceof WriteConcern) {
+            throw InvalidArgumentException::invalidType('"writeConcern" option', $options['writeConcern'], WriteConcern::class);
+        }
+
+        $this->manager = $manager;
+        $this->databaseName = (string) $databaseName;
+        $this->readConcern = $options['readConcern'] ?? $this->manager->getReadConcern();
+        $this->readPreference = $options['readPreference'] ?? $this->manager->getReadPreference();
+        $this->typeMap = $options['typeMap'] ?? self::$defaultTypeMap;
+        $this->writeConcern = $options['writeConcern'] ?? $this->manager->getWriteConcern();
+    }
+
+    /**
+     * Return internal properties for debugging purposes.
+     *
+     * @see http://php.net/manual/en/language.oop5.magic.php#language.oop5.magic.debuginfo
+     * @return array
+     */
+    public function __debugInfo()
+    {
+        return [
+            'databaseName' => $this->databaseName,
+            'manager' => $this->manager,
+            'readConcern' => $this->readConcern,
+            'readPreference' => $this->readPreference,
+            'typeMap' => $this->typeMap,
+            'writeConcern' => $this->writeConcern,
+        ];
+    }
+
+    /**
+     * Select a collection within this database.
+     *
+     * Note: collections whose names contain special characters (e.g. ".") may
+     * be selected with complex syntax (e.g. $database->{"system.profile"}) or
+     * {@link selectCollection()}.
+     *
+     * @see http://php.net/oop5.overloading#object.get
+     * @see http://php.net/types.string#language.types.string.parsing.complex
+     * @param string $collectionName Name of the collection to select
+     * @return Collection
+     */
+    public function __get($collectionName)
+    {
+        return $this->selectCollection($collectionName);
+    }
+
+    /**
+     * Return the database name.
+     *
+     * @return string
+     */
+    public function __toString()
+    {
+        return $this->databaseName;
+    }
+
+    /**
+     * Runs an aggregation framework pipeline on the database for pipeline
+     * stages that do not require an underlying collection, such as $currentOp
+     * and $listLocalSessions. Requires MongoDB >= 3.6
+     *
+     * @see Aggregate::__construct() for supported options
+     * @param array $pipeline List of pipeline operations
+     * @param array $options  Command options
+     * @return Traversable
+     * @throws UnexpectedValueException if the command response was malformed
+     * @throws UnsupportedException if options are not supported by the selected server
+     * @throws InvalidArgumentException for parameter/option parsing errors
+     * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
+     */
+    public function aggregate(array $pipeline, array $options = [])
+    {
+        $hasWriteStage = is_last_pipeline_operator_write($pipeline);
+
+        if (! isset($options['readPreference']) && ! is_in_transaction($options)) {
+            $options['readPreference'] = $this->readPreference;
+        }
+
+        if ($hasWriteStage) {
+            $options['readPreference'] = new ReadPreference(ReadPreference::RP_PRIMARY);
+        }
+
+        $server = select_server($this->manager, $options);
+
+        /* MongoDB 4.2 and later supports a read concern when an $out stage is
+         * being used, but earlier versions do not.
+         *
+         * A read concern is also not compatible with transactions.
+         */
+        if (! isset($options['readConcern']) &&
+            server_supports_feature($server, self::$wireVersionForReadConcern) &&
+            ! is_in_transaction($options) &&
+            ( ! $hasWriteStage || server_supports_feature($server, self::$wireVersionForReadConcernWithWriteStage))
+        ) {
+            $options['readConcern'] = $this->readConcern;
+        }
+
+        if (! isset($options['typeMap'])) {
+            $options['typeMap'] = $this->typeMap;
+        }
+
+        if ($hasWriteStage &&
+            ! isset($options['writeConcern']) &&
+            server_supports_feature($server, self::$wireVersionForWritableCommandWriteConcern) &&
+            ! is_in_transaction($options)) {
+            $options['writeConcern'] = $this->writeConcern;
+        }
+
+        $operation = new Aggregate($this->databaseName, null, $pipeline, $options);
+
+        return $operation->execute($server);
+    }
+
+    /**
+     * Execute a command on this database.
+     *
+     * @see DatabaseCommand::__construct() for supported options
+     * @param array|object $command Command document
+     * @param array        $options Options for command execution
+     * @return Cursor
+     * @throws InvalidArgumentException for parameter/option parsing errors
+     * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
+     */
+    public function command($command, array $options = [])
+    {
+        if (! isset($options['typeMap'])) {
+            $options['typeMap'] = $this->typeMap;
+        }
+
+        $operation = new DatabaseCommand($this->databaseName, $command, $options);
+        $server = select_server($this->manager, $options);
+
+        return $operation->execute($server);
+    }
+
+    /**
+     * Create a new collection explicitly.
+     *
+     * @see CreateCollection::__construct() for supported options
+     * @param string $collectionName
+     * @param array  $options
+     * @return array|object Command result document
+     * @throws UnsupportedException if options are not supported by the selected server
+     * @throws InvalidArgumentException for parameter/option parsing errors
+     * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
+     */
+    public function createCollection($collectionName, array $options = [])
+    {
+        if (! isset($options['typeMap'])) {
+            $options['typeMap'] = $this->typeMap;
+        }
+
+        $server = select_server($this->manager, $options);
+
+        if (! isset($options['writeConcern']) && server_supports_feature($server, self::$wireVersionForWritableCommandWriteConcern) && ! is_in_transaction($options)) {
+            $options['writeConcern'] = $this->writeConcern;
+        }
+
+        $operation = new CreateCollection($this->databaseName, $collectionName, $options);
+
+        return $operation->execute($server);
+    }
+
+    /**
+     * Drop this database.
+     *
+     * @see DropDatabase::__construct() for supported options
+     * @param array $options Additional options
+     * @return array|object Command result document
+     * @throws UnsupportedException if options are unsupported on the selected server
+     * @throws InvalidArgumentException for parameter/option parsing errors
+     * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
+     */
+    public function drop(array $options = [])
+    {
+        if (! isset($options['typeMap'])) {
+            $options['typeMap'] = $this->typeMap;
+        }
+
+        $server = select_server($this->manager, $options);
+
+        if (! isset($options['writeConcern']) && server_supports_feature($server, self::$wireVersionForWritableCommandWriteConcern) && ! is_in_transaction($options)) {
+            $options['writeConcern'] = $this->writeConcern;
+        }
+
+        $operation = new DropDatabase($this->databaseName, $options);
+
+        return $operation->execute($server);
+    }
+
+    /**
+     * Drop a collection within this database.
+     *
+     * @see DropCollection::__construct() for supported options
+     * @param string $collectionName Collection name
+     * @param array  $options        Additional options
+     * @return array|object Command result document
+     * @throws UnsupportedException if options are unsupported on the selected server
+     * @throws InvalidArgumentException for parameter/option parsing errors
+     * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
+     */
+    public function dropCollection($collectionName, array $options = [])
+    {
+        if (! isset($options['typeMap'])) {
+            $options['typeMap'] = $this->typeMap;
+        }
+
+        $server = select_server($this->manager, $options);
+
+        if (! isset($options['writeConcern']) && server_supports_feature($server, self::$wireVersionForWritableCommandWriteConcern) && ! is_in_transaction($options)) {
+            $options['writeConcern'] = $this->writeConcern;
+        }
+
+        $operation = new DropCollection($this->databaseName, $collectionName, $options);
+
+        return $operation->execute($server);
+    }
+
+    /**
+     * Returns the database name.
+     *
+     * @return string
+     */
+    public function getDatabaseName()
+    {
+        return $this->databaseName;
+    }
+
+    /**
+     * Return the Manager.
+     *
+     * @return Manager
+     */
+    public function getManager()
+    {
+        return $this->manager;
+    }
+
+    /**
+     * Return the read concern for this database.
+     *
+     * @see http://php.net/manual/en/mongodb-driver-readconcern.isdefault.php
+     * @return ReadConcern
+     */
+    public function getReadConcern()
+    {
+        return $this->readConcern;
+    }
+
+    /**
+     * Return the read preference for this database.
+     *
+     * @return ReadPreference
+     */
+    public function getReadPreference()
+    {
+        return $this->readPreference;
+    }
+
+    /**
+     * Return the type map for this database.
+     *
+     * @return array
+     */
+    public function getTypeMap()
+    {
+        return $this->typeMap;
+    }
+
+    /**
+     * Return the write concern for this database.
+     *
+     * @see http://php.net/manual/en/mongodb-driver-writeconcern.isdefault.php
+     * @return WriteConcern
+     */
+    public function getWriteConcern()
+    {
+        return $this->writeConcern;
+    }
+
+    /**
+     * Returns the names of all collections in this database
+     *
+     * @see ListCollectionNames::__construct() for supported options
+     * @throws InvalidArgumentException for parameter/option parsing errors
+     * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
+     */
+    public function listCollectionNames(array $options = []) : Iterator
+    {
+        $operation = new ListCollectionNames($this->databaseName, $options);
+        $server = select_server($this->manager, $options);
+
+        return $operation->execute($server);
+    }
+
+    /**
+     * Returns information for all collections in this database.
+     *
+     * @see ListCollections::__construct() for supported options
+     * @param array $options
+     * @return CollectionInfoIterator
+     * @throws InvalidArgumentException for parameter/option parsing errors
+     * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
+     */
+    public function listCollections(array $options = [])
+    {
+        $operation = new ListCollections($this->databaseName, $options);
+        $server = select_server($this->manager, $options);
+
+        return $operation->execute($server);
+    }
+
+    /**
+     * Modifies a collection or view.
+     *
+     * @see ModifyCollection::__construct() for supported options
+     * @param string $collectionName    Collection or view to modify
+     * @param array  $collectionOptions Collection or view options to assign
+     * @param array  $options           Command options
+     * @return array|object
+     * @throws InvalidArgumentException for parameter/option parsing errors
+     * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
+     */
+    public function modifyCollection($collectionName, array $collectionOptions, array $options = [])
+    {
+        if (! isset($options['typeMap'])) {
+            $options['typeMap'] = $this->typeMap;
+        }
+
+        $server = select_server($this->manager, $options);
+
+        if (! isset($options['writeConcern']) && server_supports_feature($server, self::$wireVersionForWritableCommandWriteConcern) && ! is_in_transaction($options)) {
+            $options['writeConcern'] = $this->writeConcern;
+        }
+
+        $operation = new ModifyCollection($this->databaseName, $collectionName, $collectionOptions, $options);
+
+        return $operation->execute($server);
+    }
+
+    /**
+     * Select a collection within this database.
+     *
+     * @see Collection::__construct() for supported options
+     * @param string $collectionName Name of the collection to select
+     * @param array  $options        Collection constructor options
+     * @return Collection
+     * @throws InvalidArgumentException for parameter/option parsing errors
+     */
+    public function selectCollection($collectionName, array $options = [])
+    {
+        $options += [
+            'readConcern' => $this->readConcern,
+            'readPreference' => $this->readPreference,
+            'typeMap' => $this->typeMap,
+            'writeConcern' => $this->writeConcern,
+        ];
+
+        return new Collection($this->manager, $this->databaseName, $collectionName, $options);
+    }
+
+    /**
+     * Select a GridFS bucket within this database.
+     *
+     * @see Bucket::__construct() for supported options
+     * @param array $options Bucket constructor options
+     * @return Bucket
+     * @throws InvalidArgumentException for parameter/option parsing errors
+     */
+    public function selectGridFSBucket(array $options = [])
+    {
+        $options += [
+            'readConcern' => $this->readConcern,
+            'readPreference' => $this->readPreference,
+            'typeMap' => $this->typeMap,
+            'writeConcern' => $this->writeConcern,
+        ];
+
+        return new Bucket($this->manager, $this->databaseName, $options);
+    }
+
+    /**
+     * Create a change stream for watching changes to the database.
+     *
+     * @see Watch::__construct() for supported options
+     * @param array $pipeline List of pipeline operations
+     * @param array $options  Command options
+     * @return ChangeStream
+     * @throws InvalidArgumentException for parameter/option parsing errors
+     */
+    public function watch(array $pipeline = [], array $options = [])
+    {
+        if (! isset($options['readPreference']) && ! is_in_transaction($options)) {
+            $options['readPreference'] = $this->readPreference;
+        }
+
+        $server = select_server($this->manager, $options);
+
+        if (! isset($options['readConcern']) && server_supports_feature($server, self::$wireVersionForReadConcern) && ! is_in_transaction($options)) {
+            $options['readConcern'] = $this->readConcern;
+        }
+
+        if (! isset($options['typeMap'])) {
+            $options['typeMap'] = $this->typeMap;
+        }
+
+        $operation = new Watch($this->manager, $this->databaseName, null, $pipeline, $options);
+
+        return $operation->execute($server);
+    }
+
+    /**
+     * Get a clone of this database with different options.
+     *
+     * @see Database::__construct() for supported options
+     * @param array $options Database constructor options
+     * @return Database
+     * @throws InvalidArgumentException for parameter/option parsing errors
+     */
+    public function withOptions(array $options = [])
+    {
+        $options += [
+            'readConcern' => $this->readConcern,
+            'readPreference' => $this->readPreference,
+            'typeMap' => $this->typeMap,
+            'writeConcern' => $this->writeConcern,
+        ];
+
+        return new Database($this->manager, $this->databaseName, $options);
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/DeleteResult.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/DeleteResult.php
new file mode 100644
index 0000000000000000000000000000000000000000..c5b9ce64d427fdcaa18bea057bc3297d9ddd2b49
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/DeleteResult.php	
@@ -0,0 +1,70 @@
+<?php
+/*
+ * Copyright 2015-2017 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace MongoDB;
+
+use MongoDB\Driver\WriteResult;
+use MongoDB\Exception\BadMethodCallException;
+
+/**
+ * Result class for a delete operation.
+ */
+class DeleteResult
+{
+    /** @var WriteResult */
+    private $writeResult;
+
+    /** @var boolean */
+    private $isAcknowledged;
+
+    public function __construct(WriteResult $writeResult)
+    {
+        $this->writeResult = $writeResult;
+        $this->isAcknowledged = $writeResult->isAcknowledged();
+    }
+
+    /**
+     * Return the number of documents that were deleted.
+     *
+     * This method should only be called if the write was acknowledged.
+     *
+     * @see DeleteResult::isAcknowledged()
+     * @return integer
+     * @throws BadMethodCallException is the write result is unacknowledged
+     */
+    public function getDeletedCount()
+    {
+        if ($this->isAcknowledged) {
+            return $this->writeResult->getDeletedCount();
+        }
+
+        throw BadMethodCallException::unacknowledgedWriteResultAccess(__METHOD__);
+    }
+
+    /**
+     * Return whether this delete was acknowledged by the server.
+     *
+     * If the delete was not acknowledged, other fields from the WriteResult
+     * (e.g. deletedCount) will be undefined.
+     *
+     * @return boolean
+     */
+    public function isAcknowledged()
+    {
+        return $this->isAcknowledged;
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Exception/BadMethodCallException.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Exception/BadMethodCallException.php
new file mode 100644
index 0000000000000000000000000000000000000000..00cd79cf224248393db1ae1bc46200b1aaba898e
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Exception/BadMethodCallException.php	
@@ -0,0 +1,46 @@
+<?php
+/*
+ * Copyright 2015-2017 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace MongoDB\Exception;
+
+use BadMethodCallException as BaseBadMethodCallException;
+use function sprintf;
+
+class BadMethodCallException extends BaseBadMethodCallException implements Exception
+{
+    /**
+     * Thrown when a mutable method is invoked on an immutable object.
+     *
+     * @param string $class Class name
+     * @return self
+     */
+    public static function classIsImmutable($class)
+    {
+        return new static(sprintf('%s is immutable', $class));
+    }
+
+    /**
+     * Thrown when accessing a result field on an unacknowledged write result.
+     *
+     * @param string $method Method name
+     * @return self
+     */
+    public static function unacknowledgedWriteResultAccess($method)
+    {
+        return new static(sprintf('%s should not be called for an unacknowledged write result', $method));
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Exception/Exception.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Exception/Exception.php
new file mode 100644
index 0000000000000000000000000000000000000000..154a193915c50f0703d93df1f05d414a3b8eaee5
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Exception/Exception.php	
@@ -0,0 +1,24 @@
+<?php
+/*
+ * Copyright 2015-2017 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace MongoDB\Exception;
+
+use MongoDB\Driver\Exception\Exception as DriverException;
+
+interface Exception extends DriverException
+{
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Exception/InvalidArgumentException.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Exception/InvalidArgumentException.php
new file mode 100644
index 0000000000000000000000000000000000000000..83271c180ed078a92caccd6b9f21de39ac318934
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Exception/InvalidArgumentException.php	
@@ -0,0 +1,61 @@
+<?php
+/*
+ * Copyright 2015-2017 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace MongoDB\Exception;
+
+use MongoDB\Driver\Exception\InvalidArgumentException as DriverInvalidArgumentException;
+use function array_pop;
+use function count;
+use function get_debug_type;
+use function implode;
+use function is_array;
+use function sprintf;
+
+class InvalidArgumentException extends DriverInvalidArgumentException implements Exception
+{
+    /**
+     * Thrown when an argument or option has an invalid type.
+     *
+     * @param string          $name         Name of the argument or option
+     * @param mixed           $value        Actual value (used to derive the type)
+     * @param string|string[] $expectedType Expected type
+     * @return self
+     */
+    public static function invalidType($name, $value, $expectedType)
+    {
+        if (is_array($expectedType)) {
+            switch (count($expectedType)) {
+                case 1:
+                    $typeString = array_pop($expectedType);
+                    break;
+
+                case 2:
+                    $typeString = implode('" or "', $expectedType);
+                    break;
+
+                default:
+                    $lastType = array_pop($expectedType);
+                    $typeString = sprintf('%s", or "%s', implode('", "', $expectedType), $lastType);
+                    break;
+            }
+
+            $expectedType = $typeString;
+        }
+
+        return new static(sprintf('Expected %s to have type "%s" but found "%s"', $name, $expectedType, get_debug_type($value)));
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Exception/ResumeTokenException.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Exception/ResumeTokenException.php
new file mode 100644
index 0000000000000000000000000000000000000000..362e72fa856f7e48e020753536cb532dda45ae3c
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Exception/ResumeTokenException.php	
@@ -0,0 +1,45 @@
+<?php
+/*
+ * Copyright 2015-2017 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace MongoDB\Exception;
+
+use function get_debug_type;
+use function sprintf;
+
+class ResumeTokenException extends RuntimeException
+{
+    /**
+     * Thrown when a resume token has an invalid type.
+     *
+     * @param mixed $value Actual value (used to derive the type)
+     * @return self
+     */
+    public static function invalidType($value)
+    {
+        return new static(sprintf('Expected resume token to have type "array or object" but found "%s"', get_debug_type($value)));
+    }
+
+    /**
+     * Thrown when a resume token is not found in a change document.
+     *
+     * @return self
+     */
+    public static function notFound()
+    {
+        return new static('Resume token not found in change document');
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Exception/RuntimeException.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Exception/RuntimeException.php
new file mode 100644
index 0000000000000000000000000000000000000000..a64c0a4a41d54788ecb8f17632fc04ad1e6fdf30
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Exception/RuntimeException.php	
@@ -0,0 +1,24 @@
+<?php
+/*
+ * Copyright 2015-2017 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace MongoDB\Exception;
+
+use MongoDB\Driver\Exception\RuntimeException as DriverRuntimeException;
+
+class RuntimeException extends DriverRuntimeException implements Exception
+{
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Exception/UnexpectedValueException.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Exception/UnexpectedValueException.php
new file mode 100644
index 0000000000000000000000000000000000000000..e91b36981f27b9f5652dc2053c9cc48fd50f40e7
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Exception/UnexpectedValueException.php	
@@ -0,0 +1,24 @@
+<?php
+/*
+ * Copyright 2015-2017 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace MongoDB\Exception;
+
+use MongoDB\Driver\Exception\UnexpectedValueException as DriverUnexpectedValueException;
+
+class UnexpectedValueException extends DriverUnexpectedValueException implements Exception
+{
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Exception/UnsupportedException.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Exception/UnsupportedException.php
new file mode 100644
index 0000000000000000000000000000000000000000..545580285ab92c2670792de58bea0323d6b73a36
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Exception/UnsupportedException.php	
@@ -0,0 +1,122 @@
+<?php
+/*
+ * Copyright 2015-2017 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace MongoDB\Exception;
+
+class UnsupportedException extends RuntimeException
+{
+    /**
+     * Thrown when a command's allowDiskUse option is not supported by a server.
+     *
+     * @return self
+     */
+    public static function allowDiskUseNotSupported()
+    {
+        return new static('The "allowDiskUse" option is not supported by the server executing this operation');
+    }
+
+    /**
+     * Thrown when array filters are not supported by a server.
+     *
+     * @return self
+     */
+    public static function arrayFiltersNotSupported()
+    {
+        return new static('Array filters are not supported by the server executing this operation');
+    }
+
+    /**
+     * Thrown when collations are not supported by a server.
+     *
+     * @return self
+     */
+    public static function collationNotSupported()
+    {
+        return new static('Collations are not supported by the server executing this operation');
+    }
+
+    /**
+     * Thrown when the commitQuorum option for createIndexes is not supported
+     * by a server.
+     *
+     * @return self
+     */
+    public static function commitQuorumNotSupported()
+    {
+        return new static('The "commitQuorum" option is not supported by the server executing this operation');
+    }
+
+    /**
+     * Thrown when explain is not supported by a server.
+     *
+     * @return self
+     */
+    public static function explainNotSupported()
+    {
+        return new static('Explain is not supported by the server executing this operation');
+    }
+
+    /**
+     * Thrown when a command's hint option is not supported by a server.
+     *
+     * @return self
+     */
+    public static function hintNotSupported()
+    {
+        return new static('Hint is not supported by the server executing this operation');
+    }
+
+    /**
+     * Thrown when a command's readConcern option is not supported by a server.
+     *
+     * @return self
+     */
+    public static function readConcernNotSupported()
+    {
+        return new static('Read concern is not supported by the server executing this command');
+    }
+
+    /**
+     * Thrown when a readConcern is used with a read operation in a transaction.
+     *
+     * @return self
+     */
+    public static function readConcernNotSupportedInTransaction()
+    {
+        return new static('The "readConcern" option cannot be specified within a transaction. Instead, specify it when starting the transaction.');
+    }
+
+    /**
+     * Thrown when a command's writeConcern option is not supported by a server.
+     *
+     * @return self
+     */
+    public static function writeConcernNotSupported()
+    {
+        return new static('Write concern is not supported by the server executing this command');
+    }
+
+    /**
+     * Thrown when a writeConcern is used with a write operation in a transaction.
+     *
+     * @return self
+     */
+    public static function writeConcernNotSupportedInTransaction()
+    {
+        return new static('The "writeConcern" option cannot be specified within a transaction. Instead, specify it when starting the transaction.');
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/GridFS/Bucket.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/GridFS/Bucket.php
new file mode 100644
index 0000000000000000000000000000000000000000..ac96305153800543ab01818e27a137f2acf4a7f8
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/GridFS/Bucket.php	
@@ -0,0 +1,741 @@
+<?php
+/*
+ * Copyright 2016-2017 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace MongoDB\GridFS;
+
+use MongoDB\Collection;
+use MongoDB\Driver\Cursor;
+use MongoDB\Driver\Exception\RuntimeException as DriverRuntimeException;
+use MongoDB\Driver\Manager;
+use MongoDB\Driver\ReadConcern;
+use MongoDB\Driver\ReadPreference;
+use MongoDB\Driver\WriteConcern;
+use MongoDB\Exception\InvalidArgumentException;
+use MongoDB\Exception\UnsupportedException;
+use MongoDB\GridFS\Exception\CorruptFileException;
+use MongoDB\GridFS\Exception\FileNotFoundException;
+use MongoDB\GridFS\Exception\StreamException;
+use MongoDB\Model\BSONArray;
+use MongoDB\Model\BSONDocument;
+use MongoDB\Operation\Find;
+use stdClass;
+use function array_intersect_key;
+use function fopen;
+use function get_resource_type;
+use function in_array;
+use function is_array;
+use function is_bool;
+use function is_integer;
+use function is_object;
+use function is_resource;
+use function is_string;
+use function method_exists;
+use function MongoDB\apply_type_map_to_document;
+use function MongoDB\BSON\fromPHP;
+use function MongoDB\BSON\toJSON;
+use function property_exists;
+use function sprintf;
+use function stream_context_create;
+use function stream_copy_to_stream;
+use function stream_get_meta_data;
+use function stream_get_wrappers;
+use function urlencode;
+
+/**
+ * Bucket provides a public API for interacting with the GridFS files and chunks
+ * collections.
+ *
+ * @api
+ */
+class Bucket
+{
+    /** @var string */
+    private static $defaultBucketName = 'fs';
+
+    /** @var integer */
+    private static $defaultChunkSizeBytes = 261120;
+
+    /** @var array */
+    private static $defaultTypeMap = [
+        'array' => BSONArray::class,
+        'document' => BSONDocument::class,
+        'root' => BSONDocument::class,
+    ];
+
+    /** @var string */
+    private static $streamWrapperProtocol = 'gridfs';
+
+    /** @var CollectionWrapper */
+    private $collectionWrapper;
+
+    /** @var string */
+    private $databaseName;
+
+    /** @var Manager */
+    private $manager;
+
+    /** @var string */
+    private $bucketName;
+
+    /** @var boolean */
+    private $disableMD5;
+
+    /** @var integer */
+    private $chunkSizeBytes;
+
+    /** @var ReadConcern */
+    private $readConcern;
+
+    /** @var ReadPreference */
+    private $readPreference;
+
+    /** @var array */
+    private $typeMap;
+
+    /** @var WriteConcern */
+    private $writeConcern;
+
+    /**
+     * Constructs a GridFS bucket.
+     *
+     * Supported options:
+     *
+     *  * bucketName (string): The bucket name, which will be used as a prefix
+     *    for the files and chunks collections. Defaults to "fs".
+     *
+     *  * chunkSizeBytes (integer): The chunk size in bytes. Defaults to
+     *    261120 (i.e. 255 KiB).
+     *
+     *  * disableMD5 (boolean): When true, no MD5 sum will be generated for
+     *    each stored file. Defaults to "false".
+     *
+     *  * readConcern (MongoDB\Driver\ReadConcern): Read concern.
+     *
+     *  * readPreference (MongoDB\Driver\ReadPreference): Read preference.
+     *
+     *  * typeMap (array): Default type map for cursors and BSON documents.
+     *
+     *  * writeConcern (MongoDB\Driver\WriteConcern): Write concern.
+     *
+     * @param Manager $manager      Manager instance from the driver
+     * @param string  $databaseName Database name
+     * @param array   $options      Bucket options
+     * @throws InvalidArgumentException for parameter/option parsing errors
+     */
+    public function __construct(Manager $manager, $databaseName, array $options = [])
+    {
+        $options += [
+            'bucketName' => self::$defaultBucketName,
+            'chunkSizeBytes' => self::$defaultChunkSizeBytes,
+            'disableMD5' => false,
+        ];
+
+        if (! is_string($options['bucketName'])) {
+            throw InvalidArgumentException::invalidType('"bucketName" option', $options['bucketName'], 'string');
+        }
+
+        if (! is_integer($options['chunkSizeBytes'])) {
+            throw InvalidArgumentException::invalidType('"chunkSizeBytes" option', $options['chunkSizeBytes'], 'integer');
+        }
+
+        if ($options['chunkSizeBytes'] < 1) {
+            throw new InvalidArgumentException(sprintf('Expected "chunkSizeBytes" option to be >= 1, %d given', $options['chunkSizeBytes']));
+        }
+
+        if (! is_bool($options['disableMD5'])) {
+            throw InvalidArgumentException::invalidType('"disableMD5" option', $options['disableMD5'], 'boolean');
+        }
+
+        if (isset($options['readConcern']) && ! $options['readConcern'] instanceof ReadConcern) {
+            throw InvalidArgumentException::invalidType('"readConcern" option', $options['readConcern'], ReadConcern::class);
+        }
+
+        if (isset($options['readPreference']) && ! $options['readPreference'] instanceof ReadPreference) {
+            throw InvalidArgumentException::invalidType('"readPreference" option', $options['readPreference'], ReadPreference::class);
+        }
+
+        if (isset($options['typeMap']) && ! is_array($options['typeMap'])) {
+            throw InvalidArgumentException::invalidType('"typeMap" option', $options['typeMap'], 'array');
+        }
+
+        if (isset($options['writeConcern']) && ! $options['writeConcern'] instanceof WriteConcern) {
+            throw InvalidArgumentException::invalidType('"writeConcern" option', $options['writeConcern'], WriteConcern::class);
+        }
+
+        $this->manager = $manager;
+        $this->databaseName = (string) $databaseName;
+        $this->bucketName = $options['bucketName'];
+        $this->chunkSizeBytes = $options['chunkSizeBytes'];
+        $this->disableMD5 = $options['disableMD5'];
+        $this->readConcern = $options['readConcern'] ?? $this->manager->getReadConcern();
+        $this->readPreference = $options['readPreference'] ?? $this->manager->getReadPreference();
+        $this->typeMap = $options['typeMap'] ?? self::$defaultTypeMap;
+        $this->writeConcern = $options['writeConcern'] ?? $this->manager->getWriteConcern();
+
+        $collectionOptions = array_intersect_key($options, ['readConcern' => 1, 'readPreference' => 1, 'typeMap' => 1, 'writeConcern' => 1]);
+
+        $this->collectionWrapper = new CollectionWrapper($manager, $databaseName, $options['bucketName'], $collectionOptions);
+        $this->registerStreamWrapper();
+    }
+
+    /**
+     * Return internal properties for debugging purposes.
+     *
+     * @see http://php.net/manual/en/language.oop5.magic.php#language.oop5.magic.debuginfo
+     * @return array
+     */
+    public function __debugInfo()
+    {
+        return [
+            'bucketName' => $this->bucketName,
+            'databaseName' => $this->databaseName,
+            'manager' => $this->manager,
+            'chunkSizeBytes' => $this->chunkSizeBytes,
+            'readConcern' => $this->readConcern,
+            'readPreference' => $this->readPreference,
+            'typeMap' => $this->typeMap,
+            'writeConcern' => $this->writeConcern,
+        ];
+    }
+
+    /**
+     * Delete a file from the GridFS bucket.
+     *
+     * If the files collection document is not found, this method will still
+     * attempt to delete orphaned chunks.
+     *
+     * @param mixed $id File ID
+     * @throws FileNotFoundException if no file could be selected
+     * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
+     */
+    public function delete($id)
+    {
+        $file = $this->collectionWrapper->findFileById($id);
+        $this->collectionWrapper->deleteFileAndChunksById($id);
+
+        if ($file === null) {
+            throw FileNotFoundException::byId($id, $this->getFilesNamespace());
+        }
+    }
+
+    /**
+     * Writes the contents of a GridFS file to a writable stream.
+     *
+     * @param mixed    $id          File ID
+     * @param resource $destination Writable Stream
+     * @throws FileNotFoundException if no file could be selected
+     * @throws InvalidArgumentException if $destination is not a stream
+     * @throws StreamException if the file could not be uploaded
+     * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
+     */
+    public function downloadToStream($id, $destination)
+    {
+        if (! is_resource($destination) || get_resource_type($destination) != "stream") {
+            throw InvalidArgumentException::invalidType('$destination', $destination, 'resource');
+        }
+
+        $source = $this->openDownloadStream($id);
+        if (@stream_copy_to_stream($source, $destination) === false) {
+            throw StreamException::downloadFromIdFailed($id, $source, $destination);
+        }
+    }
+
+    /**
+     * Writes the contents of a GridFS file, which is selected by name and
+     * revision, to a writable stream.
+     *
+     * Supported options:
+     *
+     *  * revision (integer): Which revision (i.e. documents with the same
+     *    filename and different uploadDate) of the file to retrieve. Defaults
+     *    to -1 (i.e. the most recent revision).
+     *
+     * Revision numbers are defined as follows:
+     *
+     *  * 0 = the original stored file
+     *  * 1 = the first revision
+     *  * 2 = the second revision
+     *  * etc…
+     *  * -2 = the second most recent revision
+     *  * -1 = the most recent revision
+     *
+     * @param string   $filename    Filename
+     * @param resource $destination Writable Stream
+     * @param array    $options     Download options
+     * @throws FileNotFoundException if no file could be selected
+     * @throws InvalidArgumentException if $destination is not a stream
+     * @throws StreamException if the file could not be uploaded
+     * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
+     */
+    public function downloadToStreamByName($filename, $destination, array $options = [])
+    {
+        if (! is_resource($destination) || get_resource_type($destination) != "stream") {
+            throw InvalidArgumentException::invalidType('$destination', $destination, 'resource');
+        }
+
+        $source = $this->openDownloadStreamByName($filename, $options);
+        if (@stream_copy_to_stream($source, $destination) === false) {
+            throw StreamException::downloadFromFilenameFailed($filename, $source, $destination);
+        }
+    }
+
+    /**
+     * Drops the files and chunks collections associated with this GridFS
+     * bucket.
+     *
+     * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
+     */
+    public function drop()
+    {
+        $this->collectionWrapper->dropCollections();
+    }
+
+    /**
+     * Finds documents from the GridFS bucket's files collection matching the
+     * query.
+     *
+     * @see Find::__construct() for supported options
+     * @param array|object $filter  Query by which to filter documents
+     * @param array        $options Additional options
+     * @return Cursor
+     * @throws UnsupportedException if options are not supported by the selected server
+     * @throws InvalidArgumentException for parameter/option parsing errors
+     * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
+     */
+    public function find($filter = [], array $options = [])
+    {
+        return $this->collectionWrapper->findFiles($filter, $options);
+    }
+
+    /**
+     * Finds a single document from the GridFS bucket's files collection
+     * matching the query.
+     *
+     * @see FindOne::__construct() for supported options
+     * @param array|object $filter  Query by which to filter documents
+     * @param array        $options Additional options
+     * @return array|object|null
+     * @throws UnsupportedException if options are not supported by the selected server
+     * @throws InvalidArgumentException for parameter/option parsing errors
+     * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
+     */
+    public function findOne($filter = [], array $options = [])
+    {
+        return $this->collectionWrapper->findOneFile($filter, $options);
+    }
+
+    /**
+     * Return the bucket name.
+     *
+     * @return string
+     */
+    public function getBucketName()
+    {
+        return $this->bucketName;
+    }
+
+    /**
+     * Return the chunks collection.
+     *
+     * @return Collection
+     */
+    public function getChunksCollection()
+    {
+        return $this->collectionWrapper->getChunksCollection();
+    }
+
+    /**
+     * Return the chunk size in bytes.
+     *
+     * @return integer
+     */
+    public function getChunkSizeBytes()
+    {
+        return $this->chunkSizeBytes;
+    }
+
+    /**
+     * Return the database name.
+     *
+     * @return string
+     */
+    public function getDatabaseName()
+    {
+        return $this->databaseName;
+    }
+
+    /**
+     * Gets the file document of the GridFS file associated with a stream.
+     *
+     * @param resource $stream GridFS stream
+     * @return array|object
+     * @throws InvalidArgumentException if $stream is not a GridFS stream
+     * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
+     */
+    public function getFileDocumentForStream($stream)
+    {
+        $file = $this->getRawFileDocumentForStream($stream);
+
+        // Filter the raw document through the specified type map
+        return apply_type_map_to_document($file, $this->typeMap);
+    }
+
+    /**
+     * Gets the file document's ID of the GridFS file associated with a stream.
+     *
+     * @param resource $stream GridFS stream
+     * @return mixed
+     * @throws CorruptFileException if the file "_id" field does not exist
+     * @throws InvalidArgumentException if $stream is not a GridFS stream
+     * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
+     */
+    public function getFileIdForStream($stream)
+    {
+        $file = $this->getRawFileDocumentForStream($stream);
+
+        /* Filter the raw document through the specified type map, but override
+         * the root type so we can reliably access the ID.
+         */
+        $typeMap = ['root' => 'stdClass'] + $this->typeMap;
+        $file = apply_type_map_to_document($file, $typeMap);
+
+        if (! isset($file->_id) && ! property_exists($file, '_id')) {
+            throw new CorruptFileException('file._id does not exist');
+        }
+
+        return $file->_id;
+    }
+
+    /**
+     * Return the files collection.
+     *
+     * @return Collection
+     */
+    public function getFilesCollection()
+    {
+        return $this->collectionWrapper->getFilesCollection();
+    }
+
+    /**
+     * Return the read concern for this GridFS bucket.
+     *
+     * @see http://php.net/manual/en/mongodb-driver-readconcern.isdefault.php
+     * @return ReadConcern
+     */
+    public function getReadConcern()
+    {
+        return $this->readConcern;
+    }
+
+    /**
+     * Return the read preference for this GridFS bucket.
+     *
+     * @return ReadPreference
+     */
+    public function getReadPreference()
+    {
+        return $this->readPreference;
+    }
+
+    /**
+     * Return the type map for this GridFS bucket.
+     *
+     * @return array
+     */
+    public function getTypeMap()
+    {
+        return $this->typeMap;
+    }
+
+    /**
+     * Return the write concern for this GridFS bucket.
+     *
+     * @see http://php.net/manual/en/mongodb-driver-writeconcern.isdefault.php
+     * @return WriteConcern
+     */
+    public function getWriteConcern()
+    {
+        return $this->writeConcern;
+    }
+
+    /**
+     * Opens a readable stream for reading a GridFS file.
+     *
+     * @param mixed $id File ID
+     * @return resource
+     * @throws FileNotFoundException if no file could be selected
+     * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
+     */
+    public function openDownloadStream($id)
+    {
+        $file = $this->collectionWrapper->findFileById($id);
+
+        if ($file === null) {
+            throw FileNotFoundException::byId($id, $this->getFilesNamespace());
+        }
+
+        return $this->openDownloadStreamByFile($file);
+    }
+
+    /**
+     * Opens a readable stream stream to read a GridFS file, which is selected
+     * by name and revision.
+     *
+     * Supported options:
+     *
+     *  * revision (integer): Which revision (i.e. documents with the same
+     *    filename and different uploadDate) of the file to retrieve. Defaults
+     *    to -1 (i.e. the most recent revision).
+     *
+     * Revision numbers are defined as follows:
+     *
+     *  * 0 = the original stored file
+     *  * 1 = the first revision
+     *  * 2 = the second revision
+     *  * etc…
+     *  * -2 = the second most recent revision
+     *  * -1 = the most recent revision
+     *
+     * @param string $filename Filename
+     * @param array  $options  Download options
+     * @return resource
+     * @throws FileNotFoundException if no file could be selected
+     * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
+     */
+    public function openDownloadStreamByName($filename, array $options = [])
+    {
+        $options += ['revision' => -1];
+
+        $file = $this->collectionWrapper->findFileByFilenameAndRevision($filename, $options['revision']);
+
+        if ($file === null) {
+            throw FileNotFoundException::byFilenameAndRevision($filename, $options['revision'], $this->getFilesNamespace());
+        }
+
+        return $this->openDownloadStreamByFile($file);
+    }
+
+    /**
+     * Opens a writable stream for writing a GridFS file.
+     *
+     * Supported options:
+     *
+     *  * _id (mixed): File document identifier. Defaults to a new ObjectId.
+     *
+     *  * chunkSizeBytes (integer): The chunk size in bytes. Defaults to the
+     *    bucket's chunk size.
+     *
+     *  * disableMD5 (boolean): When true, no MD5 sum will be generated for
+     *    the stored file. Defaults to "false".
+     *
+     *  * metadata (document): User data for the "metadata" field of the files
+     *    collection document.
+     *
+     * @param string $filename Filename
+     * @param array  $options  Upload options
+     * @return resource
+     */
+    public function openUploadStream($filename, array $options = [])
+    {
+        $options += ['chunkSizeBytes' => $this->chunkSizeBytes];
+
+        $path = $this->createPathForUpload();
+        $context = stream_context_create([
+            self::$streamWrapperProtocol => [
+                'collectionWrapper' => $this->collectionWrapper,
+                'filename' => $filename,
+                'options' => $options,
+            ],
+        ]);
+
+        return fopen($path, 'w', false, $context);
+    }
+
+    /**
+     * Renames the GridFS file with the specified ID.
+     *
+     * @param mixed  $id          File ID
+     * @param string $newFilename New filename
+     * @throws FileNotFoundException if no file could be selected
+     * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
+     */
+    public function rename($id, $newFilename)
+    {
+        $updateResult = $this->collectionWrapper->updateFilenameForId($id, $newFilename);
+
+        if ($updateResult->getModifiedCount() === 1) {
+            return;
+        }
+
+        /* If the update resulted in no modification, it's possible that the
+         * file did not exist, in which case we must raise an error. Checking
+         * the write result's matched count will be most efficient, but fall
+         * back to a findOne operation if necessary (i.e. legacy writes).
+         */
+        $found = $updateResult->getMatchedCount() !== null
+            ? $updateResult->getMatchedCount() === 1
+            : $this->collectionWrapper->findFileById($id) !== null;
+
+        if (! $found) {
+            throw FileNotFoundException::byId($id, $this->getFilesNamespace());
+        }
+    }
+
+    /**
+     * Writes the contents of a readable stream to a GridFS file.
+     *
+     * Supported options:
+     *
+     *  * _id (mixed): File document identifier. Defaults to a new ObjectId.
+     *
+     *  * chunkSizeBytes (integer): The chunk size in bytes. Defaults to the
+     *    bucket's chunk size.
+     *
+     *  * disableMD5 (boolean): When true, no MD5 sum will be generated for
+     *    the stored file. Defaults to "false".
+     *
+     *  * metadata (document): User data for the "metadata" field of the files
+     *    collection document.
+     *
+     * @param string   $filename Filename
+     * @param resource $source   Readable stream
+     * @param array    $options  Stream options
+     * @return mixed ID of the newly created GridFS file
+     * @throws InvalidArgumentException if $source is not a GridFS stream
+     * @throws StreamException if the file could not be uploaded
+     * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
+     */
+    public function uploadFromStream($filename, $source, array $options = [])
+    {
+        if (! is_resource($source) || get_resource_type($source) != "stream") {
+            throw InvalidArgumentException::invalidType('$source', $source, 'resource');
+        }
+
+        $destination = $this->openUploadStream($filename, $options);
+
+        if (@stream_copy_to_stream($source, $destination) === false) {
+            $destinationUri = $this->createPathForFile($this->getRawFileDocumentForStream($destination));
+            throw StreamException::uploadFailed($filename, $source, $destinationUri);
+        }
+
+        return $this->getFileIdForStream($destination);
+    }
+
+    /**
+     * Creates a path for an existing GridFS file.
+     *
+     * @param stdClass $file GridFS file document
+     * @return string
+     */
+    private function createPathForFile(stdClass $file)
+    {
+        if (! is_object($file->_id) || method_exists($file->_id, '__toString')) {
+            $id = (string) $file->_id;
+        } else {
+            $id = toJSON(fromPHP(['_id' => $file->_id]));
+        }
+
+        return sprintf(
+            '%s://%s/%s.files/%s',
+            self::$streamWrapperProtocol,
+            urlencode($this->databaseName),
+            urlencode($this->bucketName),
+            urlencode($id)
+        );
+    }
+
+    /**
+     * Creates a path for a new GridFS file, which does not yet have an ID.
+     *
+     * @return string
+     */
+    private function createPathForUpload()
+    {
+        return sprintf(
+            '%s://%s/%s.files',
+            self::$streamWrapperProtocol,
+            urlencode($this->databaseName),
+            urlencode($this->bucketName)
+        );
+    }
+
+    /**
+     * Returns the names of the files collection.
+     *
+     * @return string
+     */
+    private function getFilesNamespace()
+    {
+        return sprintf('%s.%s.files', $this->databaseName, $this->bucketName);
+    }
+
+    /**
+     * Gets the file document of the GridFS file associated with a stream.
+     *
+     * This returns the raw document from the StreamWrapper, which does not
+     * respect the Bucket's type map.
+     *
+     * @param resource $stream GridFS stream
+     * @return stdClass
+     * @throws InvalidArgumentException
+     */
+    private function getRawFileDocumentForStream($stream)
+    {
+        if (! is_resource($stream) || get_resource_type($stream) != "stream") {
+            throw InvalidArgumentException::invalidType('$stream', $stream, 'resource');
+        }
+
+        $metadata = stream_get_meta_data($stream);
+
+        if (! isset($metadata['wrapper_data']) || ! $metadata['wrapper_data'] instanceof StreamWrapper) {
+            throw InvalidArgumentException::invalidType('$stream wrapper data', $metadata['wrapper_data'] ?? null, StreamWrapper::class);
+        }
+
+        return $metadata['wrapper_data']->getFile();
+    }
+
+    /**
+     * Opens a readable stream for the GridFS file.
+     *
+     * @param stdClass $file GridFS file document
+     * @return resource
+     */
+    private function openDownloadStreamByFile(stdClass $file)
+    {
+        $path = $this->createPathForFile($file);
+        $context = stream_context_create([
+            self::$streamWrapperProtocol => [
+                'collectionWrapper' => $this->collectionWrapper,
+                'file' => $file,
+            ],
+        ]);
+
+        return fopen($path, 'r', false, $context);
+    }
+
+    /**
+     * Registers the GridFS stream wrapper if it is not already registered.
+     */
+    private function registerStreamWrapper()
+    {
+        if (in_array(self::$streamWrapperProtocol, stream_get_wrappers())) {
+            return;
+        }
+
+        StreamWrapper::register(self::$streamWrapperProtocol);
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/GridFS/CollectionWrapper.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/GridFS/CollectionWrapper.php
new file mode 100644
index 0000000000000000000000000000000000000000..0b7f43091838ebfa1586d73c9db3d70ac6a83d3f
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/GridFS/CollectionWrapper.php	
@@ -0,0 +1,388 @@
+<?php
+/*
+ * Copyright 2016-2017 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace MongoDB\GridFS;
+
+use ArrayIterator;
+use MongoDB\Collection;
+use MongoDB\Driver\Cursor;
+use MongoDB\Driver\Manager;
+use MongoDB\Driver\ReadPreference;
+use MongoDB\Exception\InvalidArgumentException;
+use MongoDB\UpdateResult;
+use MultipleIterator;
+use stdClass;
+use function abs;
+use function count;
+use function is_numeric;
+use function sprintf;
+
+/**
+ * CollectionWrapper abstracts the GridFS files and chunks collections.
+ *
+ * @internal
+ */
+class CollectionWrapper
+{
+    /** @var string */
+    private $bucketName;
+
+    /** @var Collection */
+    private $chunksCollection;
+
+    /** @var string */
+    private $databaseName;
+
+    /** @var boolean */
+    private $checkedIndexes = false;
+
+    /** @var Collection */
+    private $filesCollection;
+
+    /**
+     * Constructs a GridFS collection wrapper.
+     *
+     * @see Collection::__construct() for supported options
+     * @param Manager $manager           Manager instance from the driver
+     * @param string  $databaseName      Database name
+     * @param string  $bucketName        Bucket name
+     * @param array   $collectionOptions Collection options
+     * @throws InvalidArgumentException
+     */
+    public function __construct(Manager $manager, $databaseName, $bucketName, array $collectionOptions = [])
+    {
+        $this->databaseName = (string) $databaseName;
+        $this->bucketName = (string) $bucketName;
+
+        $this->filesCollection = new Collection($manager, $databaseName, sprintf('%s.files', $bucketName), $collectionOptions);
+        $this->chunksCollection = new Collection($manager, $databaseName, sprintf('%s.chunks', $bucketName), $collectionOptions);
+    }
+
+    /**
+     * Deletes all GridFS chunks for a given file ID.
+     *
+     * @param mixed $id
+     */
+    public function deleteChunksByFilesId($id)
+    {
+        $this->chunksCollection->deleteMany(['files_id' => $id]);
+    }
+
+    /**
+     * Deletes a GridFS file and related chunks by ID.
+     *
+     * @param mixed $id
+     */
+    public function deleteFileAndChunksById($id)
+    {
+        $this->filesCollection->deleteOne(['_id' => $id]);
+        $this->chunksCollection->deleteMany(['files_id' => $id]);
+    }
+
+    /**
+     * Drops the GridFS files and chunks collections.
+     */
+    public function dropCollections()
+    {
+        $this->filesCollection->drop(['typeMap' => []]);
+        $this->chunksCollection->drop(['typeMap' => []]);
+    }
+
+    /**
+     * Finds GridFS chunk documents for a given file ID and optional offset.
+     *
+     * @param mixed   $id        File ID
+     * @param integer $fromChunk Starting chunk (inclusive)
+     * @return Cursor
+     */
+    public function findChunksByFileId($id, $fromChunk = 0)
+    {
+        return $this->chunksCollection->find(
+            [
+                'files_id' => $id,
+                'n' => ['$gte' => $fromChunk],
+            ],
+            [
+                'sort' => ['n' => 1],
+                'typeMap' => ['root' => 'stdClass'],
+            ]
+        );
+    }
+
+    /**
+     * Finds a GridFS file document for a given filename and revision.
+     *
+     * Revision numbers are defined as follows:
+     *
+     *  * 0 = the original stored file
+     *  * 1 = the first revision
+     *  * 2 = the second revision
+     *  * etc…
+     *  * -2 = the second most recent revision
+     *  * -1 = the most recent revision
+     *
+     * @see Bucket::downloadToStreamByName()
+     * @see Bucket::openDownloadStreamByName()
+     * @param string  $filename
+     * @param integer $revision
+     * @return stdClass|null
+     */
+    public function findFileByFilenameAndRevision($filename, $revision)
+    {
+        $filename = (string) $filename;
+        $revision = (integer) $revision;
+
+        if ($revision < 0) {
+            $skip = abs($revision) - 1;
+            $sortOrder = -1;
+        } else {
+            $skip = $revision;
+            $sortOrder = 1;
+        }
+
+        return $this->filesCollection->findOne(
+            ['filename' => $filename],
+            [
+                'skip' => $skip,
+                'sort' => ['uploadDate' => $sortOrder],
+                'typeMap' => ['root' => 'stdClass'],
+            ]
+        );
+    }
+
+    /**
+     * Finds a GridFS file document for a given ID.
+     *
+     * @param mixed $id
+     * @return stdClass|null
+     */
+    public function findFileById($id)
+    {
+        return $this->filesCollection->findOne(
+            ['_id' => $id],
+            ['typeMap' => ['root' => 'stdClass']]
+        );
+    }
+
+    /**
+     * Finds documents from the GridFS bucket's files collection.
+     *
+     * @see Find::__construct() for supported options
+     * @param array|object $filter  Query by which to filter documents
+     * @param array        $options Additional options
+     * @return Cursor
+     */
+    public function findFiles($filter, array $options = [])
+    {
+        return $this->filesCollection->find($filter, $options);
+    }
+
+    /**
+     * Finds a single document from the GridFS bucket's files collection.
+     *
+     * @param array|object $filter  Query by which to filter documents
+     * @param array        $options Additional options
+     * @return array|object|null
+     */
+    public function findOneFile($filter, array $options = [])
+    {
+        return $this->filesCollection->findOne($filter, $options);
+    }
+
+    /**
+     * Return the bucket name.
+     *
+     * @return string
+     */
+    public function getBucketName()
+    {
+        return $this->bucketName;
+    }
+
+    /**
+     * Return the chunks collection.
+     *
+     * @return Collection
+     */
+    public function getChunksCollection()
+    {
+        return $this->chunksCollection;
+    }
+
+    /**
+     * Return the database name.
+     *
+     * @return string
+     */
+    public function getDatabaseName()
+    {
+        return $this->databaseName;
+    }
+
+    /**
+     * Return the files collection.
+     *
+     * @return Collection
+     */
+    public function getFilesCollection()
+    {
+        return $this->filesCollection;
+    }
+
+    /**
+     * Inserts a document into the chunks collection.
+     *
+     * @param array|object $chunk Chunk document
+     */
+    public function insertChunk($chunk)
+    {
+        if (! $this->checkedIndexes) {
+            $this->ensureIndexes();
+        }
+
+        $this->chunksCollection->insertOne($chunk);
+    }
+
+    /**
+     * Inserts a document into the files collection.
+     *
+     * The file document should be inserted after all chunks have been inserted.
+     *
+     * @param array|object $file File document
+     */
+    public function insertFile($file)
+    {
+        if (! $this->checkedIndexes) {
+            $this->ensureIndexes();
+        }
+
+        $this->filesCollection->insertOne($file);
+    }
+
+    /**
+     * Updates the filename field in the file document for a given ID.
+     *
+     * @param mixed  $id
+     * @param string $filename
+     * @return UpdateResult
+     */
+    public function updateFilenameForId($id, $filename)
+    {
+        return $this->filesCollection->updateOne(
+            ['_id' => $id],
+            ['$set' => ['filename' => (string) $filename]]
+        );
+    }
+
+    /**
+     * Create an index on the chunks collection if it does not already exist.
+     */
+    private function ensureChunksIndex()
+    {
+        $expectedIndex = ['files_id' => 1, 'n' => 1];
+
+        foreach ($this->chunksCollection->listIndexes() as $index) {
+            if ($index->isUnique() && $this->indexKeysMatch($expectedIndex, $index->getKey())) {
+                return;
+            }
+        }
+
+        $this->chunksCollection->createIndex($expectedIndex, ['unique' => true]);
+    }
+
+    /**
+     * Create an index on the files collection if it does not already exist.
+     */
+    private function ensureFilesIndex()
+    {
+        $expectedIndex = ['filename' => 1, 'uploadDate' => 1];
+
+        foreach ($this->filesCollection->listIndexes() as $index) {
+            if ($this->indexKeysMatch($expectedIndex, $index->getKey())) {
+                return;
+            }
+        }
+
+        $this->filesCollection->createIndex($expectedIndex);
+    }
+
+    /**
+     * Ensure indexes on the files and chunks collections exist.
+     *
+     * This method is called once before the first write operation on a GridFS
+     * bucket. Indexes are only be created if the files collection is empty.
+     */
+    private function ensureIndexes()
+    {
+        if ($this->checkedIndexes) {
+            return;
+        }
+
+        $this->checkedIndexes = true;
+
+        if (! $this->isFilesCollectionEmpty()) {
+            return;
+        }
+
+        $this->ensureFilesIndex();
+        $this->ensureChunksIndex();
+    }
+
+    private function indexKeysMatch(array $expectedKeys, array $actualKeys) : bool
+    {
+        if (count($expectedKeys) !== count($actualKeys)) {
+            return false;
+        }
+
+        $iterator = new MultipleIterator(MultipleIterator::MIT_NEED_ANY);
+        $iterator->attachIterator(new ArrayIterator($expectedKeys));
+        $iterator->attachIterator(new ArrayIterator($actualKeys));
+
+        foreach ($iterator as $key => $value) {
+            list($expectedKey, $actualKey)     = $key;
+            list($expectedValue, $actualValue) = $value;
+
+            if ($expectedKey !== $actualKey) {
+                return false;
+            }
+
+            /* Since we don't expect special indexes (e.g. text), we mark any
+             * index with a non-numeric definition as unequal. All others are
+             * compared against their int value to avoid differences due to
+             * some drivers using float values in the key specification. */
+            if (! is_numeric($actualValue) || (int) $expectedValue !== (int) $actualValue) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * Returns whether the files collection is empty.
+     *
+     * @return boolean
+     */
+    private function isFilesCollectionEmpty()
+    {
+        return null === $this->filesCollection->findOne([], [
+            'readPreference' => new ReadPreference(ReadPreference::RP_PRIMARY),
+            'projection' => ['_id' => 1],
+            'typeMap' => [],
+        ]);
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/GridFS/Exception/CorruptFileException.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/GridFS/Exception/CorruptFileException.php
new file mode 100644
index 0000000000000000000000000000000000000000..c353725692e844b30d39467bcc53549a4df572a1
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/GridFS/Exception/CorruptFileException.php	
@@ -0,0 +1,59 @@
+<?php
+/*
+ * Copyright 2016-2017 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace MongoDB\GridFS\Exception;
+
+use MongoDB\Exception\RuntimeException;
+use function sprintf;
+
+class CorruptFileException extends RuntimeException
+{
+    /**
+     * Thrown when a chunk is not found for an expected index.
+     *
+     * @param integer $expectedIndex Expected index number
+     * @return self
+     */
+    public static function missingChunk($expectedIndex)
+    {
+        return new static(sprintf('Chunk not found for index "%d"', $expectedIndex));
+    }
+
+    /**
+     * Thrown when a chunk has an unexpected index number.
+     *
+     * @param integer $index         Actual index number (i.e. "n" field)
+     * @param integer $expectedIndex Expected index number
+     * @return self
+     */
+    public static function unexpectedIndex($index, $expectedIndex)
+    {
+        return new static(sprintf('Expected chunk to have index "%d" but found "%d"', $expectedIndex, $index));
+    }
+
+    /**
+     * Thrown when a chunk has an unexpected data size.
+     *
+     * @param integer $size         Actual size (i.e. "data" field length)
+     * @param integer $expectedSize Expected size
+     * @return self
+     */
+    public static function unexpectedSize($size, $expectedSize)
+    {
+        return new static(sprintf('Expected chunk to have size "%d" but found "%d"', $expectedSize, $size));
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/GridFS/Exception/FileNotFoundException.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/GridFS/Exception/FileNotFoundException.php
new file mode 100644
index 0000000000000000000000000000000000000000..f0d222381c261d615f10c1707211087c5f7495de
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/GridFS/Exception/FileNotFoundException.php	
@@ -0,0 +1,53 @@
+<?php
+/*
+ * Copyright 2016-2017 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace MongoDB\GridFS\Exception;
+
+use MongoDB\Exception\RuntimeException;
+use function MongoDB\BSON\fromPHP;
+use function MongoDB\BSON\toJSON;
+use function sprintf;
+
+class FileNotFoundException extends RuntimeException
+{
+    /**
+     * Thrown when a file cannot be found by its filename and revision.
+     *
+     * @param string  $filename  Filename
+     * @param integer $revision  Revision
+     * @param string  $namespace Namespace for the files collection
+     * @return self
+     */
+    public static function byFilenameAndRevision($filename, $revision, $namespace)
+    {
+        return new static(sprintf('File with name "%s" and revision "%d" not found in "%s"', $filename, $revision, $namespace));
+    }
+
+    /**
+     * Thrown when a file cannot be found by its ID.
+     *
+     * @param mixed  $id        File ID
+     * @param string $namespace Namespace for the files collection
+     * @return self
+     */
+    public static function byId($id, $namespace)
+    {
+        $json = toJSON(fromPHP(['_id' => $id]));
+
+        return new static(sprintf('File "%s" not found in "%s"', $json, $namespace));
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/GridFS/Exception/StreamException.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/GridFS/Exception/StreamException.php
new file mode 100644
index 0000000000000000000000000000000000000000..53aa9e351ec4546dd0a243d4539bcf6322e4ad37
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/GridFS/Exception/StreamException.php	
@@ -0,0 +1,46 @@
+<?php
+
+namespace MongoDB\GridFS\Exception;
+
+use MongoDB\Exception\RuntimeException;
+use function MongoDB\BSON\fromPHP;
+use function MongoDB\BSON\toJSON;
+use function sprintf;
+use function stream_get_meta_data;
+
+class StreamException extends RuntimeException
+{
+    /**
+     * @param resource $source
+     * @param resource $destination
+     */
+    public static function downloadFromFilenameFailed(string $filename, $source, $destination) : self
+    {
+        $sourceMetadata = stream_get_meta_data($source);
+        $destinationMetadata = stream_get_meta_data($destination);
+
+        return new static(sprintf('Downloading file from "%s" to "%s" failed. GridFS filename: "%s"', $sourceMetadata['uri'], $destinationMetadata['uri'], $filename));
+    }
+
+    /**
+     * @param mixed    $id
+     * @param resource $source
+     * @param resource $destination
+     */
+    public static function downloadFromIdFailed($id, $source, $destination) : self
+    {
+        $idString = toJSON(fromPHP(['_id' => $id]));
+        $sourceMetadata = stream_get_meta_data($source);
+        $destinationMetadata = stream_get_meta_data($destination);
+
+        return new static(sprintf('Downloading file from "%s" to "%s" failed. GridFS identifier: "%s"', $sourceMetadata['uri'], $destinationMetadata['uri'], $idString));
+    }
+
+    /** @param resource $source */
+    public static function uploadFailed(string $filename, $source, string $destinationUri) : self
+    {
+        $sourceMetadata = stream_get_meta_data($source);
+
+        return new static(sprintf('Uploading file from "%s" to "%s" failed. GridFS filename: "%s"', $sourceMetadata['uri'], $destinationUri, $filename));
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/GridFS/ReadableStream.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/GridFS/ReadableStream.php
new file mode 100644
index 0000000000000000000000000000000000000000..7978de9727076f22dcdf005e67743dec24861161
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/GridFS/ReadableStream.php	
@@ -0,0 +1,323 @@
+<?php
+/*
+ * Copyright 2016-2017 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace MongoDB\GridFS;
+
+use IteratorIterator;
+use MongoDB\Exception\InvalidArgumentException;
+use MongoDB\GridFS\Exception\CorruptFileException;
+use stdClass;
+use function ceil;
+use function floor;
+use function is_integer;
+use function property_exists;
+use function sprintf;
+use function strlen;
+use function substr;
+
+/**
+ * ReadableStream abstracts the process of reading a GridFS file.
+ *
+ * @internal
+ */
+class ReadableStream
+{
+    /** @var string|null */
+    private $buffer;
+
+    /** @var integer */
+    private $bufferOffset = 0;
+
+    /** @var integer */
+    private $chunkSize;
+
+    /** @var integer */
+    private $chunkOffset = 0;
+
+    /** @var IteratorIterator|null */
+    private $chunksIterator;
+
+    /** @var CollectionWrapper */
+    private $collectionWrapper;
+
+    /** @var float|integer */
+    private $expectedLastChunkSize = 0;
+
+    /** @var stdClass */
+    private $file;
+
+    /** @var integer */
+    private $length;
+
+    /** @var integer */
+    private $numChunks = 0;
+
+    /**
+     * Constructs a readable GridFS stream.
+     *
+     * @param CollectionWrapper $collectionWrapper GridFS collection wrapper
+     * @param stdClass          $file              GridFS file document
+     * @throws CorruptFileException
+     */
+    public function __construct(CollectionWrapper $collectionWrapper, stdClass $file)
+    {
+        if (! isset($file->chunkSize) || ! is_integer($file->chunkSize) || $file->chunkSize < 1) {
+            throw new CorruptFileException('file.chunkSize is not an integer >= 1');
+        }
+
+        if (! isset($file->length) || ! is_integer($file->length) || $file->length < 0) {
+            throw new CorruptFileException('file.length is not an integer > 0');
+        }
+
+        if (! isset($file->_id) && ! property_exists($file, '_id')) {
+            throw new CorruptFileException('file._id does not exist');
+        }
+
+        $this->file = $file;
+        $this->chunkSize = (integer) $file->chunkSize;
+        $this->length = (integer) $file->length;
+
+        $this->collectionWrapper = $collectionWrapper;
+
+        if ($this->length > 0) {
+            $this->numChunks = (integer) ceil($this->length / $this->chunkSize);
+            $this->expectedLastChunkSize = ($this->length - (($this->numChunks - 1) * $this->chunkSize));
+        }
+    }
+
+    /**
+     * Return internal properties for debugging purposes.
+     *
+     * @see http://php.net/manual/en/language.oop5.magic.php#language.oop5.magic.debuginfo
+     * @return array
+     */
+    public function __debugInfo()
+    {
+        return [
+            'bucketName' => $this->collectionWrapper->getBucketName(),
+            'databaseName' => $this->collectionWrapper->getDatabaseName(),
+            'file' => $this->file,
+        ];
+    }
+
+    public function close()
+    {
+        // Nothing to do
+    }
+
+    /**
+     * Return the stream's file document.
+     *
+     * @return stdClass
+     */
+    public function getFile()
+    {
+        return $this->file;
+    }
+
+    /**
+     * Return the stream's size in bytes.
+     *
+     * @return integer
+     */
+    public function getSize()
+    {
+        return $this->length;
+    }
+
+    /**
+     * Return whether the current read position is at the end of the stream.
+     *
+     * @return boolean
+     */
+    public function isEOF()
+    {
+        if ($this->chunkOffset === $this->numChunks - 1) {
+            return $this->bufferOffset >= $this->expectedLastChunkSize;
+        }
+
+        return $this->chunkOffset >= $this->numChunks;
+    }
+
+    /**
+     * Read bytes from the stream.
+     *
+     * Note: this method may return a string smaller than the requested length
+     * if data is not available to be read.
+     *
+     * @param integer $length Number of bytes to read
+     * @return string
+     * @throws InvalidArgumentException if $length is negative
+     */
+    public function readBytes($length)
+    {
+        if ($length < 0) {
+            throw new InvalidArgumentException(sprintf('$length must be >= 0; given: %d', $length));
+        }
+
+        if ($this->chunksIterator === null) {
+            $this->initChunksIterator();
+        }
+
+        if ($this->buffer === null && ! $this->initBufferFromCurrentChunk()) {
+            return '';
+        }
+
+        $data = '';
+
+        while (strlen($data) < $length) {
+            if ($this->bufferOffset >= strlen($this->buffer) && ! $this->initBufferFromNextChunk()) {
+                break;
+            }
+
+            $initialDataLength = strlen($data);
+            $data .= substr($this->buffer, $this->bufferOffset, $length - $initialDataLength);
+            $this->bufferOffset += strlen($data) - $initialDataLength;
+        }
+
+        return $data;
+    }
+
+    /**
+     * Seeks the chunk and buffer offsets for the next read operation.
+     *
+     * @param integer $offset
+     * @throws InvalidArgumentException if $offset is out of range
+     */
+    public function seek($offset)
+    {
+        if ($offset < 0 || $offset > $this->file->length) {
+            throw new InvalidArgumentException(sprintf('$offset must be >= 0 and <= %d; given: %d', $this->file->length, $offset));
+        }
+
+        /* Compute the offsets for the chunk and buffer (i.e. chunk data) from
+         * which we will expect to read after seeking. If the chunk offset
+         * changed, we'll also need to reset the buffer.
+         */
+        $lastChunkOffset = $this->chunkOffset;
+        $this->chunkOffset = (integer) floor($offset / $this->chunkSize);
+        $this->bufferOffset = $offset % $this->chunkSize;
+
+        if ($lastChunkOffset === $this->chunkOffset) {
+            return;
+        }
+
+        if ($this->chunksIterator === null) {
+            return;
+        }
+
+        // Clear the buffer since the current chunk will be changed
+        $this->buffer = null;
+
+        /* If we are seeking to a previous chunk, we need to reinitialize the
+         * chunk iterator.
+         */
+        if ($lastChunkOffset > $this->chunkOffset) {
+            $this->chunksIterator = null;
+
+            return;
+        }
+
+        /* If we are seeking to a subsequent chunk, we do not need to
+         * reinitalize the chunk iterator. Instead, we can simply move forward
+         * to $this->chunkOffset.
+         */
+        $numChunks = $this->chunkOffset - $lastChunkOffset;
+        for ($i = 0; $i < $numChunks; $i++) {
+            $this->chunksIterator->next();
+        }
+    }
+
+    /**
+     * Return the current position of the stream.
+     *
+     * This is the offset within the stream where the next byte would be read.
+     *
+     * @return integer
+     */
+    public function tell()
+    {
+        return ($this->chunkOffset * $this->chunkSize) + $this->bufferOffset;
+    }
+
+    /**
+     * Initialize the buffer to the current chunk's data.
+     *
+     * @return boolean Whether there was a current chunk to read
+     * @throws CorruptFileException if an expected chunk could not be read successfully
+     */
+    private function initBufferFromCurrentChunk()
+    {
+        if ($this->chunkOffset === 0 && $this->numChunks === 0) {
+            return false;
+        }
+
+        if (! $this->chunksIterator->valid()) {
+            throw CorruptFileException::missingChunk($this->chunkOffset);
+        }
+
+        $currentChunk = $this->chunksIterator->current();
+
+        if ($currentChunk->n !== $this->chunkOffset) {
+            throw CorruptFileException::unexpectedIndex($currentChunk->n, $this->chunkOffset);
+        }
+
+        $this->buffer = $currentChunk->data->getData();
+
+        $actualChunkSize = strlen($this->buffer);
+
+        $expectedChunkSize = $this->chunkOffset === $this->numChunks - 1
+            ? $this->expectedLastChunkSize
+            : $this->chunkSize;
+
+        if ($actualChunkSize !== $expectedChunkSize) {
+            throw CorruptFileException::unexpectedSize($actualChunkSize, $expectedChunkSize);
+        }
+
+        return true;
+    }
+
+    /**
+     * Advance to the next chunk and initialize the buffer to its data.
+     *
+     * @return boolean Whether there was a next chunk to read
+     * @throws CorruptFileException if an expected chunk could not be read successfully
+     */
+    private function initBufferFromNextChunk()
+    {
+        if ($this->chunkOffset === $this->numChunks - 1) {
+            return false;
+        }
+
+        $this->bufferOffset = 0;
+        $this->chunkOffset++;
+        $this->chunksIterator->next();
+
+        return $this->initBufferFromCurrentChunk();
+    }
+
+    /**
+     * Initializes the chunk iterator starting from the current offset.
+     */
+    private function initChunksIterator()
+    {
+        $cursor = $this->collectionWrapper->findChunksByFileId($this->file->_id, $this->chunkOffset);
+
+        $this->chunksIterator = new IteratorIterator($cursor);
+        $this->chunksIterator->rewind();
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/GridFS/StreamWrapper.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/GridFS/StreamWrapper.php
new file mode 100644
index 0000000000000000000000000000000000000000..a5136b349cc6b2324860ca1c49bf44ec76da70e7
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/GridFS/StreamWrapper.php	
@@ -0,0 +1,343 @@
+<?php
+/*
+ * Copyright 2016-2017 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace MongoDB\GridFS;
+
+use MongoDB\BSON\UTCDateTime;
+use stdClass;
+use Throwable;
+use function explode;
+use function get_class;
+use function in_array;
+use function is_integer;
+use function sprintf;
+use function stream_context_get_options;
+use function stream_get_wrappers;
+use function stream_wrapper_register;
+use function stream_wrapper_unregister;
+use function trigger_error;
+use const E_USER_WARNING;
+use const SEEK_CUR;
+use const SEEK_END;
+use const SEEK_SET;
+use const STREAM_IS_URL;
+
+/**
+ * Stream wrapper for reading and writing a GridFS file.
+ *
+ * @internal
+ * @see Bucket::openUploadStream()
+ * @see Bucket::openDownloadStream()
+ */
+class StreamWrapper
+{
+    /** @var resource|null Stream context (set by PHP) */
+    public $context;
+
+    /** @var string|null */
+    private $mode;
+
+    /** @var string|null */
+    private $protocol;
+
+    /** @var ReadableStream|WritableStream|null */
+    private $stream;
+
+    public function __destruct()
+    {
+        /* This destructor is a workaround for PHP trying to use the stream well
+         * after all objects have been destructed. This can cause autoloading
+         * issues and possibly segmentation faults during PHP shutdown. */
+        $this->stream = null;
+    }
+
+    /**
+     * Return the stream's file document.
+     *
+     * @return stdClass
+     */
+    public function getFile()
+    {
+        return $this->stream->getFile();
+    }
+
+    /**
+     * Register the GridFS stream wrapper.
+     *
+     * @param string $protocol Protocol to use for stream_wrapper_register()
+     */
+    public static function register($protocol = 'gridfs')
+    {
+        if (in_array($protocol, stream_get_wrappers())) {
+            stream_wrapper_unregister($protocol);
+        }
+
+        stream_wrapper_register($protocol, static::class, STREAM_IS_URL);
+    }
+
+    /**
+     * Closes the stream.
+     *
+     * @see http://php.net/manual/en/streamwrapper.stream-close.php
+     */
+    public function stream_close()
+    {
+        if (! $this->stream) {
+            return;
+        }
+
+        $this->stream->close();
+    }
+
+    /**
+     * Returns whether the file pointer is at the end of the stream.
+     *
+     * @see http://php.net/manual/en/streamwrapper.stream-eof.php
+     * @return boolean
+     */
+    public function stream_eof()
+    {
+        if (! $this->stream instanceof ReadableStream) {
+            return false;
+        }
+
+        return $this->stream->isEOF();
+    }
+
+    /**
+     * Opens the stream.
+     *
+     * @see http://php.net/manual/en/streamwrapper.stream-open.php
+     * @param string  $path       Path to the file resource
+     * @param string  $mode       Mode used to open the file (only "r" and "w" are supported)
+     * @param integer $options    Additional flags set by the streams API
+     * @param string  $openedPath Not used
+     * @return boolean
+     */
+    public function stream_open($path, $mode, $options, &$openedPath)
+    {
+        $this->initProtocol($path);
+        $this->mode = $mode;
+
+        if ($mode === 'r') {
+            return $this->initReadableStream();
+        }
+
+        if ($mode === 'w') {
+            return $this->initWritableStream();
+        }
+
+        return false;
+    }
+
+    /**
+     * Read bytes from the stream.
+     *
+     * Note: this method may return a string smaller than the requested length
+     * if data is not available to be read.
+     *
+     * @see http://php.net/manual/en/streamwrapper.stream-read.php
+     * @param integer $length Number of bytes to read
+     * @return string
+     */
+    public function stream_read($length)
+    {
+        if (! $this->stream instanceof ReadableStream) {
+            return '';
+        }
+
+        try {
+            return $this->stream->readBytes($length);
+        } catch (Throwable $e) {
+            trigger_error(sprintf('%s: %s', get_class($e), $e->getMessage()), E_USER_WARNING);
+
+            return false;
+        }
+    }
+
+    /**
+     * Return the current position of the stream.
+     *
+     * @see http://php.net/manual/en/streamwrapper.stream-seek.php
+     * @param integer $offset Stream offset to seek to
+     * @param integer $whence One of SEEK_SET, SEEK_CUR, or SEEK_END
+     * @return boolean True if the position was updated and false otherwise
+     */
+    public function stream_seek($offset, $whence = SEEK_SET)
+    {
+        $size = $this->stream->getSize();
+
+        if ($whence === SEEK_CUR) {
+            $offset += $this->stream->tell();
+        }
+
+        if ($whence === SEEK_END) {
+            $offset += $size;
+        }
+
+        // WritableStreams are always positioned at the end of the stream
+        if ($this->stream instanceof WritableStream) {
+            return $offset === $size;
+        }
+
+        if ($offset < 0 || $offset > $size) {
+            return false;
+        }
+
+        $this->stream->seek($offset);
+
+        return true;
+    }
+
+    /**
+     * Return information about the stream.
+     *
+     * @see http://php.net/manual/en/streamwrapper.stream-stat.php
+     * @return array
+     */
+    public function stream_stat()
+    {
+        $stat = $this->getStatTemplate();
+
+        $stat[2] = $stat['mode'] = $this->stream instanceof ReadableStream
+            ? 0100444  // S_IFREG & S_IRUSR & S_IRGRP & S_IROTH
+            : 0100222; // S_IFREG & S_IWUSR & S_IWGRP & S_IWOTH
+        $stat[7] = $stat['size'] = $this->stream->getSize();
+
+        $file = $this->stream->getFile();
+
+        if (isset($file->uploadDate) && $file->uploadDate instanceof UTCDateTime) {
+            $timestamp = $file->uploadDate->toDateTime()->getTimestamp();
+            $stat[9] = $stat['mtime'] = $timestamp;
+            $stat[10] = $stat['ctime'] = $timestamp;
+        }
+
+        if (isset($file->chunkSize) && is_integer($file->chunkSize)) {
+            $stat[11] = $stat['blksize'] = $file->chunkSize;
+        }
+
+        return $stat;
+    }
+
+    /**
+     * Return the current position of the stream.
+     *
+     * @see http://php.net/manual/en/streamwrapper.stream-tell.php
+     * @return integer The current position of the stream
+     */
+    public function stream_tell()
+    {
+        return $this->stream->tell();
+    }
+
+    /**
+     * Write bytes to the stream.
+     *
+     * @see http://php.net/manual/en/streamwrapper.stream-write.php
+     * @param string $data Data to write
+     * @return integer The number of bytes written
+     */
+    public function stream_write($data)
+    {
+        if (! $this->stream instanceof WritableStream) {
+            return 0;
+        }
+
+        try {
+            return $this->stream->writeBytes($data);
+        } catch (Throwable $e) {
+            trigger_error(sprintf('%s: %s', get_class($e), $e->getMessage()), E_USER_WARNING);
+
+            return false;
+        }
+    }
+
+    /**
+     * Returns a stat template with default values.
+     *
+     * @return array
+     */
+    private function getStatTemplate()
+    {
+        return [
+            // phpcs:disable Squiz.Arrays.ArrayDeclaration.IndexNoNewline
+            0  => 0,  'dev'     => 0,
+            1  => 0,  'ino'     => 0,
+            2  => 0,  'mode'    => 0,
+            3  => 0,  'nlink'   => 0,
+            4  => 0,  'uid'     => 0,
+            5  => 0,  'gid'     => 0,
+            6  => -1, 'rdev'    => -1,
+            7  => 0,  'size'    => 0,
+            8  => 0,  'atime'   => 0,
+            9  => 0,  'mtime'   => 0,
+            10 => 0,  'ctime'   => 0,
+            11 => -1, 'blksize' => -1,
+            12 => -1, 'blocks'  => -1,
+            // phpcs:enable
+        ];
+    }
+
+    /**
+     * Initialize the protocol from the given path.
+     *
+     * @see StreamWrapper::stream_open()
+     * @param string $path
+     */
+    private function initProtocol($path)
+    {
+        $parts = explode('://', $path, 2);
+        $this->protocol = $parts[0] ?: 'gridfs';
+    }
+
+    /**
+     * Initialize the internal stream for reading.
+     *
+     * @see StreamWrapper::stream_open()
+     * @return boolean
+     */
+    private function initReadableStream()
+    {
+        $context = stream_context_get_options($this->context);
+
+        $this->stream = new ReadableStream(
+            $context[$this->protocol]['collectionWrapper'],
+            $context[$this->protocol]['file']
+        );
+
+        return true;
+    }
+
+    /**
+     * Initialize the internal stream for writing.
+     *
+     * @see StreamWrapper::stream_open()
+     * @return boolean
+     */
+    private function initWritableStream()
+    {
+        $context = stream_context_get_options($this->context);
+
+        $this->stream = new WritableStream(
+            $context[$this->protocol]['collectionWrapper'],
+            $context[$this->protocol]['filename'],
+            $context[$this->protocol]['options']
+        );
+
+        return true;
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/GridFS/WritableStream.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/GridFS/WritableStream.php
new file mode 100644
index 0000000000000000000000000000000000000000..2e12285dd46df626f66b50bb7147b86d950f2cba
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/GridFS/WritableStream.php	
@@ -0,0 +1,314 @@
+<?php
+/*
+ * Copyright 2016-2017 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace MongoDB\GridFS;
+
+use MongoDB\BSON\Binary;
+use MongoDB\BSON\ObjectId;
+use MongoDB\BSON\UTCDateTime;
+use MongoDB\Driver\Exception\RuntimeException as DriverRuntimeException;
+use MongoDB\Exception\InvalidArgumentException;
+use stdClass;
+use function array_intersect_key;
+use function hash_final;
+use function hash_init;
+use function hash_update;
+use function is_array;
+use function is_bool;
+use function is_integer;
+use function is_object;
+use function is_string;
+use function MongoDB\is_string_array;
+use function sprintf;
+use function strlen;
+use function substr;
+
+/**
+ * WritableStream abstracts the process of writing a GridFS file.
+ *
+ * @internal
+ */
+class WritableStream
+{
+    /** @var integer */
+    private static $defaultChunkSizeBytes = 261120;
+
+    /** @var string */
+    private $buffer = '';
+
+    /** @var integer */
+    private $chunkOffset = 0;
+
+    /** @var integer */
+    private $chunkSize;
+
+    /** @var boolean */
+    private $disableMD5;
+
+    /** @var CollectionWrapper */
+    private $collectionWrapper;
+
+    /** @var array */
+    private $file;
+
+    /** @var resource */
+    private $hashCtx;
+
+    /** @var boolean */
+    private $isClosed = false;
+
+    /** @var integer */
+    private $length = 0;
+
+    /**
+     * Constructs a writable GridFS stream.
+     *
+     * Supported options:
+     *
+     *  * _id (mixed): File document identifier. Defaults to a new ObjectId.
+     *
+     *  * aliases (array of strings): DEPRECATED An array of aliases.
+     *    Applications wishing to store aliases should add an aliases field to
+     *    the metadata document instead.
+     *
+     *  * chunkSizeBytes (integer): The chunk size in bytes. Defaults to
+     *    261120 (i.e. 255 KiB).
+     *
+     *  * disableMD5 (boolean): When true, no MD5 sum will be generated.
+     *    Defaults to "false".
+     *
+     *  * contentType (string): DEPRECATED content type to be stored with the
+     *    file. This information should now be added to the metadata.
+     *
+     *  * metadata (document): User data for the "metadata" field of the files
+     *    collection document.
+     *
+     * @param CollectionWrapper $collectionWrapper GridFS collection wrapper
+     * @param string            $filename          Filename
+     * @param array             $options           Upload options
+     * @throws InvalidArgumentException
+     */
+    public function __construct(CollectionWrapper $collectionWrapper, $filename, array $options = [])
+    {
+        $options += [
+            '_id' => new ObjectId(),
+            'chunkSizeBytes' => self::$defaultChunkSizeBytes,
+            'disableMD5' => false,
+        ];
+
+        if (isset($options['aliases']) && ! is_string_array($options['aliases'])) {
+            throw InvalidArgumentException::invalidType('"aliases" option', $options['aliases'], 'array of strings');
+        }
+
+        if (! is_integer($options['chunkSizeBytes'])) {
+            throw InvalidArgumentException::invalidType('"chunkSizeBytes" option', $options['chunkSizeBytes'], 'integer');
+        }
+
+        if ($options['chunkSizeBytes'] < 1) {
+            throw new InvalidArgumentException(sprintf('Expected "chunkSizeBytes" option to be >= 1, %d given', $options['chunkSizeBytes']));
+        }
+
+        if (! is_bool($options['disableMD5'])) {
+            throw InvalidArgumentException::invalidType('"disableMD5" option', $options['disableMD5'], 'boolean');
+        }
+
+        if (isset($options['contentType']) && ! is_string($options['contentType'])) {
+            throw InvalidArgumentException::invalidType('"contentType" option', $options['contentType'], 'string');
+        }
+
+        if (isset($options['metadata']) && ! is_array($options['metadata']) && ! is_object($options['metadata'])) {
+            throw InvalidArgumentException::invalidType('"metadata" option', $options['metadata'], 'array or object');
+        }
+
+        $this->chunkSize = $options['chunkSizeBytes'];
+        $this->collectionWrapper = $collectionWrapper;
+        $this->disableMD5 = $options['disableMD5'];
+
+        if (! $this->disableMD5) {
+            $this->hashCtx = hash_init('md5');
+        }
+
+        $this->file = [
+            '_id' => $options['_id'],
+            'chunkSize' => $this->chunkSize,
+            'filename' => (string) $filename,
+        ] + array_intersect_key($options, ['aliases' => 1, 'contentType' => 1, 'metadata' => 1]);
+    }
+
+    /**
+     * Return internal properties for debugging purposes.
+     *
+     * @see http://php.net/manual/en/language.oop5.magic.php#language.oop5.magic.debuginfo
+     * @return array
+     */
+    public function __debugInfo()
+    {
+        return [
+            'bucketName' => $this->collectionWrapper->getBucketName(),
+            'databaseName' => $this->collectionWrapper->getDatabaseName(),
+            'file' => $this->file,
+        ];
+    }
+
+    /**
+     * Closes an active stream and flushes all buffered data to GridFS.
+     */
+    public function close()
+    {
+        if ($this->isClosed) {
+            // TODO: Should this be an error condition? e.g. BadMethodCallException
+            return;
+        }
+
+        if (strlen($this->buffer) > 0) {
+            $this->insertChunkFromBuffer();
+        }
+
+        $this->fileCollectionInsert();
+        $this->isClosed = true;
+    }
+
+    /**
+     * Return the stream's file document.
+     *
+     * @return stdClass
+     */
+    public function getFile()
+    {
+        return (object) $this->file;
+    }
+
+    /**
+     * Return the stream's size in bytes.
+     *
+     * Note: this value will increase as more data is written to the stream.
+     *
+     * @return integer
+     */
+    public function getSize()
+    {
+        return $this->length + strlen($this->buffer);
+    }
+
+    /**
+     * Return the current position of the stream.
+     *
+     * This is the offset within the stream where the next byte would be
+     * written. Since seeking is not supported and writes are appended, this is
+     * always the end of the stream.
+     *
+     * @see WritableStream::getSize()
+     * @return integer
+     */
+    public function tell()
+    {
+        return $this->getSize();
+    }
+
+    /**
+     * Inserts binary data into GridFS via chunks.
+     *
+     * Data will be buffered internally until chunkSizeBytes are accumulated, at
+     * which point a chunk document will be inserted and the buffer reset.
+     *
+     * @param string $data Binary data to write
+     * @return integer
+     */
+    public function writeBytes($data)
+    {
+        if ($this->isClosed) {
+            // TODO: Should this be an error condition? e.g. BadMethodCallException
+            return;
+        }
+
+        $bytesRead = 0;
+
+        while ($bytesRead != strlen($data)) {
+            $initialBufferLength = strlen($this->buffer);
+            $this->buffer .= substr($data, $bytesRead, $this->chunkSize - $initialBufferLength);
+            $bytesRead += strlen($this->buffer) - $initialBufferLength;
+
+            if (strlen($this->buffer) == $this->chunkSize) {
+                $this->insertChunkFromBuffer();
+            }
+        }
+
+        return $bytesRead;
+    }
+
+    private function abort()
+    {
+        try {
+            $this->collectionWrapper->deleteChunksByFilesId($this->file['_id']);
+        } catch (DriverRuntimeException $e) {
+            // We are already handling an error if abort() is called, so suppress this
+        }
+
+        $this->isClosed = true;
+    }
+
+    private function fileCollectionInsert()
+    {
+        $this->file['length'] = $this->length;
+        $this->file['uploadDate'] = new UTCDateTime();
+
+        if (! $this->disableMD5) {
+            $this->file['md5'] = hash_final($this->hashCtx);
+        }
+
+        try {
+            $this->collectionWrapper->insertFile($this->file);
+        } catch (DriverRuntimeException $e) {
+            $this->abort();
+
+            throw $e;
+        }
+
+        return $this->file['_id'];
+    }
+
+    private function insertChunkFromBuffer()
+    {
+        if (strlen($this->buffer) == 0) {
+            return;
+        }
+
+        $data = $this->buffer;
+        $this->buffer = '';
+
+        $chunk = [
+            'files_id' => $this->file['_id'],
+            'n' => $this->chunkOffset,
+            'data' => new Binary($data, Binary::TYPE_GENERIC),
+        ];
+
+        if (! $this->disableMD5) {
+            hash_update($this->hashCtx, $data);
+        }
+
+        try {
+            $this->collectionWrapper->insertChunk($chunk);
+        } catch (DriverRuntimeException $e) {
+            $this->abort();
+
+            throw $e;
+        }
+
+        $this->length += strlen($data);
+        $this->chunkOffset++;
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/InsertManyResult.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/InsertManyResult.php
new file mode 100644
index 0000000000000000000000000000000000000000..2d288af4cfa6e30939900f1ecd0a1b9dbfde79f6
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/InsertManyResult.php	
@@ -0,0 +1,94 @@
+<?php
+/*
+ * Copyright 2015-2017 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace MongoDB;
+
+use MongoDB\Driver\WriteResult;
+use MongoDB\Exception\BadMethodCallException;
+
+/**
+ * Result class for a multi-document insert operation.
+ */
+class InsertManyResult
+{
+    /** @var WriteResult */
+    private $writeResult;
+
+    /** @var mixed[] */
+    private $insertedIds;
+
+    /** @var boolean */
+    private $isAcknowledged;
+
+    /**
+     * @param WriteResult $writeResult
+     * @param mixed[]     $insertedIds
+     */
+    public function __construct(WriteResult $writeResult, array $insertedIds)
+    {
+        $this->writeResult = $writeResult;
+        $this->insertedIds = $insertedIds;
+        $this->isAcknowledged = $writeResult->isAcknowledged();
+    }
+
+    /**
+     * Return the number of documents that were inserted.
+     *
+     * This method should only be called if the write was acknowledged.
+     *
+     * @see InsertManyResult::isAcknowledged()
+     * @return integer
+     * @throws BadMethodCallException is the write result is unacknowledged
+     */
+    public function getInsertedCount()
+    {
+        if ($this->isAcknowledged) {
+            return $this->writeResult->getInsertedCount();
+        }
+
+        throw BadMethodCallException::unacknowledgedWriteResultAccess(__METHOD__);
+    }
+
+    /**
+     * Return a map of the inserted documents' IDs.
+     *
+     * The index of each ID in the map corresponds to each document's position
+     * in the bulk operation. If a document had an ID prior to inserting (i.e.
+     * the driver did not generate an ID), the index will contain its "_id"
+     * field value. Any driver-generated ID will be a MongoDB\BSON\ObjectId
+     * instance.
+     *
+     * @return mixed[]
+     */
+    public function getInsertedIds()
+    {
+        return $this->insertedIds;
+    }
+
+    /**
+     * Return whether this insert result was acknowledged by the server.
+     *
+     * If the insert was not acknowledged, other fields from the WriteResult
+     * (e.g. insertedCount) will be undefined.
+     *
+     * @return boolean
+     */
+    public function isAcknowledged()
+    {
+        return $this->writeResult->isAcknowledged();
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/InsertOneResult.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/InsertOneResult.php
new file mode 100644
index 0000000000000000000000000000000000000000..c4dee6e9320f2489d42a02a877a19fc1e1369fa5
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/InsertOneResult.php	
@@ -0,0 +1,96 @@
+<?php
+/*
+ * Copyright 2015-2017 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace MongoDB;
+
+use MongoDB\Driver\WriteResult;
+use MongoDB\Exception\BadMethodCallException;
+
+/**
+ * Result class for a single-document insert operation.
+ */
+class InsertOneResult
+{
+    /** @var WriteResult */
+    private $writeResult;
+
+    /** @var mixed */
+    private $insertedId;
+
+    /** @var boolean */
+    private $isAcknowledged;
+
+    /**
+     * @param WriteResult $writeResult
+     * @param mixed       $insertedId
+     */
+    public function __construct(WriteResult $writeResult, $insertedId)
+    {
+        $this->writeResult = $writeResult;
+        $this->insertedId = $insertedId;
+        $this->isAcknowledged = $writeResult->isAcknowledged();
+    }
+
+    /**
+     * Return the number of documents that were inserted.
+     *
+     * This method should only be called if the write was acknowledged.
+     *
+     * @see InsertOneResult::isAcknowledged()
+     * @return integer
+     * @throws BadMethodCallException is the write result is unacknowledged
+     */
+    public function getInsertedCount()
+    {
+        if ($this->isAcknowledged) {
+            return $this->writeResult->getInsertedCount();
+        }
+
+        throw BadMethodCallException::unacknowledgedWriteResultAccess(__METHOD__);
+    }
+
+    /**
+     * Return the inserted document's ID.
+     *
+     * If the document had an ID prior to inserting (i.e. the driver did not
+     * need to generate an ID), this will contain its "_id". Any
+     * driver-generated ID will be a MongoDB\BSON\ObjectId instance.
+     *
+     * @return mixed
+     */
+    public function getInsertedId()
+    {
+        return $this->insertedId;
+    }
+
+    /**
+     * Return whether this insert was acknowledged by the server.
+     *
+     * If the insert was not acknowledged, other fields from the WriteResult
+     * (e.g. insertedCount) will be undefined.
+     *
+     * If the insert was not acknowledged, other fields from the WriteResult
+     * (e.g. insertedCount) will be undefined and their getter methods should
+     * not be invoked.
+     *
+     * @return boolean
+     */
+    public function isAcknowledged()
+    {
+        return $this->writeResult->isAcknowledged();
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/MapReduceResult.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/MapReduceResult.php
new file mode 100644
index 0000000000000000000000000000000000000000..aaa36b172f88f69472c6422ce0811a37f3b88004
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/MapReduceResult.php	
@@ -0,0 +1,106 @@
+<?php
+/*
+ * Copyright 2017 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace MongoDB;
+
+use IteratorAggregate;
+use stdClass;
+use Traversable;
+use function call_user_func;
+
+/**
+ * Result class for mapReduce command results.
+ *
+ * This class allows for iteration of mapReduce results irrespective of the
+ * output method (e.g. inline, collection) via the IteratorAggregate interface.
+ * It also provides access to command statistics.
+ *
+ * @api
+ * @see \MongoDB\Collection::mapReduce()
+ * @see https://docs.mongodb.com/manual/reference/command/mapReduce/
+ */
+class MapReduceResult implements IteratorAggregate
+{
+    /** @var callable */
+    private $getIterator;
+
+    /** @var integer */
+    private $executionTimeMS;
+
+    /** @var array */
+    private $counts;
+
+    /** @var array */
+    private $timing;
+
+    /**
+     * @internal
+     * @param callable $getIterator Callback that returns a Traversable for mapReduce results
+     * @param stdClass $result      Result document from the mapReduce command
+     */
+    public function __construct(callable $getIterator, stdClass $result)
+    {
+        $this->getIterator = $getIterator;
+        $this->executionTimeMS = isset($result->timeMillis) ? (integer) $result->timeMillis : 0;
+        $this->counts = isset($result->counts) ? (array) $result->counts : [];
+        $this->timing = isset($result->timing) ? (array) $result->timing : [];
+    }
+
+    /**
+     * Returns various count statistics from the mapReduce command.
+     *
+     * @return array
+     */
+    public function getCounts()
+    {
+        return $this->counts;
+    }
+
+    /**
+     * Return the command execution time in milliseconds.
+     *
+     * @return integer
+     */
+    public function getExecutionTimeMS()
+    {
+        return (integer) $this->executionTimeMS;
+    }
+
+    /**
+     * Return the mapReduce results as a Traversable.
+     *
+     * @see http://php.net/iteratoraggregate.getiterator
+     * @return Traversable
+     */
+    public function getIterator()
+    {
+        return call_user_func($this->getIterator);
+    }
+
+    /**
+     * Returns various timing statistics from the mapReduce command.
+     *
+     * Note: timing statistics are only available if the mapReduce command's
+     * "verbose" option was true; otherwise, an empty array will be returned.
+     *
+     * @return array
+     */
+    public function getTiming()
+    {
+        return $this->timing;
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Model/BSONArray.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Model/BSONArray.php
new file mode 100644
index 0000000000000000000000000000000000000000..8230a5e5a9d24739b754e92bcb76b73c56f78630
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Model/BSONArray.php	
@@ -0,0 +1,101 @@
+<?php
+/*
+ * Copyright 2016-present MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace MongoDB\Model;
+
+use ArrayObject;
+use JsonSerializable;
+use MongoDB\BSON\Serializable;
+use MongoDB\BSON\Unserializable;
+use function array_values;
+use function MongoDB\recursive_copy;
+
+/**
+ * Model class for a BSON array.
+ *
+ * The internal data will be filtered through array_values() during BSON
+ * serialization to ensure that it becomes a BSON array.
+ *
+ * @api
+ */
+class BSONArray extends ArrayObject implements JsonSerializable, Serializable, Unserializable
+{
+    /**
+     * Clone this BSONArray.
+     */
+    public function __clone()
+    {
+        foreach ($this as $key => $value) {
+            $this[$key] = recursive_copy($value);
+        }
+    }
+
+    /**
+     * Factory method for var_export().
+     *
+     * @see http://php.net/oop5.magic#object.set-state
+     * @see http://php.net/var-export
+     * @param array $properties
+     * @return self
+     */
+    public static function __set_state(array $properties)
+    {
+        $array = new static();
+        $array->exchangeArray($properties);
+
+        return $array;
+    }
+
+    /**
+     * Serialize the array to BSON.
+     *
+     * The array data will be numerically reindexed to ensure that it is stored
+     * as a BSON array.
+     *
+     * @see http://php.net/mongodb-bson-serializable.bsonserialize
+     * @return array
+     */
+    public function bsonSerialize()
+    {
+        return array_values($this->getArrayCopy());
+    }
+
+    /**
+     * Unserialize the document to BSON.
+     *
+     * @see http://php.net/mongodb-bson-unserializable.bsonunserialize
+     * @param array $data Array data
+     */
+    public function bsonUnserialize(array $data)
+    {
+        self::__construct($data);
+    }
+
+    /**
+     * Serialize the array to JSON.
+     *
+     * The array data will be numerically reindexed to ensure that it is stored
+     * as a JSON array.
+     *
+     * @see http://php.net/jsonserializable.jsonserialize
+     * @return array
+     */
+    public function jsonSerialize()
+    {
+        return array_values($this->getArrayCopy());
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Model/BSONDocument.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Model/BSONDocument.php
new file mode 100644
index 0000000000000000000000000000000000000000..b00ac48942fa0ca00969330665ed02ff7f853428
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Model/BSONDocument.php	
@@ -0,0 +1,108 @@
+<?php
+/*
+ * Copyright 2016-present MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace MongoDB\Model;
+
+use ArrayObject;
+use JsonSerializable;
+use MongoDB\BSON\Serializable;
+use MongoDB\BSON\Unserializable;
+use function MongoDB\recursive_copy;
+
+/**
+ * Model class for a BSON document.
+ *
+ * The internal data will be cast to an object during BSON serialization to
+ * ensure that it becomes a BSON document.
+ *
+ * @api
+ */
+class BSONDocument extends ArrayObject implements JsonSerializable, Serializable, Unserializable
+{
+    /**
+     * Deep clone this BSONDocument.
+     */
+    public function __clone()
+    {
+        foreach ($this as $key => $value) {
+            $this[$key] = recursive_copy($value);
+        }
+    }
+
+    /**
+     * This overrides the parent constructor to allow property access of entries
+     * by default.
+     *
+     * @see http://php.net/arrayobject.construct
+     * @param array   $input
+     * @param integer $flags
+     * @param string  $iterator_class
+     */
+    public function __construct($input = [], $flags = ArrayObject::ARRAY_AS_PROPS, $iterator_class = 'ArrayIterator')
+    {
+        parent::__construct($input, $flags, $iterator_class);
+    }
+
+    /**
+     * Factory method for var_export().
+     *
+     * @see http://php.net/oop5.magic#object.set-state
+     * @see http://php.net/var-export
+     * @param array $properties
+     * @return self
+     */
+    public static function __set_state(array $properties)
+    {
+        $document = new static();
+        $document->exchangeArray($properties);
+
+        return $document;
+    }
+
+    /**
+     * Serialize the document to BSON.
+     *
+     * @see http://php.net/mongodb-bson-serializable.bsonserialize
+     * @return object
+     */
+    public function bsonSerialize()
+    {
+        return (object) $this->getArrayCopy();
+    }
+
+    /**
+     * Unserialize the document to BSON.
+     *
+     * @see http://php.net/mongodb-bson-unserializable.bsonunserialize
+     * @param array $data Array data
+     */
+    public function bsonUnserialize(array $data)
+    {
+        parent::__construct($data, ArrayObject::ARRAY_AS_PROPS);
+    }
+
+    /**
+     * Serialize the array to JSON.
+     *
+     * @see http://php.net/jsonserializable.jsonserialize
+     * @return object
+     */
+    public function jsonSerialize()
+    {
+        return (object) $this->getArrayCopy();
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Model/BSONIterator.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Model/BSONIterator.php
new file mode 100644
index 0000000000000000000000000000000000000000..093bfbe5566412f273e41aa3406a8917e6d6a0bf
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Model/BSONIterator.php	
@@ -0,0 +1,153 @@
+<?php
+/*
+ * Copyright 2018 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace MongoDB\Model;
+
+use Iterator;
+use MongoDB\Exception\InvalidArgumentException;
+use MongoDB\Exception\UnexpectedValueException;
+use function is_array;
+use function MongoDB\BSON\toPHP;
+use function sprintf;
+use function strlen;
+use function substr;
+use function unpack;
+
+/**
+ * Iterator for BSON documents.
+ */
+class BSONIterator implements Iterator
+{
+    /** @var integer */
+    private static $bsonSize = 4;
+
+    /** @var string */
+    private $buffer;
+
+    /** @var integer */
+    private $bufferLength;
+
+    /** @var mixed */
+    private $current;
+
+    /** @var integer */
+    private $key = 0;
+
+    /** @var integer */
+    private $position = 0;
+
+    /** @var array */
+    private $options;
+
+    /**
+     * Constructs a BSON Iterator.
+     *
+     * Supported options:
+     *
+     *  * typeMap (array): Type map for BSON deserialization.
+     *
+     * @internal
+     * @see http://php.net/manual/en/function.mongodb.bson-tophp.php
+     * @param string $data    Concatenated, valid, BSON-encoded documents
+     * @param array  $options Iterator options
+     * @throws InvalidArgumentException for parameter/option parsing errors
+     */
+    public function __construct($data, array $options = [])
+    {
+        if (isset($options['typeMap']) && ! is_array($options['typeMap'])) {
+            throw InvalidArgumentException::invalidType('"typeMap" option', $options['typeMap'], 'array');
+        }
+
+        if (! isset($options['typeMap'])) {
+            $options['typeMap'] = [];
+        }
+
+        $this->buffer = $data;
+        $this->bufferLength = strlen($data);
+        $this->options = $options;
+    }
+
+    /**
+     * @see http://php.net/iterator.current
+     * @return mixed
+     */
+    public function current()
+    {
+        return $this->current;
+    }
+
+    /**
+     * @see http://php.net/iterator.key
+     * @return mixed
+     */
+    public function key()
+    {
+        return $this->key;
+    }
+
+    /**
+     * @see http://php.net/iterator.next
+     * @return void
+     */
+    public function next()
+    {
+        $this->key++;
+        $this->current = null;
+        $this->advance();
+    }
+
+    /**
+     * @see http://php.net/iterator.rewind
+     * @return void
+     */
+    public function rewind()
+    {
+        $this->key = 0;
+        $this->position = 0;
+        $this->current = null;
+        $this->advance();
+    }
+
+    /**
+     * @see http://php.net/iterator.valid
+     * @return boolean
+     */
+    public function valid()
+    {
+        return $this->current !== null;
+    }
+
+    private function advance()
+    {
+        if ($this->position === $this->bufferLength) {
+            return;
+        }
+
+        if (($this->bufferLength - $this->position) < self::$bsonSize) {
+            throw new UnexpectedValueException(sprintf('Expected at least %d bytes; %d remaining', self::$bsonSize, $this->bufferLength - $this->position));
+        }
+
+        list(,$documentLength) = unpack('V', substr($this->buffer, $this->position, self::$bsonSize));
+
+        if (($this->bufferLength - $this->position) < $documentLength) {
+            throw new UnexpectedValueException(sprintf('Expected %d bytes; %d remaining', $documentLength, $this->bufferLength - $this->position));
+        }
+
+        $this->current = toPHP(substr($this->buffer, $this->position, $documentLength), $this->options['typeMap']);
+        $this->position += $documentLength;
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Model/CachingIterator.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Model/CachingIterator.php
new file mode 100644
index 0000000000000000000000000000000000000000..3eb94b22dbbca1c39b5e8d3d981cf0827d89fb67
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Model/CachingIterator.php	
@@ -0,0 +1,164 @@
+<?php
+/*
+ * Copyright 2017 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace MongoDB\Model;
+
+use Countable;
+use Iterator;
+use IteratorIterator;
+use Traversable;
+use function count;
+use function current;
+use function key;
+use function next;
+use function reset;
+
+/**
+ * Iterator for wrapping a Traversable and caching its results.
+ *
+ * By caching results, this iterators allows a Traversable to be counted and
+ * rewound multiple times, even if the wrapped object does not natively support
+ * those operations (e.g. MongoDB\Driver\Cursor).
+ *
+ * @internal
+ */
+class CachingIterator implements Countable, Iterator
+{
+    /** @var array */
+    private $items = [];
+
+    /** @var IteratorIterator */
+    private $iterator;
+
+    /** @var boolean */
+    private $iteratorAdvanced = false;
+
+    /** @var boolean */
+    private $iteratorExhausted = false;
+
+    /**
+     * Initialize the iterator and stores the first item in the cache. This
+     * effectively rewinds the Traversable and the wrapping IteratorIterator.
+     *  Additionally, this mimics behavior of the SPL iterators and allows users
+     * to omit an explicit call * to rewind() before using the other methods.
+     *
+     * @param Traversable $traversable
+     */
+    public function __construct(Traversable $traversable)
+    {
+        $this->iterator = new IteratorIterator($traversable);
+
+        $this->iterator->rewind();
+        $this->storeCurrentItem();
+    }
+
+    /**
+     * @see http://php.net/countable.count
+     * @return integer
+     */
+    public function count()
+    {
+        $this->exhaustIterator();
+
+        return count($this->items);
+    }
+
+    /**
+     * @see http://php.net/iterator.current
+     * @return mixed
+     */
+    public function current()
+    {
+        return current($this->items);
+    }
+
+    /**
+     * @see http://php.net/iterator.key
+     * @return mixed
+     */
+    public function key()
+    {
+        return key($this->items);
+    }
+
+    /**
+     * @see http://php.net/iterator.next
+     * @return void
+     */
+    public function next()
+    {
+        if (! $this->iteratorExhausted) {
+            $this->iteratorAdvanced = true;
+            $this->iterator->next();
+
+            $this->storeCurrentItem();
+
+            $this->iteratorExhausted = ! $this->iterator->valid();
+        }
+
+        next($this->items);
+    }
+
+    /**
+     * @see http://php.net/iterator.rewind
+     * @return void
+     */
+    public function rewind()
+    {
+        /* If the iterator has advanced, exhaust it now so that future iteration
+         * can rely on the cache.
+         */
+        if ($this->iteratorAdvanced) {
+            $this->exhaustIterator();
+        }
+
+        reset($this->items);
+    }
+
+    /**
+     * @see http://php.net/iterator.valid
+     * @return boolean
+     */
+    public function valid()
+    {
+        return $this->key() !== null;
+    }
+
+    /**
+     * Ensures that the inner iterator is fully consumed and cached.
+     */
+    private function exhaustIterator()
+    {
+        while (! $this->iteratorExhausted) {
+            $this->next();
+        }
+    }
+
+    /**
+     * Stores the current item in the cache.
+     */
+    private function storeCurrentItem()
+    {
+        $key = $this->iterator->key();
+
+        if ($key === null) {
+            return;
+        }
+
+        $this->items[$key] = $this->iterator->current();
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Model/CallbackIterator.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Model/CallbackIterator.php
new file mode 100644
index 0000000000000000000000000000000000000000..23b7c1035219abcc046b81fb4decfd2dda7d7f68
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Model/CallbackIterator.php	
@@ -0,0 +1,88 @@
+<?php
+/*
+ * Copyright 2017 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace MongoDB\Model;
+
+use Closure;
+use Iterator;
+use IteratorIterator;
+use Traversable;
+
+/**
+ * Iterator to apply a callback before returning an element
+ *
+ * @internal
+ */
+class CallbackIterator implements Iterator
+{
+    /** @var Closure */
+    private $callback;
+
+    /** @var IteratorIterator */
+    private $iterator;
+
+    public function __construct(Traversable $traversable, Closure $callback)
+    {
+        $this->iterator = new IteratorIterator($traversable);
+        $this->callback = $callback;
+    }
+
+    /**
+     * @see http://php.net/iterator.current
+     * @return mixed
+     */
+    public function current()
+    {
+        return ($this->callback)($this->iterator->current());
+    }
+
+    /**
+     * @see http://php.net/iterator.key
+     * @return mixed
+     */
+    public function key()
+    {
+        return $this->iterator->key();
+    }
+
+    /**
+     * @see http://php.net/iterator.next
+     * @return void
+     */
+    public function next()
+    {
+        $this->iterator->next();
+    }
+
+    /**
+     * @see http://php.net/iterator.rewind
+     * @return void
+     */
+    public function rewind()
+    {
+        $this->iterator->rewind();
+    }
+
+    /**
+     * @see http://php.net/iterator.valid
+     * @return boolean
+     */
+    public function valid()
+    {
+        return $this->iterator->valid();
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Model/ChangeStreamIterator.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Model/ChangeStreamIterator.php
new file mode 100644
index 0000000000000000000000000000000000000000..6f0a1a89d0b28418747ba26e5963b5506d9f485b
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Model/ChangeStreamIterator.php	
@@ -0,0 +1,305 @@
+<?php
+/*
+ * Copyright 2019 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace MongoDB\Model;
+
+use IteratorIterator;
+use MongoDB\BSON\Serializable;
+use MongoDB\Driver\Cursor;
+use MongoDB\Driver\Monitoring\CommandFailedEvent;
+use MongoDB\Driver\Monitoring\CommandStartedEvent;
+use MongoDB\Driver\Monitoring\CommandSubscriber;
+use MongoDB\Driver\Monitoring\CommandSucceededEvent;
+use MongoDB\Driver\Server;
+use MongoDB\Exception\InvalidArgumentException;
+use MongoDB\Exception\ResumeTokenException;
+use MongoDB\Exception\UnexpectedValueException;
+use function count;
+use function is_array;
+use function is_integer;
+use function is_object;
+use function MongoDB\Driver\Monitoring\addSubscriber;
+use function MongoDB\Driver\Monitoring\removeSubscriber;
+
+/**
+ * ChangeStreamIterator wraps a change stream's tailable cursor.
+ *
+ * This iterator tracks the size of each batch in order to determine when the
+ * postBatchResumeToken is applicable. It also ensures that initial calls to
+ * rewind() do not execute getMore commands.
+ *
+ * @internal
+ */
+class ChangeStreamIterator extends IteratorIterator implements CommandSubscriber
+{
+    /** @var integer */
+    private $batchPosition = 0;
+
+    /** @var integer */
+    private $batchSize;
+
+    /** @var boolean */
+    private $isRewindNop;
+
+    /** @var boolean */
+    private $isValid = false;
+
+    /** @var object|null */
+    private $postBatchResumeToken;
+
+    /** @var array|object|null */
+    private $resumeToken;
+
+    /** @var Server */
+    private $server;
+
+    /**
+     * @internal
+     * @param Cursor            $cursor
+     * @param integer           $firstBatchSize
+     * @param array|object|null $initialResumeToken
+     * @param object|null       $postBatchResumeToken
+     */
+    public function __construct(Cursor $cursor, $firstBatchSize, $initialResumeToken, $postBatchResumeToken)
+    {
+        if (! is_integer($firstBatchSize)) {
+            throw InvalidArgumentException::invalidType('$firstBatchSize', $firstBatchSize, 'integer');
+        }
+
+        if (isset($initialResumeToken) && ! is_array($initialResumeToken) && ! is_object($initialResumeToken)) {
+            throw InvalidArgumentException::invalidType('$initialResumeToken', $initialResumeToken, 'array or object');
+        }
+
+        if (isset($postBatchResumeToken) && ! is_object($postBatchResumeToken)) {
+            throw InvalidArgumentException::invalidType('$postBatchResumeToken', $postBatchResumeToken, 'object');
+        }
+
+        parent::__construct($cursor);
+
+        $this->batchSize = $firstBatchSize;
+        $this->isRewindNop = ($firstBatchSize === 0);
+        $this->postBatchResumeToken = $postBatchResumeToken;
+        $this->resumeToken = $initialResumeToken;
+        $this->server = $cursor->getServer();
+    }
+
+    /** @internal */
+    final public function commandFailed(CommandFailedEvent $event)
+    {
+    }
+
+    /** @internal */
+    final public function commandStarted(CommandStartedEvent $event)
+    {
+        if ($event->getCommandName() !== 'getMore') {
+            return;
+        }
+
+        $this->batchPosition = 0;
+        $this->batchSize = null;
+        $this->postBatchResumeToken = null;
+    }
+
+    /** @internal */
+    final public function commandSucceeded(CommandSucceededEvent $event)
+    {
+        if ($event->getCommandName() !== 'getMore') {
+            return;
+        }
+
+        $reply = $event->getReply();
+
+        if (! isset($reply->cursor->nextBatch) || ! is_array($reply->cursor->nextBatch)) {
+            throw new UnexpectedValueException('getMore command did not return a "cursor.nextBatch" array');
+        }
+
+        $this->batchSize = count($reply->cursor->nextBatch);
+
+        if (isset($reply->cursor->postBatchResumeToken) && is_object($reply->cursor->postBatchResumeToken)) {
+            $this->postBatchResumeToken = $reply->cursor->postBatchResumeToken;
+        }
+    }
+
+    /**
+     * @see https://php.net/iteratoriterator.current
+     * @return mixed
+     */
+    public function current()
+    {
+        return $this->isValid ? parent::current() : null;
+    }
+
+    /**
+     * Returns the resume token for the iterator's current position.
+     *
+     * Null may be returned if no change documents have been iterated and the
+     * server did not include a postBatchResumeToken in its aggregate or getMore
+     * command response.
+     *
+     * @return array|object|null
+     */
+    public function getResumeToken()
+    {
+        return $this->resumeToken;
+    }
+
+    /**
+     * Returns the server the cursor is running on.
+     */
+    public function getServer() : Server
+    {
+        return $this->server;
+    }
+
+    /**
+     * @see https://php.net/iteratoriterator.key
+     * @return mixed
+     */
+    public function key()
+    {
+        return $this->isValid ? parent::key() : null;
+    }
+
+    /**
+     * @see https://php.net/iteratoriterator.rewind
+     * @return void
+     */
+    public function next()
+    {
+        /* Determine if advancing the iterator will execute a getMore command
+         * (i.e. we are already positioned at the end of the current batch). If
+         * so, rely on the APM callbacks to reset $batchPosition and update
+         * $batchSize. Otherwise, we can forgo APM and manually increment
+         * $batchPosition after calling next(). */
+        $getMore = $this->isAtEndOfBatch();
+
+        if ($getMore) {
+            addSubscriber($this);
+        }
+
+        try {
+            parent::next();
+            $this->onIteration(! $getMore);
+        } finally {
+            if ($getMore) {
+                removeSubscriber($this);
+            }
+        }
+    }
+
+    /**
+     * @see https://php.net/iteratoriterator.rewind
+     * @return void
+     */
+    public function rewind()
+    {
+        if ($this->isRewindNop) {
+            return;
+        }
+
+        parent::rewind();
+        $this->onIteration(false);
+    }
+
+    /**
+     * @see https://php.net/iteratoriterator.valid
+     * @return boolean
+     */
+    public function valid()
+    {
+        return $this->isValid;
+    }
+
+    /**
+     * Extracts the resume token (i.e. "_id" field) from a change document.
+     *
+     * @param array|object $document Change document
+     * @return array|object
+     * @throws InvalidArgumentException
+     * @throws ResumeTokenException if the resume token is not found or invalid
+     */
+    private function extractResumeToken($document)
+    {
+        if (! is_array($document) && ! is_object($document)) {
+            throw InvalidArgumentException::invalidType('$document', $document, 'array or object');
+        }
+
+        if ($document instanceof Serializable) {
+            return $this->extractResumeToken($document->bsonSerialize());
+        }
+
+        $resumeToken = is_array($document)
+            ? ($document['_id'] ?? null)
+            : ($document->_id ?? null);
+
+        if (! isset($resumeToken)) {
+            $this->isValid = false;
+            throw ResumeTokenException::notFound();
+        }
+
+        if (! is_array($resumeToken) && ! is_object($resumeToken)) {
+            $this->isValid = false;
+            throw ResumeTokenException::invalidType($resumeToken);
+        }
+
+        return $resumeToken;
+    }
+
+    /**
+     * Return whether the iterator is positioned at the end of the batch.
+     *
+     * @return boolean
+     */
+    private function isAtEndOfBatch()
+    {
+        return $this->batchPosition + 1 >= $this->batchSize;
+    }
+
+    /**
+     * Perform housekeeping after an iteration event.
+     *
+     * @see https://github.com/mongodb/specifications/blob/master/source/change-streams/change-streams.rst#updating-the-cached-resume-token
+     * @param boolean $incrementBatchPosition
+     */
+    private function onIteration($incrementBatchPosition)
+    {
+        $this->isValid = parent::valid();
+
+        /* Disable rewind()'s NOP behavior once we advance to a valid position.
+         * This will allow the driver to throw a LogicException if rewind() is
+         * called after the cursor has advanced past its first element. */
+        if ($this->isRewindNop && $this->isValid) {
+            $this->isRewindNop = false;
+        }
+
+        if ($incrementBatchPosition && $this->isValid) {
+            $this->batchPosition++;
+        }
+
+        /* If the iterator is positioned at the end of the batch, apply the
+         * postBatchResumeToken if it's available. This handles both the case
+         * where the current batch is empty (since onIteration() will be called
+         * after a successful getMore) and when the iterator has advanced to the
+         * last document in its current batch. Otherwise, extract a resume token
+         * from the current document if possible. */
+        if ($this->isAtEndOfBatch() && $this->postBatchResumeToken !== null) {
+            $this->resumeToken = $this->postBatchResumeToken;
+        } elseif ($this->isValid) {
+            $this->resumeToken = $this->extractResumeToken($this->current());
+        }
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Model/CollectionInfo.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Model/CollectionInfo.php
new file mode 100644
index 0000000000000000000000000000000000000000..f4d61df2b711975a8ad21bb6c5f45fc785489d05
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Model/CollectionInfo.php	
@@ -0,0 +1,159 @@
+<?php
+/*
+ * Copyright 2015-2017 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace MongoDB\Model;
+
+use ArrayAccess;
+use MongoDB\Exception\BadMethodCallException;
+use function array_key_exists;
+
+/**
+ * Collection information model class.
+ *
+ * This class models the collection information returned by the listCollections
+ * command or, for legacy servers, queries on the "system.namespaces"
+ * collection. It provides methods to access options for the collection.
+ *
+ * @api
+ * @see \MongoDB\Database::listCollections()
+ * @see https://github.com/mongodb/specifications/blob/master/source/enumerate-collections.rst
+ */
+class CollectionInfo implements ArrayAccess
+{
+    /** @var array */
+    private $info;
+
+    /**
+     * @param array $info Collection info
+     */
+    public function __construct(array $info)
+    {
+        $this->info = $info;
+    }
+
+    /**
+     * Return the collection info as an array.
+     *
+     * @see http://php.net/oop5.magic#language.oop5.magic.debuginfo
+     * @return array
+     */
+    public function __debugInfo()
+    {
+        return $this->info;
+    }
+
+    /**
+     * Return the maximum number of documents to keep in the capped collection.
+     *
+     * @return integer|null
+     */
+    public function getCappedMax()
+    {
+        /* The MongoDB server might return this number as an integer or float */
+        return isset($this->info['options']['max']) ? (integer) $this->info['options']['max'] : null;
+    }
+
+    /**
+     * Return the maximum size (in bytes) of the capped collection.
+     *
+     * @return integer|null
+     */
+    public function getCappedSize()
+    {
+        /* The MongoDB server might return this number as an integer or float */
+        return isset($this->info['options']['size']) ? (integer) $this->info['options']['size'] : null;
+    }
+
+    /**
+     * Return the collection name.
+     *
+     * @return string
+     */
+    public function getName()
+    {
+        return (string) $this->info['name'];
+    }
+
+    /**
+     * Return the collection options.
+     *
+     * @return array
+     */
+    public function getOptions()
+    {
+        return isset($this->info['options']) ? (array) $this->info['options'] : [];
+    }
+
+    /**
+     * Return whether the collection is a capped collection.
+     *
+     * @return boolean
+     */
+    public function isCapped()
+    {
+        return ! empty($this->info['options']['capped']);
+    }
+
+    /**
+     * Check whether a field exists in the collection information.
+     *
+     * @see http://php.net/arrayaccess.offsetexists
+     * @param mixed $key
+     * @return boolean
+     */
+    public function offsetExists($key)
+    {
+        return array_key_exists($key, $this->info);
+    }
+
+    /**
+     * Return the field's value from the collection information.
+     *
+     * @see http://php.net/arrayaccess.offsetget
+     * @param mixed $key
+     * @return mixed
+     */
+    public function offsetGet($key)
+    {
+        return $this->info[$key];
+    }
+
+    /**
+     * Not supported.
+     *
+     * @see http://php.net/arrayaccess.offsetset
+     * @param mixed $key
+     * @param mixed $value
+     * @throws BadMethodCallException
+     */
+    public function offsetSet($key, $value)
+    {
+        throw BadMethodCallException::classIsImmutable(self::class);
+    }
+
+    /**
+     * Not supported.
+     *
+     * @see http://php.net/arrayaccess.offsetunset
+     * @param mixed $key
+     * @throws BadMethodCallException
+     */
+    public function offsetUnset($key)
+    {
+        throw BadMethodCallException::classIsImmutable(self::class);
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Model/CollectionInfoCommandIterator.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Model/CollectionInfoCommandIterator.php
new file mode 100644
index 0000000000000000000000000000000000000000..5cfa904b64cb1d99ac05ecfb97c138e0cc8ed29f
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Model/CollectionInfoCommandIterator.php	
@@ -0,0 +1,66 @@
+<?php
+/*
+ * Copyright 2015-2017 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace MongoDB\Model;
+
+use IteratorIterator;
+use Traversable;
+
+/**
+ * CollectionInfoIterator for listCollections command results.
+ *
+ * This iterator may be used to wrap a Cursor returned by the listCollections
+ * command.
+ *
+ * @internal
+ * @see \MongoDB\Database::listCollections()
+ * @see https://github.com/mongodb/specifications/blob/master/source/enumerate-collections.rst
+ * @see http://docs.mongodb.org/manual/reference/command/listCollections/
+ */
+class CollectionInfoCommandIterator extends IteratorIterator implements CollectionInfoIterator
+{
+    /** @var string|null */
+    private $databaseName;
+
+    /**
+     * @param string|null $databaseName
+     */
+    public function __construct(Traversable $iterator, $databaseName = null)
+    {
+        parent::__construct($iterator);
+
+        $this->databaseName = $databaseName;
+    }
+
+    /**
+     * Return the current element as a CollectionInfo instance.
+     *
+     * @see CollectionInfoIterator::current()
+     * @see http://php.net/iterator.current
+     * @return CollectionInfo
+     */
+    public function current()
+    {
+        $info = parent::current();
+
+        if ($this->databaseName !== null && isset($info['idIndex']) && ! isset($info['idIndex']['ns'])) {
+            $info['idIndex']['ns'] = $this->databaseName . '.' . $info['name'];
+        }
+
+        return new CollectionInfo($info);
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Model/CollectionInfoIterator.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Model/CollectionInfoIterator.php
new file mode 100644
index 0000000000000000000000000000000000000000..999ee9aecf602e3f4687b7082eb6f1f03db61377
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Model/CollectionInfoIterator.php	
@@ -0,0 +1,38 @@
+<?php
+/*
+ * Copyright 2015-2017 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace MongoDB\Model;
+
+use Iterator;
+
+/**
+ * CollectionInfoIterator interface.
+ *
+ * This iterator is used for enumerating collections in a database.
+ *
+ * @api
+ * @see \MongoDB\Database::listCollections()
+ */
+interface CollectionInfoIterator extends Iterator
+{
+    /**
+     * Return the current element as a CollectionInfo instance.
+     *
+     * @return CollectionInfo
+     */
+    public function current();
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Model/DatabaseInfo.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Model/DatabaseInfo.php
new file mode 100644
index 0000000000000000000000000000000000000000..385b46497cae9cbce4f695cc3c90c6de17bff358
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Model/DatabaseInfo.php	
@@ -0,0 +1,137 @@
+<?php
+/*
+ * Copyright 2015-2017 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace MongoDB\Model;
+
+use ArrayAccess;
+use MongoDB\Exception\BadMethodCallException;
+use function array_key_exists;
+
+/**
+ * Database information model class.
+ *
+ * This class models the database information returned by the listDatabases
+ * command. It provides methods to access common database properties.
+ *
+ * @api
+ * @see \MongoDB\Client::listDatabases()
+ * @see http://docs.mongodb.org/manual/reference/command/listDatabases/
+ */
+class DatabaseInfo implements ArrayAccess
+{
+    /** @var array */
+    private $info;
+
+    /**
+     * @param array $info Database info
+     */
+    public function __construct(array $info)
+    {
+        $this->info = $info;
+    }
+
+    /**
+     * Return the database info as an array.
+     *
+     * @see http://php.net/oop5.magic#language.oop5.magic.debuginfo
+     * @return array
+     */
+    public function __debugInfo()
+    {
+        return $this->info;
+    }
+
+    /**
+     * Return the database name.
+     *
+     * @return string
+     */
+    public function getName()
+    {
+        return (string) $this->info['name'];
+    }
+
+    /**
+     * Return the databases size on disk (in bytes).
+     *
+     * @return integer
+     */
+    public function getSizeOnDisk()
+    {
+        /* The MongoDB server might return this number as an integer or float */
+        return (integer) $this->info['sizeOnDisk'];
+    }
+
+    /**
+     * Return whether the database is empty.
+     *
+     * @return boolean
+     */
+    public function isEmpty()
+    {
+        return (boolean) $this->info['empty'];
+    }
+
+    /**
+     * Check whether a field exists in the database information.
+     *
+     * @see http://php.net/arrayaccess.offsetexists
+     * @param mixed $key
+     * @return boolean
+     */
+    public function offsetExists($key)
+    {
+        return array_key_exists($key, $this->info);
+    }
+
+    /**
+     * Return the field's value from the database information.
+     *
+     * @see http://php.net/arrayaccess.offsetget
+     * @param mixed $key
+     * @return mixed
+     */
+    public function offsetGet($key)
+    {
+        return $this->info[$key];
+    }
+
+    /**
+     * Not supported.
+     *
+     * @see http://php.net/arrayaccess.offsetset
+     * @param mixed $key
+     * @param mixed $value
+     * @throws BadMethodCallException
+     */
+    public function offsetSet($key, $value)
+    {
+        throw BadMethodCallException::classIsImmutable(self::class);
+    }
+
+    /**
+     * Not supported.
+     *
+     * @see http://php.net/arrayaccess.offsetunset
+     * @param mixed $key
+     * @throws BadMethodCallException
+     */
+    public function offsetUnset($key)
+    {
+        throw BadMethodCallException::classIsImmutable(self::class);
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Model/DatabaseInfoIterator.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Model/DatabaseInfoIterator.php
new file mode 100644
index 0000000000000000000000000000000000000000..91576eb1bccc9613eeee6222c0459375b38f9216
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Model/DatabaseInfoIterator.php	
@@ -0,0 +1,38 @@
+<?php
+/*
+ * Copyright 2015-2017 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace MongoDB\Model;
+
+use Iterator;
+
+/**
+ * DatabaseInfoIterator interface.
+ *
+ * This iterator is used for enumerating databases on a server.
+ *
+ * @api
+ * @see \MongoDB\Client::listDatabases()
+ */
+interface DatabaseInfoIterator extends Iterator
+{
+    /**
+     * Return the current element as a DatabaseInfo instance.
+     *
+     * @return DatabaseInfo
+     */
+    public function current();
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Model/DatabaseInfoLegacyIterator.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Model/DatabaseInfoLegacyIterator.php
new file mode 100644
index 0000000000000000000000000000000000000000..e50b54166ef489916080e50c51d2bf03d74184e9
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Model/DatabaseInfoLegacyIterator.php	
@@ -0,0 +1,101 @@
+<?php
+/*
+ * Copyright 2015-2017 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace MongoDB\Model;
+
+use function current;
+use function key;
+use function next;
+use function reset;
+
+/**
+ * DatabaseInfoIterator for inline listDatabases command results.
+ *
+ * This iterator may be used to wrap the array returned within the listDatabases
+ * command's single-document result.
+ *
+ * @internal
+ * @see \MongoDB\Client::listDatabases()
+ * @see http://docs.mongodb.org/manual/reference/command/listDatabases/
+ */
+class DatabaseInfoLegacyIterator implements DatabaseInfoIterator
+{
+    /** @var array */
+    private $databases;
+
+    /**
+     * @param array $databases
+     */
+    public function __construct(array $databases)
+    {
+        $this->databases = $databases;
+    }
+
+    /**
+     * Return the current element as a DatabaseInfo instance.
+     *
+     * @see DatabaseInfoIterator::current()
+     * @see http://php.net/iterator.current
+     * @return DatabaseInfo
+     */
+    public function current()
+    {
+        return new DatabaseInfo(current($this->databases));
+    }
+
+    /**
+     * Return the key of the current element.
+     *
+     * @see http://php.net/iterator.key
+     * @return integer
+     */
+    public function key()
+    {
+        return key($this->databases);
+    }
+
+    /**
+     * Move forward to next element.
+     *
+     * @see http://php.net/iterator.next
+     */
+    public function next()
+    {
+        next($this->databases);
+    }
+
+    /**
+     * Rewind the Iterator to the first element.
+     *
+     * @see http://php.net/iterator.rewind
+     */
+    public function rewind()
+    {
+        reset($this->databases);
+    }
+
+    /**
+     * Checks if current position is valid.
+     *
+     * @see http://php.net/iterator.valid
+     * @return boolean
+     */
+    public function valid()
+    {
+        return key($this->databases) !== null;
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Model/IndexInfo.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Model/IndexInfo.php
new file mode 100644
index 0000000000000000000000000000000000000000..ee8a29357a1d289a314a9482e44f4a28c7543ceb
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Model/IndexInfo.php	
@@ -0,0 +1,230 @@
+<?php
+/*
+ * Copyright 2015-2017 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace MongoDB\Model;
+
+use ArrayAccess;
+use MongoDB\Exception\BadMethodCallException;
+use function array_key_exists;
+use function array_search;
+
+/**
+ * Index information model class.
+ *
+ * This class models the index information returned by the listIndexes command
+ * or, for legacy servers, queries on the "system.indexes" collection. It
+ * provides methods to access common index options, and allows access to other
+ * options through the ArrayAccess interface (write methods are not supported).
+ * For information on keys and index options, see the referenced
+ * db.collection.createIndex() documentation.
+ *
+ * @api
+ * @see \MongoDB\Collection::listIndexes()
+ * @see https://github.com/mongodb/specifications/blob/master/source/enumerate-indexes.rst
+ * @see http://docs.mongodb.org/manual/reference/method/db.collection.createIndex/
+ */
+class IndexInfo implements ArrayAccess
+{
+    /** @var array */
+    private $info;
+
+    /**
+     * @param array $info Index info
+     */
+    public function __construct(array $info)
+    {
+        $this->info = $info;
+    }
+
+    /**
+     * Return the collection info as an array.
+     *
+     * @see http://php.net/oop5.magic#language.oop5.magic.debuginfo
+     * @return array
+     */
+    public function __debugInfo()
+    {
+        return $this->info;
+    }
+
+    /**
+     * Return the index name to allow casting IndexInfo to string.
+     *
+     * @return string
+     */
+    public function __toString()
+    {
+        return $this->getName();
+    }
+
+    /**
+     * Return the index key.
+     *
+     * @return array
+     */
+    public function getKey()
+    {
+        return (array) $this->info['key'];
+    }
+
+    /**
+     * Return the index name.
+     *
+     * @return string
+     */
+    public function getName()
+    {
+        return (string) $this->info['name'];
+    }
+
+    /**
+     * Return the index namespace (e.g. "db.collection").
+     *
+     * @return string
+     */
+    public function getNamespace()
+    {
+        return (string) $this->info['ns'];
+    }
+
+    /**
+     * Return the index version.
+     *
+     * @return integer
+     */
+    public function getVersion()
+    {
+        return (integer) $this->info['v'];
+    }
+
+    /**
+     * Return whether or not this index is of type 2dsphere.
+     *
+     * @return boolean
+     */
+    public function is2dSphere()
+    {
+        return array_search('2dsphere', $this->getKey(), true) !== false;
+    }
+
+    /**
+     * Return whether or not this index is of type geoHaystack.
+     *
+     * @return boolean
+     */
+    public function isGeoHaystack()
+    {
+        return array_search('geoHaystack', $this->getKey(), true) !== false;
+    }
+
+    /**
+     * Return whether this is a sparse index.
+     *
+     * @see http://docs.mongodb.org/manual/core/index-sparse/
+     * @return boolean
+     */
+    public function isSparse()
+    {
+        return ! empty($this->info['sparse']);
+    }
+
+    /**
+     * Return whether or not this index is of type text.
+     *
+     * @return boolean
+     */
+    public function isText()
+    {
+        return array_search('text', $this->getKey(), true) !== false;
+    }
+
+    /**
+     * Return whether this is a TTL index.
+     *
+     * @see http://docs.mongodb.org/manual/core/index-ttl/
+     * @return boolean
+     */
+    public function isTtl()
+    {
+        return array_key_exists('expireAfterSeconds', $this->info);
+    }
+
+    /**
+     * Return whether this is a unique index.
+     *
+     * @see http://docs.mongodb.org/manual/core/index-unique/
+     * @return boolean
+     */
+    public function isUnique()
+    {
+        return ! empty($this->info['unique']);
+    }
+
+    /**
+     * Check whether a field exists in the index information.
+     *
+     * @see http://php.net/arrayaccess.offsetexists
+     * @param mixed $key
+     * @return boolean
+     */
+    public function offsetExists($key)
+    {
+        return array_key_exists($key, $this->info);
+    }
+
+    /**
+     * Return the field's value from the index information.
+     *
+     * This method satisfies the Enumerating Indexes specification's requirement
+     * that index fields be made accessible under their original names. It may
+     * also be used to access fields that do not have a helper method.
+     *
+     * @see http://php.net/arrayaccess.offsetget
+     * @see https://github.com/mongodb/specifications/blob/master/source/enumerate-indexes.rst#getting-full-index-information
+     * @param mixed $key
+     * @return mixed
+     */
+    public function offsetGet($key)
+    {
+        return $this->info[$key];
+    }
+
+    /**
+     * Not supported.
+     *
+     * @see http://php.net/arrayaccess.offsetset
+     * @param mixed $key
+     * @param mixed $value
+     * @throws BadMethodCallException
+     */
+    public function offsetSet($key, $value)
+    {
+        throw BadMethodCallException::classIsImmutable(self::class);
+    }
+
+    /**
+     * Not supported.
+     *
+     * @see http://php.net/arrayaccess.offsetunset
+     * @param mixed $key
+     * @throws BadMethodCallException
+     */
+    public function offsetUnset($key)
+    {
+        throw BadMethodCallException::classIsImmutable(self::class);
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Model/IndexInfoIterator.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Model/IndexInfoIterator.php
new file mode 100644
index 0000000000000000000000000000000000000000..5195172c4753a2f7d07d8400658ef2b87e30f9e9
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Model/IndexInfoIterator.php	
@@ -0,0 +1,38 @@
+<?php
+/*
+ * Copyright 2015-2017 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace MongoDB\Model;
+
+use Iterator;
+
+/**
+ * IndexInfoIterator interface.
+ *
+ * This iterator is used for enumerating indexes in a collection.
+ *
+ * @api
+ * @see \MongoDB\Collection::listIndexes()
+ */
+interface IndexInfoIterator extends Iterator
+{
+    /**
+     * Return the current element as a IndexInfo instance.
+     *
+     * @return IndexInfo
+     */
+    public function current();
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Model/IndexInfoIteratorIterator.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Model/IndexInfoIteratorIterator.php
new file mode 100644
index 0000000000000000000000000000000000000000..c02cf1be156080181b2469deab7b87f88d297b57
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Model/IndexInfoIteratorIterator.php	
@@ -0,0 +1,69 @@
+<?php
+/*
+ * Copyright 2015-2017 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace MongoDB\Model;
+
+use IteratorIterator;
+use Traversable;
+use function array_key_exists;
+
+/**
+ * IndexInfoIterator for both listIndexes command and legacy query results.
+ *
+ * This common iterator may be used to wrap a Cursor returned by both the
+ * listIndexes command and, for legacy servers, queries on the "system.indexes"
+ * collection.
+ *
+ * @internal
+ * @see \MongoDB\Collection::listIndexes()
+ * @see https://github.com/mongodb/specifications/blob/master/source/enumerate-indexes.rst
+ * @see http://docs.mongodb.org/manual/reference/command/listIndexes/
+ * @see http://docs.mongodb.org/manual/reference/system-collections/
+ */
+class IndexInfoIteratorIterator extends IteratorIterator implements IndexInfoIterator
+{
+    /** @var string|null $ns */
+    private $ns;
+
+    /**
+     * @param string|null $ns
+     */
+    public function __construct(Traversable $iterator, $ns = null)
+    {
+        parent::__construct($iterator);
+
+        $this->ns = $ns;
+    }
+
+    /**
+     * Return the current element as an IndexInfo instance.
+     *
+     * @see IndexInfoIterator::current()
+     * @see http://php.net/iterator.current
+     * @return IndexInfo
+     */
+    public function current()
+    {
+        $info = parent::current();
+
+        if (! array_key_exists('ns', $info) && $this->ns !== null) {
+            $info['ns'] = $this->ns;
+        }
+
+        return new IndexInfo($info);
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Model/IndexInput.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Model/IndexInput.php
new file mode 100644
index 0000000000000000000000000000000000000000..d7ec50fc2836c8d05db84bee7ecfe1e8f6b4d4d3
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Model/IndexInput.php	
@@ -0,0 +1,97 @@
+<?php
+/*
+ * Copyright 2015-2017 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace MongoDB\Model;
+
+use MongoDB\BSON\Serializable;
+use MongoDB\Exception\InvalidArgumentException;
+use function is_array;
+use function is_float;
+use function is_int;
+use function is_object;
+use function is_string;
+use function MongoDB\generate_index_name;
+use function sprintf;
+
+/**
+ * Index input model class.
+ *
+ * This class is used to validate user input for index creation.
+ *
+ * @internal
+ * @see \MongoDB\Collection::createIndexes()
+ * @see https://github.com/mongodb/specifications/blob/master/source/enumerate-indexes.rst
+ * @see http://docs.mongodb.org/manual/reference/method/db.collection.createIndex/
+ */
+class IndexInput implements Serializable
+{
+    /** @var array */
+    private $index;
+
+    /**
+     * @param array $index Index specification
+     * @throws InvalidArgumentException
+     */
+    public function __construct(array $index)
+    {
+        if (! isset($index['key'])) {
+            throw new InvalidArgumentException('Required "key" document is missing from index specification');
+        }
+
+        if (! is_array($index['key']) && ! is_object($index['key'])) {
+            throw InvalidArgumentException::invalidType('"key" option', $index['key'], 'array or object');
+        }
+
+        foreach ($index['key'] as $fieldName => $order) {
+            if (! is_int($order) && ! is_float($order) && ! is_string($order)) {
+                throw InvalidArgumentException::invalidType(sprintf('order value for "%s" field within "key" option', $fieldName), $order, 'numeric or string');
+            }
+        }
+
+        if (! isset($index['name'])) {
+            $index['name'] = generate_index_name($index['key']);
+        }
+
+        if (! is_string($index['name'])) {
+            throw InvalidArgumentException::invalidType('"name" option', $index['name'], 'string');
+        }
+
+        $this->index = $index;
+    }
+
+    /**
+     * Return the index name.
+     *
+     * @return string
+     */
+    public function __toString()
+    {
+        return $this->index['name'];
+    }
+
+    /**
+     * Serialize the index information to BSON for index creation.
+     *
+     * @see \MongoDB\Collection::createIndexes()
+     * @see http://php.net/mongodb-bson-serializable.bsonserialize
+     * @return array
+     */
+    public function bsonSerialize()
+    {
+        return $this->index;
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/Aggregate.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/Aggregate.php
new file mode 100644
index 0000000000000000000000000000000000000000..85df84b44380dc143e2b7a335abd6e4a9c9da57b
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/Aggregate.php	
@@ -0,0 +1,414 @@
+<?php
+/*
+ * Copyright 2015-2017 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace MongoDB\Operation;
+
+use ArrayIterator;
+use MongoDB\Driver\Command;
+use MongoDB\Driver\Exception\RuntimeException as DriverRuntimeException;
+use MongoDB\Driver\ReadConcern;
+use MongoDB\Driver\ReadPreference;
+use MongoDB\Driver\Server;
+use MongoDB\Driver\Session;
+use MongoDB\Driver\WriteConcern;
+use MongoDB\Exception\InvalidArgumentException;
+use MongoDB\Exception\UnexpectedValueException;
+use MongoDB\Exception\UnsupportedException;
+use stdClass;
+use Traversable;
+use function current;
+use function is_array;
+use function is_bool;
+use function is_integer;
+use function is_object;
+use function is_string;
+use function MongoDB\create_field_path_type_map;
+use function MongoDB\is_last_pipeline_operator_write;
+use function MongoDB\server_supports_feature;
+use function sprintf;
+
+/**
+ * Operation for the aggregate command.
+ *
+ * @api
+ * @see \MongoDB\Collection::aggregate()
+ * @see http://docs.mongodb.org/manual/reference/command/aggregate/
+ */
+class Aggregate implements Executable, Explainable
+{
+    /** @var integer */
+    private static $wireVersionForCollation = 5;
+
+    /** @var integer */
+    private static $wireVersionForDocumentLevelValidation = 4;
+
+    /** @var integer */
+    private static $wireVersionForReadConcern = 4;
+
+    /** @var integer */
+    private static $wireVersionForWriteConcern = 5;
+
+    /** @var string */
+    private $databaseName;
+
+    /** @var string|null */
+    private $collectionName;
+
+    /** @var array */
+    private $pipeline;
+
+    /** @var array */
+    private $options;
+
+    /**
+     * Constructs an aggregate command.
+     *
+     * Supported options:
+     *
+     *  * allowDiskUse (boolean): Enables writing to temporary files. When set
+     *    to true, aggregation stages can write data to the _tmp sub-directory
+     *    in the dbPath directory. The default is false.
+     *
+     *  * batchSize (integer): The number of documents to return per batch.
+     *
+     *  * bypassDocumentValidation (boolean): If true, allows the write to
+     *    circumvent document level validation. This only applies when an $out
+     *    or $merge stage is specified.
+     *
+     *    For servers < 3.2, this option is ignored as document level validation
+     *    is not available.
+     *
+     *  * collation (document): Collation specification.
+     *
+     *    This is not supported for server versions < 3.4 and will result in an
+     *    exception at execution time if used.
+     *
+     *  * comment (string): An arbitrary string to help trace the operation
+     *    through the database profiler, currentOp, and logs.
+     *
+     *  * explain (boolean): Specifies whether or not to return the information
+     *    on the processing of the pipeline.
+     *
+     *  * hint (string|document): The index to use. Specify either the index
+     *    name as a string or the index key pattern as a document. If specified,
+     *    then the query system will only consider plans using the hinted index.
+     *
+     *  * maxTimeMS (integer): The maximum amount of time to allow the query to
+     *    run.
+     *
+     *  * readConcern (MongoDB\Driver\ReadConcern): Read concern.
+     *
+     *    This is not supported for server versions < 3.2 and will result in an
+     *    exception at execution time if used.
+     *
+     *  * readPreference (MongoDB\Driver\ReadPreference): Read preference.
+     *
+     *    This option is ignored if an $out or $merge stage is specified.
+     *
+     *  * session (MongoDB\Driver\Session): Client session.
+     *
+     *    Sessions are not supported for server versions < 3.6.
+     *
+     *  * typeMap (array): Type map for BSON deserialization. This will be
+     *    applied to the returned Cursor (it is not sent to the server).
+     *
+     *  * useCursor (boolean): Indicates whether the command will request that
+     *    the server provide results using a cursor. The default is true.
+     *
+     *    This option allows users to turn off cursors if necessary to aid in
+     *    mongod/mongos upgrades.
+     *
+     *  * writeConcern (MongoDB\Driver\WriteConcern): Write concern. This only
+     *    applies when an $out or $merge stage is specified.
+     *
+     *    This is not supported for server versions < 3.4 and will result in an
+     *    exception at execution time if used.
+     *
+     * Note: Collection-agnostic commands (e.g. $currentOp) may be executed by
+     * specifying null for the collection name.
+     *
+     * @param string      $databaseName   Database name
+     * @param string|null $collectionName Collection name
+     * @param array       $pipeline       List of pipeline operations
+     * @param array       $options        Command options
+     * @throws InvalidArgumentException for parameter/option parsing errors
+     */
+    public function __construct($databaseName, $collectionName, array $pipeline, array $options = [])
+    {
+        $expectedIndex = 0;
+
+        foreach ($pipeline as $i => $operation) {
+            if ($i !== $expectedIndex) {
+                throw new InvalidArgumentException(sprintf('$pipeline is not a list (unexpected index: "%s")', $i));
+            }
+
+            if (! is_array($operation) && ! is_object($operation)) {
+                throw InvalidArgumentException::invalidType(sprintf('$pipeline[%d]', $i), $operation, 'array or object');
+            }
+
+            $expectedIndex += 1;
+        }
+
+        $options += [
+            'allowDiskUse' => false,
+            'useCursor' => true,
+        ];
+
+        if (! is_bool($options['allowDiskUse'])) {
+            throw InvalidArgumentException::invalidType('"allowDiskUse" option', $options['allowDiskUse'], 'boolean');
+        }
+
+        if (isset($options['batchSize']) && ! is_integer($options['batchSize'])) {
+            throw InvalidArgumentException::invalidType('"batchSize" option', $options['batchSize'], 'integer');
+        }
+
+        if (isset($options['bypassDocumentValidation']) && ! is_bool($options['bypassDocumentValidation'])) {
+            throw InvalidArgumentException::invalidType('"bypassDocumentValidation" option', $options['bypassDocumentValidation'], 'boolean');
+        }
+
+        if (isset($options['collation']) && ! is_array($options['collation']) && ! is_object($options['collation'])) {
+            throw InvalidArgumentException::invalidType('"collation" option', $options['collation'], 'array or object');
+        }
+
+        if (isset($options['comment']) && ! is_string($options['comment'])) {
+            throw InvalidArgumentException::invalidType('"comment" option', $options['comment'], 'string');
+        }
+
+        if (isset($options['explain']) && ! is_bool($options['explain'])) {
+            throw InvalidArgumentException::invalidType('"explain" option', $options['explain'], 'boolean');
+        }
+
+        if (isset($options['hint']) && ! is_string($options['hint']) && ! is_array($options['hint']) && ! is_object($options['hint'])) {
+            throw InvalidArgumentException::invalidType('"hint" option', $options['hint'], 'string or array or object');
+        }
+
+        if (isset($options['maxAwaitTimeMS']) && ! is_integer($options['maxAwaitTimeMS'])) {
+            throw InvalidArgumentException::invalidType('"maxAwaitTimeMS" option', $options['maxAwaitTimeMS'], 'integer');
+        }
+
+        if (isset($options['maxTimeMS']) && ! is_integer($options['maxTimeMS'])) {
+            throw InvalidArgumentException::invalidType('"maxTimeMS" option', $options['maxTimeMS'], 'integer');
+        }
+
+        if (isset($options['readConcern']) && ! $options['readConcern'] instanceof ReadConcern) {
+            throw InvalidArgumentException::invalidType('"readConcern" option', $options['readConcern'], ReadConcern::class);
+        }
+
+        if (isset($options['readPreference']) && ! $options['readPreference'] instanceof ReadPreference) {
+            throw InvalidArgumentException::invalidType('"readPreference" option', $options['readPreference'], ReadPreference::class);
+        }
+
+        if (isset($options['session']) && ! $options['session'] instanceof Session) {
+            throw InvalidArgumentException::invalidType('"session" option', $options['session'], Session::class);
+        }
+
+        if (isset($options['typeMap']) && ! is_array($options['typeMap'])) {
+            throw InvalidArgumentException::invalidType('"typeMap" option', $options['typeMap'], 'array');
+        }
+
+        if (! is_bool($options['useCursor'])) {
+            throw InvalidArgumentException::invalidType('"useCursor" option', $options['useCursor'], 'boolean');
+        }
+
+        if (isset($options['writeConcern']) && ! $options['writeConcern'] instanceof WriteConcern) {
+            throw InvalidArgumentException::invalidType('"writeConcern" option', $options['writeConcern'], WriteConcern::class);
+        }
+
+        if (isset($options['batchSize']) && ! $options['useCursor']) {
+            throw new InvalidArgumentException('"batchSize" option should not be used if "useCursor" is false');
+        }
+
+        if (isset($options['readConcern']) && $options['readConcern']->isDefault()) {
+            unset($options['readConcern']);
+        }
+
+        if (isset($options['writeConcern']) && $options['writeConcern']->isDefault()) {
+            unset($options['writeConcern']);
+        }
+
+        if (! empty($options['explain'])) {
+            $options['useCursor'] = false;
+        }
+
+        $this->databaseName = (string) $databaseName;
+        $this->collectionName = isset($collectionName) ? (string) $collectionName : null;
+        $this->pipeline = $pipeline;
+        $this->options = $options;
+    }
+
+    /**
+     * Execute the operation.
+     *
+     * @see Executable::execute()
+     * @param Server $server
+     * @return Traversable
+     * @throws UnexpectedValueException if the command response was malformed
+     * @throws UnsupportedException if collation, read concern, or write concern is used and unsupported
+     * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
+     */
+    public function execute(Server $server)
+    {
+        if (isset($this->options['collation']) && ! server_supports_feature($server, self::$wireVersionForCollation)) {
+            throw UnsupportedException::collationNotSupported();
+        }
+
+        if (isset($this->options['readConcern']) && ! server_supports_feature($server, self::$wireVersionForReadConcern)) {
+            throw UnsupportedException::readConcernNotSupported();
+        }
+
+        if (isset($this->options['writeConcern']) && ! server_supports_feature($server, self::$wireVersionForWriteConcern)) {
+            throw UnsupportedException::writeConcernNotSupported();
+        }
+
+        $inTransaction = isset($this->options['session']) && $this->options['session']->isInTransaction();
+        if ($inTransaction) {
+            if (isset($this->options['readConcern'])) {
+                throw UnsupportedException::readConcernNotSupportedInTransaction();
+            }
+            if (isset($this->options['writeConcern'])) {
+                throw UnsupportedException::writeConcernNotSupportedInTransaction();
+            }
+        }
+
+        $hasExplain = ! empty($this->options['explain']);
+        $hasWriteStage = $this->hasWriteStage();
+
+        $command = new Command(
+            $this->createCommandDocument($server, $hasWriteStage),
+            $this->createCommandOptions()
+        );
+        $options = $this->createOptions($hasWriteStage, $hasExplain);
+
+        $cursor = $hasWriteStage && ! $hasExplain
+            ? $server->executeReadWriteCommand($this->databaseName, $command, $options)
+            : $server->executeReadCommand($this->databaseName, $command, $options);
+
+        if ($this->options['useCursor'] || $hasExplain) {
+            if (isset($this->options['typeMap'])) {
+                $cursor->setTypeMap($this->options['typeMap']);
+            }
+
+            return $cursor;
+        }
+
+        if (isset($this->options['typeMap'])) {
+            $cursor->setTypeMap(create_field_path_type_map($this->options['typeMap'], 'result.$'));
+        }
+
+        $result = current($cursor->toArray());
+
+        if (! isset($result->result) || ! is_array($result->result)) {
+            throw new UnexpectedValueException('aggregate command did not return a "result" array');
+        }
+
+        return new ArrayIterator($result->result);
+    }
+
+    public function getCommandDocument(Server $server)
+    {
+        return $this->createCommandDocument($server, $this->hasWriteStage());
+    }
+
+    private function createCommandDocument(Server $server, bool $hasWriteStage) : array
+    {
+        $cmd = [
+            'aggregate' => $this->collectionName ?? 1,
+            'pipeline' => $this->pipeline,
+        ];
+
+        $cmd['allowDiskUse'] = $this->options['allowDiskUse'];
+
+        if (! empty($this->options['bypassDocumentValidation']) &&
+            server_supports_feature($server, self::$wireVersionForDocumentLevelValidation)
+        ) {
+            $cmd['bypassDocumentValidation'] = $this->options['bypassDocumentValidation'];
+        }
+
+        foreach (['comment', 'explain', 'maxTimeMS'] as $option) {
+            if (isset($this->options[$option])) {
+                $cmd[$option] = $this->options[$option];
+            }
+        }
+
+        if (isset($this->options['collation'])) {
+            $cmd['collation'] = (object) $this->options['collation'];
+        }
+
+        if (isset($this->options['hint'])) {
+            $cmd['hint'] = is_array($this->options['hint']) ? (object) $this->options['hint'] : $this->options['hint'];
+        }
+
+        if ($this->options['useCursor']) {
+            /* Ignore batchSize if pipeline includes an $out or $merge stage, as
+             * no documents will be returned and sending a batchSize of zero
+             * could prevent the pipeline from executing at all. */
+            $cmd['cursor'] = isset($this->options["batchSize"]) && ! $hasWriteStage
+                ? ['batchSize' => $this->options["batchSize"]]
+                : new stdClass();
+        }
+
+        return $cmd;
+    }
+
+    private function createCommandOptions() : array
+    {
+        $cmdOptions = [];
+
+        if (isset($this->options['maxAwaitTimeMS'])) {
+            $cmdOptions['maxAwaitTimeMS'] = $this->options['maxAwaitTimeMS'];
+        }
+
+        return $cmdOptions;
+    }
+
+    /**
+     * Create options for executing the command.
+     *
+     * @see http://php.net/manual/en/mongodb-driver-server.executereadcommand.php
+     * @see http://php.net/manual/en/mongodb-driver-server.executereadwritecommand.php
+     * @param boolean $hasWriteStage
+     * @param boolean $hasExplain
+     * @return array
+     */
+    private function createOptions($hasWriteStage, $hasExplain)
+    {
+        $options = [];
+
+        if (isset($this->options['readConcern'])) {
+            $options['readConcern'] = $this->options['readConcern'];
+        }
+
+        if (! $hasWriteStage && isset($this->options['readPreference'])) {
+            $options['readPreference'] = $this->options['readPreference'];
+        }
+
+        if (isset($this->options['session'])) {
+            $options['session'] = $this->options['session'];
+        }
+
+        if ($hasWriteStage && ! $hasExplain && isset($this->options['writeConcern'])) {
+            $options['writeConcern'] = $this->options['writeConcern'];
+        }
+
+        return $options;
+    }
+
+    private function hasWriteStage() : bool
+    {
+        return is_last_pipeline_operator_write($this->pipeline);
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/BulkWrite.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/BulkWrite.php
new file mode 100644
index 0000000000000000000000000000000000000000..95bd4bb1c43e90d3ca5d614da2ac9e214f03f989
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/BulkWrite.php	
@@ -0,0 +1,414 @@
+<?php
+/*
+ * Copyright 2015-2017 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace MongoDB\Operation;
+
+use MongoDB\BulkWriteResult;
+use MongoDB\Driver\BulkWrite as Bulk;
+use MongoDB\Driver\Exception\RuntimeException as DriverRuntimeException;
+use MongoDB\Driver\Server;
+use MongoDB\Driver\Session;
+use MongoDB\Driver\WriteConcern;
+use MongoDB\Exception\InvalidArgumentException;
+use MongoDB\Exception\UnsupportedException;
+use function array_key_exists;
+use function count;
+use function current;
+use function is_array;
+use function is_bool;
+use function is_object;
+use function key;
+use function MongoDB\is_first_key_operator;
+use function MongoDB\is_pipeline;
+use function MongoDB\server_supports_feature;
+use function sprintf;
+
+/**
+ * Operation for executing multiple write operations.
+ *
+ * @api
+ * @see \MongoDB\Collection::bulkWrite()
+ */
+class BulkWrite implements Executable
+{
+    const DELETE_MANY = 'deleteMany';
+    const DELETE_ONE  = 'deleteOne';
+    const INSERT_ONE  = 'insertOne';
+    const REPLACE_ONE = 'replaceOne';
+    const UPDATE_MANY = 'updateMany';
+    const UPDATE_ONE  = 'updateOne';
+
+    /** @var integer */
+    private static $wireVersionForArrayFilters = 6;
+
+    /** @var integer */
+    private static $wireVersionForCollation = 5;
+
+    /** @var integer */
+    private static $wireVersionForDocumentLevelValidation = 4;
+
+    /** @var string */
+    private $databaseName;
+
+    /** @var string */
+    private $collectionName;
+
+    /** @var array[] */
+    private $operations;
+
+    /** @var array */
+    private $options;
+
+    /** @var boolean */
+    private $isArrayFiltersUsed = false;
+
+    /** @var boolean */
+    private $isCollationUsed = false;
+
+    /**
+     * Constructs a bulk write operation.
+     *
+     * Example array structure for all supported operation types:
+     *
+     *  [
+     *    [ 'deleteMany' => [ $filter, $options ] ],
+     *    [ 'deleteOne'  => [ $filter, $options ] ],
+     *    [ 'insertOne'  => [ $document ] ],
+     *    [ 'replaceOne' => [ $filter, $replacement, $options ] ],
+     *    [ 'updateMany' => [ $filter, $update, $options ] ],
+     *    [ 'updateOne'  => [ $filter, $update, $options ] ],
+     *  ]
+     *
+     * Arguments correspond to the respective Operation classes; however, the
+     * writeConcern option is specified for the top-level bulk write operation
+     * instead of each individual operation.
+     *
+     * Supported options for deleteMany and deleteOne operations:
+     *
+     *  * collation (document): Collation specification.
+     *
+     *    This is not supported for server versions < 3.4 and will result in an
+     *    exception at execution time if used.
+     *
+     * Supported options for replaceOne, updateMany, and updateOne operations:
+     *
+     *  * collation (document): Collation specification.
+     *
+     *    This is not supported for server versions < 3.4 and will result in an
+     *    exception at execution time if used.
+     *
+     *  * upsert (boolean): When true, a new document is created if no document
+     *    matches the query. The default is false.
+     *
+     * Supported options for updateMany and updateOne operations:
+     *
+     *  * arrayFilters (document array): A set of filters specifying to which
+     *    array elements an update should apply.
+     *
+     *    This is not supported for server versions < 3.6 and will result in an
+     *    exception at execution time if used.
+     *
+     * Supported options for the bulk write operation:
+     *
+     *  * bypassDocumentValidation (boolean): If true, allows the write to
+     *    circumvent document level validation. The default is false.
+     *
+     *    For servers < 3.2, this option is ignored as document level validation
+     *    is not available.
+     *
+     *  * ordered (boolean): If true, when an insert fails, return without
+     *    performing the remaining writes. If false, when a write fails,
+     *    continue with the remaining writes, if any. The default is true.
+     *
+     *  * session (MongoDB\Driver\Session): Client session.
+     *
+     *    Sessions are not supported for server versions < 3.6.
+     *
+     *  * writeConcern (MongoDB\Driver\WriteConcern): Write concern.
+     *
+     * @param string  $databaseName   Database name
+     * @param string  $collectionName Collection name
+     * @param array[] $operations     List of write operations
+     * @param array   $options        Command options
+     * @throws InvalidArgumentException for parameter/option parsing errors
+     */
+    public function __construct($databaseName, $collectionName, array $operations, array $options = [])
+    {
+        if (empty($operations)) {
+            throw new InvalidArgumentException('$operations is empty');
+        }
+
+        $expectedIndex = 0;
+
+        foreach ($operations as $i => $operation) {
+            if ($i !== $expectedIndex) {
+                throw new InvalidArgumentException(sprintf('$operations is not a list (unexpected index: "%s")', $i));
+            }
+
+            if (! is_array($operation)) {
+                throw InvalidArgumentException::invalidType(sprintf('$operations[%d]', $i), $operation, 'array');
+            }
+
+            if (count($operation) !== 1) {
+                throw new InvalidArgumentException(sprintf('Expected one element in $operation[%d], actually: %d', $i, count($operation)));
+            }
+
+            $type = key($operation);
+            $args = current($operation);
+
+            if (! isset($args[0]) && ! array_key_exists(0, $args)) {
+                throw new InvalidArgumentException(sprintf('Missing first argument for $operations[%d]["%s"]', $i, $type));
+            }
+
+            if (! is_array($args[0]) && ! is_object($args[0])) {
+                throw InvalidArgumentException::invalidType(sprintf('$operations[%d]["%s"][0]', $i, $type), $args[0], 'array or object');
+            }
+
+            switch ($type) {
+                case self::INSERT_ONE:
+                    break;
+
+                case self::DELETE_MANY:
+                case self::DELETE_ONE:
+                    if (! isset($args[1])) {
+                        $args[1] = [];
+                    }
+
+                    if (! is_array($args[1])) {
+                        throw InvalidArgumentException::invalidType(sprintf('$operations[%d]["%s"][1]', $i, $type), $args[1], 'array');
+                    }
+
+                    $args[1]['limit'] = ($type === self::DELETE_ONE ? 1 : 0);
+
+                    if (isset($args[1]['collation'])) {
+                        $this->isCollationUsed = true;
+
+                        if (! is_array($args[1]['collation']) && ! is_object($args[1]['collation'])) {
+                            throw InvalidArgumentException::invalidType(sprintf('$operations[%d]["%s"][1]["collation"]', $i, $type), $args[1]['collation'], 'array or object');
+                        }
+                    }
+
+                    $operations[$i][$type][1] = $args[1];
+
+                    break;
+
+                case self::REPLACE_ONE:
+                    if (! isset($args[1]) && ! array_key_exists(1, $args)) {
+                        throw new InvalidArgumentException(sprintf('Missing second argument for $operations[%d]["%s"]', $i, $type));
+                    }
+
+                    if (! is_array($args[1]) && ! is_object($args[1])) {
+                        throw InvalidArgumentException::invalidType(sprintf('$operations[%d]["%s"][1]', $i, $type), $args[1], 'array or object');
+                    }
+
+                    if (is_first_key_operator($args[1])) {
+                        throw new InvalidArgumentException(sprintf('First key in $operations[%d]["%s"][1] is an update operator', $i, $type));
+                    }
+
+                    if (! isset($args[2])) {
+                        $args[2] = [];
+                    }
+
+                    if (! is_array($args[2])) {
+                        throw InvalidArgumentException::invalidType(sprintf('$operations[%d]["%s"][2]', $i, $type), $args[2], 'array');
+                    }
+
+                    $args[2]['multi'] = false;
+                    $args[2] += ['upsert' => false];
+
+                    if (isset($args[2]['collation'])) {
+                        $this->isCollationUsed = true;
+
+                        if (! is_array($args[2]['collation']) && ! is_object($args[2]['collation'])) {
+                            throw InvalidArgumentException::invalidType(sprintf('$operations[%d]["%s"][2]["collation"]', $i, $type), $args[2]['collation'], 'array or object');
+                        }
+                    }
+
+                    if (! is_bool($args[2]['upsert'])) {
+                        throw InvalidArgumentException::invalidType(sprintf('$operations[%d]["%s"][2]["upsert"]', $i, $type), $args[2]['upsert'], 'boolean');
+                    }
+
+                    $operations[$i][$type][2] = $args[2];
+
+                    break;
+
+                case self::UPDATE_MANY:
+                case self::UPDATE_ONE:
+                    if (! isset($args[1]) && ! array_key_exists(1, $args)) {
+                        throw new InvalidArgumentException(sprintf('Missing second argument for $operations[%d]["%s"]', $i, $type));
+                    }
+
+                    if (! is_array($args[1]) && ! is_object($args[1])) {
+                        throw InvalidArgumentException::invalidType(sprintf('$operations[%d]["%s"][1]', $i, $type), $args[1], 'array or object');
+                    }
+
+                    if (! is_first_key_operator($args[1]) && ! is_pipeline($args[1])) {
+                        throw new InvalidArgumentException(sprintf('First key in $operations[%d]["%s"][1] is neither an update operator nor a pipeline', $i, $type));
+                    }
+
+                    if (! isset($args[2])) {
+                        $args[2] = [];
+                    }
+
+                    if (! is_array($args[2])) {
+                        throw InvalidArgumentException::invalidType(sprintf('$operations[%d]["%s"][2]', $i, $type), $args[2], 'array');
+                    }
+
+                    $args[2]['multi'] = ($type === self::UPDATE_MANY);
+                    $args[2] += ['upsert' => false];
+
+                    if (isset($args[2]['arrayFilters'])) {
+                        $this->isArrayFiltersUsed = true;
+
+                        if (! is_array($args[2]['arrayFilters'])) {
+                            throw InvalidArgumentException::invalidType(sprintf('$operations[%d]["%s"][2]["arrayFilters"]', $i, $type), $args[2]['arrayFilters'], 'array');
+                        }
+                    }
+
+                    if (isset($args[2]['collation'])) {
+                        $this->isCollationUsed = true;
+
+                        if (! is_array($args[2]['collation']) && ! is_object($args[2]['collation'])) {
+                            throw InvalidArgumentException::invalidType(sprintf('$operations[%d]["%s"][2]["collation"]', $i, $type), $args[2]['collation'], 'array or object');
+                        }
+                    }
+
+                    if (! is_bool($args[2]['upsert'])) {
+                        throw InvalidArgumentException::invalidType(sprintf('$operations[%d]["%s"][2]["upsert"]', $i, $type), $args[2]['upsert'], 'boolean');
+                    }
+
+                    $operations[$i][$type][2] = $args[2];
+
+                    break;
+
+                default:
+                    throw new InvalidArgumentException(sprintf('Unknown operation type "%s" in $operations[%d]', $type, $i));
+            }
+
+            $expectedIndex += 1;
+        }
+
+        $options += ['ordered' => true];
+
+        if (isset($options['bypassDocumentValidation']) && ! is_bool($options['bypassDocumentValidation'])) {
+            throw InvalidArgumentException::invalidType('"bypassDocumentValidation" option', $options['bypassDocumentValidation'], 'boolean');
+        }
+
+        if (! is_bool($options['ordered'])) {
+            throw InvalidArgumentException::invalidType('"ordered" option', $options['ordered'], 'boolean');
+        }
+
+        if (isset($options['session']) && ! $options['session'] instanceof Session) {
+            throw InvalidArgumentException::invalidType('"session" option', $options['session'], Session::class);
+        }
+
+        if (isset($options['writeConcern']) && ! $options['writeConcern'] instanceof WriteConcern) {
+            throw InvalidArgumentException::invalidType('"writeConcern" option', $options['writeConcern'], WriteConcern::class);
+        }
+
+        if (isset($options['writeConcern']) && $options['writeConcern']->isDefault()) {
+            unset($options['writeConcern']);
+        }
+
+        $this->databaseName = (string) $databaseName;
+        $this->collectionName = (string) $collectionName;
+        $this->operations = $operations;
+        $this->options = $options;
+    }
+
+    /**
+     * Execute the operation.
+     *
+     * @see Executable::execute()
+     * @param Server $server
+     * @return BulkWriteResult
+     * @throws UnsupportedException if array filters or collation is used and unsupported
+     * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
+     */
+    public function execute(Server $server)
+    {
+        if ($this->isArrayFiltersUsed && ! server_supports_feature($server, self::$wireVersionForArrayFilters)) {
+            throw UnsupportedException::arrayFiltersNotSupported();
+        }
+
+        if ($this->isCollationUsed && ! server_supports_feature($server, self::$wireVersionForCollation)) {
+            throw UnsupportedException::collationNotSupported();
+        }
+
+        $inTransaction = isset($this->options['session']) && $this->options['session']->isInTransaction();
+        if ($inTransaction && isset($this->options['writeConcern'])) {
+            throw UnsupportedException::writeConcernNotSupportedInTransaction();
+        }
+
+        $options = ['ordered' => $this->options['ordered']];
+
+        if (! empty($this->options['bypassDocumentValidation']) &&
+            server_supports_feature($server, self::$wireVersionForDocumentLevelValidation)
+        ) {
+            $options['bypassDocumentValidation'] = $this->options['bypassDocumentValidation'];
+        }
+
+        $bulk = new Bulk($options);
+        $insertedIds = [];
+
+        foreach ($this->operations as $i => $operation) {
+            $type = key($operation);
+            $args = current($operation);
+
+            switch ($type) {
+                case self::DELETE_MANY:
+                case self::DELETE_ONE:
+                    $bulk->delete($args[0], $args[1]);
+                    break;
+
+                case self::INSERT_ONE:
+                    $insertedIds[$i] = $bulk->insert($args[0]);
+                    break;
+
+                case self::REPLACE_ONE:
+                case self::UPDATE_MANY:
+                case self::UPDATE_ONE:
+                    $bulk->update($args[0], $args[1], $args[2]);
+            }
+        }
+
+        $writeResult = $server->executeBulkWrite($this->databaseName . '.' . $this->collectionName, $bulk, $this->createOptions());
+
+        return new BulkWriteResult($writeResult, $insertedIds);
+    }
+
+    /**
+     * Create options for executing the bulk write.
+     *
+     * @see http://php.net/manual/en/mongodb-driver-server.executebulkwrite.php
+     * @return array
+     */
+    private function createOptions()
+    {
+        $options = [];
+
+        if (isset($this->options['session'])) {
+            $options['session'] = $this->options['session'];
+        }
+
+        if (isset($this->options['writeConcern'])) {
+            $options['writeConcern'] = $this->options['writeConcern'];
+        }
+
+        return $options;
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/Count.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/Count.php
new file mode 100644
index 0000000000000000000000000000000000000000..2e00ae555f3c74950b65aff833ddf87217f14585
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/Count.php	
@@ -0,0 +1,246 @@
+<?php
+/*
+ * Copyright 2015-2017 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace MongoDB\Operation;
+
+use MongoDB\Driver\Command;
+use MongoDB\Driver\Exception\RuntimeException as DriverRuntimeException;
+use MongoDB\Driver\ReadConcern;
+use MongoDB\Driver\ReadPreference;
+use MongoDB\Driver\Server;
+use MongoDB\Driver\Session;
+use MongoDB\Exception\InvalidArgumentException;
+use MongoDB\Exception\UnexpectedValueException;
+use MongoDB\Exception\UnsupportedException;
+use function current;
+use function is_array;
+use function is_float;
+use function is_integer;
+use function is_object;
+use function is_string;
+use function MongoDB\server_supports_feature;
+
+/**
+ * Operation for the count command.
+ *
+ * @api
+ * @see \MongoDB\Collection::count()
+ * @see http://docs.mongodb.org/manual/reference/command/count/
+ */
+class Count implements Executable, Explainable
+{
+    /** @var integer */
+    private static $wireVersionForCollation = 5;
+
+    /** @var integer */
+    private static $wireVersionForReadConcern = 4;
+
+    /** @var string */
+    private $databaseName;
+
+    /** @var string */
+    private $collectionName;
+
+    /** @var array|object */
+    private $filter;
+
+    /** @var array */
+    private $options;
+
+    /**
+     * Constructs a count command.
+     *
+     * Supported options:
+     *
+     *  * collation (document): Collation specification.
+     *
+     *    This is not supported for server versions < 3.4 and will result in an
+     *    exception at execution time if used.
+     *
+     *  * hint (string|document): The index to use. Specify either the index
+     *    name as a string or the index key pattern as a document. If specified,
+     *    then the query system will only consider plans using the hinted index.
+     *
+     *  * limit (integer): The maximum number of documents to count.
+     *
+     *  * maxTimeMS (integer): The maximum amount of time to allow the query to
+     *    run.
+     *
+     *  * readConcern (MongoDB\Driver\ReadConcern): Read concern.
+     *
+     *    This is not supported for server versions < 3.2 and will result in an
+     *    exception at execution time if used.
+     *
+     *  * readPreference (MongoDB\Driver\ReadPreference): Read preference.
+     *
+     *  * session (MongoDB\Driver\Session): Client session.
+     *
+     *    Sessions are not supported for server versions < 3.6.
+     *
+     *  * skip (integer): The number of documents to skip before returning the
+     *    documents.
+     *
+     * @param string       $databaseName   Database name
+     * @param string       $collectionName Collection name
+     * @param array|object $filter         Query by which to filter documents
+     * @param array        $options        Command options
+     * @throws InvalidArgumentException for parameter/option parsing errors
+     */
+    public function __construct($databaseName, $collectionName, $filter = [], array $options = [])
+    {
+        if (! is_array($filter) && ! is_object($filter)) {
+            throw InvalidArgumentException::invalidType('$filter', $filter, 'array or object');
+        }
+
+        if (isset($options['collation']) && ! is_array($options['collation']) && ! is_object($options['collation'])) {
+            throw InvalidArgumentException::invalidType('"collation" option', $options['collation'], 'array or object');
+        }
+
+        if (isset($options['hint']) && ! is_string($options['hint']) && ! is_array($options['hint']) && ! is_object($options['hint'])) {
+            throw InvalidArgumentException::invalidType('"hint" option', $options['hint'], 'string or array or object');
+        }
+
+        if (isset($options['limit']) && ! is_integer($options['limit'])) {
+            throw InvalidArgumentException::invalidType('"limit" option', $options['limit'], 'integer');
+        }
+
+        if (isset($options['maxTimeMS']) && ! is_integer($options['maxTimeMS'])) {
+            throw InvalidArgumentException::invalidType('"maxTimeMS" option', $options['maxTimeMS'], 'integer');
+        }
+
+        if (isset($options['readConcern']) && ! $options['readConcern'] instanceof ReadConcern) {
+            throw InvalidArgumentException::invalidType('"readConcern" option', $options['readConcern'], ReadConcern::class);
+        }
+
+        if (isset($options['readPreference']) && ! $options['readPreference'] instanceof ReadPreference) {
+            throw InvalidArgumentException::invalidType('"readPreference" option', $options['readPreference'], ReadPreference::class);
+        }
+
+        if (isset($options['session']) && ! $options['session'] instanceof Session) {
+            throw InvalidArgumentException::invalidType('"session" option', $options['session'], Session::class);
+        }
+
+        if (isset($options['skip']) && ! is_integer($options['skip'])) {
+            throw InvalidArgumentException::invalidType('"skip" option', $options['skip'], 'integer');
+        }
+
+        if (isset($options['readConcern']) && $options['readConcern']->isDefault()) {
+            unset($options['readConcern']);
+        }
+
+        $this->databaseName = (string) $databaseName;
+        $this->collectionName = (string) $collectionName;
+        $this->filter = $filter;
+        $this->options = $options;
+    }
+
+    /**
+     * Execute the operation.
+     *
+     * @see Executable::execute()
+     * @param Server $server
+     * @return integer
+     * @throws UnexpectedValueException if the command response was malformed
+     * @throws UnsupportedException if collation or read concern is used and unsupported
+     * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
+     */
+    public function execute(Server $server)
+    {
+        if (isset($this->options['collation']) && ! server_supports_feature($server, self::$wireVersionForCollation)) {
+            throw UnsupportedException::collationNotSupported();
+        }
+
+        if (isset($this->options['readConcern']) && ! server_supports_feature($server, self::$wireVersionForReadConcern)) {
+            throw UnsupportedException::readConcernNotSupported();
+        }
+
+        $inTransaction = isset($this->options['session']) && $this->options['session']->isInTransaction();
+        if ($inTransaction && isset($this->options['readConcern'])) {
+            throw UnsupportedException::readConcernNotSupportedInTransaction();
+        }
+
+        $cursor = $server->executeReadCommand($this->databaseName, new Command($this->createCommandDocument()), $this->createOptions());
+        $result = current($cursor->toArray());
+
+        // Older server versions may return a float
+        if (! isset($result->n) || ! (is_integer($result->n) || is_float($result->n))) {
+            throw new UnexpectedValueException('count command did not return a numeric "n" value');
+        }
+
+        return (integer) $result->n;
+    }
+
+    public function getCommandDocument(Server $server)
+    {
+        return $this->createCommandDocument();
+    }
+
+    /**
+     * Create the count command document.
+     *
+     * @return array
+     */
+    private function createCommandDocument()
+    {
+        $cmd = ['count' => $this->collectionName];
+
+        if (! empty($this->filter)) {
+            $cmd['query'] = (object) $this->filter;
+        }
+
+        if (isset($this->options['collation'])) {
+            $cmd['collation'] = (object) $this->options['collation'];
+        }
+
+        if (isset($this->options['hint'])) {
+            $cmd['hint'] = is_array($this->options['hint']) ? (object) $this->options['hint'] : $this->options['hint'];
+        }
+
+        foreach (['limit', 'maxTimeMS', 'skip'] as $option) {
+            if (isset($this->options[$option])) {
+                $cmd[$option] = $this->options[$option];
+            }
+        }
+
+        return $cmd;
+    }
+
+    /**
+     * Create options for executing the command.
+     *
+     * @see http://php.net/manual/en/mongodb-driver-server.executereadcommand.php
+     * @return array
+     */
+    private function createOptions()
+    {
+        $options = [];
+
+        if (isset($this->options['readConcern'])) {
+            $options['readConcern'] = $this->options['readConcern'];
+        }
+
+        if (isset($this->options['readPreference'])) {
+            $options['readPreference'] = $this->options['readPreference'];
+        }
+
+        if (isset($this->options['session'])) {
+            $options['session'] = $this->options['session'];
+        }
+
+        return $options;
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/CountDocuments.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/CountDocuments.php
new file mode 100644
index 0000000000000000000000000000000000000000..77499e5b73e8767c00f3aca043c2bb362da122d2
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/CountDocuments.php	
@@ -0,0 +1,173 @@
+<?php
+/*
+ * Copyright 2015-2017 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace MongoDB\Operation;
+
+use MongoDB\Driver\Exception\RuntimeException as DriverRuntimeException;
+use MongoDB\Driver\Server;
+use MongoDB\Exception\InvalidArgumentException;
+use MongoDB\Exception\UnexpectedValueException;
+use MongoDB\Exception\UnsupportedException;
+use function array_intersect_key;
+use function count;
+use function current;
+use function is_array;
+use function is_float;
+use function is_integer;
+use function is_object;
+
+/**
+ * Operation for obtaining an exact count of documents in a collection
+ *
+ * @api
+ * @see \MongoDB\Collection::countDocuments()
+ * @see https://github.com/mongodb/specifications/blob/master/source/crud/crud.rst#countdocuments
+ */
+class CountDocuments implements Executable
+{
+    /** @var string */
+    private $databaseName;
+
+    /** @var string */
+    private $collectionName;
+
+    /** @var array|object */
+    private $filter;
+
+    /** @var array */
+    private $aggregateOptions;
+
+    /** @var array */
+    private $countOptions;
+
+    /** @var Aggregate */
+    private $aggregate;
+
+    /**
+     * Constructs an aggregate command for counting documents
+     *
+     * Supported options:
+     *
+     *  * collation (document): Collation specification.
+     *
+     *    This is not supported for server versions < 3.4 and will result in an
+     *    exception at execution time if used.
+     *
+     *  * hint (string|document): The index to use. Specify either the index
+     *    name as a string or the index key pattern as a document. If specified,
+     *    then the query system will only consider plans using the hinted index.
+     *
+     *  * limit (integer): The maximum number of documents to count.
+     *
+     *  * maxTimeMS (integer): The maximum amount of time to allow the query to
+     *    run.
+     *
+     *  * readConcern (MongoDB\Driver\ReadConcern): Read concern.
+     *
+     *    This is not supported for server versions < 3.2 and will result in an
+     *    exception at execution time if used.
+     *
+     *  * readPreference (MongoDB\Driver\ReadPreference): Read preference.
+     *
+     *  * session (MongoDB\Driver\Session): Client session.
+     *
+     *    Sessions are not supported for server versions < 3.6.
+     *
+     *  * skip (integer): The number of documents to skip before returning the
+     *    documents.
+     *
+     * @param string       $databaseName   Database name
+     * @param string       $collectionName Collection name
+     * @param array|object $filter         Query by which to filter documents
+     * @param array        $options        Command options
+     * @throws InvalidArgumentException for parameter/option parsing errors
+     */
+    public function __construct($databaseName, $collectionName, $filter, array $options = [])
+    {
+        if (! is_array($filter) && ! is_object($filter)) {
+            throw InvalidArgumentException::invalidType('$filter', $filter, 'array or object');
+        }
+
+        if (isset($options['limit']) && ! is_integer($options['limit'])) {
+            throw InvalidArgumentException::invalidType('"limit" option', $options['limit'], 'integer');
+        }
+
+        if (isset($options['skip']) && ! is_integer($options['skip'])) {
+            throw InvalidArgumentException::invalidType('"skip" option', $options['skip'], 'integer');
+        }
+
+        $this->databaseName = (string) $databaseName;
+        $this->collectionName = (string) $collectionName;
+        $this->filter = $filter;
+
+        $this->aggregateOptions = array_intersect_key($options, ['collation' => 1, 'hint' => 1, 'maxTimeMS' => 1, 'readConcern' => 1, 'readPreference' => 1, 'session' => 1]);
+        $this->countOptions = array_intersect_key($options, ['limit' => 1, 'skip' => 1]);
+
+        $this->aggregate = $this->createAggregate();
+    }
+
+    /**
+     * Execute the operation.
+     *
+     * @see Executable::execute()
+     * @param Server $server
+     * @return integer
+     * @throws UnexpectedValueException if the command response was malformed
+     * @throws UnsupportedException if collation or read concern is used and unsupported
+     * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
+     */
+    public function execute(Server $server)
+    {
+        $cursor = $this->aggregate->execute($server);
+        $allResults = $cursor->toArray();
+
+        /* If there are no documents to count, the aggregation pipeline has no items to group, and
+         * hence the result is an empty array (PHPLIB-376) */
+        if (count($allResults) == 0) {
+            return 0;
+        }
+
+        $result = current($allResults);
+        if (! isset($result->n) || ! (is_integer($result->n) || is_float($result->n))) {
+            throw new UnexpectedValueException('count command did not return a numeric "n" value');
+        }
+
+        return (integer) $result->n;
+    }
+
+    /**
+     * @return Aggregate
+     */
+    private function createAggregate()
+    {
+        $pipeline = [
+            ['$match' => (object) $this->filter],
+        ];
+
+        if (isset($this->countOptions['skip'])) {
+            $pipeline[] = ['$skip' => $this->countOptions['skip']];
+        }
+
+        if (isset($this->countOptions['limit'])) {
+            $pipeline[] = ['$limit' => $this->countOptions['limit']];
+        }
+
+        $pipeline[] = ['$group' => ['_id' => 1, 'n' => ['$sum' => 1]]];
+
+        return new Aggregate($this->databaseName, $this->collectionName, $pipeline, $this->aggregateOptions);
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/CreateCollection.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/CreateCollection.php
new file mode 100644
index 0000000000000000000000000000000000000000..98fac51d6035471c613dc6b17899c21b5266f6d0
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/CreateCollection.php	
@@ -0,0 +1,275 @@
+<?php
+/*
+ * Copyright 2015-2017 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace MongoDB\Operation;
+
+use MongoDB\Driver\Command;
+use MongoDB\Driver\Exception\RuntimeException as DriverRuntimeException;
+use MongoDB\Driver\Server;
+use MongoDB\Driver\Session;
+use MongoDB\Driver\WriteConcern;
+use MongoDB\Exception\InvalidArgumentException;
+use MongoDB\Exception\UnsupportedException;
+use function current;
+use function is_array;
+use function is_bool;
+use function is_integer;
+use function is_object;
+use function is_string;
+use function MongoDB\server_supports_feature;
+use function trigger_error;
+use const E_USER_DEPRECATED;
+
+/**
+ * Operation for the create command.
+ *
+ * @api
+ * @see \MongoDB\Database::createCollection()
+ * @see http://docs.mongodb.org/manual/reference/command/create/
+ */
+class CreateCollection implements Executable
+{
+    const USE_POWER_OF_2_SIZES = 1;
+    const NO_PADDING = 2;
+
+    /** @var integer */
+    private static $wireVersionForCollation = 5;
+
+    /** @var integer */
+    private static $wireVersionForWriteConcern = 5;
+
+    /** @var string */
+    private $databaseName;
+
+    /** @var string */
+    private $collectionName;
+
+    /** @var array */
+    private $options = [];
+
+    /**
+     * Constructs a create command.
+     *
+     * Supported options:
+     *
+     *  * autoIndexId (boolean): Specify false to disable the automatic creation
+     *    of an index on the _id field. For replica sets, this option cannot be
+     *    false. The default is true.
+     *
+     *    This option has been deprecated since MongoDB 3.2. As of MongoDB 4.0,
+     *    this option cannot be false when creating a replicated collection
+     *    (i.e. a collection outside of the local database in any mongod mode).
+     *
+     *  * capped (boolean): Specify true to create a capped collection. If set,
+     *    the size option must also be specified. The default is false.
+     *
+     *  * collation (document): Collation specification.
+     *
+     *    This is not supported for server versions < 3.4 and will result in an
+     *    exception at execution time if used.
+     *
+     *  * flags (integer): Options for the MMAPv1 storage engine only. Must be a
+     *    bitwise combination CreateCollection::USE_POWER_OF_2_SIZES and
+     *    CreateCollection::NO_PADDING. The default is
+     *    CreateCollection::USE_POWER_OF_2_SIZES.
+     *
+     *  * indexOptionDefaults (document): Default configuration for indexes when
+     *    creating the collection.
+     *
+     *  * max (integer): The maximum number of documents allowed in the capped
+     *    collection. The size option takes precedence over this limit.
+     *
+     *  * maxTimeMS (integer): The maximum amount of time to allow the query to
+     *    run.
+     *
+     *  * session (MongoDB\Driver\Session): Client session.
+     *
+     *    Sessions are not supported for server versions < 3.6.
+     *
+     *  * size (integer): The maximum number of bytes for a capped collection.
+     *
+     *  * storageEngine (document): Storage engine options.
+     *
+     *  * typeMap (array): Type map for BSON deserialization. This will only be
+     *    used for the returned command result document.
+     *
+     *  * validationAction (string): Validation action.
+     *
+     *  * validationLevel (string): Validation level.
+     *
+     *  * validator (document): Validation rules or expressions.
+     *
+     *  * writeConcern (MongoDB\Driver\WriteConcern): Write concern.
+     *
+     *    This is not supported for server versions < 3.4 and will result in an
+     *    exception at execution time if used.
+     *
+     * @see http://source.wiredtiger.com/2.4.1/struct_w_t___s_e_s_s_i_o_n.html#a358ca4141d59c345f401c58501276bbb
+     * @see https://docs.mongodb.org/manual/core/document-validation/
+     * @param string $databaseName   Database name
+     * @param string $collectionName Collection name
+     * @param array  $options        Command options
+     * @throws InvalidArgumentException for parameter/option parsing errors
+     */
+    public function __construct($databaseName, $collectionName, array $options = [])
+    {
+        if (isset($options['autoIndexId']) && ! is_bool($options['autoIndexId'])) {
+            throw InvalidArgumentException::invalidType('"autoIndexId" option', $options['autoIndexId'], 'boolean');
+        }
+
+        if (isset($options['capped']) && ! is_bool($options['capped'])) {
+            throw InvalidArgumentException::invalidType('"capped" option', $options['capped'], 'boolean');
+        }
+
+        if (isset($options['collation']) && ! is_array($options['collation']) && ! is_object($options['collation'])) {
+            throw InvalidArgumentException::invalidType('"collation" option', $options['collation'], 'array or object');
+        }
+
+        if (isset($options['flags']) && ! is_integer($options['flags'])) {
+            throw InvalidArgumentException::invalidType('"flags" option', $options['flags'], 'integer');
+        }
+
+        if (isset($options['indexOptionDefaults']) && ! is_array($options['indexOptionDefaults']) && ! is_object($options['indexOptionDefaults'])) {
+            throw InvalidArgumentException::invalidType('"indexOptionDefaults" option', $options['indexOptionDefaults'], 'array or object');
+        }
+
+        if (isset($options['max']) && ! is_integer($options['max'])) {
+            throw InvalidArgumentException::invalidType('"max" option', $options['max'], 'integer');
+        }
+
+        if (isset($options['maxTimeMS']) && ! is_integer($options['maxTimeMS'])) {
+            throw InvalidArgumentException::invalidType('"maxTimeMS" option', $options['maxTimeMS'], 'integer');
+        }
+
+        if (isset($options['session']) && ! $options['session'] instanceof Session) {
+            throw InvalidArgumentException::invalidType('"session" option', $options['session'], Session::class);
+        }
+
+        if (isset($options['size']) && ! is_integer($options['size'])) {
+            throw InvalidArgumentException::invalidType('"size" option', $options['size'], 'integer');
+        }
+
+        if (isset($options['storageEngine']) && ! is_array($options['storageEngine']) && ! is_object($options['storageEngine'])) {
+            throw InvalidArgumentException::invalidType('"storageEngine" option', $options['storageEngine'], 'array or object');
+        }
+
+        if (isset($options['typeMap']) && ! is_array($options['typeMap'])) {
+            throw InvalidArgumentException::invalidType('"typeMap" option', $options['typeMap'], 'array');
+        }
+
+        if (isset($options['validationAction']) && ! is_string($options['validationAction'])) {
+            throw InvalidArgumentException::invalidType('"validationAction" option', $options['validationAction'], 'string');
+        }
+
+        if (isset($options['validationLevel']) && ! is_string($options['validationLevel'])) {
+            throw InvalidArgumentException::invalidType('"validationLevel" option', $options['validationLevel'], 'string');
+        }
+
+        if (isset($options['validator']) && ! is_array($options['validator']) && ! is_object($options['validator'])) {
+            throw InvalidArgumentException::invalidType('"validator" option', $options['validator'], 'array or object');
+        }
+
+        if (isset($options['writeConcern']) && ! $options['writeConcern'] instanceof WriteConcern) {
+            throw InvalidArgumentException::invalidType('"writeConcern" option', $options['writeConcern'], WriteConcern::class);
+        }
+
+        if (isset($options['writeConcern']) && $options['writeConcern']->isDefault()) {
+            unset($options['writeConcern']);
+        }
+
+        if (isset($options['autoIndexId'])) {
+            trigger_error('The "autoIndexId" option is deprecated and will be removed in a future release', E_USER_DEPRECATED);
+        }
+
+        $this->databaseName = (string) $databaseName;
+        $this->collectionName = (string) $collectionName;
+        $this->options = $options;
+    }
+
+    /**
+     * Execute the operation.
+     *
+     * @see Executable::execute()
+     * @param Server $server
+     * @return array|object Command result document
+     * @throws UnsupportedException if collation or write concern is used and unsupported
+     * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
+     */
+    public function execute(Server $server)
+    {
+        if (isset($this->options['collation']) && ! server_supports_feature($server, self::$wireVersionForCollation)) {
+            throw UnsupportedException::collationNotSupported();
+        }
+
+        if (isset($this->options['writeConcern']) && ! server_supports_feature($server, self::$wireVersionForWriteConcern)) {
+            throw UnsupportedException::writeConcernNotSupported();
+        }
+
+        $cursor = $server->executeWriteCommand($this->databaseName, $this->createCommand(), $this->createOptions());
+
+        if (isset($this->options['typeMap'])) {
+            $cursor->setTypeMap($this->options['typeMap']);
+        }
+
+        return current($cursor->toArray());
+    }
+
+    /**
+     * Create the create command.
+     *
+     * @return Command
+     */
+    private function createCommand()
+    {
+        $cmd = ['create' => $this->collectionName];
+
+        foreach (['autoIndexId', 'capped', 'flags', 'max', 'maxTimeMS', 'size', 'validationAction', 'validationLevel'] as $option) {
+            if (isset($this->options[$option])) {
+                $cmd[$option] = $this->options[$option];
+            }
+        }
+
+        foreach (['collation', 'indexOptionDefaults', 'storageEngine', 'validator'] as $option) {
+            if (isset($this->options[$option])) {
+                $cmd[$option] = (object) $this->options[$option];
+            }
+        }
+
+        return new Command($cmd);
+    }
+
+    /**
+     * Create options for executing the command.
+     *
+     * @see http://php.net/manual/en/mongodb-driver-server.executewritecommand.php
+     * @return array
+     */
+    private function createOptions()
+    {
+        $options = [];
+
+        if (isset($this->options['session'])) {
+            $options['session'] = $this->options['session'];
+        }
+
+        if (isset($this->options['writeConcern'])) {
+            $options['writeConcern'] = $this->options['writeConcern'];
+        }
+
+        return $options;
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/CreateIndexes.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/CreateIndexes.php
new file mode 100644
index 0000000000000000000000000000000000000000..ba53d95b7d1ec6cd115d294357fc4c9f9bc7f599
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/CreateIndexes.php	
@@ -0,0 +1,229 @@
+<?php
+/*
+ * Copyright 2015-2017 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace MongoDB\Operation;
+
+use MongoDB\Driver\Command;
+use MongoDB\Driver\Exception\RuntimeException as DriverRuntimeException;
+use MongoDB\Driver\Server;
+use MongoDB\Driver\Session;
+use MongoDB\Driver\WriteConcern;
+use MongoDB\Exception\InvalidArgumentException;
+use MongoDB\Exception\UnsupportedException;
+use MongoDB\Model\IndexInput;
+use function array_map;
+use function is_array;
+use function is_integer;
+use function is_string;
+use function MongoDB\server_supports_feature;
+use function sprintf;
+
+/**
+ * Operation for the createIndexes command.
+ *
+ * @api
+ * @see \MongoDB\Collection::createIndex()
+ * @see \MongoDB\Collection::createIndexes()
+ * @see http://docs.mongodb.org/manual/reference/command/createIndexes/
+ */
+class CreateIndexes implements Executable
+{
+    /** @var integer */
+    private static $wireVersionForCollation = 5;
+
+    /** @var integer */
+    private static $wireVersionForWriteConcern = 5;
+
+    /** @var integer */
+    private static $wireVersionForCommitQuorum = 9;
+
+    /** @var string */
+    private $databaseName;
+
+    /** @var string */
+    private $collectionName;
+
+    /** @var array */
+    private $indexes = [];
+
+    /** @var boolean */
+    private $isCollationUsed = false;
+
+    /** @var array */
+    private $options = [];
+
+    /**
+     * Constructs a createIndexes command.
+     *
+     * Supported options:
+     *
+     *  * commitQuorum (integer|string): Specifies how many data-bearing members
+     *    of a replica set, including the primary, must complete the index
+     *    builds successfully before the primary marks the indexes as ready.
+     *
+     *  * maxTimeMS (integer): The maximum amount of time to allow the query to
+     *    run.
+     *
+     *  * session (MongoDB\Driver\Session): Client session.
+     *
+     *    Sessions are not supported for server versions < 3.6.
+     *
+     *  * writeConcern (MongoDB\Driver\WriteConcern): Write concern.
+     *
+     *    This is not supported for server versions < 3.4 and will result in an
+     *    exception at execution time if used.
+     *
+     * @param string  $databaseName   Database name
+     * @param string  $collectionName Collection name
+     * @param array[] $indexes        List of index specifications
+     * @param array   $options        Command options
+     * @throws InvalidArgumentException for parameter/option parsing errors
+     */
+    public function __construct($databaseName, $collectionName, array $indexes, array $options = [])
+    {
+        if (empty($indexes)) {
+            throw new InvalidArgumentException('$indexes is empty');
+        }
+
+        $expectedIndex = 0;
+
+        foreach ($indexes as $i => $index) {
+            if ($i !== $expectedIndex) {
+                throw new InvalidArgumentException(sprintf('$indexes is not a list (unexpected index: "%s")', $i));
+            }
+
+            if (! is_array($index)) {
+                throw InvalidArgumentException::invalidType(sprintf('$index[%d]', $i), $index, 'array');
+            }
+
+            if (isset($index['collation'])) {
+                $this->isCollationUsed = true;
+            }
+
+            $this->indexes[] = new IndexInput($index);
+
+            $expectedIndex += 1;
+        }
+
+        if (isset($options['commitQuorum']) && ! is_string($options['commitQuorum']) && ! is_integer($options['commitQuorum'])) {
+            throw InvalidArgumentException::invalidType('"commitQuorum" option', $options['commitQuorum'], ['integer', 'string']);
+        }
+
+        if (isset($options['maxTimeMS']) && ! is_integer($options['maxTimeMS'])) {
+            throw InvalidArgumentException::invalidType('"maxTimeMS" option', $options['maxTimeMS'], 'integer');
+        }
+
+        if (isset($options['session']) && ! $options['session'] instanceof Session) {
+            throw InvalidArgumentException::invalidType('"session" option', $options['session'], Session::class);
+        }
+
+        if (isset($options['writeConcern']) && ! $options['writeConcern'] instanceof WriteConcern) {
+            throw InvalidArgumentException::invalidType('"writeConcern" option', $options['writeConcern'], WriteConcern::class);
+        }
+
+        if (isset($options['writeConcern']) && $options['writeConcern']->isDefault()) {
+            unset($options['writeConcern']);
+        }
+
+        $this->databaseName = (string) $databaseName;
+        $this->collectionName = (string) $collectionName;
+        $this->options = $options;
+    }
+
+    /**
+     * Execute the operation.
+     *
+     * @see Executable::execute()
+     * @param Server $server
+     * @return string[] The names of the created indexes
+     * @throws UnsupportedException if collation or write concern is used and unsupported
+     * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
+     */
+    public function execute(Server $server)
+    {
+        if ($this->isCollationUsed && ! server_supports_feature($server, self::$wireVersionForCollation)) {
+            throw UnsupportedException::collationNotSupported();
+        }
+
+        if (isset($this->options['writeConcern']) && ! server_supports_feature($server, self::$wireVersionForWriteConcern)) {
+            throw UnsupportedException::writeConcernNotSupported();
+        }
+
+        $inTransaction = isset($this->options['session']) && $this->options['session']->isInTransaction();
+        if ($inTransaction && isset($this->options['writeConcern'])) {
+            throw UnsupportedException::writeConcernNotSupportedInTransaction();
+        }
+
+        $this->executeCommand($server);
+
+        return array_map(function (IndexInput $index) {
+            return (string) $index;
+        }, $this->indexes);
+    }
+
+    /**
+     * Create options for executing the command.
+     *
+     * @see http://php.net/manual/en/mongodb-driver-server.executewritecommand.php
+     * @return array
+     */
+    private function createOptions()
+    {
+        $options = [];
+
+        if (isset($this->options['session'])) {
+            $options['session'] = $this->options['session'];
+        }
+
+        if (isset($this->options['writeConcern'])) {
+            $options['writeConcern'] = $this->options['writeConcern'];
+        }
+
+        return $options;
+    }
+
+    /**
+     * Create one or more indexes for the collection using the createIndexes
+     * command.
+     *
+     * @param Server $server
+     * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
+     */
+    private function executeCommand(Server $server)
+    {
+        $cmd = [
+            'createIndexes' => $this->collectionName,
+            'indexes' => $this->indexes,
+        ];
+
+        if (isset($this->options['commitQuorum'])) {
+            /* Drivers MUST manually raise an error if this option is specified
+             * when creating an index on a pre 4.4 server. */
+            if (! server_supports_feature($server, self::$wireVersionForCommitQuorum)) {
+                throw UnsupportedException::commitQuorumNotSupported();
+            }
+
+            $cmd['commitQuorum'] = $this->options['commitQuorum'];
+        }
+
+        if (isset($this->options['maxTimeMS'])) {
+            $cmd['maxTimeMS'] = $this->options['maxTimeMS'];
+        }
+
+        $server->executeWriteCommand($this->databaseName, new Command($cmd), $this->createOptions());
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/DatabaseCommand.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/DatabaseCommand.php
new file mode 100644
index 0000000000000000000000000000000000000000..af0f7624898955894abbe2cfd62552bdcc059879
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/DatabaseCommand.php	
@@ -0,0 +1,130 @@
+<?php
+/*
+ * Copyright 2015-2017 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace MongoDB\Operation;
+
+use MongoDB\Driver\Command;
+use MongoDB\Driver\Cursor;
+use MongoDB\Driver\ReadPreference;
+use MongoDB\Driver\Server;
+use MongoDB\Driver\Session;
+use MongoDB\Exception\InvalidArgumentException;
+use function is_array;
+use function is_object;
+
+/**
+ * Operation for executing a database command.
+ *
+ * @api
+ * @see \MongoDB\Database::command()
+ */
+class DatabaseCommand implements Executable
+{
+    /** @var string */
+    private $databaseName;
+
+    /** @var array|Command|object */
+    private $command;
+
+    /** @var array */
+    private $options;
+
+    /**
+     * Constructs a command.
+     *
+     * Supported options:
+     *
+     *  * readPreference (MongoDB\Driver\ReadPreference): The read preference to
+     *    use when executing the command. This may be used when issuing the
+     *    command to a replica set or mongos node to ensure that the driver sets
+     *    the wire protocol accordingly or adds the read preference to the
+     *    command document, respectively.
+     *
+     *  * session (MongoDB\Driver\Session): Client session.
+     *
+     *    Sessions are not supported for server versions < 3.6.
+     *
+     *  * typeMap (array): Type map for BSON deserialization. This will be
+     *    applied to the returned Cursor (it is not sent to the server).
+     *
+     * @param string       $databaseName Database name
+     * @param array|object $command      Command document
+     * @param array        $options      Options for command execution
+     * @throws InvalidArgumentException for parameter/option parsing errors
+     */
+    public function __construct($databaseName, $command, array $options = [])
+    {
+        if (! is_array($command) && ! is_object($command)) {
+            throw InvalidArgumentException::invalidType('$command', $command, 'array or object');
+        }
+
+        if (isset($options['readPreference']) && ! $options['readPreference'] instanceof ReadPreference) {
+            throw InvalidArgumentException::invalidType('"readPreference" option', $options['readPreference'], ReadPreference::class);
+        }
+
+        if (isset($options['session']) && ! $options['session'] instanceof Session) {
+            throw InvalidArgumentException::invalidType('"session" option', $options['session'], Session::class);
+        }
+
+        if (isset($options['typeMap']) && ! is_array($options['typeMap'])) {
+            throw InvalidArgumentException::invalidType('"typeMap" option', $options['typeMap'], 'array');
+        }
+
+        $this->databaseName = (string) $databaseName;
+        $this->command = $command instanceof Command ? $command : new Command($command);
+        $this->options = $options;
+    }
+
+    /**
+     * Execute the operation.
+     *
+     * @see Executable::execute()
+     * @param Server $server
+     * @return Cursor
+     */
+    public function execute(Server $server)
+    {
+        $cursor = $server->executeCommand($this->databaseName, $this->command, $this->createOptions());
+
+        if (isset($this->options['typeMap'])) {
+            $cursor->setTypeMap($this->options['typeMap']);
+        }
+
+        return $cursor;
+    }
+
+    /**
+     * Create options for executing the command.
+     *
+     * @see http://php.net/manual/en/mongodb-driver-server.executecommand.php
+     * @return array
+     */
+    private function createOptions()
+    {
+        $options = [];
+
+        if (isset($this->options['readPreference'])) {
+            $options['readPreference'] = $this->options['readPreference'];
+        }
+
+        if (isset($this->options['session'])) {
+            $options['session'] = $this->options['session'];
+        }
+
+        return $options;
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/Delete.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/Delete.php
new file mode 100644
index 0000000000000000000000000000000000000000..65cc6f6e933ba3ce40ab79b3d0b5e455e1b0abef
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/Delete.php	
@@ -0,0 +1,222 @@
+<?php
+/*
+ * Copyright 2015-2017 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace MongoDB\Operation;
+
+use MongoDB\DeleteResult;
+use MongoDB\Driver\BulkWrite as Bulk;
+use MongoDB\Driver\Exception\RuntimeException as DriverRuntimeException;
+use MongoDB\Driver\Server;
+use MongoDB\Driver\Session;
+use MongoDB\Driver\WriteConcern;
+use MongoDB\Exception\InvalidArgumentException;
+use MongoDB\Exception\UnsupportedException;
+use function is_array;
+use function is_object;
+use function is_string;
+use function MongoDB\server_supports_feature;
+
+/**
+ * Operation for the delete command.
+ *
+ * This class is used internally by the DeleteMany and DeleteOne operation
+ * classes.
+ *
+ * @internal
+ * @see http://docs.mongodb.org/manual/reference/command/delete/
+ */
+class Delete implements Executable, Explainable
+{
+    /** @var integer */
+    private static $wireVersionForCollation = 5;
+
+    /** @var int */
+    private static $wireVersionForHintServerSideError = 5;
+
+    /** @var string */
+    private $databaseName;
+
+    /** @var string */
+    private $collectionName;
+
+    /** @var array|object */
+    private $filter;
+
+    /** @var integer */
+    private $limit;
+
+    /** @var array */
+    private $options;
+
+    /**
+     * Constructs a delete command.
+     *
+     * Supported options:
+     *
+     *  * collation (document): Collation specification.
+     *
+     *    This is not supported for server versions < 3.4 and will result in an
+     *    exception at execution time if used.
+     *
+     *  * hint (string|document): The index to use. Specify either the index
+     *    name as a string or the index key pattern as a document. If specified,
+     *    then the query system will only consider plans using the hinted index.
+     *
+     *    This is not supported for server versions < 4.4 and will result in an
+     *    exception at execution time if used.
+     *
+     *  * session (MongoDB\Driver\Session): Client session.
+     *
+     *    Sessions are not supported for server versions < 3.6.
+     *
+     *  * writeConcern (MongoDB\Driver\WriteConcern): Write concern.
+     *
+     * @param string       $databaseName   Database name
+     * @param string       $collectionName Collection name
+     * @param array|object $filter         Query by which to delete documents
+     * @param integer      $limit          The number of matching documents to
+     *                                     delete. Must be 0 or 1, for all or a
+     *                                     single document, respectively.
+     * @param array        $options        Command options
+     * @throws InvalidArgumentException for parameter/option parsing errors
+     */
+    public function __construct($databaseName, $collectionName, $filter, $limit, array $options = [])
+    {
+        if (! is_array($filter) && ! is_object($filter)) {
+            throw InvalidArgumentException::invalidType('$filter', $filter, 'array or object');
+        }
+
+        if ($limit !== 0 && $limit !== 1) {
+            throw new InvalidArgumentException('$limit must be 0 or 1');
+        }
+
+        if (isset($options['collation']) && ! is_array($options['collation']) && ! is_object($options['collation'])) {
+            throw InvalidArgumentException::invalidType('"collation" option', $options['collation'], 'array or object');
+        }
+
+        if (isset($options['hint']) && ! is_string($options['hint']) && ! is_array($options['hint']) && ! is_object($options['hint'])) {
+            throw InvalidArgumentException::invalidType('"hint" option', $options['hint'], ['string', 'array', 'object']);
+        }
+
+        if (isset($options['session']) && ! $options['session'] instanceof Session) {
+            throw InvalidArgumentException::invalidType('"session" option', $options['session'], Session::class);
+        }
+
+        if (isset($options['writeConcern']) && ! $options['writeConcern'] instanceof WriteConcern) {
+            throw InvalidArgumentException::invalidType('"writeConcern" option', $options['writeConcern'], WriteConcern::class);
+        }
+
+        if (isset($options['writeConcern']) && $options['writeConcern']->isDefault()) {
+            unset($options['writeConcern']);
+        }
+
+        $this->databaseName = (string) $databaseName;
+        $this->collectionName = (string) $collectionName;
+        $this->filter = $filter;
+        $this->limit = $limit;
+        $this->options = $options;
+    }
+
+    /**
+     * Execute the operation.
+     *
+     * @see Executable::execute()
+     * @param Server $server
+     * @return DeleteResult
+     * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
+     */
+    public function execute(Server $server)
+    {
+        if (isset($this->options['collation']) && ! server_supports_feature($server, self::$wireVersionForCollation)) {
+            throw UnsupportedException::collationNotSupported();
+        }
+
+        /* Server versions >= 3.4.0 raise errors for unknown update
+         * options. For previous versions, the CRUD spec requires a client-side
+         * error. */
+        if (isset($this->options['hint']) && ! server_supports_feature($server, self::$wireVersionForHintServerSideError)) {
+            throw UnsupportedException::hintNotSupported();
+        }
+
+        $inTransaction = isset($this->options['session']) && $this->options['session']->isInTransaction();
+        if ($inTransaction && isset($this->options['writeConcern'])) {
+            throw UnsupportedException::writeConcernNotSupportedInTransaction();
+        }
+
+        $bulk = new Bulk();
+        $bulk->delete($this->filter, $this->createDeleteOptions());
+
+        $writeResult = $server->executeBulkWrite($this->databaseName . '.' . $this->collectionName, $bulk, $this->createExecuteOptions());
+
+        return new DeleteResult($writeResult);
+    }
+
+    public function getCommandDocument(Server $server)
+    {
+        $cmd = ['delete' => $this->collectionName, 'deletes' => [['q' => $this->filter] + $this->createDeleteOptions()]];
+
+        if (isset($this->options['writeConcern'])) {
+            $cmd['writeConcern'] = $this->options['writeConcern'];
+        }
+
+        return $cmd;
+    }
+
+    /**
+     * Create options for the delete command.
+     *
+     * Note that these options are different from the bulk write options, which
+     * are created in createExecuteOptions().
+     *
+     * @return array
+     */
+    private function createDeleteOptions()
+    {
+        $deleteOptions = ['limit' => $this->limit];
+
+        if (isset($this->options['collation'])) {
+            $deleteOptions['collation'] = (object) $this->options['collation'];
+        }
+
+        if (isset($this->options['hint'])) {
+            $deleteOptions['hint'] = $this->options['hint'];
+        }
+
+        return $deleteOptions;
+    }
+
+    /**
+     * Create options for executing the bulk write.
+     *
+     * @see http://php.net/manual/en/mongodb-driver-server.executebulkwrite.php
+     * @return array
+     */
+    private function createExecuteOptions()
+    {
+        $options = [];
+
+        if (isset($this->options['session'])) {
+            $options['session'] = $this->options['session'];
+        }
+
+        if (isset($this->options['writeConcern'])) {
+            $options['writeConcern'] = $this->options['writeConcern'];
+        }
+
+        return $options;
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/DeleteMany.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/DeleteMany.php
new file mode 100644
index 0000000000000000000000000000000000000000..ffda516ca8ee168c4728954b0a02d28d25990e2f
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/DeleteMany.php	
@@ -0,0 +1,90 @@
+<?php
+/*
+ * Copyright 2015-2017 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace MongoDB\Operation;
+
+use MongoDB\DeleteResult;
+use MongoDB\Driver\Exception\RuntimeException as DriverRuntimeException;
+use MongoDB\Driver\Server;
+use MongoDB\Exception\InvalidArgumentException;
+use MongoDB\Exception\UnsupportedException;
+
+/**
+ * Operation for deleting multiple document with the delete command.
+ *
+ * @api
+ * @see \MongoDB\Collection::deleteOne()
+ * @see http://docs.mongodb.org/manual/reference/command/delete/
+ */
+class DeleteMany implements Executable, Explainable
+{
+    /** @var Delete */
+    private $delete;
+
+    /**
+     * Constructs a delete command.
+     *
+     * Supported options:
+     *
+     *  * collation (document): Collation specification.
+     *
+     *    This is not supported for server versions < 3.4 and will result in an
+     *    exception at execution time if used.
+     *
+     *  * hint (string|document): The index to use. Specify either the index
+     *    name as a string or the index key pattern as a document. If specified,
+     *    then the query system will only consider plans using the hinted index.
+     *
+     *    This is not supported for server versions < 4.4 and will result in an
+     *    exception at execution time if used.
+     *
+     *  * session (MongoDB\Driver\Session): Client session.
+     *
+     *    Sessions are not supported for server versions < 3.6.
+     *
+     *  * writeConcern (MongoDB\Driver\WriteConcern): Write concern.
+     *
+     * @param string       $databaseName   Database name
+     * @param string       $collectionName Collection name
+     * @param array|object $filter         Query by which to delete documents
+     * @param array        $options        Command options
+     * @throws InvalidArgumentException for parameter/option parsing errors
+     */
+    public function __construct($databaseName, $collectionName, $filter, array $options = [])
+    {
+        $this->delete = new Delete($databaseName, $collectionName, $filter, 0, $options);
+    }
+
+    /**
+     * Execute the operation.
+     *
+     * @see Executable::execute()
+     * @param Server $server
+     * @return DeleteResult
+     * @throws UnsupportedException if collation is used and unsupported
+     * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
+     */
+    public function execute(Server $server)
+    {
+        return $this->delete->execute($server);
+    }
+
+    public function getCommandDocument(Server $server)
+    {
+        return $this->delete->getCommandDocument($server);
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/DeleteOne.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/DeleteOne.php
new file mode 100644
index 0000000000000000000000000000000000000000..742a58f73f9c21af23ab7f82109cdce5a3f76c80
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/DeleteOne.php	
@@ -0,0 +1,90 @@
+<?php
+/*
+ * Copyright 2015-2017 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace MongoDB\Operation;
+
+use MongoDB\DeleteResult;
+use MongoDB\Driver\Exception\RuntimeException as DriverRuntimeException;
+use MongoDB\Driver\Server;
+use MongoDB\Exception\InvalidArgumentException;
+use MongoDB\Exception\UnsupportedException;
+
+/**
+ * Operation for deleting a single document with the delete command.
+ *
+ * @api
+ * @see \MongoDB\Collection::deleteOne()
+ * @see http://docs.mongodb.org/manual/reference/command/delete/
+ */
+class DeleteOne implements Executable, Explainable
+{
+    /** @var Delete */
+    private $delete;
+
+    /**
+     * Constructs a delete command.
+     *
+     * Supported options:
+     *
+     *  * collation (document): Collation specification.
+     *
+     *    This is not supported for server versions < 3.4 and will result in an
+     *    exception at execution time if used.
+     *
+     *  * hint (string|document): The index to use. Specify either the index
+     *    name as a string or the index key pattern as a document. If specified,
+     *    then the query system will only consider plans using the hinted index.
+     *
+     *    This is not supported for server versions < 4.4 and will result in an
+     *    exception at execution time if used.
+     *
+     *  * session (MongoDB\Driver\Session): Client session.
+     *
+     *    Sessions are not supported for server versions < 3.6.
+     *
+     *  * writeConcern (MongoDB\Driver\WriteConcern): Write concern.
+     *
+     * @param string       $databaseName   Database name
+     * @param string       $collectionName Collection name
+     * @param array|object $filter         Query by which to delete documents
+     * @param array        $options        Command options
+     * @throws InvalidArgumentException for parameter/option parsing errors
+     */
+    public function __construct($databaseName, $collectionName, $filter, array $options = [])
+    {
+        $this->delete = new Delete($databaseName, $collectionName, $filter, 1, $options);
+    }
+
+    /**
+     * Execute the operation.
+     *
+     * @see Executable::execute()
+     * @param Server $server
+     * @return DeleteResult
+     * @throws UnsupportedException if collation is used and unsupported
+     * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
+     */
+    public function execute(Server $server)
+    {
+        return $this->delete->execute($server);
+    }
+
+    public function getCommandDocument(Server $server)
+    {
+        return $this->delete->getCommandDocument($server);
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/Distinct.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/Distinct.php
new file mode 100644
index 0000000000000000000000000000000000000000..f8e169ca71cf906a6329713032027b72e293e7aa
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/Distinct.php	
@@ -0,0 +1,236 @@
+<?php
+/*
+ * Copyright 2015-2017 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace MongoDB\Operation;
+
+use MongoDB\Driver\Command;
+use MongoDB\Driver\Exception\RuntimeException as DriverRuntimeException;
+use MongoDB\Driver\ReadConcern;
+use MongoDB\Driver\ReadPreference;
+use MongoDB\Driver\Server;
+use MongoDB\Driver\Session;
+use MongoDB\Exception\InvalidArgumentException;
+use MongoDB\Exception\UnexpectedValueException;
+use MongoDB\Exception\UnsupportedException;
+use function current;
+use function is_array;
+use function is_integer;
+use function is_object;
+use function MongoDB\create_field_path_type_map;
+use function MongoDB\server_supports_feature;
+
+/**
+ * Operation for the distinct command.
+ *
+ * @api
+ * @see \MongoDB\Collection::distinct()
+ * @see http://docs.mongodb.org/manual/reference/command/distinct/
+ */
+class Distinct implements Executable, Explainable
+{
+    /** @var integer */
+    private static $wireVersionForCollation = 5;
+
+    /** @var integer */
+    private static $wireVersionForReadConcern = 4;
+
+    /** @var string */
+    private $databaseName;
+
+    /** @var string */
+    private $collectionName;
+
+    /** @var string */
+    private $fieldName;
+
+    /** @var array|object */
+    private $filter;
+
+    /** @var array */
+    private $options;
+
+    /**
+     * Constructs a distinct command.
+     *
+     * Supported options:
+     *
+     *  * collation (document): Collation specification.
+     *
+     *    This is not supported for server versions < 3.4 and will result in an
+     *    exception at execution time if used.
+     *
+     *  * maxTimeMS (integer): The maximum amount of time to allow the query to
+     *    run.
+     *
+     *  * readConcern (MongoDB\Driver\ReadConcern): Read concern.
+     *
+     *    This is not supported for server versions < 3.2 and will result in an
+     *    exception at execution time if used.
+     *
+     *  * readPreference (MongoDB\Driver\ReadPreference): Read preference.
+     *
+     *  * session (MongoDB\Driver\Session): Client session.
+     *
+     *    Sessions are not supported for server versions < 3.6.
+     *
+     *  * typeMap (array): Type map for BSON deserialization.
+     *
+     * @param string       $databaseName   Database name
+     * @param string       $collectionName Collection name
+     * @param string       $fieldName      Field for which to return distinct values
+     * @param array|object $filter         Query by which to filter documents
+     * @param array        $options        Command options
+     * @throws InvalidArgumentException for parameter/option parsing errors
+     */
+    public function __construct($databaseName, $collectionName, $fieldName, $filter = [], array $options = [])
+    {
+        if (! is_array($filter) && ! is_object($filter)) {
+            throw InvalidArgumentException::invalidType('$filter', $filter, 'array or object');
+        }
+
+        if (isset($options['collation']) && ! is_array($options['collation']) && ! is_object($options['collation'])) {
+            throw InvalidArgumentException::invalidType('"collation" option', $options['collation'], 'array or object');
+        }
+
+        if (isset($options['maxTimeMS']) && ! is_integer($options['maxTimeMS'])) {
+            throw InvalidArgumentException::invalidType('"maxTimeMS" option', $options['maxTimeMS'], 'integer');
+        }
+
+        if (isset($options['readConcern']) && ! $options['readConcern'] instanceof ReadConcern) {
+            throw InvalidArgumentException::invalidType('"readConcern" option', $options['readConcern'], ReadConcern::class);
+        }
+
+        if (isset($options['readPreference']) && ! $options['readPreference'] instanceof ReadPreference) {
+            throw InvalidArgumentException::invalidType('"readPreference" option', $options['readPreference'], ReadPreference::class);
+        }
+
+        if (isset($options['session']) && ! $options['session'] instanceof Session) {
+            throw InvalidArgumentException::invalidType('"session" option', $options['session'], Session::class);
+        }
+
+        if (isset($options['typeMap']) && ! is_array($options['typeMap'])) {
+            throw InvalidArgumentException::invalidType('"typeMap" option', $options['typeMap'], 'array');
+        }
+
+        if (isset($options['readConcern']) && $options['readConcern']->isDefault()) {
+            unset($options['readConcern']);
+        }
+
+        $this->databaseName = (string) $databaseName;
+        $this->collectionName = (string) $collectionName;
+        $this->fieldName = (string) $fieldName;
+        $this->filter = $filter;
+        $this->options = $options;
+    }
+
+    /**
+     * Execute the operation.
+     *
+     * @see Executable::execute()
+     * @param Server $server
+     * @return mixed[]
+     * @throws UnexpectedValueException if the command response was malformed
+     * @throws UnsupportedException if collation or read concern is used and unsupported
+     * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
+     */
+    public function execute(Server $server)
+    {
+        if (isset($this->options['collation']) && ! server_supports_feature($server, self::$wireVersionForCollation)) {
+            throw UnsupportedException::collationNotSupported();
+        }
+
+        if (isset($this->options['readConcern']) && ! server_supports_feature($server, self::$wireVersionForReadConcern)) {
+            throw UnsupportedException::readConcernNotSupported();
+        }
+
+        $inTransaction = isset($this->options['session']) && $this->options['session']->isInTransaction();
+        if ($inTransaction && isset($this->options['readConcern'])) {
+            throw UnsupportedException::readConcernNotSupportedInTransaction();
+        }
+
+        $cursor = $server->executeReadCommand($this->databaseName, new Command($this->createCommandDocument()), $this->createOptions());
+
+        if (isset($this->options['typeMap'])) {
+            $cursor->setTypeMap(create_field_path_type_map($this->options['typeMap'], 'values.$'));
+        }
+
+        $result = current($cursor->toArray());
+
+        if (! isset($result->values) || ! is_array($result->values)) {
+            throw new UnexpectedValueException('distinct command did not return a "values" array');
+        }
+
+        return $result->values;
+    }
+
+    public function getCommandDocument(Server $server)
+    {
+        return $this->createCommandDocument();
+    }
+
+    /**
+     * Create the distinct command document.
+     *
+     * @return array
+     */
+    private function createCommandDocument()
+    {
+        $cmd = [
+            'distinct' => $this->collectionName,
+            'key' => $this->fieldName,
+        ];
+
+        if (! empty($this->filter)) {
+            $cmd['query'] = (object) $this->filter;
+        }
+
+        if (isset($this->options['collation'])) {
+            $cmd['collation'] = (object) $this->options['collation'];
+        }
+
+        if (isset($this->options['maxTimeMS'])) {
+            $cmd['maxTimeMS'] = $this->options['maxTimeMS'];
+        }
+
+        return $cmd;
+    }
+
+    /**
+     * Create options for executing the command.
+     *
+     * @see http://php.net/manual/en/mongodb-driver-server.executereadcommand.php
+     * @return array
+     */
+    private function createOptions()
+    {
+        $options = [];
+
+        if (isset($this->options['readConcern'])) {
+            $options['readConcern'] = $this->options['readConcern'];
+        }
+
+        if (isset($this->options['readPreference'])) {
+            $options['readPreference'] = $this->options['readPreference'];
+        }
+
+        if (isset($this->options['session'])) {
+            $options['session'] = $this->options['session'];
+        }
+
+        return $options;
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/DropCollection.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/DropCollection.php
new file mode 100644
index 0000000000000000000000000000000000000000..10f16e1edafb2dbd4962bad23a1db3270312c88b
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/DropCollection.php	
@@ -0,0 +1,167 @@
+<?php
+/*
+ * Copyright 2015-2017 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace MongoDB\Operation;
+
+use MongoDB\Driver\Command;
+use MongoDB\Driver\Exception\CommandException;
+use MongoDB\Driver\Server;
+use MongoDB\Driver\Session;
+use MongoDB\Driver\WriteConcern;
+use MongoDB\Exception\InvalidArgumentException;
+use MongoDB\Exception\UnsupportedException;
+use function current;
+use function is_array;
+use function MongoDB\server_supports_feature;
+
+/**
+ * Operation for the drop command.
+ *
+ * @api
+ * @see \MongoDB\Collection::drop()
+ * @see \MongoDB\Database::dropCollection()
+ * @see http://docs.mongodb.org/manual/reference/command/drop/
+ */
+class DropCollection implements Executable
+{
+    /** @var integer */
+    private static $errorCodeNamespaceNotFound = 26;
+
+    /** @var string */
+    private static $errorMessageNamespaceNotFound = 'ns not found';
+
+    /** @var integer */
+    private static $wireVersionForWriteConcern = 5;
+
+    /** @var string */
+    private $databaseName;
+
+    /** @var string */
+    private $collectionName;
+
+    /** @var array */
+    private $options;
+
+    /**
+     * Constructs a drop command.
+     *
+     * Supported options:
+     *
+     *  * session (MongoDB\Driver\Session): Client session.
+     *
+     *    Sessions are not supported for server versions < 3.6.
+     *
+     *  * typeMap (array): Type map for BSON deserialization. This will be used
+     *    for the returned command result document.
+     *
+     *  * writeConcern (MongoDB\Driver\WriteConcern): Write concern.
+     *
+     *    This is not supported for server versions < 3.4 and will result in an
+     *    exception at execution time if used.
+     *
+     * @param string $databaseName   Database name
+     * @param string $collectionName Collection name
+     * @param array  $options        Command options
+     * @throws InvalidArgumentException for parameter/option parsing errors
+     */
+    public function __construct($databaseName, $collectionName, array $options = [])
+    {
+        if (isset($options['session']) && ! $options['session'] instanceof Session) {
+            throw InvalidArgumentException::invalidType('"session" option', $options['session'], Session::class);
+        }
+
+        if (isset($options['typeMap']) && ! is_array($options['typeMap'])) {
+            throw InvalidArgumentException::invalidType('"typeMap" option', $options['typeMap'], 'array');
+        }
+
+        if (isset($options['writeConcern']) && ! $options['writeConcern'] instanceof WriteConcern) {
+            throw InvalidArgumentException::invalidType('"writeConcern" option', $options['writeConcern'], WriteConcern::class);
+        }
+
+        if (isset($options['writeConcern']) && $options['writeConcern']->isDefault()) {
+            unset($options['writeConcern']);
+        }
+
+        $this->databaseName = (string) $databaseName;
+        $this->collectionName = (string) $collectionName;
+        $this->options = $options;
+    }
+
+    /**
+     * Execute the operation.
+     *
+     * @see Executable::execute()
+     * @param Server $server
+     * @return array|object Command result document
+     * @throws UnsupportedException if writeConcern is used and unsupported
+     * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
+     */
+    public function execute(Server $server)
+    {
+        if (isset($this->options['writeConcern']) && ! server_supports_feature($server, self::$wireVersionForWriteConcern)) {
+            throw UnsupportedException::writeConcernNotSupported();
+        }
+
+        $inTransaction = isset($this->options['session']) && $this->options['session']->isInTransaction();
+        if ($inTransaction && isset($this->options['writeConcern'])) {
+            throw UnsupportedException::writeConcernNotSupportedInTransaction();
+        }
+
+        $command = new Command(['drop' => $this->collectionName]);
+
+        try {
+            $cursor = $server->executeWriteCommand($this->databaseName, $command, $this->createOptions());
+        } catch (CommandException $e) {
+            /* The server may return an error if the collection does not exist.
+             * Check for an error code (or message for pre-3.2 servers) and
+             * return the command reply instead of throwing. */
+            if ($e->getCode() === self::$errorCodeNamespaceNotFound ||
+                $e->getMessage() === self::$errorMessageNamespaceNotFound) {
+                return $e->getResultDocument();
+            }
+
+            throw $e;
+        }
+
+        if (isset($this->options['typeMap'])) {
+            $cursor->setTypeMap($this->options['typeMap']);
+        }
+
+        return current($cursor->toArray());
+    }
+
+    /**
+     * Create options for executing the command.
+     *
+     * @see http://php.net/manual/en/mongodb-driver-server.executewritecommand.php
+     * @return array
+     */
+    private function createOptions()
+    {
+        $options = [];
+
+        if (isset($this->options['session'])) {
+            $options['session'] = $this->options['session'];
+        }
+
+        if (isset($this->options['writeConcern'])) {
+            $options['writeConcern'] = $this->options['writeConcern'];
+        }
+
+        return $options;
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/DropDatabase.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/DropDatabase.php
new file mode 100644
index 0000000000000000000000000000000000000000..5a4335a7d8d497c6db8bd51cb11006ece1be7deb
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/DropDatabase.php	
@@ -0,0 +1,138 @@
+<?php
+/*
+ * Copyright 2015-2017 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace MongoDB\Operation;
+
+use MongoDB\Driver\Command;
+use MongoDB\Driver\Exception\RuntimeException as DriverRuntimeException;
+use MongoDB\Driver\Server;
+use MongoDB\Driver\Session;
+use MongoDB\Driver\WriteConcern;
+use MongoDB\Exception\InvalidArgumentException;
+use MongoDB\Exception\UnsupportedException;
+use function current;
+use function is_array;
+use function MongoDB\server_supports_feature;
+
+/**
+ * Operation for the dropDatabase command.
+ *
+ * @api
+ * @see \MongoDB\Client::dropDatabase()
+ * @see \MongoDB\Database::drop()
+ * @see http://docs.mongodb.org/manual/reference/command/dropDatabase/
+ */
+class DropDatabase implements Executable
+{
+    /** @var integer */
+    private static $wireVersionForWriteConcern = 5;
+
+    /** @var string */
+    private $databaseName;
+
+    /** @var array */
+    private $options;
+
+    /**
+     * Constructs a dropDatabase command.
+     *
+     * Supported options:
+     *
+     *  * session (MongoDB\Driver\Session): Client session.
+     *
+     *    Sessions are not supported for server versions < 3.6.
+     *
+     *  * typeMap (array): Type map for BSON deserialization. This will be used
+     *    for the returned command result document.
+     *
+     *  * writeConcern (MongoDB\Driver\WriteConcern): Write concern.
+     *
+     *    This is not supported for server versions < 3.4 and will result in an
+     *    exception at execution time if used.
+     *
+     * @param string $databaseName Database name
+     * @param array  $options      Command options
+     * @throws InvalidArgumentException for parameter/option parsing errors
+     */
+    public function __construct($databaseName, array $options = [])
+    {
+        if (isset($options['session']) && ! $options['session'] instanceof Session) {
+            throw InvalidArgumentException::invalidType('"session" option', $options['session'], Session::class);
+        }
+
+        if (isset($options['typeMap']) && ! is_array($options['typeMap'])) {
+            throw InvalidArgumentException::invalidType('"typeMap" option', $options['typeMap'], 'array');
+        }
+
+        if (isset($options['writeConcern']) && ! $options['writeConcern'] instanceof WriteConcern) {
+            throw InvalidArgumentException::invalidType('"writeConcern" option', $options['writeConcern'], WriteConcern::class);
+        }
+
+        if (isset($options['writeConcern']) && $options['writeConcern']->isDefault()) {
+            unset($options['writeConcern']);
+        }
+
+        $this->databaseName = (string) $databaseName;
+        $this->options = $options;
+    }
+
+    /**
+     * Execute the operation.
+     *
+     * @see Executable::execute()
+     * @param Server $server
+     * @return array|object Command result document
+     * @throws UnsupportedException if writeConcern is used and unsupported
+     * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
+     */
+    public function execute(Server $server)
+    {
+        if (isset($this->options['writeConcern']) && ! server_supports_feature($server, self::$wireVersionForWriteConcern)) {
+            throw UnsupportedException::writeConcernNotSupported();
+        }
+
+        $command = new Command(['dropDatabase' => 1]);
+        $cursor = $server->executeWriteCommand($this->databaseName, $command, $this->createOptions());
+
+        if (isset($this->options['typeMap'])) {
+            $cursor->setTypeMap($this->options['typeMap']);
+        }
+
+        return current($cursor->toArray());
+    }
+
+    /**
+     * Create options for executing the command.
+     *
+     * @see http://php.net/manual/en/mongodb-driver-server.executewritecommand.php
+     * @return array
+     */
+    private function createOptions()
+    {
+        $options = [];
+
+        if (isset($this->options['session'])) {
+            $options['session'] = $this->options['session'];
+        }
+
+        if (isset($this->options['writeConcern'])) {
+            $options['writeConcern'] = $this->options['writeConcern'];
+        }
+
+        return $options;
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/DropIndexes.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/DropIndexes.php
new file mode 100644
index 0000000000000000000000000000000000000000..322e3b10f9a6603fe7bcb0d8d3787bfe2a02a83d
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/DropIndexes.php	
@@ -0,0 +1,184 @@
+<?php
+/*
+ * Copyright 2015-2017 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace MongoDB\Operation;
+
+use MongoDB\Driver\Command;
+use MongoDB\Driver\Exception\RuntimeException as DriverRuntimeException;
+use MongoDB\Driver\Server;
+use MongoDB\Driver\Session;
+use MongoDB\Driver\WriteConcern;
+use MongoDB\Exception\InvalidArgumentException;
+use MongoDB\Exception\UnsupportedException;
+use function current;
+use function is_array;
+use function is_integer;
+use function MongoDB\server_supports_feature;
+
+/**
+ * Operation for the dropIndexes command.
+ *
+ * @api
+ * @see \MongoDB\Collection::dropIndexes()
+ * @see http://docs.mongodb.org/manual/reference/command/dropIndexes/
+ */
+class DropIndexes implements Executable
+{
+    /** @var integer */
+    private static $wireVersionForWriteConcern = 5;
+
+    /** @var string */
+    private $databaseName;
+
+    /** @var string */
+    private $collectionName;
+
+    /** @var string */
+    private $indexName;
+
+    /** @var array */
+    private $options;
+
+    /**
+     * Constructs a dropIndexes command.
+     *
+     * Supported options:
+     *
+     *  * maxTimeMS (integer): The maximum amount of time to allow the query to
+     *    run.
+     *
+     *  * session (MongoDB\Driver\Session): Client session.
+     *
+     *    Sessions are not supported for server versions < 3.6.
+     *
+     *  * typeMap (array): Type map for BSON deserialization. This will be used
+     *    for the returned command result document.
+     *
+     *  * writeConcern (MongoDB\Driver\WriteConcern): Write concern.
+     *
+     *    This is not supported for server versions < 3.4 and will result in an
+     *    exception at execution time if used.
+     *
+     * @param string $databaseName   Database name
+     * @param string $collectionName Collection name
+     * @param string $indexName      Index name (use "*" to drop all indexes)
+     * @param array  $options        Command options
+     * @throws InvalidArgumentException for parameter/option parsing errors
+     */
+    public function __construct($databaseName, $collectionName, $indexName, array $options = [])
+    {
+        $indexName = (string) $indexName;
+
+        if ($indexName === '') {
+            throw new InvalidArgumentException('$indexName cannot be empty');
+        }
+
+        if (isset($options['maxTimeMS']) && ! is_integer($options['maxTimeMS'])) {
+            throw InvalidArgumentException::invalidType('"maxTimeMS" option', $options['maxTimeMS'], 'integer');
+        }
+
+        if (isset($options['session']) && ! $options['session'] instanceof Session) {
+            throw InvalidArgumentException::invalidType('"session" option', $options['session'], Session::class);
+        }
+
+        if (isset($options['typeMap']) && ! is_array($options['typeMap'])) {
+            throw InvalidArgumentException::invalidType('"typeMap" option', $options['typeMap'], 'array');
+        }
+
+        if (isset($options['writeConcern']) && ! $options['writeConcern'] instanceof WriteConcern) {
+            throw InvalidArgumentException::invalidType('"writeConcern" option', $options['writeConcern'], WriteConcern::class);
+        }
+
+        if (isset($options['writeConcern']) && $options['writeConcern']->isDefault()) {
+            unset($options['writeConcern']);
+        }
+
+        $this->databaseName = (string) $databaseName;
+        $this->collectionName = (string) $collectionName;
+        $this->indexName = $indexName;
+        $this->options = $options;
+    }
+
+    /**
+     * Execute the operation.
+     *
+     * @see Executable::execute()
+     * @param Server $server
+     * @return array|object Command result document
+     * @throws UnsupportedException if writeConcern is used and unsupported
+     * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
+     */
+    public function execute(Server $server)
+    {
+        if (isset($this->options['writeConcern']) && ! server_supports_feature($server, self::$wireVersionForWriteConcern)) {
+            throw UnsupportedException::writeConcernNotSupported();
+        }
+
+        $inTransaction = isset($this->options['session']) && $this->options['session']->isInTransaction();
+        if ($inTransaction && isset($this->options['writeConcern'])) {
+            throw UnsupportedException::writeConcernNotSupportedInTransaction();
+        }
+
+        $cursor = $server->executeWriteCommand($this->databaseName, $this->createCommand(), $this->createOptions());
+
+        if (isset($this->options['typeMap'])) {
+            $cursor->setTypeMap($this->options['typeMap']);
+        }
+
+        return current($cursor->toArray());
+    }
+
+    /**
+     * Create the dropIndexes command.
+     *
+     * @return Command
+     */
+    private function createCommand()
+    {
+        $cmd = [
+            'dropIndexes' => $this->collectionName,
+            'index' => $this->indexName,
+        ];
+
+        if (isset($this->options['maxTimeMS'])) {
+            $cmd['maxTimeMS'] = $this->options['maxTimeMS'];
+        }
+
+        return new Command($cmd);
+    }
+
+    /**
+     * Create options for executing the command.
+     *
+     * @see http://php.net/manual/en/mongodb-driver-server.executewritecommand.php
+     * @return array
+     */
+    private function createOptions()
+    {
+        $options = [];
+
+        if (isset($this->options['session'])) {
+            $options['session'] = $this->options['session'];
+        }
+
+        if (isset($this->options['writeConcern'])) {
+            $options['writeConcern'] = $this->options['writeConcern'];
+        }
+
+        return $options;
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/EstimatedDocumentCount.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/EstimatedDocumentCount.php
new file mode 100644
index 0000000000000000000000000000000000000000..2e6dd5ca13207e499fadd2da33c27874d90302bf
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/EstimatedDocumentCount.php	
@@ -0,0 +1,108 @@
+<?php
+/*
+ * Copyright 2015-2017 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace MongoDB\Operation;
+
+use MongoDB\Driver\Exception\RuntimeException as DriverRuntimeException;
+use MongoDB\Driver\Server;
+use MongoDB\Exception\InvalidArgumentException;
+use MongoDB\Exception\UnexpectedValueException;
+use MongoDB\Exception\UnsupportedException;
+use function array_intersect_key;
+
+/**
+ * Operation for obtaining an estimated count of documents in a collection
+ *
+ * @api
+ * @see \MongoDB\Collection::estimatedDocumentCount()
+ * @see http://docs.mongodb.org/manual/reference/command/count/
+ */
+class EstimatedDocumentCount implements Executable, Explainable
+{
+    /** @var string */
+    private $databaseName;
+
+    /** @var string */
+    private $collectionName;
+
+    /** @var array */
+    private $options;
+
+    /** @var Count */
+    private $count;
+
+    /**
+     * Constructs a count command.
+     *
+     * Supported options:
+     *
+     *  * maxTimeMS (integer): The maximum amount of time to allow the query to
+     *    run.
+     *
+     *  * readConcern (MongoDB\Driver\ReadConcern): Read concern.
+     *
+     *    This is not supported for server versions < 3.2 and will result in an
+     *    exception at execution time if used.
+     *
+     *  * readPreference (MongoDB\Driver\ReadPreference): Read preference.
+     *
+     *  * session (MongoDB\Driver\Session): Client session.
+     *
+     *    Sessions are not supported for server versions < 3.6.
+     *
+     * @param string $databaseName   Database name
+     * @param string $collectionName Collection name
+     * @param array  $options        Command options
+     * @throws InvalidArgumentException for parameter/option parsing errors
+     */
+    public function __construct($databaseName, $collectionName, array $options = [])
+    {
+        $this->databaseName = (string) $databaseName;
+        $this->collectionName = (string) $collectionName;
+        $this->options = array_intersect_key($options, ['maxTimeMS' => 1, 'readConcern' => 1, 'readPreference' => 1, 'session' => 1]);
+
+        $this->count = $this->createCount();
+    }
+
+    /**
+     * Execute the operation.
+     *
+     * @see Executable::execute()
+     * @param Server $server
+     * @return integer
+     * @throws UnexpectedValueException if the command response was malformed
+     * @throws UnsupportedException if collation or read concern is used and unsupported
+     * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
+     */
+    public function execute(Server $server)
+    {
+        return $this->count->execute($server);
+    }
+
+    public function getCommandDocument(Server $server)
+    {
+        return $this->count->getCommandDocument($server);
+    }
+
+    /**
+     * @return Count
+     */
+    private function createCount()
+    {
+        return new Count($this->databaseName, $this->collectionName, [], $this->options);
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/Executable.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/Executable.php
new file mode 100644
index 0000000000000000000000000000000000000000..eee1b5fdcf5dffafc791b0b8c8e935dd307fe1eb
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/Executable.php	
@@ -0,0 +1,39 @@
+<?php
+/*
+ * Copyright 2015-2017 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace MongoDB\Operation;
+
+use MongoDB\Driver\Server;
+
+/**
+ * Executable interface for operation classes.
+ *
+ * This interface is reserved for internal use until PHPC-378 is implemented,
+ * since execute() should ultimately be changed to use ServerInterface.
+ *
+ * @internal
+ */
+interface Executable
+{
+    /**
+     * Execute the operation.
+     *
+     * @param Server $server
+     * @return mixed
+     */
+    public function execute(Server $server);
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/Explain.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/Explain.php
new file mode 100644
index 0000000000000000000000000000000000000000..aa240bb51cfe018235035a36d8793f387bfaf33e
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/Explain.php	
@@ -0,0 +1,162 @@
+<?php
+/*
+ * Copyright 2018 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace MongoDB\Operation;
+
+use MongoDB\Driver\Command;
+use MongoDB\Driver\ReadPreference;
+use MongoDB\Driver\Server;
+use MongoDB\Driver\Session;
+use MongoDB\Exception\InvalidArgumentException;
+use MongoDB\Exception\UnsupportedException;
+use function current;
+use function is_array;
+use function is_string;
+use function MongoDB\server_supports_feature;
+
+/**
+ * Operation for the explain command.
+ *
+ * @api
+ * @see \MongoDB\Collection::explain()
+ * @see http://docs.mongodb.org/manual/reference/command/explain/
+ */
+class Explain implements Executable
+{
+    const VERBOSITY_ALL_PLANS = 'allPlansExecution';
+    const VERBOSITY_EXEC_STATS = 'executionStats';
+    const VERBOSITY_QUERY = 'queryPlanner';
+
+    /** @var integer */
+    private static $wireVersionForAggregate = 7;
+
+    /** @var integer */
+    private static $wireVersionForDistinct = 4;
+
+    /** @var integer */
+    private static $wireVersionForFindAndModify = 4;
+
+    /** @var string */
+    private $databaseName;
+
+    /** @var Explainable */
+    private $explainable;
+
+    /** @var array */
+    private $options;
+
+    /**
+     * Constructs an explain command for explainable operations.
+     *
+     * Supported options:
+     *
+     *  * readPreference (MongoDB\Driver\ReadPreference): Read preference.
+     *
+     *  * session (MongoDB\Driver\Session): Client session.
+     *
+     *  * typeMap (array): Type map for BSON deserialization. This will be used
+     *    used for the returned command result document.
+     *
+     *  * verbosity (string): The mode in which the explain command will be run.
+     *
+     * @param string      $databaseName Database name
+     * @param Explainable $explainable  Operation to explain
+     * @param array       $options      Command options
+     * @throws InvalidArgumentException for parameter/option parsing errors
+     */
+    public function __construct($databaseName, Explainable $explainable, array $options = [])
+    {
+        if (isset($options['readPreference']) && ! $options['readPreference'] instanceof ReadPreference) {
+            throw InvalidArgumentException::invalidType('"readPreference" option', $options['readPreference'], ReadPreference::class);
+        }
+
+        if (isset($options['session']) && ! $options['session'] instanceof Session) {
+            throw InvalidArgumentException::invalidType('"session" option', $options['session'], Session::class);
+        }
+
+        if (isset($options['typeMap']) && ! is_array($options['typeMap'])) {
+            throw InvalidArgumentException::invalidType('"typeMap" option', $options['typeMap'], 'array');
+        }
+
+        if (isset($options['verbosity']) && ! is_string($options['verbosity'])) {
+            throw InvalidArgumentException::invalidType('"verbosity" option', $options['verbosity'], 'string');
+        }
+
+        $this->databaseName = $databaseName;
+        $this->explainable = $explainable;
+        $this->options = $options;
+    }
+
+    public function execute(Server $server)
+    {
+        if ($this->explainable instanceof Distinct && ! server_supports_feature($server, self::$wireVersionForDistinct)) {
+            throw UnsupportedException::explainNotSupported();
+        }
+
+        if ($this->isFindAndModify($this->explainable) && ! server_supports_feature($server, self::$wireVersionForFindAndModify)) {
+            throw UnsupportedException::explainNotSupported();
+        }
+
+        if ($this->explainable instanceof Aggregate && ! server_supports_feature($server, self::$wireVersionForAggregate)) {
+            throw UnsupportedException::explainNotSupported();
+        }
+
+        $cmd = ['explain' => $this->explainable->getCommandDocument($server)];
+
+        if (isset($this->options['verbosity'])) {
+            $cmd['verbosity'] = $this->options['verbosity'];
+        }
+
+        $cursor = $server->executeCommand($this->databaseName, new Command($cmd), $this->createOptions());
+
+        if (isset($this->options['typeMap'])) {
+            $cursor->setTypeMap($this->options['typeMap']);
+        }
+
+        return current($cursor->toArray());
+    }
+
+    /**
+     * Create options for executing the command.
+     *
+     * @see http://php.net/manual/en/mongodb-driver-server.executecommand.php
+     * @return array
+     */
+    private function createOptions()
+    {
+        $options = [];
+
+        if (isset($this->options['readPreference'])) {
+            $options['readPreference'] = $this->options['readPreference'];
+        }
+
+        if (isset($this->options['session'])) {
+            $options['session'] = $this->options['session'];
+        }
+
+        return $options;
+    }
+
+    private function isFindAndModify($explainable)
+    {
+        if ($explainable instanceof FindAndModify || $explainable instanceof FindOneAndDelete || $explainable instanceof FindOneAndReplace || $explainable instanceof FindOneAndUpdate) {
+            return true;
+        }
+
+        return false;
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/Explainable.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/Explainable.php
new file mode 100644
index 0000000000000000000000000000000000000000..fb531f23997fac6ab63c9c6f347678f0d9a6b928
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/Explainable.php	
@@ -0,0 +1,31 @@
+<?php
+/*
+ * Copyright 2018 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace MongoDB\Operation;
+
+use MongoDB\Driver\Server;
+
+/**
+ * Explainable interface for explainable operations (aggregate, count, distinct,
+ * find, findAndModify, delete, and update).
+ *
+ * @internal
+ */
+interface Explainable extends Executable
+{
+    public function getCommandDocument(Server $server);
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/Find.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/Find.php
new file mode 100644
index 0000000000000000000000000000000000000000..4555ebd5d77834bda4e0fbcda7b43f25991ef24b
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/Find.php	
@@ -0,0 +1,454 @@
+<?php
+/*
+ * Copyright 2015-2017 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace MongoDB\Operation;
+
+use MongoDB\Driver\Cursor;
+use MongoDB\Driver\Exception\RuntimeException as DriverRuntimeException;
+use MongoDB\Driver\Query;
+use MongoDB\Driver\ReadConcern;
+use MongoDB\Driver\ReadPreference;
+use MongoDB\Driver\Server;
+use MongoDB\Driver\Session;
+use MongoDB\Exception\InvalidArgumentException;
+use MongoDB\Exception\UnsupportedException;
+use function is_array;
+use function is_bool;
+use function is_integer;
+use function is_object;
+use function is_string;
+use function MongoDB\server_supports_feature;
+use function trigger_error;
+use const E_USER_DEPRECATED;
+
+/**
+ * Operation for the find command.
+ *
+ * @api
+ * @see \MongoDB\Collection::find()
+ * @see http://docs.mongodb.org/manual/tutorial/query-documents/
+ * @see http://docs.mongodb.org/manual/reference/operator/query-modifier/
+ */
+class Find implements Executable, Explainable
+{
+    const NON_TAILABLE = 1;
+    const TAILABLE = 2;
+    const TAILABLE_AWAIT = 3;
+
+    /** @var integer */
+    private static $wireVersionForCollation = 5;
+
+    /** @var integer */
+    private static $wireVersionForReadConcern = 4;
+
+    /** @var integer */
+    private static $wireVersionForAllowDiskUseServerSideError = 4;
+
+    /** @var string */
+    private $databaseName;
+
+    /** @var string */
+    private $collectionName;
+
+    /** @var array|object */
+    private $filter;
+
+    /** @var array */
+    private $options;
+
+    /**
+     * Constructs a find command.
+     *
+     * Supported options:
+     *
+     *  * allowDiskUse (boolean): Enables writing to temporary files. When set
+     *    to true, queries can write data to the _tmp sub-directory in the
+     *    dbPath directory. The default is false.
+     *
+     *  * allowPartialResults (boolean): Get partial results from a mongos if
+     *    some shards are inaccessible (instead of throwing an error).
+     *
+     *  * batchSize (integer): The number of documents to return per batch.
+     *
+     *  * collation (document): Collation specification.
+     *
+     *    This is not supported for server versions < 3.4 and will result in an
+     *    exception at execution time if used.
+     *
+     *  * comment (string): Attaches a comment to the query. If "$comment" also
+     *    exists in the modifiers document, this option will take precedence.
+     *
+     *  * cursorType (enum): Indicates the type of cursor to use. Must be either
+     *    NON_TAILABLE, TAILABLE, or TAILABLE_AWAIT. The default is
+     *    NON_TAILABLE.
+     *
+     *  * hint (string|document): The index to use. Specify either the index
+     *    name as a string or the index key pattern as a document. If specified,
+     *    then the query system will only consider plans using the hinted index.
+     *
+     *  * limit (integer): The maximum number of documents to return.
+     *
+     *  * max (document): The exclusive upper bound for a specific index.
+     *
+     *  * maxAwaitTimeMS (integer): The maxium amount of time for the server to wait
+     *    on new documents to satisfy a query, if cursorType is TAILABLE_AWAIT.
+     *
+     *  * maxScan (integer): Maximum number of documents or index keys to scan
+     *    when executing the query.
+     *
+     *    This option has been deprecated since version 1.4.
+     *
+     *  * maxTimeMS (integer): The maximum amount of time to allow the query to
+     *    run. If "$maxTimeMS" also exists in the modifiers document, this
+     *    option will take precedence.
+     *
+     *  * min (document): The inclusive upper bound for a specific index.
+     *
+     *  * modifiers (document): Meta operators that modify the output or
+     *    behavior of a query. Use of these operators is deprecated in favor of
+     *    named options.
+     *
+     *  * noCursorTimeout (boolean): The server normally times out idle cursors
+     *    after an inactivity period (10 minutes) to prevent excess memory use.
+     *    Set this option to prevent that.
+     *
+     *  * oplogReplay (boolean): Internal replication use only. The driver
+     *    should not set this. This option is deprecated as of MongoDB 4.4.
+     *
+     *  * projection (document): Limits the fields to return for the matching
+     *    document.
+     *
+     *  * readConcern (MongoDB\Driver\ReadConcern): Read concern.
+     *
+     *    This is not supported for server versions < 3.2 and will result in an
+     *    exception at execution time if used.
+     *
+     *  * readPreference (MongoDB\Driver\ReadPreference): Read preference.
+     *
+     *  * returnKey (boolean): If true, returns only the index keys in the
+     *    resulting documents.
+     *
+     *  * session (MongoDB\Driver\Session): Client session.
+     *
+     *    Sessions are not supported for server versions < 3.6.
+     *
+     *  * showRecordId (boolean): Determines whether to return the record
+     *    identifier for each document. If true, adds a field $recordId to the
+     *    returned documents.
+     *
+     *  * skip (integer): The number of documents to skip before returning.
+     *
+     *  * snapshot (boolean): Prevents the cursor from returning a document more
+     *    than once because of an intervening write operation.
+     *
+     *    This options has been deprecated since version 1.4.
+     *
+     *  * sort (document): The order in which to return matching documents. If
+     *    "$orderby" also exists in the modifiers document, this option will
+     *    take precedence.
+     *
+     *  * typeMap (array): Type map for BSON deserialization. This will be
+     *    applied to the returned Cursor (it is not sent to the server).
+     *
+     * @param string       $databaseName   Database name
+     * @param string       $collectionName Collection name
+     * @param array|object $filter         Query by which to filter documents
+     * @param array        $options        Command options
+     * @throws InvalidArgumentException for parameter/option parsing errors
+     */
+    public function __construct($databaseName, $collectionName, $filter, array $options = [])
+    {
+        if (! is_array($filter) && ! is_object($filter)) {
+            throw InvalidArgumentException::invalidType('$filter', $filter, 'array or object');
+        }
+
+        if (isset($options['allowDiskUse']) && ! is_bool($options['allowDiskUse'])) {
+            throw InvalidArgumentException::invalidType('"allowDiskUse" option', $options['allowDiskUse'], 'boolean');
+        }
+
+        if (isset($options['allowPartialResults']) && ! is_bool($options['allowPartialResults'])) {
+            throw InvalidArgumentException::invalidType('"allowPartialResults" option', $options['allowPartialResults'], 'boolean');
+        }
+
+        if (isset($options['batchSize']) && ! is_integer($options['batchSize'])) {
+            throw InvalidArgumentException::invalidType('"batchSize" option', $options['batchSize'], 'integer');
+        }
+
+        if (isset($options['collation']) && ! is_array($options['collation']) && ! is_object($options['collation'])) {
+            throw InvalidArgumentException::invalidType('"collation" option', $options['collation'], 'array or object');
+        }
+
+        if (isset($options['comment']) && ! is_string($options['comment'])) {
+            throw InvalidArgumentException::invalidType('"comment" option', $options['comment'], 'comment');
+        }
+
+        if (isset($options['cursorType'])) {
+            if (! is_integer($options['cursorType'])) {
+                throw InvalidArgumentException::invalidType('"cursorType" option', $options['cursorType'], 'integer');
+            }
+
+            if ($options['cursorType'] !== self::NON_TAILABLE &&
+                $options['cursorType'] !== self::TAILABLE &&
+                $options['cursorType'] !== self::TAILABLE_AWAIT) {
+                throw new InvalidArgumentException('Invalid value for "cursorType" option: ' . $options['cursorType']);
+            }
+        }
+
+        if (isset($options['hint']) && ! is_string($options['hint']) && ! is_array($options['hint']) && ! is_object($options['hint'])) {
+            throw InvalidArgumentException::invalidType('"hint" option', $options['hint'], 'string or array or object');
+        }
+
+        if (isset($options['limit']) && ! is_integer($options['limit'])) {
+            throw InvalidArgumentException::invalidType('"limit" option', $options['limit'], 'integer');
+        }
+
+        if (isset($options['max']) && ! is_array($options['max']) && ! is_object($options['max'])) {
+            throw InvalidArgumentException::invalidType('"max" option', $options['max'], 'array or object');
+        }
+
+        if (isset($options['maxAwaitTimeMS']) && ! is_integer($options['maxAwaitTimeMS'])) {
+            throw InvalidArgumentException::invalidType('"maxAwaitTimeMS" option', $options['maxAwaitTimeMS'], 'integer');
+        }
+
+        if (isset($options['maxScan']) && ! is_integer($options['maxScan'])) {
+            throw InvalidArgumentException::invalidType('"maxScan" option', $options['maxScan'], 'integer');
+        }
+
+        if (isset($options['maxTimeMS']) && ! is_integer($options['maxTimeMS'])) {
+            throw InvalidArgumentException::invalidType('"maxTimeMS" option', $options['maxTimeMS'], 'integer');
+        }
+
+        if (isset($options['min']) && ! is_array($options['min']) && ! is_object($options['min'])) {
+            throw InvalidArgumentException::invalidType('"min" option', $options['min'], 'array or object');
+        }
+
+        if (isset($options['modifiers']) && ! is_array($options['modifiers']) && ! is_object($options['modifiers'])) {
+            throw InvalidArgumentException::invalidType('"modifiers" option', $options['modifiers'], 'array or object');
+        }
+
+        if (isset($options['noCursorTimeout']) && ! is_bool($options['noCursorTimeout'])) {
+            throw InvalidArgumentException::invalidType('"noCursorTimeout" option', $options['noCursorTimeout'], 'boolean');
+        }
+
+        if (isset($options['oplogReplay']) && ! is_bool($options['oplogReplay'])) {
+            throw InvalidArgumentException::invalidType('"oplogReplay" option', $options['oplogReplay'], 'boolean');
+        }
+
+        if (isset($options['projection']) && ! is_array($options['projection']) && ! is_object($options['projection'])) {
+            throw InvalidArgumentException::invalidType('"projection" option', $options['projection'], 'array or object');
+        }
+
+        if (isset($options['readConcern']) && ! $options['readConcern'] instanceof ReadConcern) {
+            throw InvalidArgumentException::invalidType('"readConcern" option', $options['readConcern'], ReadConcern::class);
+        }
+
+        if (isset($options['readPreference']) && ! $options['readPreference'] instanceof ReadPreference) {
+            throw InvalidArgumentException::invalidType('"readPreference" option', $options['readPreference'], ReadPreference::class);
+        }
+
+        if (isset($options['returnKey']) && ! is_bool($options['returnKey'])) {
+            throw InvalidArgumentException::invalidType('"returnKey" option', $options['returnKey'], 'boolean');
+        }
+
+        if (isset($options['session']) && ! $options['session'] instanceof Session) {
+            throw InvalidArgumentException::invalidType('"session" option', $options['session'], Session::class);
+        }
+
+        if (isset($options['showRecordId']) && ! is_bool($options['showRecordId'])) {
+            throw InvalidArgumentException::invalidType('"showRecordId" option', $options['showRecordId'], 'boolean');
+        }
+
+        if (isset($options['skip']) && ! is_integer($options['skip'])) {
+            throw InvalidArgumentException::invalidType('"skip" option', $options['skip'], 'integer');
+        }
+
+        if (isset($options['snapshot']) && ! is_bool($options['snapshot'])) {
+            throw InvalidArgumentException::invalidType('"snapshot" option', $options['snapshot'], 'boolean');
+        }
+
+        if (isset($options['sort']) && ! is_array($options['sort']) && ! is_object($options['sort'])) {
+            throw InvalidArgumentException::invalidType('"sort" option', $options['sort'], 'array or object');
+        }
+
+        if (isset($options['typeMap']) && ! is_array($options['typeMap'])) {
+            throw InvalidArgumentException::invalidType('"typeMap" option', $options['typeMap'], 'array');
+        }
+
+        if (isset($options['readConcern']) && $options['readConcern']->isDefault()) {
+            unset($options['readConcern']);
+        }
+
+        if (isset($options['snapshot'])) {
+            trigger_error('The "snapshot" option is deprecated and will be removed in a future release', E_USER_DEPRECATED);
+        }
+
+        if (isset($options['maxScan'])) {
+            trigger_error('The "maxScan" option is deprecated and will be removed in a future release', E_USER_DEPRECATED);
+        }
+
+        $this->databaseName = (string) $databaseName;
+        $this->collectionName = (string) $collectionName;
+        $this->filter = $filter;
+        $this->options = $options;
+    }
+
+    /**
+     * Execute the operation.
+     *
+     * @see Executable::execute()
+     * @param Server $server
+     * @return Cursor
+     * @throws UnsupportedException if collation or read concern is used and unsupported
+     * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
+     */
+    public function execute(Server $server)
+    {
+        if (isset($this->options['collation']) && ! server_supports_feature($server, self::$wireVersionForCollation)) {
+            throw UnsupportedException::collationNotSupported();
+        }
+
+        if (isset($this->options['readConcern']) && ! server_supports_feature($server, self::$wireVersionForReadConcern)) {
+            throw UnsupportedException::readConcernNotSupported();
+        }
+
+        if (isset($this->options['allowDiskUse']) && ! server_supports_feature($server, self::$wireVersionForAllowDiskUseServerSideError)) {
+            throw UnsupportedException::allowDiskUseNotSupported();
+        }
+
+        $inTransaction = isset($this->options['session']) && $this->options['session']->isInTransaction();
+        if ($inTransaction && isset($this->options['readConcern'])) {
+            throw UnsupportedException::readConcernNotSupportedInTransaction();
+        }
+
+        $cursor = $server->executeQuery($this->databaseName . '.' . $this->collectionName, new Query($this->filter, $this->createQueryOptions()), $this->createExecuteOptions());
+
+        if (isset($this->options['typeMap'])) {
+            $cursor->setTypeMap($this->options['typeMap']);
+        }
+
+        return $cursor;
+    }
+
+    public function getCommandDocument(Server $server)
+    {
+        return $this->createCommandDocument();
+    }
+
+    /**
+     * Construct a command document for Find
+     */
+    private function createCommandDocument()
+    {
+        $cmd = ['find' => $this->collectionName, 'filter' => (object) $this->filter];
+
+        $options = $this->createQueryOptions();
+
+        if (empty($options)) {
+            return $cmd;
+        }
+
+        // maxAwaitTimeMS is a Query level option so should not be considered here
+        unset($options['maxAwaitTimeMS']);
+
+        $modifierFallback = [
+            ['allowPartialResults', 'partial'],
+            ['comment', '$comment'],
+            ['hint', '$hint'],
+            ['maxScan', '$maxScan'],
+            ['max', '$max'],
+            ['maxTimeMS', '$maxTimeMS'],
+            ['min', '$min'],
+            ['returnKey', '$returnKey'],
+            ['showRecordId', '$showDiskLoc'],
+            ['sort', '$orderby'],
+            ['snapshot', '$snapshot'],
+        ];
+
+        foreach ($modifierFallback as $modifier) {
+            if (! isset($options[$modifier[0]]) && isset($options['modifiers'][$modifier[1]])) {
+                $options[$modifier[0]] = $options['modifiers'][$modifier[1]];
+            }
+        }
+        unset($options['modifiers']);
+
+        return $cmd + $options;
+    }
+
+    /**
+     * Create options for executing the command.
+     *
+     * @see http://php.net/manual/en/mongodb-driver-server.executequery.php
+     * @return array
+     */
+    private function createExecuteOptions()
+    {
+        $options = [];
+
+        if (isset($this->options['readPreference'])) {
+            $options['readPreference'] = $this->options['readPreference'];
+        }
+
+        if (isset($this->options['session'])) {
+            $options['session'] = $this->options['session'];
+        }
+
+        return $options;
+    }
+
+    /**
+     * Create options for the find query.
+     *
+     * Note that these are separate from the options for executing the command,
+     * which are created in createExecuteOptions().
+     *
+     * @return array
+     */
+    private function createQueryOptions()
+    {
+        $options = [];
+
+        if (isset($this->options['cursorType'])) {
+            if ($this->options['cursorType'] === self::TAILABLE) {
+                $options['tailable'] = true;
+            }
+            if ($this->options['cursorType'] === self::TAILABLE_AWAIT) {
+                $options['tailable'] = true;
+                $options['awaitData'] = true;
+            }
+        }
+
+        foreach (['allowDiskUse', 'allowPartialResults', 'batchSize', 'comment', 'hint', 'limit', 'maxAwaitTimeMS', 'maxScan', 'maxTimeMS', 'noCursorTimeout', 'oplogReplay', 'projection', 'readConcern', 'returnKey', 'showRecordId', 'skip', 'snapshot', 'sort'] as $option) {
+            if (isset($this->options[$option])) {
+                $options[$option] = $this->options[$option];
+            }
+        }
+
+        foreach (['collation', 'max', 'min'] as $option) {
+            if (isset($this->options[$option])) {
+                $options[$option] = (object) $this->options[$option];
+            }
+        }
+
+        $modifiers = empty($this->options['modifiers']) ? [] : (array) $this->options['modifiers'];
+
+        if (! empty($modifiers)) {
+            $options['modifiers'] = $modifiers;
+        }
+
+        return $options;
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/FindAndModify.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/FindAndModify.php
new file mode 100644
index 0000000000000000000000000000000000000000..9e1e5949d271d657421a17357a587be7a1d41c43
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/FindAndModify.php	
@@ -0,0 +1,360 @@
+<?php
+/*
+ * Copyright 2015-2017 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace MongoDB\Operation;
+
+use MongoDB\Driver\Command;
+use MongoDB\Driver\Exception\RuntimeException as DriverRuntimeException;
+use MongoDB\Driver\Server;
+use MongoDB\Driver\Session;
+use MongoDB\Driver\WriteConcern;
+use MongoDB\Exception\InvalidArgumentException;
+use MongoDB\Exception\UnexpectedValueException;
+use MongoDB\Exception\UnsupportedException;
+use function current;
+use function is_array;
+use function is_bool;
+use function is_integer;
+use function is_object;
+use function is_string;
+use function MongoDB\create_field_path_type_map;
+use function MongoDB\is_pipeline;
+use function MongoDB\server_supports_feature;
+
+/**
+ * Operation for the findAndModify command.
+ *
+ * This class is used internally by the FindOneAndDelete, FindOneAndReplace, and
+ * FindOneAndUpdate operation classes.
+ *
+ * @internal
+ * @see http://docs.mongodb.org/manual/reference/command/findAndModify/
+ */
+class FindAndModify implements Executable, Explainable
+{
+    /** @var integer */
+    private static $wireVersionForArrayFilters = 6;
+
+    /** @var integer */
+    private static $wireVersionForCollation = 5;
+
+    /** @var integer */
+    private static $wireVersionForDocumentLevelValidation = 4;
+
+    /** @var integer */
+    private static $wireVersionForHint = 9;
+
+    /** @var integer */
+    private static $wireVersionForHintServerSideError = 8;
+
+    /** @var integer */
+    private static $wireVersionForWriteConcern = 4;
+
+    /** @var string */
+    private $databaseName;
+
+    /** @var string */
+    private $collectionName;
+
+    /** @var array */
+    private $options;
+
+    /**
+     * Constructs a findAndModify command.
+     *
+     * Supported options:
+     *
+     *  * arrayFilters (document array): A set of filters specifying to which
+     *    array elements an update should apply.
+     *
+     *    This is not supported for server versions < 3.6 and will result in an
+     *    exception at execution time if used.
+     *
+     *  * collation (document): Collation specification.
+     *
+     *    This is not supported for server versions < 3.4 and will result in an
+     *    exception at execution time if used.
+     *
+     *  * bypassDocumentValidation (boolean): If true, allows the write to
+     *    circumvent document level validation.
+     *
+     *    For servers < 3.2, this option is ignored as document level validation
+     *    is not available.
+     *
+     *  * fields (document): Limits the fields to return for the matching
+     *    document.
+     *
+     *  * hint (string|document): The index to use. Specify either the index
+     *    name as a string or the index key pattern as a document. If specified,
+     *    then the query system will only consider plans using the hinted index.
+     *
+     *    This is only supported on server versions >= 4.4. Using this option in
+     *    other contexts will result in an exception at execution time.
+     *
+     *  * maxTimeMS (integer): The maximum amount of time to allow the query to
+     *    run.
+     *
+     *  * new (boolean): When true, returns the modified document rather than
+     *    the original. This option is ignored for remove operations. The
+     *    The default is false.
+     *
+     *  * query (document): Query by which to filter documents.
+     *
+     *  * remove (boolean): When true, removes the matched document. This option
+     *    cannot be true if the update option is set. The default is false.
+     *
+     *  * session (MongoDB\Driver\Session): Client session.
+     *
+     *    Sessions are not supported for server versions < 3.6.
+     *
+     *  * sort (document): Determines which document the operation modifies if
+     *    the query selects multiple documents.
+     *
+     *  * typeMap (array): Type map for BSON deserialization.
+     *
+     *  * update (document): Update or replacement to apply to the matched
+     *    document. This option cannot be set if the remove option is true.
+     *
+     *  * upsert (boolean): When true, a new document is created if no document
+     *    matches the query. This option is ignored for remove operations. The
+     *    default is false.
+     *
+     *  * writeConcern (MongoDB\Driver\WriteConcern): Write concern.
+     *
+     *    This is not supported for server versions < 3.2 and will result in an
+     *    exception at execution time if used.
+     *
+     * @param string $databaseName   Database name
+     * @param string $collectionName Collection name
+     * @param array  $options        Command options
+     * @throws InvalidArgumentException for parameter/option parsing errors
+     */
+    public function __construct($databaseName, $collectionName, array $options)
+    {
+        $options += [
+            'new' => false,
+            'remove' => false,
+            'upsert' => false,
+        ];
+
+        if (isset($options['arrayFilters']) && ! is_array($options['arrayFilters'])) {
+            throw InvalidArgumentException::invalidType('"arrayFilters" option', $options['arrayFilters'], 'array');
+        }
+
+        if (isset($options['bypassDocumentValidation']) && ! is_bool($options['bypassDocumentValidation'])) {
+            throw InvalidArgumentException::invalidType('"bypassDocumentValidation" option', $options['bypassDocumentValidation'], 'boolean');
+        }
+
+        if (isset($options['collation']) && ! is_array($options['collation']) && ! is_object($options['collation'])) {
+            throw InvalidArgumentException::invalidType('"collation" option', $options['collation'], 'array or object');
+        }
+
+        if (isset($options['fields']) && ! is_array($options['fields']) && ! is_object($options['fields'])) {
+            throw InvalidArgumentException::invalidType('"fields" option', $options['fields'], 'array or object');
+        }
+
+        if (isset($options['hint']) && ! is_string($options['hint']) && ! is_array($options['hint']) && ! is_object($options['hint'])) {
+            throw InvalidArgumentException::invalidType('"hint" option', $options['hint'], ['string', 'array', 'object']);
+        }
+
+        if (isset($options['maxTimeMS']) && ! is_integer($options['maxTimeMS'])) {
+            throw InvalidArgumentException::invalidType('"maxTimeMS" option', $options['maxTimeMS'], 'integer');
+        }
+
+        if (! is_bool($options['new'])) {
+            throw InvalidArgumentException::invalidType('"new" option', $options['new'], 'boolean');
+        }
+
+        if (isset($options['query']) && ! is_array($options['query']) && ! is_object($options['query'])) {
+            throw InvalidArgumentException::invalidType('"query" option', $options['query'], 'array or object');
+        }
+
+        if (! is_bool($options['remove'])) {
+            throw InvalidArgumentException::invalidType('"remove" option', $options['remove'], 'boolean');
+        }
+
+        if (isset($options['session']) && ! $options['session'] instanceof Session) {
+            throw InvalidArgumentException::invalidType('"session" option', $options['session'], Session::class);
+        }
+
+        if (isset($options['sort']) && ! is_array($options['sort']) && ! is_object($options['sort'])) {
+            throw InvalidArgumentException::invalidType('"sort" option', $options['sort'], 'array or object');
+        }
+
+        if (isset($options['typeMap']) && ! is_array($options['typeMap'])) {
+            throw InvalidArgumentException::invalidType('"typeMap" option', $options['typeMap'], 'array');
+        }
+
+        if (isset($options['update']) && ! is_array($options['update']) && ! is_object($options['update'])) {
+            throw InvalidArgumentException::invalidType('"update" option', $options['update'], 'array or object');
+        }
+
+        if (isset($options['writeConcern']) && ! $options['writeConcern'] instanceof WriteConcern) {
+            throw InvalidArgumentException::invalidType('"writeConcern" option', $options['writeConcern'], WriteConcern::class);
+        }
+
+        if (! is_bool($options['upsert'])) {
+            throw InvalidArgumentException::invalidType('"upsert" option', $options['upsert'], 'boolean');
+        }
+
+        if (! (isset($options['update']) xor $options['remove'])) {
+            throw new InvalidArgumentException('The "remove" option must be true or an "update" document must be specified, but not both');
+        }
+
+        if (isset($options['writeConcern']) && $options['writeConcern']->isDefault()) {
+            unset($options['writeConcern']);
+        }
+
+        $this->databaseName = (string) $databaseName;
+        $this->collectionName = (string) $collectionName;
+        $this->options = $options;
+    }
+
+    /**
+     * Execute the operation.
+     *
+     * @see Executable::execute()
+     * @param Server $server
+     * @return array|object|null
+     * @throws UnexpectedValueException if the command response was malformed
+     * @throws UnsupportedException if array filters, collation, or write concern is used and unsupported
+     * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
+     */
+    public function execute(Server $server)
+    {
+        if (isset($this->options['arrayFilters']) && ! server_supports_feature($server, self::$wireVersionForArrayFilters)) {
+            throw UnsupportedException::arrayFiltersNotSupported();
+        }
+
+        if (isset($this->options['collation']) && ! server_supports_feature($server, self::$wireVersionForCollation)) {
+            throw UnsupportedException::collationNotSupported();
+        }
+
+        /* Server versions >= 4.1.10 raise errors for unknown findAndModify
+         * options (SERVER-40005), but the CRUD spec requires client-side errors
+         * for server versions < 4.2. For later versions, we'll rely on the
+         * server to either utilize the option or report its own error. */
+        if (isset($this->options['hint']) && ! $this->isHintSupported($server)) {
+            throw UnsupportedException::hintNotSupported();
+        }
+
+        if (isset($this->options['writeConcern']) && ! server_supports_feature($server, self::$wireVersionForWriteConcern)) {
+            throw UnsupportedException::writeConcernNotSupported();
+        }
+
+        $inTransaction = isset($this->options['session']) && $this->options['session']->isInTransaction();
+        if ($inTransaction && isset($this->options['writeConcern'])) {
+            throw UnsupportedException::writeConcernNotSupportedInTransaction();
+        }
+
+        $cursor = $server->executeWriteCommand($this->databaseName, new Command($this->createCommandDocument($server)), $this->createOptions());
+
+        if (isset($this->options['typeMap'])) {
+            $cursor->setTypeMap(create_field_path_type_map($this->options['typeMap'], 'value'));
+        }
+
+        $result = current($cursor->toArray());
+
+        return $result->value ?? null;
+    }
+
+    public function getCommandDocument(Server $server)
+    {
+        return $this->createCommandDocument($server);
+    }
+
+    /**
+     * Create the findAndModify command document.
+     *
+     * @param Server $server
+     * @return array
+     */
+    private function createCommandDocument(Server $server)
+    {
+        $cmd = ['findAndModify' => $this->collectionName];
+
+        if ($this->options['remove']) {
+            $cmd['remove'] = true;
+        } else {
+            $cmd['new'] = $this->options['new'];
+            $cmd['upsert'] = $this->options['upsert'];
+        }
+
+        foreach (['collation', 'fields', 'query', 'sort'] as $option) {
+            if (isset($this->options[$option])) {
+                $cmd[$option] = (object) $this->options[$option];
+            }
+        }
+
+        if (isset($this->options['update'])) {
+            $cmd['update'] = is_pipeline($this->options['update'])
+                ? $this->options['update']
+                : (object) $this->options['update'];
+        }
+
+        foreach (['arrayFilters', 'hint', 'maxTimeMS'] as $option) {
+            if (isset($this->options[$option])) {
+                $cmd[$option] = $this->options[$option];
+            }
+        }
+
+        if (! empty($this->options['bypassDocumentValidation']) &&
+            server_supports_feature($server, self::$wireVersionForDocumentLevelValidation)
+        ) {
+            $cmd['bypassDocumentValidation'] = $this->options['bypassDocumentValidation'];
+        }
+
+        return $cmd;
+    }
+
+    /**
+     * Create options for executing the command.
+     *
+     * @see http://php.net/manual/en/mongodb-driver-server.executewritecommand.php
+     * @return array
+     */
+    private function createOptions()
+    {
+        $options = [];
+
+        if (isset($this->options['session'])) {
+            $options['session'] = $this->options['session'];
+        }
+
+        if (isset($this->options['writeConcern'])) {
+            $options['writeConcern'] = $this->options['writeConcern'];
+        }
+
+        return $options;
+    }
+
+    private function isAcknowledgedWriteConcern() : bool
+    {
+        if (! isset($this->options['writeConcern'])) {
+            return true;
+        }
+
+        return $this->options['writeConcern']->getW() > 1 || $this->options['writeConcern']->getJournal();
+    }
+
+    private function isHintSupported(Server $server) : bool
+    {
+        $requiredWireVersion = $this->isAcknowledgedWriteConcern() ? self::$wireVersionForHintServerSideError : self::$wireVersionForHint;
+
+        return server_supports_feature($server, $requiredWireVersion);
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/FindOne.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/FindOne.php
new file mode 100644
index 0000000000000000000000000000000000000000..48f601ce6fa0dcb1a4ada4049872878017f1be65
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/FindOne.php	
@@ -0,0 +1,138 @@
+<?php
+/*
+ * Copyright 2015-2017 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace MongoDB\Operation;
+
+use MongoDB\Driver\Exception\RuntimeException as DriverRuntimeException;
+use MongoDB\Driver\Server;
+use MongoDB\Exception\InvalidArgumentException;
+use MongoDB\Exception\UnsupportedException;
+use function current;
+
+/**
+ * Operation for finding a single document with the find command.
+ *
+ * @api
+ * @see \MongoDB\Collection::findOne()
+ * @see http://docs.mongodb.org/manual/tutorial/query-documents/
+ * @see http://docs.mongodb.org/manual/reference/operator/query-modifier/
+ */
+class FindOne implements Executable, Explainable
+{
+    /** @var Find */
+    private $find;
+
+    /**
+     * Constructs a find command for finding a single document.
+     *
+     * Supported options:
+     *
+     *  * collation (document): Collation specification.
+     *
+     *    This is not supported for server versions < 3.4 and will result in an
+     *    exception at execution time if used.
+     *
+     *  * comment (string): Attaches a comment to the query. If "$comment" also
+     *    exists in the modifiers document, this option will take precedence.
+     *
+     *  * hint (string|document): The index to use. Specify either the index
+     *    name as a string or the index key pattern as a document. If specified,
+     *    then the query system will only consider plans using the hinted index.
+     *
+     *  * max (document): The exclusive upper bound for a specific index.
+     *
+     *  * maxScan (integer): Maximum number of documents or index keys to scan
+     *    when executing the query.
+     *
+     *    This option has been deprecated since version 1.4.
+     *
+     *  * maxTimeMS (integer): The maximum amount of time to allow the query to
+     *    run. If "$maxTimeMS" also exists in the modifiers document, this
+     *    option will take precedence.
+     *
+     *  * min (document): The inclusive upper bound for a specific index.
+     *
+     *  * modifiers (document): Meta-operators modifying the output or behavior
+     *    of a query.
+     *
+     *  * projection (document): Limits the fields to return for the matching
+     *    document.
+     *
+     *  * readConcern (MongoDB\Driver\ReadConcern): Read concern.
+     *
+     *    This is not supported for server versions < 3.2 and will result in an
+     *    exception at execution time if used.
+     *
+     *  * readPreference (MongoDB\Driver\ReadPreference): Read preference.
+     *
+     *  * returnKey (boolean): If true, returns only the index keys in the
+     *    resulting documents.
+     *
+     *  * session (MongoDB\Driver\Session): Client session.
+     *
+     *    Sessions are not supported for server versions < 3.6.
+     *
+     *  * showRecordId (boolean): Determines whether to return the record
+     *    identifier for each document. If true, adds a field $recordId to the
+     *    returned documents.
+     *
+     *  * skip (integer): The number of documents to skip before returning.
+     *
+     *  * sort (document): The order in which to return matching documents. If
+     *    "$orderby" also exists in the modifiers document, this option will
+     *    take precedence.
+     *
+     *  * typeMap (array): Type map for BSON deserialization.
+     *
+     * @param string       $databaseName   Database name
+     * @param string       $collectionName Collection name
+     * @param array|object $filter         Query by which to filter documents
+     * @param array        $options        Command options
+     * @throws InvalidArgumentException for parameter/option parsing errors
+     */
+    public function __construct($databaseName, $collectionName, $filter, array $options = [])
+    {
+        $this->find = new Find(
+            $databaseName,
+            $collectionName,
+            $filter,
+            ['limit' => 1] + $options
+        );
+    }
+
+    /**
+     * Execute the operation.
+     *
+     * @see Executable::execute()
+     * @param Server $server
+     * @return array|object|null
+     * @throws UnsupportedException if collation or read concern is used and unsupported
+     * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
+     */
+    public function execute(Server $server)
+    {
+        $cursor = $this->find->execute($server);
+        $document = current($cursor->toArray());
+
+        return $document === false ? null : $document;
+    }
+
+    public function getCommandDocument(Server $server)
+    {
+        return $this->find->getCommandDocument($server);
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/FindOneAndDelete.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/FindOneAndDelete.php
new file mode 100644
index 0000000000000000000000000000000000000000..88ed57f7eb66977c0454facd0bc3e74ae7a7f5fd
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/FindOneAndDelete.php	
@@ -0,0 +1,123 @@
+<?php
+/*
+ * Copyright 2015-2017 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace MongoDB\Operation;
+
+use MongoDB\Driver\Exception\RuntimeException as DriverRuntimeException;
+use MongoDB\Driver\Server;
+use MongoDB\Exception\InvalidArgumentException;
+use MongoDB\Exception\UnsupportedException;
+use function is_array;
+use function is_object;
+
+/**
+ * Operation for deleting a document with the findAndModify command.
+ *
+ * @api
+ * @see \MongoDB\Collection::findOneAndDelete()
+ * @see http://docs.mongodb.org/manual/reference/command/findAndModify/
+ */
+class FindOneAndDelete implements Executable, Explainable
+{
+    /** @var FindAndModify */
+    private $findAndModify;
+
+    /**
+     * Constructs a findAndModify command for deleting a document.
+     *
+     * Supported options:
+     *
+     *  * collation (document): Collation specification.
+     *
+     *    This is not supported for server versions < 3.4 and will result in an
+     *    exception at execution time if used.
+     *
+     *  * hint (string|document): The index to use. Specify either the index
+     *    name as a string or the index key pattern as a document. If specified,
+     *    then the query system will only consider plans using the hinted index.
+     *
+     *    This is not supported for server versions < 4.4 and will result in an
+     *    exception at execution time if used.
+     *
+     *  * maxTimeMS (integer): The maximum amount of time to allow the query to
+     *    run.
+     *
+     *  * projection (document): Limits the fields to return for the matching
+     *    document.
+     *
+     *  * session (MongoDB\Driver\Session): Client session.
+     *
+     *    Sessions are not supported for server versions < 3.6.
+     *
+     *  * sort (document): Determines which document the operation modifies if
+     *    the query selects multiple documents.
+     *
+     *  * typeMap (array): Type map for BSON deserialization.
+     *
+     *  * writeConcern (MongoDB\Driver\WriteConcern): Write concern.
+     *
+     *    This is not supported for server versions < 3.2 and will result in an
+     *    exception at execution time if used.
+     *
+     * @param string       $databaseName   Database name
+     * @param string       $collectionName Collection name
+     * @param array|object $filter         Query by which to filter documents
+     * @param array        $options        Command options
+     * @throws InvalidArgumentException for parameter/option parsing errors
+     */
+    public function __construct($databaseName, $collectionName, $filter, array $options = [])
+    {
+        if (! is_array($filter) && ! is_object($filter)) {
+            throw InvalidArgumentException::invalidType('$filter', $filter, 'array or object');
+        }
+
+        if (isset($options['projection']) && ! is_array($options['projection']) && ! is_object($options['projection'])) {
+            throw InvalidArgumentException::invalidType('"projection" option', $options['projection'], 'array or object');
+        }
+
+        if (isset($options['projection'])) {
+            $options['fields'] = $options['projection'];
+        }
+
+        unset($options['projection']);
+
+        $this->findAndModify = new FindAndModify(
+            $databaseName,
+            $collectionName,
+            ['query' => $filter, 'remove' => true] + $options
+        );
+    }
+
+    /**
+     * Execute the operation.
+     *
+     * @see Executable::execute()
+     * @param Server $server
+     * @return array|object|null
+     * @throws UnsupportedException if collation or write concern is used and unsupported
+     * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
+     */
+    public function execute(Server $server)
+    {
+        return $this->findAndModify->execute($server);
+    }
+
+    public function getCommandDocument(Server $server)
+    {
+        return $this->findAndModify->getCommandDocument($server);
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/FindOneAndReplace.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/FindOneAndReplace.php
new file mode 100644
index 0000000000000000000000000000000000000000..61256f51844c2fe72f8412101237386a2c6daa84
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/FindOneAndReplace.php	
@@ -0,0 +1,168 @@
+<?php
+/*
+ * Copyright 2015-2017 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace MongoDB\Operation;
+
+use MongoDB\Driver\Exception\RuntimeException as DriverRuntimeException;
+use MongoDB\Driver\Server;
+use MongoDB\Exception\InvalidArgumentException;
+use MongoDB\Exception\UnsupportedException;
+use function is_array;
+use function is_integer;
+use function is_object;
+use function MongoDB\is_first_key_operator;
+
+/**
+ * Operation for replacing a document with the findAndModify command.
+ *
+ * @api
+ * @see \MongoDB\Collection::findOneAndReplace()
+ * @see http://docs.mongodb.org/manual/reference/command/findAndModify/
+ */
+class FindOneAndReplace implements Executable, Explainable
+{
+    const RETURN_DOCUMENT_BEFORE = 1;
+    const RETURN_DOCUMENT_AFTER = 2;
+
+    /** @var FindAndModify */
+    private $findAndModify;
+
+    /**
+     * Constructs a findAndModify command for replacing a document.
+     *
+     * Supported options:
+     *
+     *  * bypassDocumentValidation (boolean): If true, allows the write to
+     *    circumvent document level validation.
+     *
+     *    For servers < 3.2, this option is ignored as document level validation
+     *    is not available.
+     *
+     *  * collation (document): Collation specification.
+     *
+     *    This is not supported for server versions < 3.4 and will result in an
+     *    exception at execution time if used.
+     *
+     *  * hint (string|document): The index to use. Specify either the index
+     *    name as a string or the index key pattern as a document. If specified,
+     *    then the query system will only consider plans using the hinted index.
+     *
+     *    This is not supported for server versions < 4.4 and will result in an
+     *    exception at execution time if used.
+     *
+     *  * maxTimeMS (integer): The maximum amount of time to allow the query to
+     *    run.
+     *
+     *  * projection (document): Limits the fields to return for the matching
+     *    document.
+     *
+     *  * returnDocument (enum): Whether to return the document before or after
+     *    the update is applied. Must be either
+     *    FindOneAndReplace::RETURN_DOCUMENT_BEFORE or
+     *    FindOneAndReplace::RETURN_DOCUMENT_AFTER. The default is
+     *    FindOneAndReplace::RETURN_DOCUMENT_BEFORE.
+     *
+     *  * session (MongoDB\Driver\Session): Client session.
+     *
+     *    Sessions are not supported for server versions < 3.6.
+     *
+     *  * sort (document): Determines which document the operation modifies if
+     *    the query selects multiple documents.
+     *
+     *  * typeMap (array): Type map for BSON deserialization.
+     *
+     *  * upsert (boolean): When true, a new document is created if no document
+     *    matches the query. The default is false.
+     *
+     *  * writeConcern (MongoDB\Driver\WriteConcern): Write concern.
+     *
+     *    This is not supported for server versions < 3.2 and will result in an
+     *    exception at execution time if used.
+     *
+     * @param string       $databaseName   Database name
+     * @param string       $collectionName Collection name
+     * @param array|object $filter         Query by which to filter documents
+     * @param array|object $replacement    Replacement document
+     * @param array        $options        Command options
+     * @throws InvalidArgumentException for parameter/option parsing errors
+     */
+    public function __construct($databaseName, $collectionName, $filter, $replacement, array $options = [])
+    {
+        if (! is_array($filter) && ! is_object($filter)) {
+            throw InvalidArgumentException::invalidType('$filter', $filter, 'array or object');
+        }
+
+        if (! is_array($replacement) && ! is_object($replacement)) {
+            throw InvalidArgumentException::invalidType('$replacement', $replacement, 'array or object');
+        }
+
+        if (is_first_key_operator($replacement)) {
+            throw new InvalidArgumentException('First key in $replacement argument is an update operator');
+        }
+
+        $options += [
+            'returnDocument' => self::RETURN_DOCUMENT_BEFORE,
+            'upsert' => false,
+        ];
+
+        if (isset($options['projection']) && ! is_array($options['projection']) && ! is_object($options['projection'])) {
+            throw InvalidArgumentException::invalidType('"projection" option', $options['projection'], 'array or object');
+        }
+
+        if (! is_integer($options['returnDocument'])) {
+            throw InvalidArgumentException::invalidType('"returnDocument" option', $options['returnDocument'], 'integer');
+        }
+
+        if ($options['returnDocument'] !== self::RETURN_DOCUMENT_AFTER &&
+            $options['returnDocument'] !== self::RETURN_DOCUMENT_BEFORE) {
+            throw new InvalidArgumentException('Invalid value for "returnDocument" option: ' . $options['returnDocument']);
+        }
+
+        if (isset($options['projection'])) {
+            $options['fields'] = $options['projection'];
+        }
+
+        $options['new'] = $options['returnDocument'] === self::RETURN_DOCUMENT_AFTER;
+
+        unset($options['projection'], $options['returnDocument']);
+
+        $this->findAndModify = new FindAndModify(
+            $databaseName,
+            $collectionName,
+            ['query' => $filter, 'update' => $replacement] + $options
+        );
+    }
+
+    /**
+     * Execute the operation.
+     *
+     * @see Executable::execute()
+     * @param Server $server
+     * @return array|object|null
+     * @throws UnsupportedException if collation or write concern is used and unsupported
+     * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
+     */
+    public function execute(Server $server)
+    {
+        return $this->findAndModify->execute($server);
+    }
+
+    public function getCommandDocument(Server $server)
+    {
+        return $this->findAndModify->getCommandDocument($server);
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/FindOneAndUpdate.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/FindOneAndUpdate.php
new file mode 100644
index 0000000000000000000000000000000000000000..c8121a9b50bfc9a478875afebe4ab9930bebfeb9
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/FindOneAndUpdate.php	
@@ -0,0 +1,172 @@
+<?php
+/*
+ * Copyright 2015-2017 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace MongoDB\Operation;
+
+use MongoDB\Driver\Exception\RuntimeException as DriverRuntimeException;
+use MongoDB\Driver\Server;
+use MongoDB\Exception\InvalidArgumentException;
+use MongoDB\Exception\UnsupportedException;
+use function is_array;
+use function is_integer;
+use function is_object;
+use function MongoDB\is_first_key_operator;
+use function MongoDB\is_pipeline;
+
+/**
+ * Operation for updating a document with the findAndModify command.
+ *
+ * @api
+ * @see \MongoDB\Collection::findOneAndUpdate()
+ * @see http://docs.mongodb.org/manual/reference/command/findAndModify/
+ */
+class FindOneAndUpdate implements Executable, Explainable
+{
+    const RETURN_DOCUMENT_BEFORE = 1;
+    const RETURN_DOCUMENT_AFTER = 2;
+
+    /** @var FindAndModify */
+    private $findAndModify;
+
+    /**
+     * Constructs a findAndModify command for updating a document.
+     *
+     * Supported options:
+     *
+     *  * arrayFilters (document array): A set of filters specifying to which
+     *    array elements an update should apply.
+     *
+     *  * bypassDocumentValidation (boolean): If true, allows the write to
+     *    circumvent document level validation.
+     *
+     *    For servers < 3.2, this option is ignored as document level validation
+     *    is not available.
+     *
+     *  * collation (document): Collation specification.
+     *
+     *    This is not supported for server versions < 3.4 and will result in an
+     *    exception at execution time if used.
+     *
+     *  * hint (string|document): The index to use. Specify either the index
+     *    name as a string or the index key pattern as a document. If specified,
+     *    then the query system will only consider plans using the hinted index.
+     *
+     *    This is not supported for server versions < 4.4 and will result in an
+     *    exception at execution time if used.
+     *
+     *  * maxTimeMS (integer): The maximum amount of time to allow the query to
+     *    run.
+     *
+     *  * projection (document): Limits the fields to return for the matching
+     *    document.
+     *
+     *  * returnDocument (enum): Whether to return the document before or after
+     *    the update is applied. Must be either
+     *    FindOneAndUpdate::RETURN_DOCUMENT_BEFORE or
+     *    FindOneAndUpdate::RETURN_DOCUMENT_AFTER. The default is
+     *    FindOneAndUpdate::RETURN_DOCUMENT_BEFORE.
+     *
+     *  * session (MongoDB\Driver\Session): Client session.
+     *
+     *    Sessions are not supported for server versions < 3.6.
+     *
+     *  * sort (document): Determines which document the operation modifies if
+     *    the query selects multiple documents.
+     *
+     *  * typeMap (array): Type map for BSON deserialization.
+     *
+     *  * upsert (boolean): When true, a new document is created if no document
+     *    matches the query. The default is false.
+     *
+     *  * writeConcern (MongoDB\Driver\WriteConcern): Write concern.
+     *
+     *    This is not supported for server versions < 3.2 and will result in an
+     *    exception at execution time if used.
+     *
+     * @param string       $databaseName   Database name
+     * @param string       $collectionName Collection name
+     * @param array|object $filter         Query by which to filter documents
+     * @param array|object $update         Update to apply to the matched document
+     * @param array        $options        Command options
+     * @throws InvalidArgumentException for parameter/option parsing errors
+     */
+    public function __construct($databaseName, $collectionName, $filter, $update, array $options = [])
+    {
+        if (! is_array($filter) && ! is_object($filter)) {
+            throw InvalidArgumentException::invalidType('$filter', $filter, 'array or object');
+        }
+
+        if (! is_array($update) && ! is_object($update)) {
+            throw InvalidArgumentException::invalidType('$update', $update, 'array or object');
+        }
+
+        if (! is_first_key_operator($update) && ! is_pipeline($update)) {
+            throw new InvalidArgumentException('Expected an update document with operator as first key or a pipeline');
+        }
+
+        $options += [
+            'returnDocument' => self::RETURN_DOCUMENT_BEFORE,
+            'upsert' => false,
+        ];
+
+        if (isset($options['projection']) && ! is_array($options['projection']) && ! is_object($options['projection'])) {
+            throw InvalidArgumentException::invalidType('"projection" option', $options['projection'], 'array or object');
+        }
+
+        if (! is_integer($options['returnDocument'])) {
+            throw InvalidArgumentException::invalidType('"returnDocument" option', $options['returnDocument'], 'integer');
+        }
+
+        if ($options['returnDocument'] !== self::RETURN_DOCUMENT_AFTER &&
+            $options['returnDocument'] !== self::RETURN_DOCUMENT_BEFORE) {
+            throw new InvalidArgumentException('Invalid value for "returnDocument" option: ' . $options['returnDocument']);
+        }
+
+        if (isset($options['projection'])) {
+            $options['fields'] = $options['projection'];
+        }
+
+        $options['new'] = $options['returnDocument'] === self::RETURN_DOCUMENT_AFTER;
+
+        unset($options['projection'], $options['returnDocument']);
+
+        $this->findAndModify = new FindAndModify(
+            $databaseName,
+            $collectionName,
+            ['query' => $filter, 'update' => $update] + $options
+        );
+    }
+
+    /**
+     * Execute the operation.
+     *
+     * @see Executable::execute()
+     * @param Server $server
+     * @return array|object|null
+     * @throws UnsupportedException if collation or write concern is used and unsupported
+     * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
+     */
+    public function execute(Server $server)
+    {
+        return $this->findAndModify->execute($server);
+    }
+
+    public function getCommandDocument(Server $server)
+    {
+        return $this->findAndModify->getCommandDocument($server);
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/InsertMany.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/InsertMany.php
new file mode 100644
index 0000000000000000000000000000000000000000..768907592b6651f00933c0aa67175f6e414d3bad
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/InsertMany.php	
@@ -0,0 +1,188 @@
+<?php
+/*
+ * Copyright 2015-2017 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace MongoDB\Operation;
+
+use MongoDB\Driver\BulkWrite as Bulk;
+use MongoDB\Driver\Exception\RuntimeException as DriverRuntimeException;
+use MongoDB\Driver\Server;
+use MongoDB\Driver\Session;
+use MongoDB\Driver\WriteConcern;
+use MongoDB\Exception\InvalidArgumentException;
+use MongoDB\Exception\UnsupportedException;
+use MongoDB\InsertManyResult;
+use function is_array;
+use function is_bool;
+use function is_object;
+use function MongoDB\server_supports_feature;
+use function sprintf;
+
+/**
+ * Operation for inserting multiple documents with the insert command.
+ *
+ * @api
+ * @see \MongoDB\Collection::insertMany()
+ * @see http://docs.mongodb.org/manual/reference/command/insert/
+ */
+class InsertMany implements Executable
+{
+    /** @var integer */
+    private static $wireVersionForDocumentLevelValidation = 4;
+
+    /** @var string */
+    private $databaseName;
+
+    /** @var string */
+    private $collectionName;
+
+    /** @var object[]|array[] */
+    private $documents;
+
+    /** @var array */
+    private $options;
+
+    /**
+     * Constructs an insert command.
+     *
+     * Supported options:
+     *
+     *  * bypassDocumentValidation (boolean): If true, allows the write to
+     *    circumvent document level validation.
+     *
+     *    For servers < 3.2, this option is ignored as document level validation
+     *    is not available.
+     *
+     *  * ordered (boolean): If true, when an insert fails, return without
+     *    performing the remaining writes. If false, when a write fails,
+     *    continue with the remaining writes, if any. The default is true.
+     *
+     *  * session (MongoDB\Driver\Session): Client session.
+     *
+     *    Sessions are not supported for server versions < 3.6.
+     *
+     *  * writeConcern (MongoDB\Driver\WriteConcern): Write concern.
+     *
+     * @param string           $databaseName   Database name
+     * @param string           $collectionName Collection name
+     * @param array[]|object[] $documents      List of documents to insert
+     * @param array            $options        Command options
+     * @throws InvalidArgumentException for parameter/option parsing errors
+     */
+    public function __construct($databaseName, $collectionName, array $documents, array $options = [])
+    {
+        if (empty($documents)) {
+            throw new InvalidArgumentException('$documents is empty');
+        }
+
+        $expectedIndex = 0;
+
+        foreach ($documents as $i => $document) {
+            if ($i !== $expectedIndex) {
+                throw new InvalidArgumentException(sprintf('$documents is not a list (unexpected index: "%s")', $i));
+            }
+
+            if (! is_array($document) && ! is_object($document)) {
+                throw InvalidArgumentException::invalidType(sprintf('$documents[%d]', $i), $document, 'array or object');
+            }
+
+            $expectedIndex += 1;
+        }
+
+        $options += ['ordered' => true];
+
+        if (isset($options['bypassDocumentValidation']) && ! is_bool($options['bypassDocumentValidation'])) {
+            throw InvalidArgumentException::invalidType('"bypassDocumentValidation" option', $options['bypassDocumentValidation'], 'boolean');
+        }
+
+        if (! is_bool($options['ordered'])) {
+            throw InvalidArgumentException::invalidType('"ordered" option', $options['ordered'], 'boolean');
+        }
+
+        if (isset($options['session']) && ! $options['session'] instanceof Session) {
+            throw InvalidArgumentException::invalidType('"session" option', $options['session'], Session::class);
+        }
+
+        if (isset($options['writeConcern']) && ! $options['writeConcern'] instanceof WriteConcern) {
+            throw InvalidArgumentException::invalidType('"writeConcern" option', $options['writeConcern'], WriteConcern::class);
+        }
+
+        if (isset($options['writeConcern']) && $options['writeConcern']->isDefault()) {
+            unset($options['writeConcern']);
+        }
+
+        $this->databaseName = (string) $databaseName;
+        $this->collectionName = (string) $collectionName;
+        $this->documents = $documents;
+        $this->options = $options;
+    }
+
+    /**
+     * Execute the operation.
+     *
+     * @see Executable::execute()
+     * @param Server $server
+     * @return InsertManyResult
+     * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
+     */
+    public function execute(Server $server)
+    {
+        $inTransaction = isset($this->options['session']) && $this->options['session']->isInTransaction();
+        if ($inTransaction && isset($this->options['writeConcern'])) {
+            throw UnsupportedException::writeConcernNotSupportedInTransaction();
+        }
+
+        $options = ['ordered' => $this->options['ordered']];
+
+        if (! empty($this->options['bypassDocumentValidation']) &&
+            server_supports_feature($server, self::$wireVersionForDocumentLevelValidation)
+        ) {
+            $options['bypassDocumentValidation'] = $this->options['bypassDocumentValidation'];
+        }
+
+        $bulk = new Bulk($options);
+        $insertedIds = [];
+
+        foreach ($this->documents as $i => $document) {
+            $insertedIds[$i] = $bulk->insert($document);
+        }
+
+        $writeResult = $server->executeBulkWrite($this->databaseName . '.' . $this->collectionName, $bulk, $this->createOptions());
+
+        return new InsertManyResult($writeResult, $insertedIds);
+    }
+
+    /**
+     * Create options for executing the bulk write.
+     *
+     * @see http://php.net/manual/en/mongodb-driver-server.executebulkwrite.php
+     * @return array
+     */
+    private function createOptions()
+    {
+        $options = [];
+
+        if (isset($this->options['session'])) {
+            $options['session'] = $this->options['session'];
+        }
+
+        if (isset($this->options['writeConcern'])) {
+            $options['writeConcern'] = $this->options['writeConcern'];
+        }
+
+        return $options;
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/InsertOne.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/InsertOne.php
new file mode 100644
index 0000000000000000000000000000000000000000..84d6a4aa17c0ac9ad294f91db0aa81b306558613
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/InsertOne.php	
@@ -0,0 +1,159 @@
+<?php
+/*
+ * Copyright 2015-2017 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace MongoDB\Operation;
+
+use MongoDB\Driver\BulkWrite as Bulk;
+use MongoDB\Driver\Exception\RuntimeException as DriverRuntimeException;
+use MongoDB\Driver\Server;
+use MongoDB\Driver\Session;
+use MongoDB\Driver\WriteConcern;
+use MongoDB\Exception\InvalidArgumentException;
+use MongoDB\Exception\UnsupportedException;
+use MongoDB\InsertOneResult;
+use function is_array;
+use function is_bool;
+use function is_object;
+use function MongoDB\server_supports_feature;
+
+/**
+ * Operation for inserting a single document with the insert command.
+ *
+ * @api
+ * @see \MongoDB\Collection::insertOne()
+ * @see http://docs.mongodb.org/manual/reference/command/insert/
+ */
+class InsertOne implements Executable
+{
+    /** @var integer */
+    private static $wireVersionForDocumentLevelValidation = 4;
+
+    /** @var string */
+    private $databaseName;
+
+    /** @var string */
+    private $collectionName;
+
+    /** @var array|object */
+    private $document;
+
+    /** @var array */
+    private $options;
+
+    /**
+     * Constructs an insert command.
+     *
+     * Supported options:
+     *
+     *  * bypassDocumentValidation (boolean): If true, allows the write to
+     *    circumvent document level validation.
+     *
+     *    For servers < 3.2, this option is ignored as document level validation
+     *    is not available.
+     *
+     *  * session (MongoDB\Driver\Session): Client session.
+     *
+     *    Sessions are not supported for server versions < 3.6.
+     *
+     *  * writeConcern (MongoDB\Driver\WriteConcern): Write concern.
+     *
+     * @param string       $databaseName   Database name
+     * @param string       $collectionName Collection name
+     * @param array|object $document       Document to insert
+     * @param array        $options        Command options
+     * @throws InvalidArgumentException for parameter/option parsing errors
+     */
+    public function __construct($databaseName, $collectionName, $document, array $options = [])
+    {
+        if (! is_array($document) && ! is_object($document)) {
+            throw InvalidArgumentException::invalidType('$document', $document, 'array or object');
+        }
+
+        if (isset($options['bypassDocumentValidation']) && ! is_bool($options['bypassDocumentValidation'])) {
+            throw InvalidArgumentException::invalidType('"bypassDocumentValidation" option', $options['bypassDocumentValidation'], 'boolean');
+        }
+
+        if (isset($options['session']) && ! $options['session'] instanceof Session) {
+            throw InvalidArgumentException::invalidType('"session" option', $options['session'], Session::class);
+        }
+
+        if (isset($options['writeConcern']) && ! $options['writeConcern'] instanceof WriteConcern) {
+            throw InvalidArgumentException::invalidType('"writeConcern" option', $options['writeConcern'], WriteConcern::class);
+        }
+
+        if (isset($options['writeConcern']) && $options['writeConcern']->isDefault()) {
+            unset($options['writeConcern']);
+        }
+
+        $this->databaseName = (string) $databaseName;
+        $this->collectionName = (string) $collectionName;
+        $this->document = $document;
+        $this->options = $options;
+    }
+
+    /**
+     * Execute the operation.
+     *
+     * @see Executable::execute()
+     * @param Server $server
+     * @return InsertOneResult
+     * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
+     */
+    public function execute(Server $server)
+    {
+        $options = [];
+
+        $inTransaction = isset($this->options['session']) && $this->options['session']->isInTransaction();
+        if (isset($this->options['writeConcern']) && $inTransaction) {
+            throw UnsupportedException::writeConcernNotSupportedInTransaction();
+        }
+
+        if (! empty($this->options['bypassDocumentValidation']) &&
+            server_supports_feature($server, self::$wireVersionForDocumentLevelValidation)
+        ) {
+            $options['bypassDocumentValidation'] = $this->options['bypassDocumentValidation'];
+        }
+
+        $bulk = new Bulk($options);
+        $insertedId = $bulk->insert($this->document);
+
+        $writeResult = $server->executeBulkWrite($this->databaseName . '.' . $this->collectionName, $bulk, $this->createOptions());
+
+        return new InsertOneResult($writeResult, $insertedId);
+    }
+
+    /**
+     * Create options for executing the bulk write.
+     *
+     * @see http://php.net/manual/en/mongodb-driver-server.executebulkwrite.php
+     * @return array
+     */
+    private function createOptions()
+    {
+        $options = [];
+
+        if (isset($this->options['session'])) {
+            $options['session'] = $this->options['session'];
+        }
+
+        if (isset($this->options['writeConcern'])) {
+            $options['writeConcern'] = $this->options['writeConcern'];
+        }
+
+        return $options;
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/ListCollectionNames.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/ListCollectionNames.php
new file mode 100644
index 0000000000000000000000000000000000000000..e36bf5688a4e9519c720e029cd6a647a7ca940b3
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/ListCollectionNames.php	
@@ -0,0 +1,79 @@
+<?php
+/*
+ * Copyright 2020-present MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace MongoDB\Operation;
+
+use Iterator;
+use MongoDB\Command\ListCollections as ListCollectionsCommand;
+use MongoDB\Driver\Exception\RuntimeException as DriverRuntimeException;
+use MongoDB\Driver\Server;
+use MongoDB\Exception\InvalidArgumentException;
+use MongoDB\Model\CallbackIterator;
+
+/**
+ * Operation for the listCollectionNames helper.
+ *
+ * @api
+ * @see \MongoDB\Database::listCollectionNames()
+ * @see http://docs.mongodb.org/manual/reference/command/listCollections/
+ */
+class ListCollectionNames implements Executable
+{
+    /** @var ListCollectionsCommand */
+    private $listCollections;
+
+    /**
+     * Constructs a listCollections command.
+     *
+     * Supported options:
+     *
+     *  * filter (document): Query by which to filter collections.
+     *
+     *  * maxTimeMS (integer): The maximum amount of time to allow the query to
+     *    run.
+     *
+     *  * session (MongoDB\Driver\Session): Client session.
+     *
+     *    Sessions are not supported for server versions < 3.6.
+     *
+     * @param string $databaseName Database name
+     * @param array  $options      Command options
+     * @throws InvalidArgumentException for parameter/option parsing errors
+     */
+    public function __construct($databaseName, array $options = [])
+    {
+        $this->listCollections = new ListCollectionsCommand($databaseName, ['nameOnly' => true] + $options);
+    }
+
+    /**
+     * Execute the operation.
+     *
+     * @see Executable::execute()
+     * @param Server $server
+     * @return Iterator
+     * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
+     */
+    public function execute(Server $server) : Iterator
+    {
+        return new CallbackIterator(
+            $this->listCollections->execute($server),
+            function (array $collectionInfo) {
+                return $collectionInfo['name'];
+            }
+        );
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/ListCollections.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/ListCollections.php
new file mode 100644
index 0000000000000000000000000000000000000000..838202cbba75af373bd6a5a2b99a3e7abf310877
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/ListCollections.php	
@@ -0,0 +1,78 @@
+<?php
+/*
+ * Copyright 2015-2017 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace MongoDB\Operation;
+
+use MongoDB\Command\ListCollections as ListCollectionsCommand;
+use MongoDB\Driver\Exception\RuntimeException as DriverRuntimeException;
+use MongoDB\Driver\Server;
+use MongoDB\Exception\InvalidArgumentException;
+use MongoDB\Model\CollectionInfoCommandIterator;
+use MongoDB\Model\CollectionInfoIterator;
+
+/**
+ * Operation for the listCollections command.
+ *
+ * @api
+ * @see \MongoDB\Database::listCollections()
+ * @see http://docs.mongodb.org/manual/reference/command/listCollections/
+ */
+class ListCollections implements Executable
+{
+    /** @var string */
+    private $databaseName;
+
+    /** @var ListCollectionsCommand */
+    private $listCollections;
+
+    /**
+     * Constructs a listCollections command.
+     *
+     * Supported options:
+     *
+     *  * filter (document): Query by which to filter collections.
+     *
+     *  * maxTimeMS (integer): The maximum amount of time to allow the query to
+     *    run.
+     *
+     *  * session (MongoDB\Driver\Session): Client session.
+     *
+     *    Sessions are not supported for server versions < 3.6.
+     *
+     * @param string $databaseName Database name
+     * @param array  $options      Command options
+     * @throws InvalidArgumentException for parameter/option parsing errors
+     */
+    public function __construct($databaseName, array $options = [])
+    {
+        $this->databaseName = (string) $databaseName;
+        $this->listCollections = new ListCollectionsCommand($databaseName, ['nameOnly' => false] + $options);
+    }
+
+    /**
+     * Execute the operation.
+     *
+     * @see Executable::execute()
+     * @param Server $server
+     * @return CollectionInfoIterator
+     * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
+     */
+    public function execute(Server $server)
+    {
+        return new CollectionInfoCommandIterator($this->listCollections->execute($server), $this->databaseName);
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/ListDatabaseNames.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/ListDatabaseNames.php
new file mode 100644
index 0000000000000000000000000000000000000000..a9d5a8a874e6bb4d4dabe76d79c53fc84e744298
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/ListDatabaseNames.php	
@@ -0,0 +1,85 @@
+<?php
+/*
+ * Copyright 2020-present MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace MongoDB\Operation;
+
+use ArrayIterator;
+use Iterator;
+use MongoDB\Command\ListDatabases as ListDatabasesCommand;
+use MongoDB\Driver\Exception\RuntimeException as DriverRuntimeException;
+use MongoDB\Driver\Server;
+use MongoDB\Exception\InvalidArgumentException;
+use MongoDB\Exception\UnexpectedValueException;
+use function array_column;
+
+/**
+ * Operation for the ListDatabases command, returning only database names.
+ *
+ * @api
+ * @see \MongoDB\Client::listDatabaseNames()
+ * @see http://docs.mongodb.org/manual/reference/command/ListDatabases/
+ */
+class ListDatabaseNames implements Executable
+{
+    /** @var ListDatabasesCommand */
+    private $listDatabases;
+
+    /**
+     * Constructs a listDatabases command.
+     *
+     * Supported options:
+     *
+     *  * authorizedDatabases (boolean): Determines which databases are returned
+     *    based on the user privileges.
+     *
+     *    For servers < 4.0.5, this option is ignored.
+     *
+     *  * filter (document): Query by which to filter databases.
+     *
+     *    For servers < 3.6, this option is ignored.
+     *
+     *  * maxTimeMS (integer): The maximum amount of time to allow the query to
+     *    run.
+     *
+     *  * session (MongoDB\Driver\Session): Client session.
+     *
+     *    Sessions are not supported for server versions < 3.6.
+     *
+     * @param array $options Command options
+     * @throws InvalidArgumentException for parameter/option parsing errors
+     */
+    public function __construct(array $options = [])
+    {
+        $this->listDatabases = new ListDatabasesCommand(['nameOnly' => true] + $options);
+    }
+
+    /**
+     * Execute the operation.
+     *
+     * @see Executable::execute()
+     * @param Server $server
+     * @return Iterator
+     * @throws UnexpectedValueException if the command response was malformed
+     * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
+     */
+    public function execute(Server $server) : Iterator
+    {
+        $result = $this->listDatabases->execute($server);
+
+        return new ArrayIterator(array_column($result, 'name'));
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/ListDatabases.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/ListDatabases.php
new file mode 100644
index 0000000000000000000000000000000000000000..66542966f30995f3498e36ff129bcad718151bd7
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/ListDatabases.php	
@@ -0,0 +1,82 @@
+<?php
+/*
+ * Copyright 2015-2017 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace MongoDB\Operation;
+
+use MongoDB\Command\ListDatabases as ListDatabasesCommand;
+use MongoDB\Driver\Exception\RuntimeException as DriverRuntimeException;
+use MongoDB\Driver\Server;
+use MongoDB\Exception\InvalidArgumentException;
+use MongoDB\Exception\UnexpectedValueException;
+use MongoDB\Model\DatabaseInfoIterator;
+use MongoDB\Model\DatabaseInfoLegacyIterator;
+
+/**
+ * Operation for the ListDatabases command.
+ *
+ * @api
+ * @see \MongoDB\Client::listDatabases()
+ * @see http://docs.mongodb.org/manual/reference/command/ListDatabases/
+ */
+class ListDatabases implements Executable
+{
+    /** @var ListDatabasesCommand */
+    private $listDatabases;
+
+    /**
+     * Constructs a listDatabases command.
+     *
+     * Supported options:
+     *
+     *  * authorizedDatabases (boolean): Determines which databases are returned
+     *    based on the user privileges.
+     *
+     *    For servers < 4.0.5, this option is ignored.
+     *
+     *  * filter (document): Query by which to filter databases.
+     *
+     *    For servers < 3.6, this option is ignored.
+     *
+     *  * maxTimeMS (integer): The maximum amount of time to allow the query to
+     *    run.
+     *
+     *  * session (MongoDB\Driver\Session): Client session.
+     *
+     *    Sessions are not supported for server versions < 3.6.
+     *
+     * @param array $options Command options
+     * @throws InvalidArgumentException for parameter/option parsing errors
+     */
+    public function __construct(array $options = [])
+    {
+        $this->listDatabases = new ListDatabasesCommand(['nameOnly' => false] + $options);
+    }
+
+    /**
+     * Execute the operation.
+     *
+     * @see Executable::execute()
+     * @param Server $server
+     * @return DatabaseInfoIterator
+     * @throws UnexpectedValueException if the command response was malformed
+     * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
+     */
+    public function execute(Server $server)
+    {
+        return new DatabaseInfoLegacyIterator($this->listDatabases->execute($server));
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/ListIndexes.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/ListIndexes.php
new file mode 100644
index 0000000000000000000000000000000000000000..9848a8847da7b66f15212d9cb9f1cfc096c108bd
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/ListIndexes.php	
@@ -0,0 +1,154 @@
+<?php
+/*
+ * Copyright 2015-2017 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace MongoDB\Operation;
+
+use EmptyIterator;
+use MongoDB\Driver\Command;
+use MongoDB\Driver\Exception\RuntimeException as DriverRuntimeException;
+use MongoDB\Driver\Server;
+use MongoDB\Driver\Session;
+use MongoDB\Exception\InvalidArgumentException;
+use MongoDB\Model\CachingIterator;
+use MongoDB\Model\IndexInfoIterator;
+use MongoDB\Model\IndexInfoIteratorIterator;
+use function is_integer;
+
+/**
+ * Operation for the listIndexes command.
+ *
+ * @api
+ * @see \MongoDB\Collection::listIndexes()
+ * @see http://docs.mongodb.org/manual/reference/command/listIndexes/
+ */
+class ListIndexes implements Executable
+{
+    /** @var integer */
+    private static $errorCodeDatabaseNotFound = 60;
+
+    /** @var integer */
+    private static $errorCodeNamespaceNotFound = 26;
+
+    /** @var string */
+    private $databaseName;
+
+    /** @var string */
+    private $collectionName;
+
+    /** @var array */
+    private $options;
+
+    /**
+     * Constructs a listIndexes command.
+     *
+     * Supported options:
+     *
+     *  * maxTimeMS (integer): The maximum amount of time to allow the query to
+     *    run.
+     *
+     *  * session (MongoDB\Driver\Session): Client session.
+     *
+     *    Sessions are not supported for server versions < 3.6.
+     *
+     * @param string $databaseName   Database name
+     * @param string $collectionName Collection name
+     * @param array  $options        Command options
+     * @throws InvalidArgumentException for parameter/option parsing errors
+     */
+    public function __construct($databaseName, $collectionName, array $options = [])
+    {
+        if (isset($options['maxTimeMS']) && ! is_integer($options['maxTimeMS'])) {
+            throw InvalidArgumentException::invalidType('"maxTimeMS" option', $options['maxTimeMS'], 'integer');
+        }
+
+        if (isset($options['session']) && ! $options['session'] instanceof Session) {
+            throw InvalidArgumentException::invalidType('"session" option', $options['session'], Session::class);
+        }
+
+        $this->databaseName = (string) $databaseName;
+        $this->collectionName = (string) $collectionName;
+        $this->options = $options;
+    }
+
+    /**
+     * Execute the operation.
+     *
+     * @see Executable::execute()
+     * @param Server $server
+     * @return IndexInfoIterator
+     * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
+     */
+    public function execute(Server $server)
+    {
+        return $this->executeCommand($server);
+    }
+
+    /**
+     * Create options for executing the command.
+     *
+     * Note: read preference is intentionally omitted, as the spec requires that
+     * the command be executed on the primary.
+     *
+     * @see http://php.net/manual/en/mongodb-driver-server.executecommand.php
+     * @return array
+     */
+    private function createOptions()
+    {
+        $options = [];
+
+        if (isset($this->options['session'])) {
+            $options['session'] = $this->options['session'];
+        }
+
+        return $options;
+    }
+
+    /**
+     * Returns information for all indexes for this collection using the
+     * listIndexes command.
+     *
+     * @param Server $server
+     * @return IndexInfoIteratorIterator
+     * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
+     */
+    private function executeCommand(Server $server)
+    {
+        $cmd = ['listIndexes' => $this->collectionName];
+
+        if (isset($this->options['maxTimeMS'])) {
+            $cmd['maxTimeMS'] = $this->options['maxTimeMS'];
+        }
+
+        try {
+            $cursor = $server->executeReadCommand($this->databaseName, new Command($cmd), $this->createOptions());
+        } catch (DriverRuntimeException $e) {
+            /* The server may return an error if the collection does not exist.
+             * Check for possible error codes (see: SERVER-20463) and return an
+             * empty iterator instead of throwing.
+             */
+            if ($e->getCode() === self::$errorCodeNamespaceNotFound || $e->getCode() === self::$errorCodeDatabaseNotFound) {
+                return new IndexInfoIteratorIterator(new EmptyIterator());
+            }
+
+            throw $e;
+        }
+
+        $cursor->setTypeMap(['root' => 'array', 'document' => 'array']);
+
+        return new IndexInfoIteratorIterator(new CachingIterator($cursor), $this->databaseName . '.' . $this->collectionName);
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/MapReduce.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/MapReduce.php
new file mode 100644
index 0000000000000000000000000000000000000000..c1bf6926aa679f8e59f8d3ecbba8f7a1a3c5bc18
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/MapReduce.php	
@@ -0,0 +1,460 @@
+<?php
+/*
+ * Copyright 2015-2017 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace MongoDB\Operation;
+
+use ArrayIterator;
+use MongoDB\BSON\JavascriptInterface;
+use MongoDB\Driver\Command;
+use MongoDB\Driver\Exception\RuntimeException as DriverRuntimeException;
+use MongoDB\Driver\ReadConcern;
+use MongoDB\Driver\ReadPreference;
+use MongoDB\Driver\Server;
+use MongoDB\Driver\Session;
+use MongoDB\Driver\WriteConcern;
+use MongoDB\Exception\InvalidArgumentException;
+use MongoDB\Exception\UnexpectedValueException;
+use MongoDB\Exception\UnsupportedException;
+use MongoDB\MapReduceResult;
+use stdClass;
+use function current;
+use function is_array;
+use function is_bool;
+use function is_integer;
+use function is_object;
+use function is_string;
+use function MongoDB\create_field_path_type_map;
+use function MongoDB\is_mapreduce_output_inline;
+use function MongoDB\server_supports_feature;
+use function trigger_error;
+use const E_USER_DEPRECATED;
+
+/**
+ * Operation for the mapReduce command.
+ *
+ * @api
+ * @see \MongoDB\Collection::mapReduce()
+ * @see https://docs.mongodb.com/manual/reference/command/mapReduce/
+ */
+class MapReduce implements Executable
+{
+    /** @var integer */
+    private static $wireVersionForCollation = 5;
+
+    /** @var integer */
+    private static $wireVersionForDocumentLevelValidation = 4;
+
+    /** @var integer */
+    private static $wireVersionForReadConcern = 4;
+
+    /** @var integer */
+    private static $wireVersionForWriteConcern = 4;
+
+    /** @var string */
+    private $databaseName;
+
+    /** @var string */
+    private $collectionName;
+
+    /** @var JavascriptInterface */
+    private $map;
+
+    /** @var JavascriptInterface */
+    private $reduce;
+
+    /** @var array|object|string */
+    private $out;
+
+    /** @var array */
+    private $options;
+
+    /**
+     * Constructs a mapReduce command.
+     *
+     * Required arguments:
+     *
+     *  * map (MongoDB\BSON\Javascript): A JavaScript function that associates
+     *    or "maps" a value with a key and emits the key and value pair.
+     *
+     *    Passing a Javascript instance with a scope is deprecated. Put all
+     *    scope variables in the "scope" option of the MapReduce operation.
+     *
+     *  * reduce (MongoDB\BSON\Javascript): A JavaScript function that "reduces"
+     *    to a single object all the values associated with a particular key.
+     *
+     *    Passing a Javascript instance with a scope is deprecated. Put all
+     *    scope variables in the "scope" option of the MapReduce operation.
+     *
+     *  * out (string|document): Specifies where to output the result of the
+     *    map-reduce operation. You can either output to a collection or return
+     *    the result inline. On a primary member of a replica set you can output
+     *    either to a collection or inline, but on a secondary, only inline
+     *    output is possible.
+     *
+     * Supported options:
+     *
+     *  * bypassDocumentValidation (boolean): If true, allows the write to
+     *    circumvent document level validation. This only applies when results
+     *    are output to a collection.
+     *
+     *    For servers < 3.2, this option is ignored as document level validation
+     *    is not available.
+     *
+     *  * collation (document): Collation specification.
+     *
+     *    This is not supported for server versions < 3.4 and will result in an
+     *    exception at execution time if used.
+     *
+     *  * finalize (MongoDB\BSON\JavascriptInterface): Follows the reduce method
+     *    and modifies the output.
+     *
+     *    Passing a Javascript instance with a scope is deprecated. Put all
+     *    scope variables in the "scope" option of the MapReduce operation.
+     *
+     *  * jsMode (boolean): Specifies whether to convert intermediate data into
+     *    BSON format between the execution of the map and reduce functions.
+     *
+     *  * limit (integer): Specifies a maximum number of documents for the input
+     *    into the map function.
+     *
+     *  * maxTimeMS (integer): The maximum amount of time to allow the query to
+     *    run.
+     *
+     *  * query (document): Specifies the selection criteria using query
+     *    operators for determining the documents input to the map function.
+     *
+     *  * readConcern (MongoDB\Driver\ReadConcern): Read concern. This is not
+     *    supported when results are returned inline.
+     *
+     *    This is not supported for server versions < 3.2 and will result in an
+     *    exception at execution time if used.
+     *
+     *  * readPreference (MongoDB\Driver\ReadPreference): Read preference.
+     *
+     *    This option is ignored if results are output to a collection.
+     *
+     *  * scope (document): Specifies global variables that are accessible in
+     *    the map, reduce and finalize functions.
+     *
+     *  * session (MongoDB\Driver\Session): Client session.
+     *
+     *    Sessions are not supported for server versions < 3.6.
+     *
+     *  * sort (document): Sorts the input documents. This option is useful for
+     *    optimization. For example, specify the sort key to be the same as the
+     *    emit key so that there are fewer reduce operations. The sort key must
+     *    be in an existing index for this collection.
+     *
+     *  * typeMap (array): Type map for BSON deserialization. This will be
+     *    applied to the returned Cursor (it is not sent to the server).
+     *
+     *  * verbose (boolean): Specifies whether to include the timing information
+     *    in the result information.
+     *
+     *  * writeConcern (MongoDB\Driver\WriteConcern): Write concern. This only
+     *    applies when results are output to a collection.
+     *
+     *    This is not supported for server versions < 3.4 and will result in an
+     *    exception at execution time if used.
+     *
+     * @param string              $databaseName   Database name
+     * @param string              $collectionName Collection name
+     * @param JavascriptInterface $map            Map function
+     * @param JavascriptInterface $reduce         Reduce function
+     * @param string|array|object $out            Output specification
+     * @param array               $options        Command options
+     * @throws InvalidArgumentException for parameter/option parsing errors
+     */
+    public function __construct($databaseName, $collectionName, JavascriptInterface $map, JavascriptInterface $reduce, $out, array $options = [])
+    {
+        if (! is_string($out) && ! is_array($out) && ! is_object($out)) {
+            throw InvalidArgumentException::invalidType('$out', $out, 'string or array or object');
+        }
+
+        if (isset($options['bypassDocumentValidation']) && ! is_bool($options['bypassDocumentValidation'])) {
+            throw InvalidArgumentException::invalidType('"bypassDocumentValidation" option', $options['bypassDocumentValidation'], 'boolean');
+        }
+
+        if (isset($options['collation']) && ! is_array($options['collation']) && ! is_object($options['collation'])) {
+            throw InvalidArgumentException::invalidType('"collation" option', $options['collation'], 'array or object');
+        }
+
+        if (isset($options['finalize']) && ! $options['finalize'] instanceof JavascriptInterface) {
+            throw InvalidArgumentException::invalidType('"finalize" option', $options['finalize'], JavascriptInterface::class);
+        }
+
+        if (isset($options['jsMode']) && ! is_bool($options['jsMode'])) {
+            throw InvalidArgumentException::invalidType('"jsMode" option', $options['jsMode'], 'boolean');
+        }
+
+        if (isset($options['limit']) && ! is_integer($options['limit'])) {
+            throw InvalidArgumentException::invalidType('"limit" option', $options['limit'], 'integer');
+        }
+
+        if (isset($options['maxTimeMS']) && ! is_integer($options['maxTimeMS'])) {
+            throw InvalidArgumentException::invalidType('"maxTimeMS" option', $options['maxTimeMS'], 'integer');
+        }
+
+        if (isset($options['query']) && ! is_array($options['query']) && ! is_object($options['query'])) {
+            throw InvalidArgumentException::invalidType('"query" option', $options['query'], 'array or object');
+        }
+
+        if (isset($options['readConcern']) && ! $options['readConcern'] instanceof ReadConcern) {
+            throw InvalidArgumentException::invalidType('"readConcern" option', $options['readConcern'], ReadConcern::class);
+        }
+
+        if (isset($options['readPreference']) && ! $options['readPreference'] instanceof ReadPreference) {
+            throw InvalidArgumentException::invalidType('"readPreference" option', $options['readPreference'], ReadPreference::class);
+        }
+
+        if (isset($options['scope']) && ! is_array($options['scope']) && ! is_object($options['scope'])) {
+            throw InvalidArgumentException::invalidType('"scope" option', $options['scope'], 'array or object');
+        }
+
+        if (isset($options['session']) && ! $options['session'] instanceof Session) {
+            throw InvalidArgumentException::invalidType('"session" option', $options['session'], Session::class);
+        }
+
+        if (isset($options['sort']) && ! is_array($options['sort']) && ! is_object($options['sort'])) {
+            throw InvalidArgumentException::invalidType('"sort" option', $options['sort'], 'array or object');
+        }
+
+        if (isset($options['typeMap']) && ! is_array($options['typeMap'])) {
+            throw InvalidArgumentException::invalidType('"typeMap" option', $options['typeMap'], 'array');
+        }
+
+        if (isset($options['verbose']) && ! is_bool($options['verbose'])) {
+            throw InvalidArgumentException::invalidType('"verbose" option', $options['verbose'], 'boolean');
+        }
+
+        if (isset($options['writeConcern']) && ! $options['writeConcern'] instanceof WriteConcern) {
+            throw InvalidArgumentException::invalidType('"writeConcern" option', $options['writeConcern'], WriteConcern::class);
+        }
+
+        if (isset($options['readConcern']) && $options['readConcern']->isDefault()) {
+            unset($options['readConcern']);
+        }
+
+        if (isset($options['writeConcern']) && $options['writeConcern']->isDefault()) {
+            unset($options['writeConcern']);
+        }
+
+        // Handle deprecation of CodeWScope
+        if ($map->getScope() !== null) {
+            @trigger_error('Use of Javascript with scope in "$map" argument for MapReduce is deprecated. Put all scope variables in the "scope" option of the MapReduce operation.', E_USER_DEPRECATED);
+        }
+
+        if ($reduce->getScope() !== null) {
+            @trigger_error('Use of Javascript with scope in "$reduce" argument for MapReduce is deprecated. Put all scope variables in the "scope" option of the MapReduce operation.', E_USER_DEPRECATED);
+        }
+
+        if (isset($options['finalize']) && $options['finalize']->getScope() !== null) {
+            @trigger_error('Use of Javascript with scope in "finalize" option for MapReduce is deprecated. Put all scope variables in the "scope" option of the MapReduce operation.', E_USER_DEPRECATED);
+        }
+
+        $this->checkOutDeprecations($out);
+
+        $this->databaseName = (string) $databaseName;
+        $this->collectionName = (string) $collectionName;
+        $this->map = $map;
+        $this->reduce = $reduce;
+        $this->out = $out;
+        $this->options = $options;
+    }
+
+    /**
+     * Execute the operation.
+     *
+     * @see Executable::execute()
+     * @param Server $server
+     * @return MapReduceResult
+     * @throws UnexpectedValueException if the command response was malformed
+     * @throws UnsupportedException if collation, read concern, or write concern is used and unsupported
+     * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
+     */
+    public function execute(Server $server)
+    {
+        if (isset($this->options['collation']) && ! server_supports_feature($server, self::$wireVersionForCollation)) {
+            throw UnsupportedException::collationNotSupported();
+        }
+
+        if (isset($this->options['readConcern']) && ! server_supports_feature($server, self::$wireVersionForReadConcern)) {
+            throw UnsupportedException::readConcernNotSupported();
+        }
+
+        if (isset($this->options['writeConcern']) && ! server_supports_feature($server, self::$wireVersionForWriteConcern)) {
+            throw UnsupportedException::writeConcernNotSupported();
+        }
+
+        $inTransaction = isset($this->options['session']) && $this->options['session']->isInTransaction();
+        if ($inTransaction) {
+            if (isset($this->options['readConcern'])) {
+                throw UnsupportedException::readConcernNotSupportedInTransaction();
+            }
+            if (isset($this->options['writeConcern'])) {
+                throw UnsupportedException::writeConcernNotSupportedInTransaction();
+            }
+        }
+
+        $hasOutputCollection = ! is_mapreduce_output_inline($this->out);
+
+        $command = $this->createCommand($server);
+        $options = $this->createOptions($hasOutputCollection);
+
+        /* If the mapReduce operation results in a write, use
+         * executeReadWriteCommand to ensure we're handling the writeConcern
+         * option.
+         * In other cases, we use executeCommand as this will prevent the
+         * mapReduce operation from being retried when retryReads is enabled.
+         * See https://github.com/mongodb/specifications/blob/master/source/retryable-reads/retryable-reads.rst#unsupported-read-operations. */
+        $cursor = $hasOutputCollection
+            ? $server->executeReadWriteCommand($this->databaseName, $command, $options)
+            : $server->executeCommand($this->databaseName, $command, $options);
+
+        if (isset($this->options['typeMap']) && ! $hasOutputCollection) {
+            $cursor->setTypeMap(create_field_path_type_map($this->options['typeMap'], 'results.$'));
+        }
+
+        $result = current($cursor->toArray());
+
+        $getIterator = $this->createGetIteratorCallable($result, $server);
+
+        return new MapReduceResult($getIterator, $result);
+    }
+
+    /**
+     * @param string|array|object $out
+     * @return void
+     */
+    private function checkOutDeprecations($out)
+    {
+        if (is_string($out)) {
+            return;
+        }
+
+        $out = (array) $out;
+
+        if (isset($out['nonAtomic']) && ! $out['nonAtomic']) {
+            @trigger_error('Specifying false for "out.nonAtomic" is deprecated.', E_USER_DEPRECATED);
+        }
+
+        if (isset($out['sharded']) && ! $out['sharded']) {
+            @trigger_error('Specifying false for "out.sharded" is deprecated.', E_USER_DEPRECATED);
+        }
+    }
+
+    /**
+     * Create the mapReduce command.
+     *
+     * @param Server $server
+     * @return Command
+     */
+    private function createCommand(Server $server)
+    {
+        $cmd = [
+            'mapReduce' => $this->collectionName,
+            'map' => $this->map,
+            'reduce' => $this->reduce,
+            'out' => $this->out,
+        ];
+
+        foreach (['finalize', 'jsMode', 'limit', 'maxTimeMS', 'verbose'] as $option) {
+            if (isset($this->options[$option])) {
+                $cmd[$option] = $this->options[$option];
+            }
+        }
+
+        foreach (['collation', 'query', 'scope', 'sort'] as $option) {
+            if (isset($this->options[$option])) {
+                $cmd[$option] = (object) $this->options[$option];
+            }
+        }
+
+        if (! empty($this->options['bypassDocumentValidation']) &&
+            server_supports_feature($server, self::$wireVersionForDocumentLevelValidation)
+        ) {
+            $cmd['bypassDocumentValidation'] = $this->options['bypassDocumentValidation'];
+        }
+
+        return new Command($cmd);
+    }
+
+    /**
+     * Creates a callable for MapReduceResult::getIterator().
+     *
+     * @param stdClass $result
+     * @param Server   $server
+     * @return callable
+     * @throws UnexpectedValueException if the command response was malformed
+     */
+    private function createGetIteratorCallable(stdClass $result, Server $server)
+    {
+        // Inline results can be wrapped with an ArrayIterator
+        if (isset($result->results) && is_array($result->results)) {
+            $results = $result->results;
+
+            return function () use ($results) {
+                return new ArrayIterator($results);
+            };
+        }
+
+        if (isset($result->result) && (is_string($result->result) || is_object($result->result))) {
+            $options = isset($this->options['typeMap']) ? ['typeMap' => $this->options['typeMap']] : [];
+
+            $find = is_string($result->result)
+                ? new Find($this->databaseName, $result->result, [], $options)
+                : new Find($result->result->db, $result->result->collection, [], $options);
+
+            return function () use ($find, $server) {
+                return $find->execute($server);
+            };
+        }
+
+        throw new UnexpectedValueException('mapReduce command did not return inline results or an output collection');
+    }
+
+    /**
+     * Create options for executing the command.
+     *
+     * @see http://php.net/manual/en/mongodb-driver-server.executereadcommand.php
+     * @see http://php.net/manual/en/mongodb-driver-server.executereadwritecommand.php
+     * @param boolean $hasOutputCollection
+     * @return array
+     */
+    private function createOptions($hasOutputCollection)
+    {
+        $options = [];
+
+        if (isset($this->options['readConcern'])) {
+            $options['readConcern'] = $this->options['readConcern'];
+        }
+
+        if (! $hasOutputCollection && isset($this->options['readPreference'])) {
+            $options['readPreference'] = $this->options['readPreference'];
+        }
+
+        if (isset($this->options['session'])) {
+            $options['session'] = $this->options['session'];
+        }
+
+        if ($hasOutputCollection && isset($this->options['writeConcern'])) {
+            $options['writeConcern'] = $this->options['writeConcern'];
+        }
+
+        return $options;
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/ModifyCollection.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/ModifyCollection.php
new file mode 100644
index 0000000000000000000000000000000000000000..3b5177fd5dbbd9e313b8cbf1e7ee18bc7edbc2b6
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/ModifyCollection.php	
@@ -0,0 +1,146 @@
+<?php
+/*
+ * Copyright 2018 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace MongoDB\Operation;
+
+use MongoDB\Driver\Command;
+use MongoDB\Driver\Exception\RuntimeException as DriverRuntimeException;
+use MongoDB\Driver\Server;
+use MongoDB\Driver\Session;
+use MongoDB\Driver\WriteConcern;
+use MongoDB\Exception\InvalidArgumentException;
+use MongoDB\Exception\UnsupportedException;
+use function current;
+use function is_array;
+use function MongoDB\server_supports_feature;
+
+/**
+ * Operation for the collMod command.
+ *
+ * @api
+ * @see \MongoDB\Database::modifyCollection()
+ * @see http://docs.mongodb.org/manual/reference/command/collMod/
+ */
+class ModifyCollection implements Executable
+{
+    /** @var string */
+    private $databaseName;
+
+    /** @var string */
+    private $collectionName;
+
+    /** @var array */
+    private $collectionOptions;
+
+    /** @var array */
+    private $options;
+
+    /**
+     * Constructs a collMod command.
+     *
+     * Supported options:
+     *
+     *  * session (MongoDB\Driver\Session): Client session.
+     *
+     *    Sessions are not supported for server versions < 3.6.
+     *
+     *  * typeMap (array): Type map for BSON deserialization. This will only be
+     *    used for the returned command result document.
+     *
+     *  * writeConcern (MongoDB\Driver\WriteConcern): Write concern.
+     *
+     *    This is not supported for server versions < 3.2 and will result in an
+     *    exception at execution time if used.
+     *
+     * @param string $databaseName      Database name
+     * @param string $collectionName    Collection or view to modify
+     * @param array  $collectionOptions Collection or view options to assign
+     * @param array  $options           Command options
+     * @throws InvalidArgumentException for parameter/option parsing errors
+     */
+    public function __construct($databaseName, $collectionName, array $collectionOptions, array $options = [])
+    {
+        if (empty($collectionOptions)) {
+            throw new InvalidArgumentException('$collectionOptions is empty');
+        }
+
+        if (isset($options['session']) && ! $options['session'] instanceof Session) {
+            throw InvalidArgumentException::invalidType('"session" option', $options['session'], Session::class);
+        }
+
+        if (isset($options['typeMap']) && ! is_array($options['typeMap'])) {
+            throw InvalidArgumentException::invalidType('"typeMap" option', $options['typeMap'], 'array');
+        }
+
+        if (isset($options['writeConcern']) && ! $options['writeConcern'] instanceof WriteConcern) {
+            throw InvalidArgumentException::invalidType('"writeConcern" option', $options['writeConcern'], WriteConcern::class);
+        }
+
+        if (isset($options['writeConcern']) && $options['writeConcern']->isDefault()) {
+            unset($options['writeConcern']);
+        }
+
+        $this->databaseName = (string) $databaseName;
+        $this->collectionName = (string) $collectionName;
+        $this->collectionOptions = $collectionOptions;
+        $this->options = $options;
+    }
+
+    /**
+     * Execute the operation.
+     *
+     * @see Executable::execute()
+     * @param Server $server
+     * @return array|object Command result document
+     * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
+     */
+    public function execute(Server $server)
+    {
+        if (isset($this->options['writeConcern']) && ! server_supports_feature($server, self::$wireVersionForWriteConcern)) {
+            throw UnsupportedException::writeConcernNotSupported();
+        }
+
+        $cursor = $server->executeWriteCommand($this->databaseName, new Command(['collMod' => $this->collectionName] + $this->collectionOptions), $this->createOptions());
+
+        if (isset($this->options['typeMap'])) {
+            $cursor->setTypeMap($this->options['typeMap']);
+        }
+
+        return current($cursor->toArray());
+    }
+
+    /**
+     * Create options for executing the command.
+     *
+     * @see http://php.net/manual/en/mongodb-driver-server.executewritecommand.php
+     * @return array
+     */
+    private function createOptions()
+    {
+        $options = [];
+
+        if (isset($this->options['session'])) {
+            $options['session'] = $this->options['session'];
+        }
+
+        if (isset($this->options['writeConcern'])) {
+            $options['writeConcern'] = $this->options['writeConcern'];
+        }
+
+        return $options;
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/ReplaceOne.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/ReplaceOne.php
new file mode 100644
index 0000000000000000000000000000000000000000..e55bf74afb7ce081ae814840f82c4ef92b305fcd
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/ReplaceOne.php	
@@ -0,0 +1,117 @@
+<?php
+/*
+ * Copyright 2015-2017 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace MongoDB\Operation;
+
+use MongoDB\Driver\Exception\RuntimeException as DriverRuntimeException;
+use MongoDB\Driver\Server;
+use MongoDB\Exception\InvalidArgumentException;
+use MongoDB\Exception\UnsupportedException;
+use MongoDB\UpdateResult;
+use function is_array;
+use function is_object;
+use function MongoDB\is_first_key_operator;
+use function MongoDB\is_pipeline;
+
+/**
+ * Operation for replacing a single document with the update command.
+ *
+ * @api
+ * @see \MongoDB\Collection::replaceOne()
+ * @see http://docs.mongodb.org/manual/reference/command/update/
+ */
+class ReplaceOne implements Executable
+{
+    /** @var Update */
+    private $update;
+
+    /**
+     * Constructs an update command.
+     *
+     * Supported options:
+     *
+     *  * bypassDocumentValidation (boolean): If true, allows the write to
+     *    circumvent document level validation.
+     *
+     *    For servers < 3.2, this option is ignored as document level validation
+     *    is not available.
+     *
+     *  * collation (document): Collation specification.
+     *
+     *    This is not supported for server versions < 3.4 and will result in an
+     *    exception at execution time if used.
+     *
+     *  * hint (string|document): The index to use. Specify either the index
+     *    name as a string or the index key pattern as a document. If specified,
+     *    then the query system will only consider plans using the hinted index.
+     *
+     *    This is not supported for server versions < 4.2 and will result in an
+     *    exception at execution time if used.
+     *
+     *  * session (MongoDB\Driver\Session): Client session.
+     *
+     *    Sessions are not supported for server versions < 3.6.
+     *
+     *  * upsert (boolean): When true, a new document is created if no document
+     *    matches the query. The default is false.
+     *
+     *  * writeConcern (MongoDB\Driver\WriteConcern): Write concern.
+     *
+     * @param string       $databaseName   Database name
+     * @param string       $collectionName Collection name
+     * @param array|object $filter         Query by which to filter documents
+     * @param array|object $replacement    Replacement document
+     * @param array        $options        Command options
+     * @throws InvalidArgumentException for parameter/option parsing errors
+     */
+    public function __construct($databaseName, $collectionName, $filter, $replacement, array $options = [])
+    {
+        if (! is_array($replacement) && ! is_object($replacement)) {
+            throw InvalidArgumentException::invalidType('$replacement', $replacement, 'array or object');
+        }
+
+        if (is_first_key_operator($replacement)) {
+            throw new InvalidArgumentException('First key in $replacement argument is an update operator');
+        }
+
+        if (is_pipeline($replacement)) {
+            throw new InvalidArgumentException('$replacement argument is a pipeline');
+        }
+
+        $this->update = new Update(
+            $databaseName,
+            $collectionName,
+            $filter,
+            $replacement,
+            ['multi' => false] + $options
+        );
+    }
+
+    /**
+     * Execute the operation.
+     *
+     * @see Executable::execute()
+     * @param Server $server
+     * @return UpdateResult
+     * @throws UnsupportedException if collation is used and unsupported
+     * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
+     */
+    public function execute(Server $server)
+    {
+        return $this->update->execute($server);
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/Update.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/Update.php
new file mode 100644
index 0000000000000000000000000000000000000000..b3b86e0c6732f8be75d391d8b61fe7a3dcb91710
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/Update.php	
@@ -0,0 +1,298 @@
+<?php
+/*
+ * Copyright 2015-2017 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace MongoDB\Operation;
+
+use MongoDB\Driver\BulkWrite as Bulk;
+use MongoDB\Driver\Exception\RuntimeException as DriverRuntimeException;
+use MongoDB\Driver\Server;
+use MongoDB\Driver\Session;
+use MongoDB\Driver\WriteConcern;
+use MongoDB\Exception\InvalidArgumentException;
+use MongoDB\Exception\UnsupportedException;
+use MongoDB\UpdateResult;
+use function is_array;
+use function is_bool;
+use function is_object;
+use function is_string;
+use function MongoDB\is_first_key_operator;
+use function MongoDB\is_pipeline;
+use function MongoDB\server_supports_feature;
+
+/**
+ * Operation for the update command.
+ *
+ * This class is used internally by the ReplaceOne, UpdateMany, and UpdateOne
+ * operation classes.
+ *
+ * @internal
+ * @see http://docs.mongodb.org/manual/reference/command/update/
+ */
+class Update implements Executable, Explainable
+{
+    /** @var integer */
+    private static $wireVersionForArrayFilters = 6;
+
+    /** @var integer */
+    private static $wireVersionForCollation = 5;
+
+    /** @var integer */
+    private static $wireVersionForDocumentLevelValidation = 4;
+
+    /** @var integer */
+    private static $wireVersionForHintServerSideError = 5;
+
+    /** @var string */
+    private $databaseName;
+
+    /** @var string */
+    private $collectionName;
+
+    /** @var array|object */
+    private $filter;
+
+    /** @var array|object */
+    private $update;
+
+    /** @var array */
+    private $options;
+
+    /**
+     * Constructs a update command.
+     *
+     * Supported options:
+     *
+     *  * arrayFilters (document array): A set of filters specifying to which
+     *    array elements an update should apply.
+     *
+     *    This is not supported for server versions < 3.6 and will result in an
+     *    exception at execution time if used.
+     *
+     *  * bypassDocumentValidation (boolean): If true, allows the write to
+     *    circumvent document level validation.
+     *
+     *    For servers < 3.2, this option is ignored as document level validation
+     *    is not available.
+     *
+     *  * collation (document): Collation specification.
+     *
+     *    This is not supported for server versions < 3.4 and will result in an
+     *    exception at execution time if used.
+     *
+     *  * hint (string|document): The index to use. Specify either the index
+     *    name as a string or the index key pattern as a document. If specified,
+     *    then the query system will only consider plans using the hinted index.
+     *
+     *    This is not supported for server versions < 4.2 and will result in an
+     *    exception at execution time if used.
+     *
+     *  * multi (boolean): When true, updates all documents matching the query.
+     *    This option cannot be true if the $update argument is a replacement
+     *    document (i.e. contains no update operators). The default is false.
+     *
+     *  * session (MongoDB\Driver\Session): Client session.
+     *
+     *    Sessions are not supported for server versions < 3.6.
+     *
+     *  * upsert (boolean): When true, a new document is created if no document
+     *    matches the query. The default is false.
+     *
+     *  * writeConcern (MongoDB\Driver\WriteConcern): Write concern.
+     *
+     * @param string       $databaseName   Database name
+     * @param string       $collectionName Collection name
+     * @param array|object $filter         Query by which to delete documents
+     * @param array|object $update         Update to apply to the matched
+     *                                     document(s) or a replacement document
+     * @param array        $options        Command options
+     * @throws InvalidArgumentException for parameter/option parsing errors
+     */
+    public function __construct($databaseName, $collectionName, $filter, $update, array $options = [])
+    {
+        if (! is_array($filter) && ! is_object($filter)) {
+            throw InvalidArgumentException::invalidType('$filter', $filter, 'array or object');
+        }
+
+        if (! is_array($update) && ! is_object($update)) {
+            throw InvalidArgumentException::invalidType('$update', $filter, 'array or object');
+        }
+
+        $options += [
+            'multi' => false,
+            'upsert' => false,
+        ];
+
+        if (isset($options['arrayFilters']) && ! is_array($options['arrayFilters'])) {
+            throw InvalidArgumentException::invalidType('"arrayFilters" option', $options['arrayFilters'], 'array');
+        }
+
+        if (isset($options['bypassDocumentValidation']) && ! is_bool($options['bypassDocumentValidation'])) {
+            throw InvalidArgumentException::invalidType('"bypassDocumentValidation" option', $options['bypassDocumentValidation'], 'boolean');
+        }
+
+        if (isset($options['collation']) && ! is_array($options['collation']) && ! is_object($options['collation'])) {
+            throw InvalidArgumentException::invalidType('"collation" option', $options['collation'], 'array or object');
+        }
+
+        if (isset($options['hint']) && ! is_string($options['hint']) && ! is_array($options['hint']) && ! is_object($options['hint'])) {
+            throw InvalidArgumentException::invalidType('"hint" option', $options['hint'], ['string', 'array', 'object']);
+        }
+
+        if (! is_bool($options['multi'])) {
+            throw InvalidArgumentException::invalidType('"multi" option', $options['multi'], 'boolean');
+        }
+
+        if ($options['multi'] && ! is_first_key_operator($update) && ! is_pipeline($update)) {
+            throw new InvalidArgumentException('"multi" option cannot be true if $update is a replacement document');
+        }
+
+        if (isset($options['session']) && ! $options['session'] instanceof Session) {
+            throw InvalidArgumentException::invalidType('"session" option', $options['session'], Session::class);
+        }
+
+        if (! is_bool($options['upsert'])) {
+            throw InvalidArgumentException::invalidType('"upsert" option', $options['upsert'], 'boolean');
+        }
+
+        if (isset($options['writeConcern']) && ! $options['writeConcern'] instanceof WriteConcern) {
+            throw InvalidArgumentException::invalidType('"writeConcern" option', $options['writeConcern'], WriteConcern::class);
+        }
+
+        if (isset($options['writeConcern']) && $options['writeConcern']->isDefault()) {
+            unset($options['writeConcern']);
+        }
+
+        $this->databaseName = (string) $databaseName;
+        $this->collectionName = (string) $collectionName;
+        $this->filter = $filter;
+        $this->update = $update;
+        $this->options = $options;
+    }
+
+    /**
+     * Execute the operation.
+     *
+     * @see Executable::execute()
+     * @param Server $server
+     * @return UpdateResult
+     * @throws UnsupportedException if array filters or collation is used and unsupported
+     * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
+     */
+    public function execute(Server $server)
+    {
+        if (isset($this->options['arrayFilters']) && ! server_supports_feature($server, self::$wireVersionForArrayFilters)) {
+            throw UnsupportedException::arrayFiltersNotSupported();
+        }
+
+        if (isset($this->options['collation']) && ! server_supports_feature($server, self::$wireVersionForCollation)) {
+            throw UnsupportedException::collationNotSupported();
+        }
+
+        /* Server versions >= 3.4.0 raise errors for unknown update
+         * options. For previous versions, the CRUD spec requires a client-side
+         * error. */
+        if (isset($this->options['hint']) && ! server_supports_feature($server, self::$wireVersionForHintServerSideError)) {
+            throw UnsupportedException::hintNotSupported();
+        }
+
+        $inTransaction = isset($this->options['session']) && $this->options['session']->isInTransaction();
+        if ($inTransaction && isset($this->options['writeConcern'])) {
+            throw UnsupportedException::writeConcernNotSupportedInTransaction();
+        }
+
+        $bulkOptions = [];
+
+        if (! empty($this->options['bypassDocumentValidation']) &&
+            server_supports_feature($server, self::$wireVersionForDocumentLevelValidation)
+        ) {
+            $bulkOptions['bypassDocumentValidation'] = $this->options['bypassDocumentValidation'];
+        }
+
+        $bulk = new Bulk($bulkOptions);
+        $bulk->update($this->filter, $this->update, $this->createUpdateOptions());
+
+        $writeResult = $server->executeBulkWrite($this->databaseName . '.' . $this->collectionName, $bulk, $this->createExecuteOptions());
+
+        return new UpdateResult($writeResult);
+    }
+
+    public function getCommandDocument(Server $server)
+    {
+        $cmd = ['update' => $this->collectionName, 'updates' => [['q' => $this->filter, 'u' => $this->update] + $this->createUpdateOptions()]];
+
+        if (isset($this->options['writeConcern'])) {
+            $cmd['writeConcern'] = $this->options['writeConcern'];
+        }
+
+        if (! empty($this->options['bypassDocumentValidation']) &&
+            server_supports_feature($server, self::$wireVersionForDocumentLevelValidation)
+        ) {
+            $cmd['bypassDocumentValidation'] = $this->options['bypassDocumentValidation'];
+        }
+
+        return $cmd;
+    }
+
+    /**
+     * Create options for executing the bulk write.
+     *
+     * @see http://php.net/manual/en/mongodb-driver-server.executebulkwrite.php
+     * @return array
+     */
+    private function createExecuteOptions()
+    {
+        $options = [];
+
+        if (isset($this->options['session'])) {
+            $options['session'] = $this->options['session'];
+        }
+
+        if (isset($this->options['writeConcern'])) {
+            $options['writeConcern'] = $this->options['writeConcern'];
+        }
+
+        return $options;
+    }
+
+    /**
+     * Create options for the update command.
+     *
+     * Note that these options are different from the bulk write options, which
+     * are created in createExecuteOptions().
+     *
+     * @return array
+     */
+    private function createUpdateOptions()
+    {
+        $updateOptions = [
+            'multi' => $this->options['multi'],
+            'upsert' => $this->options['upsert'],
+        ];
+
+        foreach (['arrayFilters', 'hint'] as $option) {
+            if (isset($this->options[$option])) {
+                $updateOptions[$option] = $this->options[$option];
+            }
+        }
+
+        if (isset($this->options['collation'])) {
+            $updateOptions['collation'] = (object) $this->options['collation'];
+        }
+
+        return $updateOptions;
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/UpdateMany.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/UpdateMany.php
new file mode 100644
index 0000000000000000000000000000000000000000..eb1bd6cd506232ed0d7003a4b1dc9a49aa7dbd62
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/UpdateMany.php	
@@ -0,0 +1,124 @@
+<?php
+/*
+ * Copyright 2015-2017 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace MongoDB\Operation;
+
+use MongoDB\Driver\Exception\RuntimeException as DriverRuntimeException;
+use MongoDB\Driver\Server;
+use MongoDB\Exception\InvalidArgumentException;
+use MongoDB\Exception\UnsupportedException;
+use MongoDB\UpdateResult;
+use function is_array;
+use function is_object;
+use function MongoDB\is_first_key_operator;
+use function MongoDB\is_pipeline;
+
+/**
+ * Operation for updating multiple documents with the update command.
+ *
+ * @api
+ * @see \MongoDB\Collection::updateMany()
+ * @see http://docs.mongodb.org/manual/reference/command/update/
+ */
+class UpdateMany implements Executable, Explainable
+{
+    /** @var Update */
+    private $update;
+
+    /**
+     * Constructs an update command.
+     *
+     * Supported options:
+     *
+     *  * arrayFilters (document array): A set of filters specifying to which
+     *    array elements an update should apply.
+     *
+     *    This is not supported for server versions < 3.6 and will result in an$
+     *    exception at execution time if used.
+     *
+     *  * bypassDocumentValidation (boolean): If true, allows the write to
+     *    circumvent document level validation.
+     *
+     *    For servers < 3.2, this option is ignored as document level validation
+     *    is not available.
+     *
+     *  * collation (document): Collation specification.
+     *
+     *    This is not supported for server versions < 3.4 and will result in an
+     *    exception at execution time if used.
+     *
+     *  * hint (string|document): The index to use. Specify either the index
+     *    name as a string or the index key pattern as a document. If specified,
+     *    then the query system will only consider plans using the hinted index.
+     *
+     *    This is not supported for server versions < 4.2 and will result in an
+     *    exception at execution time if used.
+     *
+     *  * session (MongoDB\Driver\Session): Client session.
+     *
+     *    Sessions are not supported for server versions < 3.6.
+     *
+     *  * upsert (boolean): When true, a new document is created if no document
+     *    matches the query. The default is false.
+     *
+     *  * writeConcern (MongoDB\Driver\WriteConcern): Write concern.
+     *
+     * @param string       $databaseName   Database name
+     * @param string       $collectionName Collection name
+     * @param array|object $filter         Query by which to filter documents
+     * @param array|object $update         Update to apply to the matched documents
+     * @param array        $options        Command options
+     * @throws InvalidArgumentException for parameter/option parsing errors
+     */
+    public function __construct($databaseName, $collectionName, $filter, $update, array $options = [])
+    {
+        if (! is_array($update) && ! is_object($update)) {
+            throw InvalidArgumentException::invalidType('$update', $update, 'array or object');
+        }
+
+        if (! is_first_key_operator($update) && ! is_pipeline($update)) {
+            throw new InvalidArgumentException('Expected an update document with operator as first key or a pipeline');
+        }
+
+        $this->update = new Update(
+            $databaseName,
+            $collectionName,
+            $filter,
+            $update,
+            ['multi' => true] + $options
+        );
+    }
+
+    /**
+     * Execute the operation.
+     *
+     * @see Executable::execute()
+     * @param Server $server
+     * @return UpdateResult
+     * @throws UnsupportedException if collation is used and unsupported
+     * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
+     */
+    public function execute(Server $server)
+    {
+        return $this->update->execute($server);
+    }
+
+    public function getCommandDocument(Server $server)
+    {
+        return $this->update->getCommandDocument($server);
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/UpdateOne.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/UpdateOne.php
new file mode 100644
index 0000000000000000000000000000000000000000..e8e7ef84282d73d6d262482ea1d7d6e189487043
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/UpdateOne.php	
@@ -0,0 +1,124 @@
+<?php
+/*
+ * Copyright 2015-2017 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace MongoDB\Operation;
+
+use MongoDB\Driver\Exception\RuntimeException as DriverRuntimeException;
+use MongoDB\Driver\Server;
+use MongoDB\Exception\InvalidArgumentException;
+use MongoDB\Exception\UnsupportedException;
+use MongoDB\UpdateResult;
+use function is_array;
+use function is_object;
+use function MongoDB\is_first_key_operator;
+use function MongoDB\is_pipeline;
+
+/**
+ * Operation for updating a single document with the update command.
+ *
+ * @api
+ * @see \MongoDB\Collection::updateOne()
+ * @see http://docs.mongodb.org/manual/reference/command/update/
+ */
+class UpdateOne implements Executable, Explainable
+{
+    /** @var Update */
+    private $update;
+
+    /**
+     * Constructs an update command.
+     *
+     * Supported options:
+     *
+     *  * arrayFilters (document array): A set of filters specifying to which
+     *    array elements an update should apply.
+     *
+     *    This is not supported for server versions < 3.6 and will result in an$
+     *    exception at execution time if used.
+     *
+     *  * bypassDocumentValidation (boolean): If true, allows the write to
+     *    circumvent document level validation.
+     *
+     *    For servers < 3.2, this option is ignored as document level validation
+     *    is not available.
+     *
+     *  * collation (document): Collation specification.
+     *
+     *    This is not supported for server versions < 3.4 and will result in an
+     *    exception at execution time if used.
+     *
+     *  * hint (string|document): The index to use. Specify either the index
+     *    name as a string or the index key pattern as a document. If specified,
+     *    then the query system will only consider plans using the hinted index.
+     *
+     *    This is not supported for server versions < 4.2 and will result in an
+     *    exception at execution time if used.
+     *
+     *  * session (MongoDB\Driver\Session): Client session.
+     *
+     *    Sessions are not supported for server versions < 3.6.
+     *
+     *  * upsert (boolean): When true, a new document is created if no document
+     *    matches the query. The default is false.
+     *
+     *  * writeConcern (MongoDB\Driver\WriteConcern): Write concern.
+     *
+     * @param string       $databaseName   Database name
+     * @param string       $collectionName Collection name
+     * @param array|object $filter         Query by which to filter documents
+     * @param array|object $update         Update to apply to the matched document
+     * @param array        $options        Command options
+     * @throws InvalidArgumentException for parameter/option parsing errors
+     */
+    public function __construct($databaseName, $collectionName, $filter, $update, array $options = [])
+    {
+        if (! is_array($update) && ! is_object($update)) {
+            throw InvalidArgumentException::invalidType('$update', $update, 'array or object');
+        }
+
+        if (! is_first_key_operator($update) && ! is_pipeline($update)) {
+            throw new InvalidArgumentException('Expected an update document with operator as first key or a pipeline');
+        }
+
+        $this->update = new Update(
+            $databaseName,
+            $collectionName,
+            $filter,
+            $update,
+            ['multi' => false] + $options
+        );
+    }
+
+    /**
+     * Execute the operation.
+     *
+     * @see Executable::execute()
+     * @param Server $server
+     * @return UpdateResult
+     * @throws UnsupportedException if collation is used and unsupported
+     * @throws DriverRuntimeException for other driver errors (e.g. connection errors)
+     */
+    public function execute(Server $server)
+    {
+        return $this->update->execute($server);
+    }
+
+    public function getCommandDocument(Server $server)
+    {
+        return $this->update->getCommandDocument($server);
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/Watch.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/Watch.php
new file mode 100644
index 0000000000000000000000000000000000000000..1c88b87beb4f8b795c139ef44efea7cf7fef4502
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/Watch.php	
@@ -0,0 +1,442 @@
+<?php
+/*
+ * Copyright 2017 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace MongoDB\Operation;
+
+use MongoDB\BSON\TimestampInterface;
+use MongoDB\ChangeStream;
+use MongoDB\Driver\Cursor;
+use MongoDB\Driver\Exception\RuntimeException;
+use MongoDB\Driver\Manager;
+use MongoDB\Driver\Monitoring\CommandFailedEvent;
+use MongoDB\Driver\Monitoring\CommandStartedEvent;
+use MongoDB\Driver\Monitoring\CommandSubscriber;
+use MongoDB\Driver\Monitoring\CommandSucceededEvent;
+use MongoDB\Driver\ReadPreference;
+use MongoDB\Driver\Server;
+use MongoDB\Exception\InvalidArgumentException;
+use MongoDB\Exception\UnexpectedValueException;
+use MongoDB\Exception\UnsupportedException;
+use MongoDB\Model\ChangeStreamIterator;
+use function array_intersect_key;
+use function array_unshift;
+use function count;
+use function is_array;
+use function is_object;
+use function is_string;
+use function MongoDB\Driver\Monitoring\addSubscriber;
+use function MongoDB\Driver\Monitoring\removeSubscriber;
+use function MongoDB\select_server;
+use function MongoDB\server_supports_feature;
+
+/**
+ * Operation for creating a change stream with the aggregate command.
+ *
+ * Note: the implementation of CommandSubscriber is an internal implementation
+ * detail and should not be considered part of the public API.
+ *
+ * @api
+ * @see \MongoDB\Collection::watch()
+ * @see https://docs.mongodb.com/manual/changeStreams/
+ */
+class Watch implements Executable, /* @internal */ CommandSubscriber
+{
+    const FULL_DOCUMENT_DEFAULT = 'default';
+    const FULL_DOCUMENT_UPDATE_LOOKUP = 'updateLookup';
+
+    /** @var integer */
+    private static $wireVersionForStartAtOperationTime = 7;
+
+    /** @var Aggregate */
+    private $aggregate;
+
+    /** @var array */
+    private $aggregateOptions;
+
+    /** @var array */
+    private $changeStreamOptions;
+
+    /** @var string|null */
+    private $collectionName;
+
+    /** @var string */
+    private $databaseName;
+
+    /** @var integer|null */
+    private $firstBatchSize;
+
+    /** @var boolean */
+    private $hasResumed = false;
+
+    /** @var Manager */
+    private $manager;
+
+    /** @var TimestampInterface */
+    private $operationTime;
+
+    /** @var array */
+    private $pipeline;
+
+    /** @var object|null */
+    private $postBatchResumeToken;
+
+    /**
+     * Constructs an aggregate command for creating a change stream.
+     *
+     * Supported options:
+     *
+     *  * batchSize (integer): The number of documents to return per batch.
+     *
+     *  * collation (document): Specifies a collation.
+     *
+     *  * fullDocument (string): Determines whether the "fullDocument" field
+     *    will be populated for update operations. By default, change streams
+     *    only return the delta of fields during the update operation (via the
+     *    "updateDescription" field). To additionally return the most current
+     *    majority-committed version of the updated document, specify
+     *    "updateLookup" for this option. Defaults to "default".
+     *
+     *    Insert and replace operations always include the "fullDocument" field
+     *    and delete operations omit the field as the document no longer exists.
+     *
+     *  * maxAwaitTimeMS (integer): The maximum amount of time for the server to
+     *    wait on new documents to satisfy a change stream query.
+     *
+     *  * readConcern (MongoDB\Driver\ReadConcern): Read concern.
+     *
+     *  * readPreference (MongoDB\Driver\ReadPreference): Read preference. This
+     *    will be used to select a new server when resuming. Defaults to a
+     *    "primary" read preference.
+     *
+     *  * resumeAfter (document): Specifies the logical starting point for the
+     *    new change stream.
+     *
+     *    Using this option in conjunction with "startAfter" and/or
+     *    "startAtOperationTime" will result in a server error. The options are
+     *    mutually exclusive.
+     *
+     *  * session (MongoDB\Driver\Session): Client session.
+     *
+     *    Sessions are not supported for server versions < 3.6.
+     *
+     *  * startAfter (document): Specifies the logical starting point for the
+     *    new change stream. Unlike "resumeAfter", this option can be used with
+     *    a resume token from an "invalidate" event.
+     *
+     *    Using this option in conjunction with "resumeAfter" and/or
+     *    "startAtOperationTime" will result in a server error. The options are
+     *    mutually exclusive.
+     *
+     *  * startAtOperationTime (MongoDB\BSON\TimestampInterface): If specified,
+     *    the change stream will only provide changes that occurred at or after
+     *    the specified timestamp. Any command run against the server will
+     *    return an operation time that can be used here. Alternatively, an
+     *    operation time may be obtained from MongoDB\Driver\Server::getInfo().
+     *
+     *    Using this option in conjunction with "resumeAfter" and/or
+     *    "startAfter" will result in a server error. The options are mutually
+     *    exclusive.
+     *
+     *    This option is not supported for server versions < 4.0.
+     *
+     *  * typeMap (array): Type map for BSON deserialization. This will be
+     *    applied to the returned Cursor (it is not sent to the server).
+     *
+     * Note: A database-level change stream may be created by specifying null
+     * for the collection name. A cluster-level change stream may be created by
+     * specifying null for both the database and collection name.
+     *
+     * @param Manager     $manager        Manager instance from the driver
+     * @param string|null $databaseName   Database name
+     * @param string|null $collectionName Collection name
+     * @param array       $pipeline       List of pipeline operations
+     * @param array       $options        Command options
+     * @throws InvalidArgumentException for parameter/option parsing errors
+     */
+    public function __construct(Manager $manager, $databaseName, $collectionName, array $pipeline, array $options = [])
+    {
+        if (isset($collectionName) && ! isset($databaseName)) {
+            throw new InvalidArgumentException('$collectionName should also be null if $databaseName is null');
+        }
+
+        $options += [
+            'fullDocument' => self::FULL_DOCUMENT_DEFAULT,
+            'readPreference' => new ReadPreference(ReadPreference::RP_PRIMARY),
+        ];
+
+        if (! is_string($options['fullDocument'])) {
+            throw InvalidArgumentException::invalidType('"fullDocument" option', $options['fullDocument'], 'string');
+        }
+
+        if (! $options['readPreference'] instanceof ReadPreference) {
+            throw InvalidArgumentException::invalidType('"readPreference" option', $options['readPreference'], ReadPreference::class);
+        }
+
+        if (isset($options['resumeAfter']) && ! is_array($options['resumeAfter']) && ! is_object($options['resumeAfter'])) {
+            throw InvalidArgumentException::invalidType('"resumeAfter" option', $options['resumeAfter'], 'array or object');
+        }
+
+        if (isset($options['startAfter']) && ! is_array($options['startAfter']) && ! is_object($options['startAfter'])) {
+            throw InvalidArgumentException::invalidType('"startAfter" option', $options['startAfter'], 'array or object');
+        }
+
+        if (isset($options['startAtOperationTime']) && ! $options['startAtOperationTime'] instanceof TimestampInterface) {
+            throw InvalidArgumentException::invalidType('"startAtOperationTime" option', $options['startAtOperationTime'], TimestampInterface::class);
+        }
+
+        /* In the absence of an explicit session, create one to ensure that the
+         * initial aggregation and any resume attempts can use the same session
+         * ("implicit from the user's perspective" per PHPLIB-342). Since this
+         * is filling in for an implicit session, we default "causalConsistency"
+         * to false. */
+        if (! isset($options['session'])) {
+            try {
+                $options['session'] = $manager->startSession(['causalConsistency' => false]);
+            } catch (RuntimeException $e) {
+                /* We can ignore the exception, as libmongoc likely cannot
+                 * create its own session and there is no risk of a mismatch. */
+            }
+        }
+
+        $this->aggregateOptions = array_intersect_key($options, ['batchSize' => 1, 'collation' => 1, 'maxAwaitTimeMS' => 1, 'readConcern' => 1, 'readPreference' => 1, 'session' => 1, 'typeMap' => 1]);
+        $this->changeStreamOptions = array_intersect_key($options, ['fullDocument' => 1, 'resumeAfter' => 1, 'startAfter' => 1, 'startAtOperationTime' => 1]);
+
+        // Null database name implies a cluster-wide change stream
+        if ($databaseName === null) {
+            $databaseName = 'admin';
+            $this->changeStreamOptions['allChangesForCluster'] = true;
+        }
+
+        $this->manager = $manager;
+        $this->databaseName = (string) $databaseName;
+        $this->collectionName = isset($collectionName) ? (string) $collectionName : null;
+        $this->pipeline = $pipeline;
+
+        $this->aggregate = $this->createAggregate();
+    }
+
+    /** @internal */
+    final public function commandFailed(CommandFailedEvent $event)
+    {
+    }
+
+    /** @internal */
+    final public function commandStarted(CommandStartedEvent $event)
+    {
+        if ($event->getCommandName() !== 'aggregate') {
+            return;
+        }
+
+        $this->firstBatchSize = null;
+        $this->postBatchResumeToken = null;
+    }
+
+    /** @internal */
+    final public function commandSucceeded(CommandSucceededEvent $event)
+    {
+        if ($event->getCommandName() !== 'aggregate') {
+            return;
+        }
+
+        $reply = $event->getReply();
+
+        if (! isset($reply->cursor->firstBatch) || ! is_array($reply->cursor->firstBatch)) {
+            throw new UnexpectedValueException('aggregate command did not return a "cursor.firstBatch" array');
+        }
+
+        $this->firstBatchSize = count($reply->cursor->firstBatch);
+
+        if (isset($reply->cursor->postBatchResumeToken) && is_object($reply->cursor->postBatchResumeToken)) {
+            $this->postBatchResumeToken = $reply->cursor->postBatchResumeToken;
+        }
+
+        if ($this->shouldCaptureOperationTime($event->getServer()) &&
+            isset($reply->operationTime) && $reply->operationTime instanceof TimestampInterface) {
+            $this->operationTime = $reply->operationTime;
+        }
+    }
+
+    /**
+     * Execute the operation.
+     *
+     * @see Executable::execute()
+     * @param Server $server
+     * @return ChangeStream
+     * @throws UnsupportedException if collation or read concern is used and unsupported
+     * @throws RuntimeException for other driver errors (e.g. connection errors)
+     */
+    public function execute(Server $server)
+    {
+        return new ChangeStream(
+            $this->createChangeStreamIterator($server),
+            function ($resumeToken, $hasAdvanced) {
+                return $this->resume($resumeToken, $hasAdvanced);
+            }
+        );
+    }
+
+    /**
+     * Create the aggregate command for a change stream.
+     *
+     * This method is also used to recreate the aggregate command when resuming.
+     *
+     * @return Aggregate
+     */
+    private function createAggregate()
+    {
+        $pipeline = $this->pipeline;
+        array_unshift($pipeline, ['$changeStream' => (object) $this->changeStreamOptions]);
+
+        return new Aggregate($this->databaseName, $this->collectionName, $pipeline, $this->aggregateOptions);
+    }
+
+    /**
+     * Create a ChangeStreamIterator by executing the aggregate command.
+     *
+     * @param Server $server
+     * @return ChangeStreamIterator
+     */
+    private function createChangeStreamIterator(Server $server)
+    {
+        return new ChangeStreamIterator(
+            $this->executeAggregate($server),
+            $this->firstBatchSize,
+            $this->getInitialResumeToken(),
+            $this->postBatchResumeToken
+        );
+    }
+
+    /**
+     * Execute the aggregate command.
+     *
+     * The command will be executed using APM so that we can capture data from
+     * its response (e.g. firstBatch size, postBatchResumeToken).
+     *
+     * @param Server $server
+     * @return Cursor
+     */
+    private function executeAggregate(Server $server)
+    {
+        addSubscriber($this);
+
+        try {
+            return $this->aggregate->execute($server);
+        } finally {
+            removeSubscriber($this);
+        }
+    }
+
+    /**
+     * Return the initial resume token for creating the ChangeStreamIterator.
+     *
+     * @see https://github.com/mongodb/specifications/blob/master/source/change-streams/change-streams.rst#updating-the-cached-resume-token
+     * @return array|object|null
+     */
+    private function getInitialResumeToken()
+    {
+        if ($this->firstBatchSize === 0 && isset($this->postBatchResumeToken)) {
+            return $this->postBatchResumeToken;
+        }
+
+        if (isset($this->changeStreamOptions['startAfter'])) {
+            return $this->changeStreamOptions['startAfter'];
+        }
+
+        if (isset($this->changeStreamOptions['resumeAfter'])) {
+            return $this->changeStreamOptions['resumeAfter'];
+        }
+
+        return null;
+    }
+
+    /**
+     * Resumes a change stream.
+     *
+     * @see https://github.com/mongodb/specifications/blob/master/source/change-streams/change-streams.rst#resume-process
+     * @param array|object|null $resumeToken
+     * @param bool              $hasAdvanced
+     * @return ChangeStreamIterator
+     * @throws InvalidArgumentException
+     */
+    private function resume($resumeToken = null, $hasAdvanced = false)
+    {
+        if (isset($resumeToken) && ! is_array($resumeToken) && ! is_object($resumeToken)) {
+            throw InvalidArgumentException::invalidType('$resumeToken', $resumeToken, 'array or object');
+        }
+
+        $this->hasResumed = true;
+
+        /* Select a new server using the original read preference. While watch
+         * is not usable within transactions, we still check if there is a
+         * pinned session. This is to avoid an ambiguous error message about
+         * running a command on the wrong server. */
+        $server = select_server($this->manager, $this->aggregateOptions);
+
+        $resumeOption = isset($this->changeStreamOptions['startAfter']) && ! $hasAdvanced ? 'startAfter' : 'resumeAfter';
+
+        unset($this->changeStreamOptions['resumeAfter']);
+        unset($this->changeStreamOptions['startAfter']);
+        unset($this->changeStreamOptions['startAtOperationTime']);
+
+        if ($resumeToken !== null) {
+            $this->changeStreamOptions[$resumeOption] = $resumeToken;
+        }
+
+        if ($resumeToken === null && $this->operationTime !== null) {
+            $this->changeStreamOptions['startAtOperationTime'] = $this->operationTime;
+        }
+
+        // Recreate the aggregate command and return a new ChangeStreamIterator
+        $this->aggregate = $this->createAggregate();
+
+        return $this->createChangeStreamIterator($server);
+    }
+
+    /**
+     * Determine whether to capture operation time from an aggregate response.
+     *
+     * @see https://github.com/mongodb/specifications/blob/master/source/change-streams/change-streams.rst#startatoperationtime
+     * @param Server $server
+     * @return boolean
+     */
+    private function shouldCaptureOperationTime(Server $server)
+    {
+        if ($this->hasResumed) {
+            return false;
+        }
+
+        if (isset($this->changeStreamOptions['resumeAfter']) ||
+            isset($this->changeStreamOptions['startAfter']) ||
+            isset($this->changeStreamOptions['startAtOperationTime'])) {
+            return false;
+        }
+
+        if ($this->firstBatchSize > 0) {
+            return false;
+        }
+
+        if ($this->postBatchResumeToken !== null) {
+            return false;
+        }
+
+        if (! server_supports_feature($server, self::$wireVersionForStartAtOperationTime)) {
+            return false;
+        }
+
+        return true;
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/WithTransaction.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/WithTransaction.php
new file mode 100644
index 0000000000000000000000000000000000000000..3d0474e7eadae1958a2aaf9b5115cf7bc11b9a64
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/Operation/WithTransaction.php	
@@ -0,0 +1,128 @@
+<?php
+
+namespace MongoDB\Operation;
+
+use Exception;
+use MongoDB\Driver\Exception\RuntimeException;
+use MongoDB\Driver\Session;
+use Throwable;
+use function call_user_func;
+use function time;
+
+/**
+ * @internal
+ */
+class WithTransaction
+{
+    /** @var callable */
+    private $callback;
+
+    /** @var array */
+    private $transactionOptions;
+
+    /**
+     * @see Session::startTransaction for supported transaction options
+     *
+     * @param callable $callback           A callback that will be invoked within the transaction
+     * @param array    $transactionOptions Additional options that are passed to Session::startTransaction
+     */
+    public function __construct(callable $callback, array $transactionOptions = [])
+    {
+        $this->callback = $callback;
+        $this->transactionOptions = $transactionOptions;
+    }
+
+    /**
+     * Execute the operation in the given session
+     *
+     * This helper takes care of retrying the commit operation or the entire
+     * transaction if an error occurs.
+     *
+     * If the commit fails because of an UnknownTransactionCommitResult error, the
+     * commit is retried without re-invoking the callback.
+     * If the commit fails because of a TransientTransactionError, the entire
+     * transaction will be retried. In this case, the callback will be invoked
+     * again. It is important that the logic inside the callback is idempotent.
+     *
+     * In case of failures, the commit or transaction are retried until 120 seconds
+     * from the initial call have elapsed. After that, no retries will happen and
+     * the helper will throw the last exception received from the driver.
+     *
+     * @see Client::startSession
+     *
+     * @param Session $session A session object as retrieved by Client::startSession
+     * @return void
+     * @throws RuntimeException for driver errors while committing the transaction
+     * @throws Exception for any other errors, including those thrown in the callback
+     */
+    public function execute(Session $session)
+    {
+        $startTime = time();
+
+        while (true) {
+            $session->startTransaction($this->transactionOptions);
+
+            try {
+                call_user_func($this->callback, $session);
+            } catch (Throwable $e) {
+                if ($session->isInTransaction()) {
+                    $session->abortTransaction();
+                }
+
+                if ($e instanceof RuntimeException &&
+                    $e->hasErrorLabel('TransientTransactionError') &&
+                    ! $this->isTransactionTimeLimitExceeded($startTime)
+                ) {
+                    continue;
+                }
+
+                throw $e;
+            }
+
+            if (! $session->isInTransaction()) {
+                // Assume callback intentionally ended the transaction
+                return;
+            }
+
+            while (true) {
+                try {
+                    $session->commitTransaction();
+                } catch (RuntimeException $e) {
+                    if ($e->getCode() !== 50 /* MaxTimeMSExpired */ &&
+                        $e->hasErrorLabel('UnknownTransactionCommitResult') &&
+                        ! $this->isTransactionTimeLimitExceeded($startTime)
+                    ) {
+                        // Retry committing the transaction
+                        continue;
+                    }
+
+                    if ($e->hasErrorLabel('TransientTransactionError') &&
+                        ! $this->isTransactionTimeLimitExceeded($startTime)
+                    ) {
+                        // Restart the transaction, invoking the callback again
+                        continue 2;
+                    }
+
+                    throw $e;
+                }
+
+                // Commit was successful
+                break;
+            }
+
+            // Transaction was successful
+            break;
+        }
+    }
+
+    /**
+     * Returns whether the time limit for retrying transactions in the convenient transaction API has passed
+     *
+     * @param int $startTime The time the transaction was started
+     * @return bool
+     */
+    private function isTransactionTimeLimitExceeded($startTime)
+    {
+        return time() - $startTime >= 120;
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/UpdateResult.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/UpdateResult.php
new file mode 100644
index 0000000000000000000000000000000000000000..62660d2cadeee943fe7c96dbd732033d87a1b71b
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/UpdateResult.php	
@@ -0,0 +1,138 @@
+<?php
+/*
+ * Copyright 2015-2017 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace MongoDB;
+
+use MongoDB\Driver\WriteResult;
+use MongoDB\Exception\BadMethodCallException;
+
+/**
+ * Result class for an update operation.
+ */
+class UpdateResult
+{
+    /** @var WriteResult */
+    private $writeResult;
+
+    /** @var boolean */
+    private $isAcknowledged;
+
+    public function __construct(WriteResult $writeResult)
+    {
+        $this->writeResult = $writeResult;
+        $this->isAcknowledged = $writeResult->isAcknowledged();
+    }
+
+    /**
+     * Return the number of documents that were matched by the filter.
+     *
+     * This method should only be called if the write was acknowledged.
+     *
+     * @see UpdateResult::isAcknowledged()
+     * @return integer
+     * @throws BadMethodCallException is the write result is unacknowledged
+     */
+    public function getMatchedCount()
+    {
+        if ($this->isAcknowledged) {
+            return $this->writeResult->getMatchedCount();
+        }
+
+        throw BadMethodCallException::unacknowledgedWriteResultAccess(__METHOD__);
+    }
+
+    /**
+     * Return the number of documents that were modified.
+     *
+     * This value is undefined (i.e. null) if the write executed as a legacy
+     * operation instead of command.
+     *
+     * This method should only be called if the write was acknowledged.
+     *
+     * @see UpdateResult::isAcknowledged()
+     * @return integer|null
+     * @throws BadMethodCallException is the write result is unacknowledged
+     */
+    public function getModifiedCount()
+    {
+        if ($this->isAcknowledged) {
+            return $this->writeResult->getModifiedCount();
+        }
+
+        throw BadMethodCallException::unacknowledgedWriteResultAccess(__METHOD__);
+    }
+
+    /**
+     * Return the number of documents that were upserted.
+     *
+     * This method should only be called if the write was acknowledged.
+     *
+     * @see UpdateResult::isAcknowledged()
+     * @return integer
+     * @throws BadMethodCallException is the write result is unacknowledged
+     */
+    public function getUpsertedCount()
+    {
+        if ($this->isAcknowledged) {
+            return $this->writeResult->getUpsertedCount();
+        }
+
+        throw BadMethodCallException::unacknowledgedWriteResultAccess(__METHOD__);
+    }
+
+    /**
+     * Return the ID of the document inserted by an upsert operation.
+     *
+     * If the document had an ID prior to upserting (i.e. the server did not
+     * need to generate an ID), this will contain its "_id". Any
+     * server-generated ID will be a MongoDB\BSON\ObjectId instance.
+     *
+     * This value is undefined (i.e. null) if an upsert did not take place.
+     *
+     * This method should only be called if the write was acknowledged.
+     *
+     * @see UpdateResult::isAcknowledged()
+     * @return mixed|null
+     * @throws BadMethodCallException is the write result is unacknowledged
+     */
+    public function getUpsertedId()
+    {
+        if ($this->isAcknowledged) {
+            foreach ($this->writeResult->getUpsertedIds() as $id) {
+                return $id;
+            }
+
+            return null;
+        }
+
+        throw BadMethodCallException::unacknowledgedWriteResultAccess(__METHOD__);
+    }
+
+    /**
+     * Return whether this update was acknowledged by the server.
+     *
+     * If the update was not acknowledged, other fields from the WriteResult
+     * (e.g. matchedCount) will be undefined and their getter methods should not
+     * be invoked.
+     *
+     * @return boolean
+     */
+    public function isAcknowledged()
+    {
+        return $this->isAcknowledged;
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/functions.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/functions.php
new file mode 100644
index 0000000000000000000000000000000000000000..e828e669a4bc69036359511757abbbbb8d213fdb
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/src/functions.php	
@@ -0,0 +1,432 @@
+<?php
+/*
+ * Copyright 2015-2017 MongoDB, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace MongoDB;
+
+use Exception;
+use MongoDB\BSON\Serializable;
+use MongoDB\Driver\Manager;
+use MongoDB\Driver\ReadPreference;
+use MongoDB\Driver\Server;
+use MongoDB\Driver\Session;
+use MongoDB\Exception\InvalidArgumentException;
+use MongoDB\Exception\RuntimeException;
+use MongoDB\Operation\WithTransaction;
+use ReflectionClass;
+use ReflectionException;
+use function end;
+use function get_object_vars;
+use function in_array;
+use function is_array;
+use function is_object;
+use function is_string;
+use function key;
+use function MongoDB\BSON\fromPHP;
+use function MongoDB\BSON\toPHP;
+use function reset;
+use function substr;
+
+/**
+ * Applies a type map to a document.
+ *
+ * This function is used by operations where it is not possible to apply a type
+ * map to the cursor directly because the root document is a command response
+ * (e.g. findAndModify).
+ *
+ * @internal
+ * @param array|object $document Document to which the type map will be applied
+ * @param array        $typeMap  Type map for BSON deserialization.
+ * @return array|object
+ * @throws InvalidArgumentException
+ */
+function apply_type_map_to_document($document, array $typeMap)
+{
+    if (! is_array($document) && ! is_object($document)) {
+        throw InvalidArgumentException::invalidType('$document', $document, 'array or object');
+    }
+
+    return toPHP(fromPHP($document), $typeMap);
+}
+
+/**
+ * Generate an index name from a key specification.
+ *
+ * @internal
+ * @param array|object $document Document containing fields mapped to values,
+ *                               which denote order or an index type
+ * @return string
+ * @throws InvalidArgumentException
+ */
+function generate_index_name($document)
+{
+    if ($document instanceof Serializable) {
+        $document = $document->bsonSerialize();
+    }
+
+    if (is_object($document)) {
+        $document = get_object_vars($document);
+    }
+
+    if (! is_array($document)) {
+        throw InvalidArgumentException::invalidType('$document', $document, 'array or object');
+    }
+
+    $name = '';
+
+    foreach ($document as $field => $type) {
+        $name .= ($name != '' ? '_' : '') . $field . '_' . $type;
+    }
+
+    return $name;
+}
+
+/**
+ * Return whether the first key in the document starts with a "$" character.
+ *
+ * This is used for differentiating update and replacement documents.
+ *
+ * @internal
+ * @param array|object $document Update or replacement document
+ * @return boolean
+ * @throws InvalidArgumentException
+ */
+function is_first_key_operator($document)
+{
+    if ($document instanceof Serializable) {
+        $document = $document->bsonSerialize();
+    }
+
+    if (is_object($document)) {
+        $document = get_object_vars($document);
+    }
+
+    if (! is_array($document)) {
+        throw InvalidArgumentException::invalidType('$document', $document, 'array or object');
+    }
+
+    reset($document);
+    $firstKey = (string) key($document);
+
+    return isset($firstKey[0]) && $firstKey[0] === '$';
+}
+
+/**
+ * Returns whether an update specification is a valid aggregation pipeline.
+ *
+ * @internal
+ * @param mixed $pipeline
+ * @return boolean
+ */
+function is_pipeline($pipeline)
+{
+    if (! is_array($pipeline)) {
+        return false;
+    }
+
+    if ($pipeline === []) {
+        return false;
+    }
+
+    $expectedKey = 0;
+
+    foreach ($pipeline as $key => $stage) {
+        if (! is_array($stage) && ! is_object($stage)) {
+            return false;
+        }
+
+        if ($expectedKey !== $key) {
+            return false;
+        }
+
+        $expectedKey++;
+        $stage = (array) $stage;
+        reset($stage);
+        $key = key($stage);
+
+        if (! isset($key[0]) || $key[0] !== '$') {
+            return false;
+        }
+    }
+
+    return true;
+}
+
+/**
+ * Returns whether we are currently in a transaction.
+ *
+ * @internal
+ * @param array $options Command options
+ * @return boolean
+ */
+function is_in_transaction(array $options)
+{
+    if (isset($options['session']) && $options['session'] instanceof Session && $options['session']->isInTransaction()) {
+        return true;
+    }
+
+    return false;
+}
+
+/**
+ * Return whether the aggregation pipeline ends with an $out or $merge operator.
+ *
+ * This is used for determining whether the aggregation pipeline must be
+ * executed against a primary server.
+ *
+ * @internal
+ * @param array $pipeline List of pipeline operations
+ * @return boolean
+ */
+function is_last_pipeline_operator_write(array $pipeline)
+{
+    $lastOp = end($pipeline);
+
+    if ($lastOp === false) {
+        return false;
+    }
+
+    $lastOp = (array) $lastOp;
+
+    return in_array(key($lastOp), ['$out', '$merge'], true);
+}
+
+/**
+ * Return whether the "out" option for a mapReduce operation is "inline".
+ *
+ * This is used to determine if a mapReduce command requires a primary.
+ *
+ * @internal
+ * @see https://docs.mongodb.com/manual/reference/command/mapReduce/#output-inline
+ * @param string|array|object $out Output specification
+ * @return boolean
+ * @throws InvalidArgumentException
+ */
+function is_mapreduce_output_inline($out)
+{
+    if (! is_array($out) && ! is_object($out)) {
+        return false;
+    }
+
+    if ($out instanceof Serializable) {
+        $out = $out->bsonSerialize();
+    }
+
+    if (is_object($out)) {
+        $out = get_object_vars($out);
+    }
+
+    if (! is_array($out)) {
+        throw InvalidArgumentException::invalidType('$out', $out, 'array or object');
+    }
+
+    reset($out);
+
+    return key($out) === 'inline';
+}
+
+/**
+ * Return whether the server supports a particular feature.
+ *
+ * @internal
+ * @param Server  $server  Server to check
+ * @param integer $feature Feature constant (i.e. wire protocol version)
+ * @return boolean
+ */
+function server_supports_feature(Server $server, $feature)
+{
+    $info = $server->getInfo();
+    $maxWireVersion = isset($info['maxWireVersion']) ? (integer) $info['maxWireVersion'] : 0;
+    $minWireVersion = isset($info['minWireVersion']) ? (integer) $info['minWireVersion'] : 0;
+
+    return $minWireVersion <= $feature && $maxWireVersion >= $feature;
+}
+
+function is_string_array($input)
+{
+    if (! is_array($input)) {
+        return false;
+    }
+    foreach ($input as $item) {
+        if (! is_string($item)) {
+            return false;
+        }
+    }
+
+    return true;
+}
+
+/**
+ * Performs a deep copy of a value.
+ *
+ * This function will clone objects and recursively copy values within arrays.
+ *
+ * @internal
+ * @see https://bugs.php.net/bug.php?id=49664
+ * @param mixed $element Value to be copied
+ * @return mixed
+ * @throws ReflectionException
+ */
+function recursive_copy($element)
+{
+    if (is_array($element)) {
+        foreach ($element as $key => $value) {
+            $element[$key] = recursive_copy($value);
+        }
+
+        return $element;
+    }
+
+    if (! is_object($element)) {
+        return $element;
+    }
+
+    if (! (new ReflectionClass($element))->isCloneable()) {
+        return $element;
+    }
+
+    return clone $element;
+}
+
+/**
+ * Creates a type map to apply to a field type
+ *
+ * This is used in the Aggregate, Distinct, and FindAndModify operations to
+ * apply the root-level type map to the document that will be returned. It also
+ * replaces the root type with object for consistency within these operations
+ *
+ * An existing type map for the given field path will not be overwritten
+ *
+ * @internal
+ * @param array  $typeMap   The existing typeMap
+ * @param string $fieldPath The field path to apply the root type to
+ * @return array
+ */
+function create_field_path_type_map(array $typeMap, $fieldPath)
+{
+    // If some field paths already exist, we prefix them with the field path we are assuming as the new root
+    if (isset($typeMap['fieldPaths']) && is_array($typeMap['fieldPaths'])) {
+        $fieldPaths = $typeMap['fieldPaths'];
+
+        $typeMap['fieldPaths'] = [];
+        foreach ($fieldPaths as $existingFieldPath => $type) {
+            $typeMap['fieldPaths'][$fieldPath . '.' . $existingFieldPath] = $type;
+        }
+    }
+
+    // If a root typemap was set, apply this to the field object
+    if (isset($typeMap['root'])) {
+        $typeMap['fieldPaths'][$fieldPath] = $typeMap['root'];
+    }
+
+    /* Special case if we want to convert an array, in which case we need to
+     * ensure that the field containing the array is exposed as an array,
+     * instead of the type given in the type map's array key. */
+    if (substr($fieldPath, -2, 2) === '.$') {
+        $typeMap['fieldPaths'][substr($fieldPath, 0, -2)] = 'array';
+    }
+
+    $typeMap['root'] = 'object';
+
+    return $typeMap;
+}
+
+/**
+ * Execute a callback within a transaction in the given session
+ *
+ * This helper takes care of retrying the commit operation or the entire
+ * transaction if an error occurs.
+ *
+ * If the commit fails because of an UnknownTransactionCommitResult error, the
+ * commit is retried without re-invoking the callback.
+ * If the commit fails because of a TransientTransactionError, the entire
+ * transaction will be retried. In this case, the callback will be invoked
+ * again. It is important that the logic inside the callback is idempotent.
+ *
+ * In case of failures, the commit or transaction are retried until 120 seconds
+ * from the initial call have elapsed. After that, no retries will happen and
+ * the helper will throw the last exception received from the driver.
+ *
+ * @see Client::startSession
+ * @see Session::startTransaction for supported transaction options
+ *
+ * @param Session  $session            A session object as retrieved by Client::startSession
+ * @param callable $callback           A callback that will be invoked within the transaction
+ * @param array    $transactionOptions Additional options that are passed to Session::startTransaction
+ * @return void
+ * @throws RuntimeException for driver errors while committing the transaction
+ * @throws Exception for any other errors, including those thrown in the callback
+ */
+function with_transaction(Session $session, callable $callback, array $transactionOptions = [])
+{
+    $operation = new WithTransaction($callback, $transactionOptions);
+    $operation->execute($session);
+}
+
+/**
+ * Returns the session option if it is set and valid.
+ *
+ * @internal
+ * @param array $options
+ * @return Session|null
+ */
+function extract_session_from_options(array $options)
+{
+    if (! isset($options['session']) || ! $options['session'] instanceof Session) {
+        return null;
+    }
+
+    return $options['session'];
+}
+
+/**
+ * Returns the readPreference option if it is set and valid.
+ *
+ * @internal
+ * @param array $options
+ * @return ReadPreference|null
+ */
+function extract_read_preference_from_options(array $options)
+{
+    if (! isset($options['readPreference']) || ! $options['readPreference'] instanceof ReadPreference) {
+        return null;
+    }
+
+    return $options['readPreference'];
+}
+
+/**
+ * Performs server selection, respecting the readPreference and session options
+ * (if given)
+ *
+ * @internal
+ * @return Server
+ */
+function select_server(Manager $manager, array $options)
+{
+    $session = extract_session_from_options($options);
+    if ($session instanceof Session && $session->getServer() !== null) {
+        return $session->getServer();
+    }
+
+    $readPreference = extract_read_preference_from_options($options);
+    if (! $readPreference instanceof ReadPreference) {
+        // TODO: PHPLIB-476: Read transaction read preference once PHPC-1439 is implemented
+        $readPreference = new ReadPreference(ReadPreference::RP_PRIMARY);
+    }
+
+    return $manager->selectServer($readPreference);
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/ClientFunctionalTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/ClientFunctionalTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..59d71cea9f6fd98a038e3be47cc5bc407bce7573
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/ClientFunctionalTest.php	
@@ -0,0 +1,132 @@
+<?php
+
+namespace MongoDB\Tests;
+
+use MongoDB\Client;
+use MongoDB\Driver\BulkWrite;
+use MongoDB\Driver\Manager;
+use MongoDB\Driver\Session;
+use MongoDB\Model\DatabaseInfo;
+use MongoDB\Model\DatabaseInfoIterator;
+use Symfony\Bridge\PhpUnit\SetUpTearDownTrait;
+use function call_user_func;
+use function is_callable;
+use function sprintf;
+use function version_compare;
+
+/**
+ * Functional tests for the Client class.
+ */
+class ClientFunctionalTest extends FunctionalTestCase
+{
+    use SetUpTearDownTrait;
+
+    /** @var Client */
+    private $client;
+
+    private function doSetUp()
+    {
+        parent::setUp();
+
+        $this->client = new Client(static::getUri());
+        $this->client->dropDatabase($this->getDatabaseName());
+    }
+
+    public function testGetManager()
+    {
+        $this->assertInstanceOf(Manager::class, $this->client->getManager());
+    }
+
+    public function testDropDatabase()
+    {
+        $bulkWrite = new BulkWrite();
+        $bulkWrite->insert(['x' => 1]);
+
+        $writeResult = $this->manager->executeBulkWrite($this->getNamespace(), $bulkWrite);
+        $this->assertEquals(1, $writeResult->getInsertedCount());
+
+        $commandResult = $this->client->dropDatabase($this->getDatabaseName());
+        $this->assertCommandSucceeded($commandResult);
+        $this->assertCollectionCount($this->getNamespace(), 0);
+    }
+
+    public function testListDatabases()
+    {
+        $bulkWrite = new BulkWrite();
+        $bulkWrite->insert(['x' => 1]);
+
+        $writeResult = $this->manager->executeBulkWrite($this->getNamespace(), $bulkWrite);
+        $this->assertEquals(1, $writeResult->getInsertedCount());
+
+        $databases = $this->client->listDatabases();
+
+        $this->assertInstanceOf(DatabaseInfoIterator::class, $databases);
+
+        foreach ($databases as $database) {
+            $this->assertInstanceOf(DatabaseInfo::class, $database);
+        }
+
+        $this->assertDatabaseExists($this->getDatabaseName(), function (DatabaseInfo $info) {
+            $this->assertFalse($info->isEmpty());
+            $this->assertGreaterThan(0, $info->getSizeOnDisk());
+        });
+    }
+
+    public function testListDatabaseNames()
+    {
+        $bulkWrite = new BulkWrite();
+        $bulkWrite->insert(['x' => 1]);
+
+        $writeResult = $this->manager->executeBulkWrite($this->getNamespace(), $bulkWrite);
+        $this->assertEquals(1, $writeResult->getInsertedCount());
+
+        foreach ($this->client->listDatabaseNames() as $database) {
+            $this->assertIsString($database);
+        }
+
+        $this->assertContains($this->getDatabaseName(), $this->client->listDatabaseNames(), sprintf('Database %s does not exist on the server', $this->getDatabaseName()));
+    }
+
+    /**
+     * Asserts that a database with the given name exists on the server.
+     *
+     * An optional $callback may be provided, which should take a DatabaseInfo
+     * argument as its first and only parameter. If a DatabaseInfo matching
+     * the given name is found, it will be passed to the callback, which may
+     * perform additional assertions.
+     *
+     * @param string   $databaseName
+     * @param callable $callback
+     */
+    private function assertDatabaseExists($databaseName, $callback = null)
+    {
+        if ($callback !== null && ! is_callable($callback)) {
+            throw new InvalidArgumentException('$callback is not a callable');
+        }
+
+        $databases = $this->client->listDatabases();
+
+        $foundDatabase = null;
+
+        foreach ($databases as $database) {
+            if ($database->getName() === $databaseName) {
+                $foundDatabase = $database;
+                break;
+            }
+        }
+
+        $this->assertNotNull($foundDatabase, sprintf('Database %s does not exist on the server', $databaseName));
+
+        if ($callback !== null) {
+            call_user_func($callback, $foundDatabase);
+        }
+    }
+
+    public function testStartSession()
+    {
+        if (version_compare($this->getFeatureCompatibilityVersion(), '3.6', '<')) {
+            $this->markTestSkipped('startSession() is only supported on FCV 3.6 or higher');
+        }
+        $this->assertInstanceOf(Session::class, $this->client->startSession());
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/ClientTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/ClientTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..55d3a13a559c474e25d082df0a604863a7175bb2
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/ClientTest.php	
@@ -0,0 +1,244 @@
+<?php
+
+namespace MongoDB\Tests;
+
+use MongoDB\Client;
+use MongoDB\Driver\ClientEncryption;
+use MongoDB\Driver\Exception\InvalidArgumentException as DriverInvalidArgumentException;
+use MongoDB\Driver\ReadConcern;
+use MongoDB\Driver\ReadPreference;
+use MongoDB\Driver\WriteConcern;
+use MongoDB\Exception\InvalidArgumentException;
+
+/**
+ * Unit tests for the Client class.
+ */
+class ClientTest extends TestCase
+{
+    public function testConstructorDefaultUri()
+    {
+        $client = new Client();
+
+        $this->assertEquals('mongodb://127.0.0.1/', (string) $client);
+    }
+
+    /**
+     * @doesNotPerformAssertions
+     */
+    public function testConstructorAutoEncryptionOpts()
+    {
+        $autoEncryptionOpts = [
+            'keyVaultClient' => new Client(static::getUri()),
+            'keyVaultNamespace' => 'default.keys',
+            'kmsProviders' => ['aws' => ['accessKeyId' => 'abc', 'secretAccessKey' => 'def']],
+        ];
+
+        new Client(static::getUri(), [], ['autoEncryption' => $autoEncryptionOpts]);
+    }
+
+    /**
+     * @dataProvider provideInvalidConstructorDriverOptions
+     */
+    public function testConstructorDriverOptionTypeChecks(array $driverOptions, string $exception = InvalidArgumentException::class)
+    {
+        $this->expectException($exception);
+        new Client(static::getUri(), [], $driverOptions);
+    }
+
+    public function provideInvalidConstructorDriverOptions()
+    {
+        $options = [];
+
+        foreach ($this->getInvalidArrayValues(true) as $value) {
+            $options[][] = ['typeMap' => $value];
+        }
+
+        $options[][] = ['autoEncryption' => ['keyVaultClient' => 'foo']];
+
+        foreach ($this->getInvalidStringValues() as $value) {
+            $options[][] = ['driver' => ['name' => $value]];
+        }
+
+        foreach ($this->getInvalidStringValues() as $value) {
+            $options[][] = ['driver' => ['version' => $value]];
+        }
+
+        foreach ($this->getInvalidStringValues() as $value) {
+            $options[] = [
+                'driverOptions' => ['driver' => ['platform' => $value]],
+                'exception' => DriverInvalidArgumentException::class,
+            ];
+        }
+
+        return $options;
+    }
+
+    public function testToString()
+    {
+        $client = new Client(static::getUri());
+
+        $this->assertSame(static::getUri(), (string) $client);
+    }
+
+    public function testSelectCollectionInheritsOptions()
+    {
+        $uriOptions = [
+            'readConcernLevel' => ReadConcern::LOCAL,
+            'readPreference' => 'secondaryPreferred',
+            'w' => WriteConcern::MAJORITY,
+        ];
+
+        $driverOptions = [
+            'typeMap' => ['root' => 'array'],
+        ];
+
+        $client = new Client(static::getUri(), $uriOptions, $driverOptions);
+        $collection = $client->selectCollection($this->getDatabaseName(), $this->getCollectionName());
+        $debug = $collection->__debugInfo();
+
+        $this->assertInstanceOf(ReadConcern::class, $debug['readConcern']);
+        $this->assertSame(ReadConcern::LOCAL, $debug['readConcern']->getLevel());
+        $this->assertInstanceOf(ReadPreference::class, $debug['readPreference']);
+        $this->assertSame(ReadPreference::RP_SECONDARY_PREFERRED, $debug['readPreference']->getMode());
+        $this->assertIsArray($debug['typeMap']);
+        $this->assertSame(['root' => 'array'], $debug['typeMap']);
+        $this->assertInstanceOf(WriteConcern::class, $debug['writeConcern']);
+        $this->assertSame(WriteConcern::MAJORITY, $debug['writeConcern']->getW());
+    }
+
+    public function testSelectCollectionPassesOptions()
+    {
+        $collectionOptions = [
+            'readConcern' => new ReadConcern(ReadConcern::LOCAL),
+            'readPreference' => new ReadPreference(ReadPreference::RP_SECONDARY_PREFERRED),
+            'typeMap' => ['root' => 'array'],
+            'writeConcern' => new WriteConcern(WriteConcern::MAJORITY),
+        ];
+
+        $client = new Client(static::getUri());
+        $collection = $client->selectCollection($this->getDatabaseName(), $this->getCollectionName(), $collectionOptions);
+        $debug = $collection->__debugInfo();
+
+        $this->assertInstanceOf(ReadConcern::class, $debug['readConcern']);
+        $this->assertSame(ReadConcern::LOCAL, $debug['readConcern']->getLevel());
+        $this->assertInstanceOf(ReadPreference::class, $debug['readPreference']);
+        $this->assertSame(ReadPreference::RP_SECONDARY_PREFERRED, $debug['readPreference']->getMode());
+        $this->assertIsArray($debug['typeMap']);
+        $this->assertSame(['root' => 'array'], $debug['typeMap']);
+        $this->assertInstanceOf(WriteConcern::class, $debug['writeConcern']);
+        $this->assertSame(WriteConcern::MAJORITY, $debug['writeConcern']->getW());
+    }
+
+    public function testGetSelectsDatabaseAndInheritsOptions()
+    {
+        $uriOptions = ['w' => WriteConcern::MAJORITY];
+
+        $client = new Client(static::getUri(), $uriOptions);
+        $database = $client->{$this->getDatabaseName()};
+        $debug = $database->__debugInfo();
+
+        $this->assertSame($this->getDatabaseName(), $debug['databaseName']);
+        $this->assertInstanceOf(WriteConcern::class, $debug['writeConcern']);
+        $this->assertSame(WriteConcern::MAJORITY, $debug['writeConcern']->getW());
+    }
+
+    public function testSelectDatabaseInheritsOptions()
+    {
+        $uriOptions = [
+            'readConcernLevel' => ReadConcern::LOCAL,
+            'readPreference' => 'secondaryPreferred',
+            'w' => WriteConcern::MAJORITY,
+        ];
+
+        $driverOptions = [
+            'typeMap' => ['root' => 'array'],
+        ];
+
+        $client = new Client(static::getUri(), $uriOptions, $driverOptions);
+        $database = $client->selectDatabase($this->getDatabaseName());
+        $debug = $database->__debugInfo();
+
+        $this->assertInstanceOf(ReadConcern::class, $debug['readConcern']);
+        $this->assertSame(ReadConcern::LOCAL, $debug['readConcern']->getLevel());
+        $this->assertInstanceOf(ReadPreference::class, $debug['readPreference']);
+        $this->assertSame(ReadPreference::RP_SECONDARY_PREFERRED, $debug['readPreference']->getMode());
+        $this->assertIsArray($debug['typeMap']);
+        $this->assertSame(['root' => 'array'], $debug['typeMap']);
+        $this->assertInstanceOf(WriteConcern::class, $debug['writeConcern']);
+        $this->assertSame(WriteConcern::MAJORITY, $debug['writeConcern']->getW());
+    }
+
+    public function testSelectDatabasePassesOptions()
+    {
+        $databaseOptions = [
+            'readConcern' => new ReadConcern(ReadConcern::LOCAL),
+            'readPreference' => new ReadPreference(ReadPreference::RP_SECONDARY_PREFERRED),
+            'typeMap' => ['root' => 'array'],
+            'writeConcern' => new WriteConcern(WriteConcern::MAJORITY),
+        ];
+
+        $client = new Client(static::getUri());
+        $database = $client->selectDatabase($this->getDatabaseName(), $databaseOptions);
+        $debug = $database->__debugInfo();
+
+        $this->assertInstanceOf(ReadConcern::class, $debug['readConcern']);
+        $this->assertSame(ReadConcern::LOCAL, $debug['readConcern']->getLevel());
+        $this->assertInstanceOf(ReadPreference::class, $debug['readPreference']);
+        $this->assertSame(ReadPreference::RP_SECONDARY_PREFERRED, $debug['readPreference']->getMode());
+        $this->assertIsArray($debug['typeMap']);
+        $this->assertSame(['root' => 'array'], $debug['typeMap']);
+        $this->assertInstanceOf(WriteConcern::class, $debug['writeConcern']);
+        $this->assertSame(WriteConcern::MAJORITY, $debug['writeConcern']->getW());
+    }
+
+    public function testCreateClientEncryption()
+    {
+        $client = new Client(static::getUri());
+
+        $options = [
+            'keyVaultNamespace' => 'default.keys',
+            'kmsProviders' => ['aws' => ['accessKeyId' => 'abc', 'secretAccessKey' => 'def']],
+        ];
+
+        $clientEncryption = $client->createClientEncryption($options);
+        $this->assertInstanceOf(ClientEncryption::class, $clientEncryption);
+    }
+
+    public function testCreateClientEncryptionWithKeyVaultClient()
+    {
+        $client = new Client(static::getUri());
+
+        $options = [
+            'keyVaultClient' => $client,
+            'keyVaultNamespace' => 'default.keys',
+            'kmsProviders' => ['aws' => ['accessKeyId' => 'abc', 'secretAccessKey' => 'def']],
+        ];
+
+        $clientEncryption = $client->createClientEncryption($options);
+        $this->assertInstanceOf(ClientEncryption::class, $clientEncryption);
+    }
+
+    public function testCreateClientEncryptionWithManager()
+    {
+        $client = new Client(static::getUri());
+
+        $options = [
+            'keyVaultClient' => $client->getManager(),
+            'keyVaultNamespace' => 'default.keys',
+            'kmsProviders' => ['aws' => ['accessKeyId' => 'abc', 'secretAccessKey' => 'def']],
+        ];
+
+        $clientEncryption = $client->createClientEncryption($options);
+        $this->assertInstanceOf(ClientEncryption::class, $clientEncryption);
+    }
+
+    public function testCreateClientEncryptionWithInvalidKeyVaultClient()
+    {
+        $client = new Client(static::getUri());
+
+        $this->expectException(InvalidArgumentException::class);
+        $this->expectExceptionMessage('Expected "keyVaultClient" option to have type "MongoDB\Client" or "MongoDB\Driver\Manager" but found "string"');
+
+        $client->createClientEncryption(['keyVaultClient' => 'foo']);
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/CollectionFunctionalTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/CollectionFunctionalTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..66b20a65a5b03547cef62a6b4cc670bdddd5fb40
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/CollectionFunctionalTest.php	
@@ -0,0 +1,776 @@
+<?php
+
+namespace MongoDB\Tests\Collection;
+
+use Closure;
+use MongoDB\BSON\Javascript;
+use MongoDB\Collection;
+use MongoDB\Driver\BulkWrite;
+use MongoDB\Driver\ReadConcern;
+use MongoDB\Driver\ReadPreference;
+use MongoDB\Driver\WriteConcern;
+use MongoDB\Exception\InvalidArgumentException;
+use MongoDB\Exception\UnsupportedException;
+use MongoDB\MapReduceResult;
+use MongoDB\Operation\Count;
+use MongoDB\Tests\CommandObserver;
+use function array_filter;
+use function call_user_func;
+use function is_scalar;
+use function json_encode;
+use function strchr;
+use function usort;
+use function version_compare;
+
+/**
+ * Functional tests for the Collection class.
+ */
+class CollectionFunctionalTest extends FunctionalTestCase
+{
+    /**
+     * @dataProvider provideInvalidDatabaseAndCollectionNames
+     */
+    public function testConstructorDatabaseNameArgument($databaseName)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        // TODO: Move to unit test once ManagerInterface can be mocked (PHPC-378)
+        new Collection($this->manager, $databaseName, $this->getCollectionName());
+    }
+
+    /**
+     * @dataProvider provideInvalidDatabaseAndCollectionNames
+     */
+    public function testConstructorCollectionNameArgument($collectionName)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        // TODO: Move to unit test once ManagerInterface can be mocked (PHPC-378)
+        new Collection($this->manager, $this->getDatabaseName(), $collectionName);
+    }
+
+    public function provideInvalidDatabaseAndCollectionNames()
+    {
+        return [
+            [null],
+            [''],
+        ];
+    }
+
+    /**
+     * @dataProvider provideInvalidConstructorOptions
+     */
+    public function testConstructorOptionTypeChecks(array $options)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        new Collection($this->manager, $this->getDatabaseName(), $this->getCollectionName(), $options);
+    }
+
+    public function provideInvalidConstructorOptions()
+    {
+        $options = [];
+
+        foreach ($this->getInvalidReadConcernValues() as $value) {
+            $options[][] = ['readConcern' => $value];
+        }
+
+        foreach ($this->getInvalidReadPreferenceValues() as $value) {
+            $options[][] = ['readPreference' => $value];
+        }
+
+        foreach ($this->getInvalidArrayValues() as $value) {
+            $options[][] = ['typeMap' => $value];
+        }
+
+        foreach ($this->getInvalidWriteConcernValues() as $value) {
+            $options[][] = ['writeConcern' => $value];
+        }
+
+        return $options;
+    }
+
+    public function testGetManager()
+    {
+        $this->assertSame($this->manager, $this->collection->getManager());
+    }
+
+    public function testToString()
+    {
+        $this->assertEquals($this->getNamespace(), (string) $this->collection);
+    }
+
+    public function getGetCollectionName()
+    {
+        $this->assertEquals($this->getCollectionName(), $this->collection->getCollectionName());
+    }
+
+    public function getGetDatabaseName()
+    {
+        $this->assertEquals($this->getDatabaseName(), $this->collection->getDatabaseName());
+    }
+
+    public function testGetNamespace()
+    {
+        $this->assertEquals($this->getNamespace(), $this->collection->getNamespace());
+    }
+
+    public function testAggregateWithinTransaction()
+    {
+        $this->skipIfTransactionsAreNotSupported();
+
+        // Collection must be created before the transaction starts
+        $this->createCollection();
+
+        $session = $this->manager->startSession();
+        $session->startTransaction();
+
+        try {
+            $this->createFixtures(3, ['session' => $session]);
+
+            $cursor = $this->collection->aggregate(
+                [['$match' => ['_id' => ['$lt' => 3]]]],
+                ['session' => $session]
+            );
+
+            $expected = [
+                ['_id' => 1, 'x' => 11],
+                ['_id' => 2, 'x' => 22],
+            ];
+
+            $this->assertSameDocuments($expected, $cursor);
+
+            $session->commitTransaction();
+        } finally {
+            $session->endSession();
+        }
+    }
+
+    public function testCreateIndexSplitsCommandOptions()
+    {
+        if (version_compare($this->getServerVersion(), '3.6.0', '<')) {
+            $this->markTestSkipped('Sessions are not supported');
+        }
+
+        (new CommandObserver())->observe(
+            function () {
+                $this->collection->createIndex(
+                    ['x' => 1],
+                    [
+                        'maxTimeMS' => 10000,
+                        'session' => $this->manager->startSession(),
+                        'sparse' => true,
+                        'unique' => true,
+                        'writeConcern' => new WriteConcern(1),
+                    ]
+                );
+            },
+            function (array $event) {
+                $command = $event['started']->getCommand();
+                $this->assertObjectHasAttribute('lsid', $command);
+                $this->assertObjectHasAttribute('maxTimeMS', $command);
+                $this->assertObjectHasAttribute('writeConcern', $command);
+                $this->assertObjectHasAttribute('sparse', $command->indexes[0]);
+                $this->assertObjectHasAttribute('unique', $command->indexes[0]);
+            }
+        );
+    }
+
+    /**
+     * @dataProvider provideTypeMapOptionsAndExpectedDocuments
+     */
+    public function testDistinctWithTypeMap(array $typeMap, array $expectedDocuments)
+    {
+        $bulkWrite = new BulkWrite(['ordered' => true]);
+        $bulkWrite->insert([
+            'x' => (object) ['foo' => 'bar'],
+        ]);
+        $bulkWrite->insert(['x' => 4]);
+        $bulkWrite->insert([
+            'x' => (object) ['foo' => ['foo' => 'bar']],
+        ]);
+        $this->manager->executeBulkWrite($this->getNamespace(), $bulkWrite);
+
+        $values = $this->collection->withOptions(['typeMap' => $typeMap])->distinct('x');
+
+        /* This sort callable sorts all scalars to the front of the list. All
+         * non-scalar values are sorted by running json_encode on them and
+         * comparing their string representations.
+         */
+        $sort = function ($a, $b) {
+            if (is_scalar($a) && ! is_scalar($b)) {
+                return -1;
+            }
+
+            if (! is_scalar($a)) {
+                if (is_scalar($b)) {
+                    return 1;
+                }
+
+                $a = json_encode($a);
+                $b = json_encode($b);
+            }
+
+            return $a < $b ? -1 : 1;
+        };
+
+        usort($expectedDocuments, $sort);
+        usort($values, $sort);
+
+        $this->assertEquals($expectedDocuments, $values);
+    }
+
+    public function provideTypeMapOptionsAndExpectedDocuments()
+    {
+        return [
+            'No type map' => [
+                ['root' => 'array', 'document' => 'array'],
+                [
+                    ['foo' => 'bar'],
+                    4,
+                    ['foo' => ['foo' => 'bar']],
+                ],
+            ],
+            'array/array' => [
+                ['root' => 'array', 'document' => 'array'],
+                [
+                    ['foo' => 'bar'],
+                    4,
+                    ['foo' => ['foo' => 'bar']],
+                ],
+            ],
+            'object/array' => [
+                ['root' => 'object', 'document' => 'array'],
+                [
+                    (object) ['foo' => 'bar'],
+                    4,
+                    (object) ['foo' => ['foo' => 'bar']],
+                ],
+            ],
+            'array/stdClass' => [
+                ['root' => 'array', 'document' => 'stdClass'],
+                [
+                    ['foo' => 'bar'],
+                    4,
+                    ['foo' => (object) ['foo' => 'bar']],
+                ],
+            ],
+        ];
+    }
+
+    public function testDrop()
+    {
+        $writeResult = $this->collection->insertOne(['x' => 1]);
+        $this->assertEquals(1, $writeResult->getInsertedCount());
+
+        $commandResult = $this->collection->drop();
+        $this->assertCommandSucceeded($commandResult);
+        $this->assertCollectionCount($this->getNamespace(), 0);
+    }
+
+    /**
+     * @todo Move this to a unit test once Manager can be mocked
+     */
+    public function testDropIndexShouldNotAllowWildcardCharacter()
+    {
+        $this->expectException(InvalidArgumentException::class);
+        $this->collection->dropIndex('*');
+    }
+
+    public function testExplain()
+    {
+        $this->createFixtures(3);
+
+        $operation = new Count($this->getDatabaseName(), $this->getCollectionName(), ['x' => ['$gte' => 1]], []);
+
+        $result = $this->collection->explain($operation);
+
+        $this->assertArrayHasKey('queryPlanner', $result);
+    }
+
+    public function testFindOne()
+    {
+        $this->createFixtures(5);
+
+        $filter = ['_id' => ['$lt' => 5]];
+        $options = [
+            'skip' => 1,
+            'sort' => ['x' => -1],
+        ];
+
+        $expected = ['_id' => 3, 'x' => 33];
+
+        $this->assertSameDocument($expected, $this->collection->findOne($filter, $options));
+    }
+
+    public function testFindWithinTransaction()
+    {
+        $this->skipIfTransactionsAreNotSupported();
+
+        // Collection must be created before the transaction starts
+        $this->createCollection();
+
+        $session = $this->manager->startSession();
+        $session->startTransaction();
+
+        try {
+            $this->createFixtures(3, ['session' => $session]);
+
+            $cursor = $this->collection->find(
+                ['_id' => ['$lt' => 3]],
+                ['session' => $session]
+            );
+
+            $expected = [
+                ['_id' => 1, 'x' => 11],
+                ['_id' => 2, 'x' => 22],
+            ];
+
+            $this->assertSameDocuments($expected, $cursor);
+
+            $session->commitTransaction();
+        } finally {
+            $session->endSession();
+        }
+    }
+
+    public function testWithOptionsInheritsOptions()
+    {
+        $collectionOptions = [
+            'readConcern' => new ReadConcern(ReadConcern::LOCAL),
+            'readPreference' => new ReadPreference(ReadPreference::RP_SECONDARY_PREFERRED),
+            'typeMap' => ['root' => 'array'],
+            'writeConcern' => new WriteConcern(WriteConcern::MAJORITY),
+        ];
+
+        $collection = new Collection($this->manager, $this->getDatabaseName(), $this->getCollectionName(), $collectionOptions);
+        $clone = $collection->withOptions();
+        $debug = $clone->__debugInfo();
+
+        $this->assertSame($this->manager, $debug['manager']);
+        $this->assertSame($this->getDatabaseName(), $debug['databaseName']);
+        $this->assertSame($this->getCollectionName(), $debug['collectionName']);
+        $this->assertInstanceOf(ReadConcern::class, $debug['readConcern']);
+        $this->assertSame(ReadConcern::LOCAL, $debug['readConcern']->getLevel());
+        $this->assertInstanceOf(ReadPreference::class, $debug['readPreference']);
+        $this->assertSame(ReadPreference::RP_SECONDARY_PREFERRED, $debug['readPreference']->getMode());
+        $this->assertIsArray($debug['typeMap']);
+        $this->assertSame(['root' => 'array'], $debug['typeMap']);
+        $this->assertInstanceOf(WriteConcern::class, $debug['writeConcern']);
+        $this->assertSame(WriteConcern::MAJORITY, $debug['writeConcern']->getW());
+    }
+
+    public function testWithOptionsPassesOptions()
+    {
+        $collectionOptions = [
+            'readConcern' => new ReadConcern(ReadConcern::LOCAL),
+            'readPreference' => new ReadPreference(ReadPreference::RP_SECONDARY_PREFERRED),
+            'typeMap' => ['root' => 'array'],
+            'writeConcern' => new WriteConcern(WriteConcern::MAJORITY),
+        ];
+
+        $clone = $this->collection->withOptions($collectionOptions);
+        $debug = $clone->__debugInfo();
+
+        $this->assertInstanceOf(ReadConcern::class, $debug['readConcern']);
+        $this->assertSame(ReadConcern::LOCAL, $debug['readConcern']->getLevel());
+        $this->assertInstanceOf(ReadPreference::class, $debug['readPreference']);
+        $this->assertSame(ReadPreference::RP_SECONDARY_PREFERRED, $debug['readPreference']->getMode());
+        $this->assertIsArray($debug['typeMap']);
+        $this->assertSame(['root' => 'array'], $debug['typeMap']);
+        $this->assertInstanceOf(WriteConcern::class, $debug['writeConcern']);
+        $this->assertSame(WriteConcern::MAJORITY, $debug['writeConcern']->getW());
+    }
+
+    public function testMapReduce()
+    {
+        $this->createFixtures(3);
+
+        $map = new Javascript('function() { emit(1, this.x); }');
+        $reduce = new Javascript('function(key, values) { return Array.sum(values); }');
+        $out = ['inline' => 1];
+
+        $result = $this->collection->mapReduce($map, $reduce, $out);
+
+        $this->assertInstanceOf(MapReduceResult::class, $result);
+        $expected = [
+            [ '_id' => 1.0, 'value' => 66.0 ],
+        ];
+
+        $this->assertSameDocuments($expected, $result);
+
+        if (version_compare($this->getServerVersion(), '4.3.0', '<')) {
+            $this->assertGreaterThanOrEqual(0, $result->getExecutionTimeMS());
+            $this->assertNotEmpty($result->getCounts());
+        }
+    }
+
+    public function collectionMethodClosures()
+    {
+        return [
+            [
+                function ($collection, $session, $options = []) {
+                    $collection->aggregate(
+                        [['$match' => ['_id' => ['$lt' => 3]]]],
+                        ['session' => $session] + $options
+                    );
+                }, 'rw',
+            ],
+
+            [
+                function ($collection, $session, $options = []) {
+                    $collection->bulkWrite(
+                        [['insertOne' => [['test' => 'foo']]]],
+                        ['session' => $session] + $options
+                    );
+                }, 'w',
+            ],
+
+            /* Disabled, as count command can't be used in transactions
+            [
+                function($collection, $session, $options = []) {
+                    $collection->count(
+                        [],
+                        ['session' => $session] + $options
+                    );
+                }, 'r'
+            ],
+            */
+
+            [
+                function ($collection, $session, $options = []) {
+                    $collection->countDocuments(
+                        [],
+                        ['session' => $session] + $options
+                    );
+                }, 'r',
+            ],
+
+            /* Disabled, as it's illegal to use createIndex command in transactions
+            [
+                function($collection, $session, $options = []) {
+                    $collection->createIndex(
+                        ['test' => 1],
+                        ['session' => $session] + $options
+                    );
+                }, 'w'
+            ],
+            */
+
+            [
+                function ($collection, $session, $options = []) {
+                    $collection->deleteMany(
+                        ['test' => 'foo'],
+                        ['session' => $session] + $options
+                    );
+                }, 'w',
+            ],
+
+            [
+                function ($collection, $session, $options = []) {
+                    $collection->deleteOne(
+                        ['test' => 'foo'],
+                        ['session' => $session] + $options
+                    );
+                }, 'w',
+            ],
+
+            [
+                function ($collection, $session, $options = []) {
+                    $collection->distinct(
+                        '_id',
+                        [],
+                        ['session' => $session] + $options
+                    );
+                }, 'r',
+            ],
+
+            /* Disabled, as it's illegal to use drop command in transactions
+            [
+                function($collection, $session, $options = []) {
+                    $collection->drop(
+                        ['session' => $session] + $options
+                    );
+                }, 'w'
+            ],
+            */
+
+            /* Disabled, as it's illegal to use dropIndexes command in transactions
+            [
+                function($collection, $session, $options = []) {
+                    $collection->dropIndex(
+                        '_id_1',
+                        ['session' => $session] + $options
+                    );
+                }, 'w'
+            ], */
+
+            /* Disabled, as it's illegal to use dropIndexes command in transactions
+            [
+                function($collection, $session, $options = []) {
+                    $collection->dropIndexes(
+                        ['session' => $session] + $options
+                    );
+                }, 'w'
+            ],
+            */
+
+            /* Disabled, as count command can't be used in transactions
+            [
+                function($collection, $session, $options = []) {
+                    $collection->estimatedDocumentCount(
+                        ['session' => $session] + $options
+                    );
+                }, 'r'
+            ],
+            */
+
+            [
+                function ($collection, $session, $options = []) {
+                    $collection->find(
+                        ['test' => 'foo'],
+                        ['session' => $session] + $options
+                    );
+                }, 'r',
+            ],
+
+            [
+                function ($collection, $session, $options = []) {
+                    $collection->findOne(
+                        ['test' => 'foo'],
+                        ['session' => $session] + $options
+                    );
+                }, 'r',
+            ],
+
+            [
+                function ($collection, $session, $options = []) {
+                    $collection->findOneAndDelete(
+                        ['test' => 'foo'],
+                        ['session' => $session] + $options
+                    );
+                }, 'w',
+            ],
+
+            [
+                function ($collection, $session, $options = []) {
+                    $collection->findOneAndReplace(
+                        ['test' => 'foo'],
+                        [],
+                        ['session' => $session] + $options
+                    );
+                }, 'w',
+            ],
+
+            [
+                function ($collection, $session, $options = []) {
+                    $collection->findOneAndUpdate(
+                        ['test' => 'foo'],
+                        ['$set' => ['updated' => 1]],
+                        ['session' => $session] + $options
+                    );
+                }, 'w',
+            ],
+
+            [
+                function ($collection, $session, $options = []) {
+                    $collection->insertMany(
+                        [
+                            ['test' => 'foo'],
+                            ['test' => 'bar'],
+                        ],
+                        ['session' => $session] + $options
+                    );
+                }, 'w',
+            ],
+
+            [
+                function ($collection, $session, $options = []) {
+                    $collection->insertOne(
+                        ['test' => 'foo'],
+                        ['session' => $session] + $options
+                    );
+                }, 'w',
+            ],
+
+            /* Disabled, as it's illegal to use listIndexes command in transactions
+            [
+                function($collection, $session, $options = []) {
+                    $collection->listIndexes(
+                        ['session' => $session] + $options
+                    );
+                }, 'r'
+            ],
+            */
+
+            /* Disabled, as it's illegal to use mapReduce command in transactions
+            [
+                function($collection, $session, $options = []) {
+                    $collection->mapReduce(
+                        new \MongoDB\BSON\Javascript('function() { emit(this.state, this.pop); }'),
+                        new \MongoDB\BSON\Javascript('function(key, values) { return Array.sum(values) }'),
+                        ['inline' => 1],
+                        ['session' => $session] + $options
+                    );
+                }, 'rw'
+            ],
+            */
+
+            [
+                function ($collection, $session, $options = []) {
+                    $collection->replaceOne(
+                        ['test' => 'foo'],
+                        [],
+                        ['session' => $session] + $options
+                    );
+                }, 'w',
+            ],
+
+            [
+                function ($collection, $session, $options = []) {
+                    $collection->updateMany(
+                        ['test' => 'foo'],
+                        ['$set' => ['updated' => 1]],
+                        ['session' => $session] + $options
+                    );
+                }, 'w',
+            ],
+
+            [
+                function ($collection, $session, $options = []) {
+                    $collection->updateOne(
+                        ['test' => 'foo'],
+                        ['$set' => ['updated' => 1]],
+                        ['session' => $session] + $options
+                    );
+                }, 'w',
+            ],
+
+            /* Disabled, as it's illegal to use change streams in transactions
+            [
+                function($collection, $session, $options = []) {
+                    $collection->watch(
+                        [],
+                        ['session' => $session] + $options
+                    );
+                }, 'r'
+            ],
+            */
+        ];
+    }
+
+    public function collectionReadMethodClosures()
+    {
+        return array_filter(
+            $this->collectionMethodClosures(),
+            function ($rw) {
+                if (strchr($rw[1], 'r') !== false) {
+                    return true;
+                }
+            }
+        );
+    }
+
+    public function collectionWriteMethodClosures()
+    {
+        return array_filter(
+            $this->collectionMethodClosures(),
+            function ($rw) {
+                if (strchr($rw[1], 'w') !== false) {
+                    return true;
+                }
+            }
+        );
+    }
+
+    /**
+     * @dataProvider collectionMethodClosures
+     */
+    public function testMethodDoesNotInheritReadWriteConcernInTranasaction(Closure $method)
+    {
+        $this->skipIfTransactionsAreNotSupported();
+
+        $this->createCollection();
+
+        $session = $this->manager->startSession();
+        $session->startTransaction();
+
+        $collection = $this->collection->withOptions([
+            'readConcern' => new ReadConcern(ReadConcern::LOCAL),
+            'writeConcern' => new WriteConcern(1),
+        ]);
+
+        (new CommandObserver())->observe(
+            function () use ($method, $collection, $session) {
+                call_user_func($method, $collection, $session);
+            },
+            function (array $event) {
+                $this->assertObjectNotHasAttribute('writeConcern', $event['started']->getCommand());
+                $this->assertObjectNotHasAttribute('readConcern', $event['started']->getCommand());
+            }
+        );
+    }
+
+    /**
+     * @dataProvider collectionWriteMethodClosures
+     */
+    public function testMethodInTransactionWithWriteConcernOption($method)
+    {
+        $this->skipIfTransactionsAreNotSupported();
+
+        $this->createCollection();
+
+        $session = $this->manager->startSession();
+        $session->startTransaction();
+
+        $this->expectException(UnsupportedException::class);
+        $this->expectExceptionMessage('"writeConcern" option cannot be specified within a transaction');
+
+        try {
+            call_user_func($method, $this->collection, $session, ['writeConcern' => new WriteConcern(1)]);
+        } finally {
+            $session->endSession();
+        }
+    }
+
+    /**
+     * @dataProvider collectionReadMethodClosures
+     */
+    public function testMethodInTransactionWithReadConcernOption($method)
+    {
+        $this->skipIfTransactionsAreNotSupported();
+
+        $this->createCollection();
+
+        $session = $this->manager->startSession();
+        $session->startTransaction();
+
+        $this->expectException(UnsupportedException::class);
+        $this->expectExceptionMessage('"readConcern" option cannot be specified within a transaction');
+
+        try {
+            call_user_func($method, $this->collection, $session, ['readConcern' => new ReadConcern(ReadConcern::LOCAL)]);
+        } finally {
+            $session->endSession();
+        }
+    }
+
+    /**
+     * Create data fixtures.
+     *
+     * @param integer $n
+     * @param array   $executeBulkWriteOptions
+     */
+    private function createFixtures($n, array $executeBulkWriteOptions = [])
+    {
+        $bulkWrite = new BulkWrite(['ordered' => true]);
+
+        for ($i = 1; $i <= $n; $i++) {
+            $bulkWrite->insert([
+                '_id' => $i,
+                'x' => (integer) ($i . $i),
+            ]);
+        }
+
+        $result = $this->manager->executeBulkWrite($this->getNamespace(), $bulkWrite, $executeBulkWriteOptions);
+
+        $this->assertEquals($n, $result->getInsertedCount());
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/CrudSpecFunctionalTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/CrudSpecFunctionalTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..0b33dcbc00552a86c01a94397d853f5c46ca03db
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/CrudSpecFunctionalTest.php	
@@ -0,0 +1,520 @@
+<?php
+
+namespace MongoDB\Tests\Collection;
+
+use IteratorIterator;
+use LogicException;
+use MongoDB\BulkWriteResult;
+use MongoDB\Collection;
+use MongoDB\DeleteResult;
+use MongoDB\Driver\Exception\BulkWriteException;
+use MongoDB\Driver\Exception\RuntimeException;
+use MongoDB\InsertManyResult;
+use MongoDB\InsertOneResult;
+use MongoDB\Operation\FindOneAndReplace;
+use MongoDB\UpdateResult;
+use MultipleIterator;
+use PHPUnit_Framework_SkippedTestError;
+use Symfony\Bridge\PhpUnit\SetUpTearDownTrait;
+use function array_diff_key;
+use function array_key_exists;
+use function array_map;
+use function file_get_contents;
+use function glob;
+use function json_decode;
+use function MongoDB\is_last_pipeline_operator_write;
+use function sprintf;
+use function str_replace;
+use function strtolower;
+use function version_compare;
+
+/**
+ * CRUD spec functional tests.
+ *
+ * @see https://github.com/mongodb/specifications/tree/master/source/crud/tests
+ */
+class CrudSpecFunctionalTest extends FunctionalTestCase
+{
+    use SetUpTearDownTrait;
+
+    /** @var Collection */
+    private $expectedCollection;
+
+    private function doSetUp()
+    {
+        parent::setUp();
+
+        $this->expectedCollection = new Collection($this->manager, $this->getDatabaseName(), $this->getCollectionName() . '.expected');
+        $this->expectedCollection->drop();
+    }
+
+    /**
+     * @dataProvider provideSpecificationTests
+     */
+    public function testSpecification(array $initialData, array $test, $minServerVersion, $maxServerVersion)
+    {
+        if (isset($minServerVersion) || isset($maxServerVersion)) {
+            $this->checkServerVersion($minServerVersion, $maxServerVersion);
+        }
+
+        $expectedData = $test['outcome']['collection']['data'] ?? null;
+        $this->initializeData($initialData, $expectedData);
+
+        if (isset($test['outcome']['collection']['name'])) {
+            $outputCollection = new Collection($this->manager, $this->getDatabaseName(), $test['outcome']['collection']['name']);
+            $outputCollection->drop();
+        }
+
+        $result = null;
+        $exception = null;
+
+        try {
+            $result = $this->executeOperation($test['operation']);
+        } catch (RuntimeException $e) {
+            $exception = $e;
+        }
+
+        $this->executeOutcome($test['operation'], $test['outcome'], $result, $exception);
+    }
+
+    public function provideSpecificationTests()
+    {
+        $testArgs = [];
+
+        foreach (glob(__DIR__ . '/spec-tests/*/*.json') as $filename) {
+            $json = json_decode(file_get_contents($filename), true);
+
+            $minServerVersion = $json['minServerVersion'] ?? null;
+            $maxServerVersion = $json['maxServerVersion'] ?? null;
+
+            foreach ($json['tests'] as $test) {
+                $name = str_replace(' ', '_', $test['description']);
+                $testArgs[$name] = [$json['data'], $test, $minServerVersion, $maxServerVersion];
+            }
+        }
+
+        return $testArgs;
+    }
+
+    /**
+     * Assert that the collections contain equivalent documents.
+     *
+     * @param Collection $expectedCollection
+     * @param Collection $actualCollection
+     */
+    private function assertEquivalentCollections($expectedCollection, $actualCollection)
+    {
+        $mi = new MultipleIterator(MultipleIterator::MIT_NEED_ANY);
+        $mi->attachIterator(new IteratorIterator($expectedCollection->find()));
+        $mi->attachIterator(new IteratorIterator($actualCollection->find()));
+
+        foreach ($mi as $documents) {
+            list($expectedDocument, $actualDocument) = $documents;
+            $this->assertSameDocument($expectedDocument, $actualDocument);
+        }
+    }
+
+    /**
+     * Checks that the server version is within the allowed bounds (if any).
+     *
+     * @param string|null $minServerVersion
+     * @param string|null $maxServerVersion
+     * @throws PHPUnit_Framework_SkippedTestError
+     */
+    private function checkServerVersion($minServerVersion, $maxServerVersion)
+    {
+        $serverVersion = $this->getServerVersion();
+
+        if (isset($minServerVersion) && version_compare($serverVersion, $minServerVersion, '<')) {
+            $this->markTestSkipped(sprintf('Server version "%s" < minServerVersion "%s"', $serverVersion, $minServerVersion));
+        }
+
+        if (isset($maxServerVersion) && version_compare($serverVersion, $maxServerVersion, '>=')) {
+            $this->markTestSkipped(sprintf('Server version "%s" >= maxServerVersion "%s"', $serverVersion, $maxServerVersion));
+        }
+    }
+
+    /**
+     * Executes an "operation" block.
+     *
+     * @param array $operation
+     * @return mixed
+     * @throws LogicException if the operation is unsupported
+     */
+    private function executeOperation(array $operation)
+    {
+        switch ($operation['name']) {
+            case 'aggregate':
+                return $this->collection->aggregate(
+                    $operation['arguments']['pipeline'],
+                    array_diff_key($operation['arguments'], ['pipeline' => 1])
+                );
+            case 'bulkWrite':
+                return $this->collection->bulkWrite(
+                    array_map([$this, 'prepareBulkWriteRequest'], $operation['arguments']['requests']),
+                    $operation['arguments']['options'] ?? []
+                );
+            case 'count':
+            case 'countDocuments':
+            case 'find':
+                return $this->collection->{$operation['name']}(
+                    $operation['arguments']['filter'] ?? [],
+                    array_diff_key($operation['arguments'], ['filter' => 1])
+                );
+            case 'estimatedDocumentCount':
+                return $this->collection->estimatedDocumentCount($operation['arguments']);
+            case 'deleteMany':
+            case 'deleteOne':
+            case 'findOneAndDelete':
+                return $this->collection->{$operation['name']}(
+                    $operation['arguments']['filter'],
+                    array_diff_key($operation['arguments'], ['filter' => 1])
+                );
+            case 'distinct':
+                return $this->collection->distinct(
+                    $operation['arguments']['fieldName'],
+                    $operation['arguments']['filter'] ?? [],
+                    array_diff_key($operation['arguments'], ['fieldName' => 1, 'filter' => 1])
+                );
+            case 'findOneAndReplace':
+                $operation['arguments'] = $this->prepareFindAndModifyArguments($operation['arguments']);
+                // Fall through
+
+            case 'replaceOne':
+                return $this->collection->{$operation['name']}(
+                    $operation['arguments']['filter'],
+                    $operation['arguments']['replacement'],
+                    array_diff_key($operation['arguments'], ['filter' => 1, 'replacement' => 1])
+                );
+            case 'findOneAndUpdate':
+                $operation['arguments'] = $this->prepareFindAndModifyArguments($operation['arguments']);
+                // Fall through
+
+            case 'updateMany':
+            case 'updateOne':
+                return $this->collection->{$operation['name']}(
+                    $operation['arguments']['filter'],
+                    $operation['arguments']['update'],
+                    array_diff_key($operation['arguments'], ['filter' => 1, 'update' => 1])
+                );
+            case 'insertMany':
+                return $this->collection->insertMany(
+                    $operation['arguments']['documents'],
+                    $operation['arguments']['options'] ?? []
+                );
+            case 'insertOne':
+                return $this->collection->insertOne(
+                    $operation['arguments']['document'],
+                    array_diff_key($operation['arguments'], ['document' => 1])
+                );
+            default:
+                throw new LogicException('Unsupported operation: ' . $operation['name']);
+        }
+    }
+
+    /**
+     * Executes an "outcome" block.
+     *
+     * @param array            $operation
+     * @param array            $outcome
+     * @param mixed            $result
+     * @param RuntimeException $exception
+     * @return mixed
+     * @throws LogicException if the operation is unsupported
+     */
+    private function executeOutcome(array $operation, array $outcome, $result, RuntimeException $exception = null)
+    {
+        $expectedError = array_key_exists('error', $outcome) ? $outcome['error'] : false;
+
+        if ($expectedError) {
+            $this->assertNull($result);
+            $this->assertNotNull($exception);
+
+            $result = $this->extractResultFromException($operation, $outcome, $exception);
+        }
+
+        if (array_key_exists('result', $outcome)) {
+            $this->executeAssertResult($operation, $outcome['result'], $result);
+        }
+
+        if (isset($outcome['collection'])) {
+            $actualCollection = isset($outcome['collection']['name'])
+                ? new Collection($this->manager, $this->getDatabaseName(), $outcome['collection']['name'])
+                : $this->collection;
+
+            $this->assertEquivalentCollections($this->expectedCollection, $actualCollection);
+        }
+    }
+
+    /**
+     * Extracts a result from an exception.
+     *
+     * Errors for bulkWrite and insertMany operations may still report a write
+     * result. This method will attempt to extract such a result so that it can
+     * be used in executeAssertResult().
+     *
+     * If no result can be extracted, null will be returned.
+     *
+     * @param array            $operation
+     * @param RuntimeException $exception
+     * @return mixed
+     */
+    private function extractResultFromException(array $operation, array $outcome, RuntimeException $exception)
+    {
+        switch ($operation['name']) {
+            case 'bulkWrite':
+                $insertedIds = $outcome['result']['insertedIds'] ?? [];
+
+                if ($exception instanceof BulkWriteException) {
+                    return new BulkWriteResult($exception->getWriteResult(), $insertedIds);
+                }
+                break;
+
+            case 'insertMany':
+                $insertedIds = $outcome['result']['insertedIds'] ?? [];
+
+                if ($exception instanceof BulkWriteException) {
+                    return new InsertManyResult($exception->getWriteResult(), $insertedIds);
+                }
+                break;
+        }
+
+        return null;
+    }
+
+    /**
+     * Executes the "result" section of an "outcome" block.
+     *
+     * @param array $operation
+     * @param mixed $expectedResult
+     * @param mixed $actualResult
+     * @throws LogicException if the operation is unsupported
+     */
+    private function executeAssertResult(array $operation, $expectedResult, $actualResult)
+    {
+        switch ($operation['name']) {
+            case 'aggregate':
+                /* Returning a cursor for the $out collection is optional per
+                 * the CRUD specification and is not implemented in the library
+                 * since we have no concept of lazy cursors. We will not assert
+                 * the result here; however, assertEquivalentCollections() will
+                 * assert the output collection's contents later.
+                 */
+                if (! is_last_pipeline_operator_write($operation['arguments']['pipeline'])) {
+                    $this->assertSameDocuments($expectedResult, $actualResult);
+                }
+                break;
+
+            case 'bulkWrite':
+                $this->assertIsArray($expectedResult);
+                $this->assertInstanceOf(BulkWriteResult::class, $actualResult);
+
+                if (isset($expectedResult['deletedCount'])) {
+                    $this->assertSame($expectedResult['deletedCount'], $actualResult->getDeletedCount());
+                }
+
+                if (isset($expectedResult['insertedCount'])) {
+                    $this->assertSame($expectedResult['insertedCount'], $actualResult->getInsertedCount());
+                }
+
+                if (isset($expectedResult['insertedIds'])) {
+                    $this->assertSameDocument(
+                        ['insertedIds' => $expectedResult['insertedIds']],
+                        ['insertedIds' => $actualResult->getInsertedIds()]
+                    );
+                }
+
+                if (isset($expectedResult['matchedCount'])) {
+                    $this->assertSame($expectedResult['matchedCount'], $actualResult->getMatchedCount());
+                }
+
+                if (isset($expectedResult['modifiedCount'])) {
+                    $this->assertSame($expectedResult['modifiedCount'], $actualResult->getModifiedCount());
+                }
+
+                if (isset($expectedResult['upsertedCount'])) {
+                    $this->assertSame($expectedResult['upsertedCount'], $actualResult->getUpsertedCount());
+                }
+
+                if (isset($expectedResult['upsertedIds'])) {
+                    $this->assertSameDocument(
+                        ['upsertedIds' => $expectedResult['upsertedIds']],
+                        ['upsertedIds' => $actualResult->getUpsertedIds()]
+                    );
+                }
+                break;
+
+            case 'count':
+            case 'countDocuments':
+            case 'estimatedDocumentCount':
+                $this->assertSame($expectedResult, $actualResult);
+                break;
+
+            case 'distinct':
+                $this->assertSameDocument(
+                    ['values' => $expectedResult],
+                    ['values' => $actualResult]
+                );
+                break;
+
+            case 'find':
+                $this->assertSameDocuments($expectedResult, $actualResult);
+                break;
+
+            case 'deleteMany':
+            case 'deleteOne':
+                $this->assertIsArray($expectedResult);
+                $this->assertInstanceOf(DeleteResult::class, $actualResult);
+
+                if (isset($expectedResult['deletedCount'])) {
+                    $this->assertSame($expectedResult['deletedCount'], $actualResult->getDeletedCount());
+                }
+                break;
+
+            case 'findOneAndDelete':
+            case 'findOneAndReplace':
+            case 'findOneAndUpdate':
+                $this->assertSameDocument(
+                    ['result' => $expectedResult],
+                    ['result' => $actualResult]
+                );
+                break;
+
+            case 'insertMany':
+                $this->assertIsArray($expectedResult);
+                $this->assertInstanceOf(InsertManyResult::class, $actualResult);
+
+                if (isset($expectedResult['insertedCount'])) {
+                    $this->assertSame($expectedResult['insertedCount'], $actualResult->getInsertedCount());
+                }
+
+                if (isset($expectedResult['insertedIds'])) {
+                    $this->assertSameDocument(
+                        ['insertedIds' => $expectedResult['insertedIds']],
+                        ['insertedIds' => $actualResult->getInsertedIds()]
+                    );
+                }
+                break;
+
+            case 'insertOne':
+                $this->assertIsArray($expectedResult);
+                $this->assertInstanceOf(InsertOneResult::class, $actualResult);
+
+                if (isset($expectedResult['insertedCount'])) {
+                    $this->assertSame($expectedResult['insertedCount'], $actualResult->getInsertedCount());
+                }
+
+                if (isset($expectedResult['insertedId'])) {
+                    $this->assertSameDocument(
+                        ['insertedId' => $expectedResult['insertedId']],
+                        ['insertedId' => $actualResult->getInsertedId()]
+                    );
+                }
+                break;
+
+            case 'replaceOne':
+            case 'updateMany':
+            case 'updateOne':
+                $this->assertIsArray($expectedResult);
+                $this->assertInstanceOf(UpdateResult::class, $actualResult);
+
+                if (isset($expectedResult['matchedCount'])) {
+                    $this->assertSame($expectedResult['matchedCount'], $actualResult->getMatchedCount());
+                }
+
+                if (isset($expectedResult['modifiedCount'])) {
+                    $this->assertSame($expectedResult['modifiedCount'], $actualResult->getModifiedCount());
+                }
+
+                if (isset($expectedResult['upsertedCount'])) {
+                    $this->assertSame($expectedResult['upsertedCount'], $actualResult->getUpsertedCount());
+                }
+
+                if (array_key_exists('upsertedId', $expectedResult)) {
+                    $this->assertSameDocument(
+                        ['upsertedId' => $expectedResult['upsertedId']],
+                        ['upsertedId' => $actualResult->getUpsertedId()]
+                    );
+                }
+                break;
+
+            default:
+                throw new LogicException('Unsupported operation: ' . $operation['name']);
+        }
+    }
+
+    /**
+     * Initializes data in the test collections.
+     *
+     * @param array $initialData
+     * @param array $expectedData
+     */
+    private function initializeData(array $initialData, array $expectedData = null)
+    {
+        if (! empty($initialData)) {
+            $this->collection->insertMany($initialData);
+        }
+
+        if (! empty($expectedData)) {
+            $this->expectedCollection->insertMany($expectedData);
+        }
+    }
+
+    /**
+     * Prepares a request element for a bulkWrite operation.
+     *
+     * @param array $request
+     * @return array
+     */
+    private function prepareBulkWriteRequest(array $request)
+    {
+        switch ($request['name']) {
+            case 'deleteMany':
+            case 'deleteOne':
+                return [
+                    $request['name'] => [
+                        $request['arguments']['filter'],
+                        array_diff_key($request['arguments'], ['filter' => 1]),
+                    ],
+                ];
+            case 'insertOne':
+                return [ 'insertOne' => [ $request['arguments']['document'] ]];
+            case 'replaceOne':
+                return [
+                    'replaceOne' => [
+                        $request['arguments']['filter'],
+                        $request['arguments']['replacement'],
+                        array_diff_key($request['arguments'], ['filter' => 1, 'replacement' => 1]),
+                    ],
+                ];
+            case 'updateMany':
+            case 'updateOne':
+                return [
+                    $request['name'] => [
+                        $request['arguments']['filter'],
+                        $request['arguments']['update'],
+                        array_diff_key($request['arguments'], ['filter' => 1, 'update' => 1]),
+                    ],
+                ];
+            default:
+                throw new LogicException('Unsupported bulk write request: ' . $request['name']);
+        }
+    }
+
+    /**
+     * Prepares arguments for findOneAndReplace and findOneAndUpdate operations.
+     *
+     * @param array $arguments
+     * @return array
+     */
+    private function prepareFindAndModifyArguments(array $arguments)
+    {
+        if (isset($arguments['returnDocument'])) {
+            $arguments['returnDocument'] = 'after' === strtolower($arguments['returnDocument'])
+                ? FindOneAndReplace::RETURN_DOCUMENT_AFTER
+                : FindOneAndReplace::RETURN_DOCUMENT_BEFORE;
+        }
+
+        return $arguments;
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/FunctionalTestCase.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/FunctionalTestCase.php
new file mode 100644
index 0000000000000000000000000000000000000000..1735b3ec8cb1003f318d9030ef7ad182153f1e2e
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/FunctionalTestCase.php	
@@ -0,0 +1,38 @@
+<?php
+
+namespace MongoDB\Tests\Collection;
+
+use MongoDB\Collection;
+use MongoDB\Tests\FunctionalTestCase as BaseFunctionalTestCase;
+use Symfony\Bridge\PhpUnit\SetUpTearDownTrait;
+
+/**
+ * Base class for Collection functional tests.
+ */
+abstract class FunctionalTestCase extends BaseFunctionalTestCase
+{
+    use SetUpTearDownTrait;
+
+    /** @var Collection */
+    protected $collection;
+
+    private function doSetUp()
+    {
+        parent::setUp();
+
+        $this->collection = new Collection($this->manager, $this->getDatabaseName(), $this->getCollectionName());
+
+        $this->dropCollection();
+    }
+
+    private function doTearDown()
+    {
+        if ($this->hasFailed()) {
+            return;
+        }
+
+        $this->dropCollection();
+
+        parent::tearDown();
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/read/aggregate-collation.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/read/aggregate-collation.json
new file mode 100644
index 0000000000000000000000000000000000000000..85662a442fb13f397cf4b1546cebbe2aed7c4031
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/read/aggregate-collation.json	
@@ -0,0 +1,38 @@
+{
+  "data": [
+    {
+      "_id": 1,
+      "x": "ping"
+    }
+  ],
+  "minServerVersion": "3.4",
+  "tests": [
+    {
+      "description": "Aggregate with collation",
+      "operation": {
+        "name": "aggregate",
+        "arguments": {
+          "pipeline": [
+            {
+              "$match": {
+                "x": "PING"
+              }
+            }
+          ],
+          "collation": {
+            "locale": "en_US",
+            "strength": 2
+          }
+        }
+      },
+      "outcome": {
+        "result": [
+          {
+            "_id": 1,
+            "x": "ping"
+          }
+        ]
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/read/aggregate-out.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/read/aggregate-out.json
new file mode 100644
index 0000000000000000000000000000000000000000..205cf76571b019d68004288af6af7bd1998dc75d
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/read/aggregate-out.json	
@@ -0,0 +1,121 @@
+{
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    },
+    {
+      "_id": 3,
+      "x": 33
+    }
+  ],
+  "minServerVersion": "2.6",
+  "tests": [
+    {
+      "description": "Aggregate with $out",
+      "operation": {
+        "name": "aggregate",
+        "arguments": {
+          "pipeline": [
+            {
+              "$sort": {
+                "x": 1
+              }
+            },
+            {
+              "$match": {
+                "_id": {
+                  "$gt": 1
+                }
+              }
+            },
+            {
+              "$out": "other_test_collection"
+            }
+          ],
+          "batchSize": 2
+        }
+      },
+      "outcome": {
+        "result": [
+          {
+            "_id": 2,
+            "x": 22
+          },
+          {
+            "_id": 3,
+            "x": 33
+          }
+        ],
+        "collection": {
+          "name": "other_test_collection",
+          "data": [
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "Aggregate with $out and batch size of 0",
+      "operation": {
+        "name": "aggregate",
+        "arguments": {
+          "pipeline": [
+            {
+              "$sort": {
+                "x": 1
+              }
+            },
+            {
+              "$match": {
+                "_id": {
+                  "$gt": 1
+                }
+              }
+            },
+            {
+              "$out": "other_test_collection"
+            }
+          ],
+          "batchSize": 0
+        }
+      },
+      "outcome": {
+        "result": [
+          {
+            "_id": 2,
+            "x": 22
+          },
+          {
+            "_id": 3,
+            "x": 33
+          }
+        ],
+        "collection": {
+          "name": "other_test_collection",
+          "data": [
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/read/aggregate.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/read/aggregate.json
new file mode 100644
index 0000000000000000000000000000000000000000..797a922395a8519bd8c6706a85697081a6eef1e8
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/read/aggregate.json	
@@ -0,0 +1,53 @@
+{
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    },
+    {
+      "_id": 3,
+      "x": 33
+    }
+  ],
+  "tests": [
+    {
+      "description": "Aggregate with multiple stages",
+      "operation": {
+        "name": "aggregate",
+        "arguments": {
+          "pipeline": [
+            {
+              "$sort": {
+                "x": 1
+              }
+            },
+            {
+              "$match": {
+                "_id": {
+                  "$gt": 1
+                }
+              }
+            }
+          ],
+          "batchSize": 2
+        }
+      },
+      "outcome": {
+        "result": [
+          {
+            "_id": 2,
+            "x": 22
+          },
+          {
+            "_id": 3,
+            "x": 33
+          }
+        ]
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/read/count-collation.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/read/count-collation.json
new file mode 100644
index 0000000000000000000000000000000000000000..6f75282fe0fc78636221639d91d9e4fe9a9939d0
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/read/count-collation.json	
@@ -0,0 +1,47 @@
+{
+  "data": [
+    {
+      "_id": 1,
+      "x": "PING"
+    }
+  ],
+  "minServerVersion": "3.4",
+  "tests": [
+    {
+      "description": "Count documents with collation",
+      "operation": {
+        "name": "countDocuments",
+        "arguments": {
+          "filter": {
+            "x": "ping"
+          },
+          "collation": {
+            "locale": "en_US",
+            "strength": 2
+          }
+        }
+      },
+      "outcome": {
+        "result": 1
+      }
+    },
+    {
+      "description": "Deprecated count with collation",
+      "operation": {
+        "name": "count",
+        "arguments": {
+          "filter": {
+            "x": "ping"
+          },
+          "collation": {
+            "locale": "en_US",
+            "strength": 2
+          }
+        }
+      },
+      "outcome": {
+        "result": 1
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/read/count-empty.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/read/count-empty.json
new file mode 100644
index 0000000000000000000000000000000000000000..2b8627e0c69ec22abae5709d8bd12fe83632dbf5
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/read/count-empty.json	
@@ -0,0 +1,39 @@
+{
+  "data": [],
+  "tests": [
+    {
+      "description": "Estimated document count with empty collection",
+      "operation": {
+        "name": "estimatedDocumentCount",
+        "arguments": {}
+      },
+      "outcome": {
+        "result": 0
+      }
+    },
+    {
+      "description": "Count documents with empty collection",
+      "operation": {
+        "name": "countDocuments",
+        "arguments": {
+          "filter": {}
+        }
+      },
+      "outcome": {
+        "result": 0
+      }
+    },
+    {
+      "description": "Deprecated count with empty collection",
+      "operation": {
+        "name": "count",
+        "arguments": {
+          "filter": {}
+        }
+      },
+      "outcome": {
+        "result": 0
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/read/count.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/read/count.json
new file mode 100644
index 0000000000000000000000000000000000000000..9642b2fbd087a4753a3bbe082ca9e4bf690e9651
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/read/count.json	
@@ -0,0 +1,112 @@
+{
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    },
+    {
+      "_id": 3,
+      "x": 33
+    }
+  ],
+  "tests": [
+    {
+      "description": "Estimated document count",
+      "operation": {
+        "name": "estimatedDocumentCount",
+        "arguments": {}
+      },
+      "outcome": {
+        "result": 3
+      }
+    },
+    {
+      "description": "Count documents without a filter",
+      "operation": {
+        "name": "countDocuments",
+        "arguments": {
+          "filter": {}
+        }
+      },
+      "outcome": {
+        "result": 3
+      }
+    },
+    {
+      "description": "Count documents with a filter",
+      "operation": {
+        "name": "countDocuments",
+        "arguments": {
+          "filter": {
+            "_id": {
+              "$gt": 1
+            }
+          }
+        }
+      },
+      "outcome": {
+        "result": 2
+      }
+    },
+    {
+      "description": "Count documents with skip and limit",
+      "operation": {
+        "name": "countDocuments",
+        "arguments": {
+          "filter": {},
+          "skip": 1,
+          "limit": 3
+        }
+      },
+      "outcome": {
+        "result": 2
+      }
+    },
+    {
+      "description": "Deprecated count without a filter",
+      "operation": {
+        "name": "count",
+        "arguments": {
+          "filter": {}
+        }
+      },
+      "outcome": {
+        "result": 3
+      }
+    },
+    {
+      "description": "Deprecated count with a filter",
+      "operation": {
+        "name": "count",
+        "arguments": {
+          "filter": {
+            "_id": {
+              "$gt": 1
+            }
+          }
+        }
+      },
+      "outcome": {
+        "result": 2
+      }
+    },
+    {
+      "description": "Deprecated count with skip and limit",
+      "operation": {
+        "name": "count",
+        "arguments": {
+          "filter": {},
+          "skip": 1,
+          "limit": 3
+        }
+      },
+      "outcome": {
+        "result": 2
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/read/distinct-collation.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/read/distinct-collation.json
new file mode 100644
index 0000000000000000000000000000000000000000..0af0c67cb70f9b4743a9d64cb4566d04eb7c9003
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/read/distinct-collation.json	
@@ -0,0 +1,33 @@
+{
+  "data": [
+    {
+      "_id": 1,
+      "string": "PING"
+    },
+    {
+      "_id": 2,
+      "string": "ping"
+    }
+  ],
+  "minServerVersion": "3.4",
+  "tests": [
+    {
+      "description": "Distinct with a collation",
+      "operation": {
+        "name": "distinct",
+        "arguments": {
+          "fieldName": "string",
+          "collation": {
+            "locale": "en_US",
+            "strength": 2
+          }
+        }
+      },
+      "outcome": {
+        "result": [
+          "PING"
+        ]
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/read/distinct.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/read/distinct.json
new file mode 100644
index 0000000000000000000000000000000000000000..a57ee36a8345e8e93472b996f252d02729809e3d
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/read/distinct.json	
@@ -0,0 +1,55 @@
+{
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    },
+    {
+      "_id": 3,
+      "x": 33
+    }
+  ],
+  "tests": [
+    {
+      "description": "Distinct without a filter",
+      "operation": {
+        "name": "distinct",
+        "arguments": {
+          "fieldName": "x",
+          "filter": {}
+        }
+      },
+      "outcome": {
+        "result": [
+          11,
+          22,
+          33
+        ]
+      }
+    },
+    {
+      "description": "Distinct with a filter",
+      "operation": {
+        "name": "distinct",
+        "arguments": {
+          "fieldName": "x",
+          "filter": {
+            "_id": {
+              "$gt": 1
+            }
+          }
+        }
+      },
+      "outcome": {
+        "result": [
+          22,
+          33
+        ]
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/read/find-collation.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/read/find-collation.json
new file mode 100644
index 0000000000000000000000000000000000000000..53d0e94900dd9fd085f5a330faa84c83214488d9
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/read/find-collation.json	
@@ -0,0 +1,34 @@
+{
+  "data": [
+    {
+      "_id": 1,
+      "x": "ping"
+    }
+  ],
+  "minServerVersion": "3.4",
+  "tests": [
+    {
+      "description": "Find with a collation",
+      "operation": {
+        "name": "find",
+        "arguments": {
+          "filter": {
+            "x": "PING"
+          },
+          "collation": {
+            "locale": "en_US",
+            "strength": 2
+          }
+        }
+      },
+      "outcome": {
+        "result": [
+          {
+            "_id": 1,
+            "x": "ping"
+          }
+        ]
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/read/find.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/read/find.json
new file mode 100644
index 0000000000000000000000000000000000000000..3597e37be6f5e1d7d52c7c6ce366bdf1e3ff9a48
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/read/find.json	
@@ -0,0 +1,105 @@
+{
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    },
+    {
+      "_id": 3,
+      "x": 33
+    },
+    {
+      "_id": 4,
+      "x": 44
+    },
+    {
+      "_id": 5,
+      "x": 55
+    }
+  ],
+  "tests": [
+    {
+      "description": "Find with filter",
+      "operation": {
+        "name": "find",
+        "arguments": {
+          "filter": {
+            "_id": 1
+          }
+        }
+      },
+      "outcome": {
+        "result": [
+          {
+            "_id": 1,
+            "x": 11
+          }
+        ]
+      }
+    },
+    {
+      "description": "Find with filter, sort, skip, and limit",
+      "operation": {
+        "name": "find",
+        "arguments": {
+          "filter": {
+            "_id": {
+              "$gt": 2
+            }
+          },
+          "sort": {
+            "_id": 1
+          },
+          "skip": 2,
+          "limit": 2
+        }
+      },
+      "outcome": {
+        "result": [
+          {
+            "_id": 5,
+            "x": 55
+          }
+        ]
+      }
+    },
+    {
+      "description": "Find with limit, sort, and batchsize",
+      "operation": {
+        "name": "find",
+        "arguments": {
+          "filter": {},
+          "sort": {
+            "_id": 1
+          },
+          "limit": 4,
+          "batchSize": 2
+        }
+      },
+      "outcome": {
+        "result": [
+          {
+            "_id": 1,
+            "x": 11
+          },
+          {
+            "_id": 2,
+            "x": 22
+          },
+          {
+            "_id": 3,
+            "x": 33
+          },
+          {
+            "_id": 4,
+            "x": 44
+          }
+        ]
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/write/bulkWrite-arrayFilters.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/write/bulkWrite-arrayFilters.json
new file mode 100644
index 0000000000000000000000000000000000000000..99e73f5d7554b58b659d906f0ae4d334051614d5
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/write/bulkWrite-arrayFilters.json	
@@ -0,0 +1,111 @@
+{
+  "data": [
+    {
+      "_id": 1,
+      "y": [
+        {
+          "b": 3
+        },
+        {
+          "b": 1
+        }
+      ]
+    },
+    {
+      "_id": 2,
+      "y": [
+        {
+          "b": 0
+        },
+        {
+          "b": 1
+        }
+      ]
+    }
+  ],
+  "minServerVersion": "3.5.6",
+  "tests": [
+    {
+      "description": "BulkWrite with arrayFilters",
+      "operation": {
+        "name": "bulkWrite",
+        "arguments": {
+          "requests": [
+            {
+              "name": "updateOne",
+              "arguments": {
+                "filter": {},
+                "update": {
+                  "$set": {
+                    "y.$[i].b": 2
+                  }
+                },
+                "arrayFilters": [
+                  {
+                    "i.b": 3
+                  }
+                ]
+              }
+            },
+            {
+              "name": "updateMany",
+              "arguments": {
+                "filter": {},
+                "update": {
+                  "$set": {
+                    "y.$[i].b": 2
+                  }
+                },
+                "arrayFilters": [
+                  {
+                    "i.b": 1
+                  }
+                ]
+              }
+            }
+          ],
+          "options": {
+            "ordered": true
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "deletedCount": 0,
+          "insertedCount": 0,
+          "insertedIds": {},
+          "matchedCount": 3,
+          "modifiedCount": 3,
+          "upsertedCount": 0,
+          "upsertedIds": {}
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "y": [
+                {
+                  "b": 2
+                },
+                {
+                  "b": 2
+                }
+              ]
+            },
+            {
+              "_id": 2,
+              "y": [
+                {
+                  "b": 0
+                },
+                {
+                  "b": 2
+                }
+              ]
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/write/bulkWrite-collation.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/write/bulkWrite-collation.json
new file mode 100644
index 0000000000000000000000000000000000000000..8e9d1bcb1ac4bb335988dc4591ae2b87dc4c8943
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/write/bulkWrite-collation.json	
@@ -0,0 +1,217 @@
+{
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": "ping"
+    },
+    {
+      "_id": 3,
+      "x": "pINg"
+    },
+    {
+      "_id": 4,
+      "x": "pong"
+    },
+    {
+      "_id": 5,
+      "x": "pONg"
+    }
+  ],
+  "minServerVersion": "3.4",
+  "tests": [
+    {
+      "description": "BulkWrite with delete operations and collation",
+      "operation": {
+        "name": "bulkWrite",
+        "arguments": {
+          "requests": [
+            {
+              "name": "deleteOne",
+              "arguments": {
+                "filter": {
+                  "x": "PING"
+                },
+                "collation": {
+                  "locale": "en_US",
+                  "strength": 2
+                }
+              }
+            },
+            {
+              "name": "deleteOne",
+              "arguments": {
+                "filter": {
+                  "x": "PING"
+                },
+                "collation": {
+                  "locale": "en_US",
+                  "strength": 2
+                }
+              }
+            },
+            {
+              "name": "deleteMany",
+              "arguments": {
+                "filter": {
+                  "x": "PONG"
+                },
+                "collation": {
+                  "locale": "en_US",
+                  "strength": 2
+                }
+              }
+            }
+          ],
+          "options": {
+            "ordered": true
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "deletedCount": 4,
+          "insertedCount": 0,
+          "insertedIds": {},
+          "matchedCount": 0,
+          "modifiedCount": 0,
+          "upsertedCount": 0,
+          "upsertedIds": {}
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "BulkWrite with update operations and collation",
+      "operation": {
+        "name": "bulkWrite",
+        "arguments": {
+          "requests": [
+            {
+              "name": "updateMany",
+              "arguments": {
+                "filter": {
+                  "x": "ping"
+                },
+                "update": {
+                  "$set": {
+                    "x": "PONG"
+                  }
+                },
+                "collation": {
+                  "locale": "en_US",
+                  "strength": 3
+                }
+              }
+            },
+            {
+              "name": "updateOne",
+              "arguments": {
+                "filter": {
+                  "x": "ping"
+                },
+                "update": {
+                  "$set": {
+                    "x": "PONG"
+                  }
+                },
+                "collation": {
+                  "locale": "en_US",
+                  "strength": 2
+                }
+              }
+            },
+            {
+              "name": "replaceOne",
+              "arguments": {
+                "filter": {
+                  "x": "ping"
+                },
+                "replacement": {
+                  "_id": 6,
+                  "x": "ping"
+                },
+                "upsert": true,
+                "collation": {
+                  "locale": "en_US",
+                  "strength": 3
+                }
+              }
+            },
+            {
+              "name": "updateMany",
+              "arguments": {
+                "filter": {
+                  "x": "pong"
+                },
+                "update": {
+                  "$set": {
+                    "x": "PONG"
+                  }
+                },
+                "collation": {
+                  "locale": "en_US",
+                  "strength": 2
+                }
+              }
+            }
+          ],
+          "options": {
+            "ordered": true
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "deletedCount": 0,
+          "insertedCount": 0,
+          "insertedIds": {},
+          "matchedCount": 6,
+          "modifiedCount": 4,
+          "upsertedCount": 1,
+          "upsertedIds": {
+            "2": 6
+          }
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": "PONG"
+            },
+            {
+              "_id": 3,
+              "x": "PONG"
+            },
+            {
+              "_id": 4,
+              "x": "PONG"
+            },
+            {
+              "_id": 5,
+              "x": "PONG"
+            },
+            {
+              "_id": 6,
+              "x": "ping"
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/write/bulkWrite.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/write/bulkWrite.json
new file mode 100644
index 0000000000000000000000000000000000000000..97879e7d3f3df15cb92cbef5d1fcf7041fbd2393
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/write/bulkWrite.json	
@@ -0,0 +1,790 @@
+{
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    }
+  ],
+  "minServerVersion": "2.6",
+  "tests": [
+    {
+      "description": "BulkWrite with deleteOne operations",
+      "operation": {
+        "name": "bulkWrite",
+        "arguments": {
+          "requests": [
+            {
+              "name": "deleteOne",
+              "arguments": {
+                "filter": {
+                  "_id": 3
+                }
+              }
+            },
+            {
+              "name": "deleteOne",
+              "arguments": {
+                "filter": {
+                  "_id": 2
+                }
+              }
+            }
+          ],
+          "options": {
+            "ordered": true
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "deletedCount": 1,
+          "insertedCount": 0,
+          "insertedIds": {},
+          "matchedCount": 0,
+          "modifiedCount": 0,
+          "upsertedCount": 0,
+          "upsertedIds": {}
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "BulkWrite with deleteMany operations",
+      "operation": {
+        "name": "bulkWrite",
+        "arguments": {
+          "requests": [
+            {
+              "name": "deleteMany",
+              "arguments": {
+                "filter": {
+                  "x": {
+                    "$lt": 11
+                  }
+                }
+              }
+            },
+            {
+              "name": "deleteMany",
+              "arguments": {
+                "filter": {
+                  "x": {
+                    "$lte": 22
+                  }
+                }
+              }
+            }
+          ],
+          "options": {
+            "ordered": true
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "deletedCount": 2,
+          "insertedCount": 0,
+          "insertedIds": {},
+          "matchedCount": 0,
+          "modifiedCount": 0,
+          "upsertedCount": 0,
+          "upsertedIds": {}
+        },
+        "collection": {
+          "data": []
+        }
+      }
+    },
+    {
+      "description": "BulkWrite with insertOne operations",
+      "operation": {
+        "name": "bulkWrite",
+        "arguments": {
+          "requests": [
+            {
+              "name": "insertOne",
+              "arguments": {
+                "document": {
+                  "_id": 3,
+                  "x": 33
+                }
+              }
+            },
+            {
+              "name": "insertOne",
+              "arguments": {
+                "document": {
+                  "_id": 4,
+                  "x": 44
+                }
+              }
+            }
+          ],
+          "options": {
+            "ordered": true
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "deletedCount": 0,
+          "insertedCount": 2,
+          "insertedIds": {
+            "0": 3,
+            "1": 4
+          },
+          "matchedCount": 0,
+          "modifiedCount": 0,
+          "upsertedCount": 0,
+          "upsertedIds": {}
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            },
+            {
+              "_id": 4,
+              "x": 44
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "BulkWrite with replaceOne operations",
+      "operation": {
+        "name": "bulkWrite",
+        "arguments": {
+          "requests": [
+            {
+              "name": "replaceOne",
+              "arguments": {
+                "filter": {
+                  "_id": 3
+                },
+                "replacement": {
+                  "x": 33
+                }
+              }
+            },
+            {
+              "name": "replaceOne",
+              "arguments": {
+                "filter": {
+                  "_id": 1
+                },
+                "replacement": {
+                  "_id": 1,
+                  "x": 11
+                }
+              }
+            },
+            {
+              "name": "replaceOne",
+              "arguments": {
+                "filter": {
+                  "_id": 1
+                },
+                "replacement": {
+                  "x": 12
+                }
+              }
+            },
+            {
+              "name": "replaceOne",
+              "arguments": {
+                "filter": {
+                  "_id": 3
+                },
+                "replacement": {
+                  "x": 33
+                },
+                "upsert": true
+              }
+            }
+          ],
+          "options": {
+            "ordered": true
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "deletedCount": 0,
+          "insertedCount": 0,
+          "insertedIds": {},
+          "matchedCount": 2,
+          "modifiedCount": 1,
+          "upsertedCount": 1,
+          "upsertedIds": {
+            "3": 3
+          }
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 12
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "BulkWrite with updateOne operations",
+      "operation": {
+        "name": "bulkWrite",
+        "arguments": {
+          "requests": [
+            {
+              "name": "updateOne",
+              "arguments": {
+                "filter": {
+                  "_id": 0
+                },
+                "update": {
+                  "$set": {
+                    "x": 0
+                  }
+                }
+              }
+            },
+            {
+              "name": "updateOne",
+              "arguments": {
+                "filter": {
+                  "_id": 1
+                },
+                "update": {
+                  "$set": {
+                    "x": 11
+                  }
+                }
+              }
+            },
+            {
+              "name": "updateOne",
+              "arguments": {
+                "filter": {
+                  "_id": 2
+                },
+                "update": {
+                  "$inc": {
+                    "x": 1
+                  }
+                }
+              }
+            },
+            {
+              "name": "updateOne",
+              "arguments": {
+                "filter": {
+                  "_id": 3
+                },
+                "update": {
+                  "$set": {
+                    "x": 33
+                  }
+                },
+                "upsert": true
+              }
+            }
+          ],
+          "options": {
+            "ordered": true
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "deletedCount": 0,
+          "insertedCount": 0,
+          "insertedIds": {},
+          "matchedCount": 2,
+          "modifiedCount": 1,
+          "upsertedCount": 1,
+          "upsertedIds": {
+            "3": 3
+          }
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 23
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "BulkWrite with updateMany operations",
+      "operation": {
+        "name": "bulkWrite",
+        "arguments": {
+          "requests": [
+            {
+              "name": "updateMany",
+              "arguments": {
+                "filter": {
+                  "x": {
+                    "$lt": 11
+                  }
+                },
+                "update": {
+                  "$set": {
+                    "x": 0
+                  }
+                }
+              }
+            },
+            {
+              "name": "updateMany",
+              "arguments": {
+                "filter": {
+                  "x": {
+                    "$lte": 22
+                  }
+                },
+                "update": {
+                  "$unset": {
+                    "y": 1
+                  }
+                }
+              }
+            },
+            {
+              "name": "updateMany",
+              "arguments": {
+                "filter": {
+                  "x": {
+                    "$lte": 22
+                  }
+                },
+                "update": {
+                  "$inc": {
+                    "x": 1
+                  }
+                }
+              }
+            },
+            {
+              "name": "updateMany",
+              "arguments": {
+                "filter": {
+                  "_id": 3
+                },
+                "update": {
+                  "$set": {
+                    "x": 33
+                  }
+                },
+                "upsert": true
+              }
+            }
+          ],
+          "options": {
+            "ordered": true
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "deletedCount": 0,
+          "insertedCount": 0,
+          "insertedIds": {},
+          "matchedCount": 4,
+          "modifiedCount": 2,
+          "upsertedCount": 1,
+          "upsertedIds": {
+            "3": 3
+          }
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 12
+            },
+            {
+              "_id": 2,
+              "x": 23
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "BulkWrite with mixed ordered operations",
+      "operation": {
+        "name": "bulkWrite",
+        "arguments": {
+          "requests": [
+            {
+              "name": "insertOne",
+              "arguments": {
+                "document": {
+                  "_id": 3,
+                  "x": 33
+                }
+              }
+            },
+            {
+              "name": "updateOne",
+              "arguments": {
+                "filter": {
+                  "_id": 2
+                },
+                "update": {
+                  "$inc": {
+                    "x": 1
+                  }
+                }
+              }
+            },
+            {
+              "name": "updateMany",
+              "arguments": {
+                "filter": {
+                  "_id": {
+                    "$gt": 1
+                  }
+                },
+                "update": {
+                  "$inc": {
+                    "x": 1
+                  }
+                }
+              }
+            },
+            {
+              "name": "insertOne",
+              "arguments": {
+                "document": {
+                  "_id": 4,
+                  "x": 44
+                }
+              }
+            },
+            {
+              "name": "deleteMany",
+              "arguments": {
+                "filter": {
+                  "x": {
+                    "$nin": [
+                      24,
+                      34
+                    ]
+                  }
+                }
+              }
+            },
+            {
+              "name": "replaceOne",
+              "arguments": {
+                "filter": {
+                  "_id": 4
+                },
+                "replacement": {
+                  "_id": 4,
+                  "x": 44
+                },
+                "upsert": true
+              }
+            }
+          ],
+          "options": {
+            "ordered": true
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "deletedCount": 2,
+          "insertedCount": 2,
+          "insertedIds": {
+            "0": 3,
+            "3": 4
+          },
+          "matchedCount": 3,
+          "modifiedCount": 3,
+          "upsertedCount": 1,
+          "upsertedIds": {
+            "5": 4
+          }
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 2,
+              "x": 24
+            },
+            {
+              "_id": 3,
+              "x": 34
+            },
+            {
+              "_id": 4,
+              "x": 44
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "BulkWrite with mixed unordered operations",
+      "operation": {
+        "name": "bulkWrite",
+        "arguments": {
+          "requests": [
+            {
+              "name": "replaceOne",
+              "arguments": {
+                "filter": {
+                  "_id": 3
+                },
+                "replacement": {
+                  "_id": 3,
+                  "x": 33
+                },
+                "upsert": true
+              }
+            },
+            {
+              "name": "deleteOne",
+              "arguments": {
+                "filter": {
+                  "_id": 1
+                }
+              }
+            },
+            {
+              "name": "updateOne",
+              "arguments": {
+                "filter": {
+                  "_id": 2
+                },
+                "update": {
+                  "$inc": {
+                    "x": 1
+                  }
+                }
+              }
+            }
+          ],
+          "options": {
+            "ordered": false
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "deletedCount": 1,
+          "insertedCount": 0,
+          "insertedIds": {},
+          "matchedCount": 1,
+          "modifiedCount": 1,
+          "upsertedCount": 1,
+          "upsertedIds": {
+            "0": 3
+          }
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 2,
+              "x": 23
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "BulkWrite continue-on-error behavior with unordered (preexisting duplicate key)",
+      "operation": {
+        "name": "bulkWrite",
+        "arguments": {
+          "requests": [
+            {
+              "name": "insertOne",
+              "arguments": {
+                "document": {
+                  "_id": 2,
+                  "x": 22
+                }
+              }
+            },
+            {
+              "name": "insertOne",
+              "arguments": {
+                "document": {
+                  "_id": 3,
+                  "x": 33
+                }
+              }
+            },
+            {
+              "name": "insertOne",
+              "arguments": {
+                "document": {
+                  "_id": 4,
+                  "x": 44
+                }
+              }
+            }
+          ],
+          "options": {
+            "ordered": false
+          }
+        }
+      },
+      "outcome": {
+        "error": true,
+        "result": {
+          "deletedCount": 0,
+          "insertedCount": 2,
+          "matchedCount": 0,
+          "modifiedCount": 0,
+          "upsertedCount": 0,
+          "upsertedIds": {}
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            },
+            {
+              "_id": 4,
+              "x": 44
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "BulkWrite continue-on-error behavior with unordered (duplicate key in requests)",
+      "operation": {
+        "name": "bulkWrite",
+        "arguments": {
+          "requests": [
+            {
+              "name": "insertOne",
+              "arguments": {
+                "document": {
+                  "_id": 3,
+                  "x": 33
+                }
+              }
+            },
+            {
+              "name": "insertOne",
+              "arguments": {
+                "document": {
+                  "_id": 3,
+                  "x": 33
+                }
+              }
+            },
+            {
+              "name": "insertOne",
+              "arguments": {
+                "document": {
+                  "_id": 4,
+                  "x": 44
+                }
+              }
+            }
+          ],
+          "options": {
+            "ordered": false
+          }
+        }
+      },
+      "outcome": {
+        "error": true,
+        "result": {
+          "deletedCount": 0,
+          "insertedCount": 2,
+          "matchedCount": 0,
+          "modifiedCount": 0,
+          "upsertedCount": 0,
+          "upsertedIds": {}
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            },
+            {
+              "_id": 4,
+              "x": 44
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/write/deleteMany-collation.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/write/deleteMany-collation.json
new file mode 100644
index 0000000000000000000000000000000000000000..d17bf3bcb9ead2a45addc0c2eb61763639b21b50
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/write/deleteMany-collation.json	
@@ -0,0 +1,47 @@
+{
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": "ping"
+    },
+    {
+      "_id": 3,
+      "x": "pINg"
+    }
+  ],
+  "minServerVersion": "3.4",
+  "tests": [
+    {
+      "description": "DeleteMany when many documents match with collation",
+      "operation": {
+        "name": "deleteMany",
+        "arguments": {
+          "filter": {
+            "x": "PING"
+          },
+          "collation": {
+            "locale": "en_US",
+            "strength": 2
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "deletedCount": 2
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/write/deleteMany.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/write/deleteMany.json
new file mode 100644
index 0000000000000000000000000000000000000000..7eee85e77f473ae1473603b35c895bf1e223ec59
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/write/deleteMany.json	
@@ -0,0 +1,76 @@
+{
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    },
+    {
+      "_id": 3,
+      "x": 33
+    }
+  ],
+  "tests": [
+    {
+      "description": "DeleteMany when many documents match",
+      "operation": {
+        "name": "deleteMany",
+        "arguments": {
+          "filter": {
+            "_id": {
+              "$gt": 1
+            }
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "deletedCount": 2
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "DeleteMany when no document matches",
+      "operation": {
+        "name": "deleteMany",
+        "arguments": {
+          "filter": {
+            "_id": 4
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "deletedCount": 0
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/write/deleteOne-collation.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/write/deleteOne-collation.json
new file mode 100644
index 0000000000000000000000000000000000000000..2f7f9211300e4ecbc8f1c124a7ce480a8e4724fe
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/write/deleteOne-collation.json	
@@ -0,0 +1,51 @@
+{
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": "ping"
+    },
+    {
+      "_id": 3,
+      "x": "pINg"
+    }
+  ],
+  "minServerVersion": "3.4",
+  "tests": [
+    {
+      "description": "DeleteOne when many documents matches with collation",
+      "operation": {
+        "name": "deleteOne",
+        "arguments": {
+          "filter": {
+            "x": "PING"
+          },
+          "collation": {
+            "locale": "en_US",
+            "strength": 2
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "deletedCount": 1
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 3,
+              "x": "pINg"
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/write/deleteOne.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/write/deleteOne.json
new file mode 100644
index 0000000000000000000000000000000000000000..a1106deae36dcbfcaae2093114c482e3be095a61
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/write/deleteOne.json	
@@ -0,0 +1,96 @@
+{
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    },
+    {
+      "_id": 3,
+      "x": 33
+    }
+  ],
+  "tests": [
+    {
+      "description": "DeleteOne when many documents match",
+      "operation": {
+        "name": "deleteOne",
+        "arguments": {
+          "filter": {
+            "_id": {
+              "$gt": 1
+            }
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "deletedCount": 1
+        }
+      }
+    },
+    {
+      "description": "DeleteOne when one document matches",
+      "operation": {
+        "name": "deleteOne",
+        "arguments": {
+          "filter": {
+            "_id": 2
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "deletedCount": 1
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "DeleteOne when no documents match",
+      "operation": {
+        "name": "deleteOne",
+        "arguments": {
+          "filter": {
+            "_id": 4
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "deletedCount": 0
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/write/findOneAndDelete-collation.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/write/findOneAndDelete-collation.json
new file mode 100644
index 0000000000000000000000000000000000000000..1ff37d2e88ad11ce435783113c7e46a99d30e7a3
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/write/findOneAndDelete-collation.json	
@@ -0,0 +1,59 @@
+{
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": "ping"
+    },
+    {
+      "_id": 3,
+      "x": "pINg"
+    }
+  ],
+  "minServerVersion": "3.4",
+  "tests": [
+    {
+      "description": "FindOneAndDelete when one document matches with collation",
+      "operation": {
+        "name": "findOneAndDelete",
+        "arguments": {
+          "filter": {
+            "_id": 2,
+            "x": "PING"
+          },
+          "projection": {
+            "x": 1,
+            "_id": 0
+          },
+          "sort": {
+            "x": 1
+          },
+          "collation": {
+            "locale": "en_US",
+            "strength": 2
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "x": "ping"
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 3,
+              "x": "pINg"
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/write/findOneAndDelete.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/write/findOneAndDelete.json
new file mode 100644
index 0000000000000000000000000000000000000000..e424e2aad10e359697ea4535c266f0db55837930
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/write/findOneAndDelete.json	
@@ -0,0 +1,127 @@
+{
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    },
+    {
+      "_id": 3,
+      "x": 33
+    }
+  ],
+  "tests": [
+    {
+      "description": "FindOneAndDelete when many documents match",
+      "operation": {
+        "name": "findOneAndDelete",
+        "arguments": {
+          "filter": {
+            "_id": {
+              "$gt": 1
+            }
+          },
+          "projection": {
+            "x": 1,
+            "_id": 0
+          },
+          "sort": {
+            "x": 1
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "x": 22
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "FindOneAndDelete when one document matches",
+      "operation": {
+        "name": "findOneAndDelete",
+        "arguments": {
+          "filter": {
+            "_id": 2
+          },
+          "projection": {
+            "x": 1,
+            "_id": 0
+          },
+          "sort": {
+            "x": 1
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "x": 22
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "FindOneAndDelete when no documents match",
+      "operation": {
+        "name": "findOneAndDelete",
+        "arguments": {
+          "filter": {
+            "_id": 4
+          },
+          "projection": {
+            "x": 1,
+            "_id": 0
+          },
+          "sort": {
+            "x": 1
+          }
+        }
+      },
+      "outcome": {
+        "result": null,
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/write/findOneAndReplace-collation.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/write/findOneAndReplace-collation.json
new file mode 100644
index 0000000000000000000000000000000000000000..babb2f7c11ffe0db3470f4a44e237c3d6a87e9e0
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/write/findOneAndReplace-collation.json	
@@ -0,0 +1,58 @@
+{
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": "ping"
+    }
+  ],
+  "minServerVersion": "3.4",
+  "tests": [
+    {
+      "description": "FindOneAndReplace when one document matches with collation returning the document after modification",
+      "operation": {
+        "name": "findOneAndReplace",
+        "arguments": {
+          "filter": {
+            "x": "PING"
+          },
+          "replacement": {
+            "x": "pong"
+          },
+          "projection": {
+            "x": 1,
+            "_id": 0
+          },
+          "returnDocument": "After",
+          "sort": {
+            "x": 1
+          },
+          "collation": {
+            "locale": "en_US",
+            "strength": 2
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "x": "pong"
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": "pong"
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/write/findOneAndReplace-upsert.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/write/findOneAndReplace-upsert.json
new file mode 100644
index 0000000000000000000000000000000000000000..0f07bf9c18d4cdbcb316d1d01a0636b96e6c31ad
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/write/findOneAndReplace-upsert.json	
@@ -0,0 +1,201 @@
+{
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    },
+    {
+      "_id": 3,
+      "x": 33
+    }
+  ],
+  "minServerVersion": "2.6",
+  "tests": [
+    {
+      "description": "FindOneAndReplace when no documents match without id specified with upsert returning the document before modification",
+      "operation": {
+        "name": "findOneAndReplace",
+        "arguments": {
+          "filter": {
+            "_id": 4
+          },
+          "replacement": {
+            "x": 44
+          },
+          "projection": {
+            "x": 1,
+            "_id": 0
+          },
+          "upsert": true
+        }
+      },
+      "outcome": {
+        "result": null,
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            },
+            {
+              "_id": 4,
+              "x": 44
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "FindOneAndReplace when no documents match without id specified with upsert returning the document after modification",
+      "operation": {
+        "name": "findOneAndReplace",
+        "arguments": {
+          "filter": {
+            "_id": 4
+          },
+          "replacement": {
+            "x": 44
+          },
+          "projection": {
+            "x": 1,
+            "_id": 0
+          },
+          "returnDocument": "After",
+          "sort": {
+            "x": 1
+          },
+          "upsert": true
+        }
+      },
+      "outcome": {
+        "result": {
+          "x": 44
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            },
+            {
+              "_id": 4,
+              "x": 44
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "FindOneAndReplace when no documents match with id specified with upsert returning the document before modification",
+      "operation": {
+        "name": "findOneAndReplace",
+        "arguments": {
+          "filter": {
+            "_id": 4
+          },
+          "replacement": {
+            "_id": 4,
+            "x": 44
+          },
+          "projection": {
+            "x": 1,
+            "_id": 0
+          },
+          "upsert": true
+        }
+      },
+      "outcome": {
+        "result": null,
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            },
+            {
+              "_id": 4,
+              "x": 44
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "FindOneAndReplace when no documents match with id specified with upsert returning the document after modification",
+      "operation": {
+        "name": "findOneAndReplace",
+        "arguments": {
+          "filter": {
+            "_id": 4
+          },
+          "replacement": {
+            "_id": 4,
+            "x": 44
+          },
+          "projection": {
+            "x": 1,
+            "_id": 0
+          },
+          "returnDocument": "After",
+          "sort": {
+            "x": 1
+          },
+          "upsert": true
+        }
+      },
+      "outcome": {
+        "result": {
+          "x": 44
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            },
+            {
+              "_id": 4,
+              "x": 44
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/write/findOneAndReplace.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/write/findOneAndReplace.json
new file mode 100644
index 0000000000000000000000000000000000000000..70e5c3df4e9e569a829444c6fb99f6316003974c
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/write/findOneAndReplace.json	
@@ -0,0 +1,273 @@
+{
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    },
+    {
+      "_id": 3,
+      "x": 33
+    }
+  ],
+  "tests": [
+    {
+      "description": "FindOneAndReplace when many documents match returning the document before modification",
+      "operation": {
+        "name": "findOneAndReplace",
+        "arguments": {
+          "filter": {
+            "_id": {
+              "$gt": 1
+            }
+          },
+          "replacement": {
+            "x": 32
+          },
+          "projection": {
+            "x": 1,
+            "_id": 0
+          },
+          "sort": {
+            "x": 1
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "x": 22
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 32
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "FindOneAndReplace when many documents match returning the document after modification",
+      "operation": {
+        "name": "findOneAndReplace",
+        "arguments": {
+          "filter": {
+            "_id": {
+              "$gt": 1
+            }
+          },
+          "replacement": {
+            "x": 32
+          },
+          "projection": {
+            "x": 1,
+            "_id": 0
+          },
+          "returnDocument": "After",
+          "sort": {
+            "x": 1
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "x": 32
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 32
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "FindOneAndReplace when one document matches returning the document before modification",
+      "operation": {
+        "name": "findOneAndReplace",
+        "arguments": {
+          "filter": {
+            "_id": 2
+          },
+          "replacement": {
+            "x": 32
+          },
+          "projection": {
+            "x": 1,
+            "_id": 0
+          },
+          "sort": {
+            "x": 1
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "x": 22
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 32
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "FindOneAndReplace when one document matches returning the document after modification",
+      "operation": {
+        "name": "findOneAndReplace",
+        "arguments": {
+          "filter": {
+            "_id": 2
+          },
+          "replacement": {
+            "x": 32
+          },
+          "projection": {
+            "x": 1,
+            "_id": 0
+          },
+          "returnDocument": "After",
+          "sort": {
+            "x": 1
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "x": 32
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 32
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "FindOneAndReplace when no documents match returning the document before modification",
+      "operation": {
+        "name": "findOneAndReplace",
+        "arguments": {
+          "filter": {
+            "_id": 4
+          },
+          "replacement": {
+            "x": 44
+          },
+          "projection": {
+            "x": 1,
+            "_id": 0
+          },
+          "sort": {
+            "x": 1
+          }
+        }
+      },
+      "outcome": {
+        "result": null,
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "FindOneAndReplace when no documents match returning the document after modification",
+      "operation": {
+        "name": "findOneAndReplace",
+        "arguments": {
+          "filter": {
+            "_id": 4
+          },
+          "replacement": {
+            "x": 44
+          },
+          "projection": {
+            "x": 1,
+            "_id": 0
+          },
+          "returnDocument": "After",
+          "sort": {
+            "x": 1
+          }
+        }
+      },
+      "outcome": {
+        "result": null,
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/write/findOneAndUpdate-arrayFilters.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/write/findOneAndUpdate-arrayFilters.json
new file mode 100644
index 0000000000000000000000000000000000000000..1aa13b863e7879ee26910643db8ddbd46288ea8a
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/write/findOneAndUpdate-arrayFilters.json	
@@ -0,0 +1,203 @@
+{
+  "data": [
+    {
+      "_id": 1,
+      "y": [
+        {
+          "b": 3
+        },
+        {
+          "b": 1
+        }
+      ]
+    },
+    {
+      "_id": 2,
+      "y": [
+        {
+          "b": 0
+        },
+        {
+          "b": 1
+        }
+      ]
+    }
+  ],
+  "minServerVersion": "3.5.6",
+  "tests": [
+    {
+      "description": "FindOneAndUpdate when no document matches arrayFilters",
+      "operation": {
+        "name": "findOneAndUpdate",
+        "arguments": {
+          "filter": {},
+          "update": {
+            "$set": {
+              "y.$[i].b": 2
+            }
+          },
+          "arrayFilters": [
+            {
+              "i.b": 4
+            }
+          ]
+        }
+      },
+      "outcome": {
+        "result": {
+          "_id": 1,
+          "y": [
+            {
+              "b": 3
+            },
+            {
+              "b": 1
+            }
+          ]
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "y": [
+                {
+                  "b": 3
+                },
+                {
+                  "b": 1
+                }
+              ]
+            },
+            {
+              "_id": 2,
+              "y": [
+                {
+                  "b": 0
+                },
+                {
+                  "b": 1
+                }
+              ]
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "FindOneAndUpdate when one document matches arrayFilters",
+      "operation": {
+        "name": "findOneAndUpdate",
+        "arguments": {
+          "filter": {},
+          "update": {
+            "$set": {
+              "y.$[i].b": 2
+            }
+          },
+          "arrayFilters": [
+            {
+              "i.b": 3
+            }
+          ]
+        }
+      },
+      "outcome": {
+        "result": {
+          "_id": 1,
+          "y": [
+            {
+              "b": 3
+            },
+            {
+              "b": 1
+            }
+          ]
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "y": [
+                {
+                  "b": 2
+                },
+                {
+                  "b": 1
+                }
+              ]
+            },
+            {
+              "_id": 2,
+              "y": [
+                {
+                  "b": 0
+                },
+                {
+                  "b": 1
+                }
+              ]
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "FindOneAndUpdate when multiple documents match arrayFilters",
+      "operation": {
+        "name": "findOneAndUpdate",
+        "arguments": {
+          "filter": {},
+          "update": {
+            "$set": {
+              "y.$[i].b": 2
+            }
+          },
+          "arrayFilters": [
+            {
+              "i.b": 1
+            }
+          ]
+        }
+      },
+      "outcome": {
+        "result": {
+          "_id": 1,
+          "y": [
+            {
+              "b": 3
+            },
+            {
+              "b": 1
+            }
+          ]
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "y": [
+                {
+                  "b": 3
+                },
+                {
+                  "b": 2
+                }
+              ]
+            },
+            {
+              "_id": 2,
+              "y": [
+                {
+                  "b": 0
+                },
+                {
+                  "b": 1
+                }
+              ]
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/write/findOneAndUpdate-collation.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/write/findOneAndUpdate-collation.json
new file mode 100644
index 0000000000000000000000000000000000000000..04c1fe73ec5a063330cac0cd3d38d93067128f65
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/write/findOneAndUpdate-collation.json	
@@ -0,0 +1,67 @@
+{
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": "ping"
+    },
+    {
+      "_id": 3,
+      "x": "pINg"
+    }
+  ],
+  "minServerVersion": "3.4",
+  "tests": [
+    {
+      "description": "FindOneAndUpdate when many documents match with collation returning the document before modification",
+      "operation": {
+        "name": "findOneAndUpdate",
+        "arguments": {
+          "filter": {
+            "x": "PING"
+          },
+          "update": {
+            "$set": {
+              "x": "pong"
+            }
+          },
+          "projection": {
+            "x": 1,
+            "_id": 0
+          },
+          "sort": {
+            "_id": 1
+          },
+          "collation": {
+            "locale": "en_US",
+            "strength": 2
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "x": "ping"
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": "pong"
+            },
+            {
+              "_id": 3,
+              "x": "pINg"
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/write/findOneAndUpdate.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/write/findOneAndUpdate.json
new file mode 100644
index 0000000000000000000000000000000000000000..6da8325273b061b11b9f366c766561aa2c7ab428
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/write/findOneAndUpdate.json	
@@ -0,0 +1,379 @@
+{
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    },
+    {
+      "_id": 3,
+      "x": 33
+    }
+  ],
+  "tests": [
+    {
+      "description": "FindOneAndUpdate when many documents match returning the document before modification",
+      "operation": {
+        "name": "findOneAndUpdate",
+        "arguments": {
+          "filter": {
+            "_id": {
+              "$gt": 1
+            }
+          },
+          "update": {
+            "$inc": {
+              "x": 1
+            }
+          },
+          "projection": {
+            "x": 1,
+            "_id": 0
+          },
+          "sort": {
+            "x": 1
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "x": 22
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 23
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "FindOneAndUpdate when many documents match returning the document after modification",
+      "operation": {
+        "name": "findOneAndUpdate",
+        "arguments": {
+          "filter": {
+            "_id": {
+              "$gt": 1
+            }
+          },
+          "update": {
+            "$inc": {
+              "x": 1
+            }
+          },
+          "projection": {
+            "x": 1,
+            "_id": 0
+          },
+          "returnDocument": "After",
+          "sort": {
+            "x": 1
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "x": 23
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 23
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "FindOneAndUpdate when one document matches returning the document before modification",
+      "operation": {
+        "name": "findOneAndUpdate",
+        "arguments": {
+          "filter": {
+            "_id": 2
+          },
+          "update": {
+            "$inc": {
+              "x": 1
+            }
+          },
+          "projection": {
+            "x": 1,
+            "_id": 0
+          },
+          "sort": {
+            "x": 1
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "x": 22
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 23
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "FindOneAndUpdate when one document matches returning the document after modification",
+      "operation": {
+        "name": "findOneAndUpdate",
+        "arguments": {
+          "filter": {
+            "_id": 2
+          },
+          "update": {
+            "$inc": {
+              "x": 1
+            }
+          },
+          "projection": {
+            "x": 1,
+            "_id": 0
+          },
+          "returnDocument": "After",
+          "sort": {
+            "x": 1
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "x": 23
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 23
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "FindOneAndUpdate when no documents match returning the document before modification",
+      "operation": {
+        "name": "findOneAndUpdate",
+        "arguments": {
+          "filter": {
+            "_id": 4
+          },
+          "update": {
+            "$inc": {
+              "x": 1
+            }
+          },
+          "projection": {
+            "x": 1,
+            "_id": 0
+          },
+          "sort": {
+            "x": 1
+          }
+        }
+      },
+      "outcome": {
+        "result": null,
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "FindOneAndUpdate when no documents match with upsert returning the document before modification",
+      "operation": {
+        "name": "findOneAndUpdate",
+        "arguments": {
+          "filter": {
+            "_id": 4
+          },
+          "update": {
+            "$inc": {
+              "x": 1
+            }
+          },
+          "projection": {
+            "x": 1,
+            "_id": 0
+          },
+          "upsert": true
+        }
+      },
+      "outcome": {
+        "result": null,
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            },
+            {
+              "_id": 4,
+              "x": 1
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "FindOneAndUpdate when no documents match returning the document after modification",
+      "operation": {
+        "name": "findOneAndUpdate",
+        "arguments": {
+          "filter": {
+            "_id": 4
+          },
+          "update": {
+            "$inc": {
+              "x": 1
+            }
+          },
+          "projection": {
+            "x": 1,
+            "_id": 0
+          },
+          "returnDocument": "After",
+          "sort": {
+            "x": 1
+          }
+        }
+      },
+      "outcome": {
+        "result": null,
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "FindOneAndUpdate when no documents match with upsert returning the document after modification",
+      "operation": {
+        "name": "findOneAndUpdate",
+        "arguments": {
+          "filter": {
+            "_id": 4
+          },
+          "update": {
+            "$inc": {
+              "x": 1
+            }
+          },
+          "projection": {
+            "x": 1,
+            "_id": 0
+          },
+          "returnDocument": "After",
+          "sort": {
+            "x": 1
+          },
+          "upsert": true
+        }
+      },
+      "outcome": {
+        "result": {
+          "x": 1
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            },
+            {
+              "_id": 4,
+              "x": 1
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/write/insertMany.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/write/insertMany.json
new file mode 100644
index 0000000000000000000000000000000000000000..6a2e5261b74a4eadf71cb59d07a192fd3ffde87f
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/write/insertMany.json	
@@ -0,0 +1,159 @@
+{
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    }
+  ],
+  "tests": [
+    {
+      "description": "InsertMany with non-existing documents",
+      "operation": {
+        "name": "insertMany",
+        "arguments": {
+          "documents": [
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ],
+          "options": {
+            "ordered": true
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "insertedIds": {
+            "0": 2,
+            "1": 3
+          }
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "InsertMany continue-on-error behavior with unordered (preexisting duplicate key)",
+      "operation": {
+        "name": "insertMany",
+        "arguments": {
+          "documents": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ],
+          "options": {
+            "ordered": false
+          }
+        }
+      },
+      "outcome": {
+        "error": true,
+        "result": {
+          "deletedCount": 0,
+          "insertedCount": 2,
+          "matchedCount": 0,
+          "modifiedCount": 0,
+          "upsertedCount": 0,
+          "upsertedIds": {}
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "InsertMany continue-on-error behavior with unordered (duplicate key in requests)",
+      "operation": {
+        "name": "insertMany",
+        "arguments": {
+          "documents": [
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ],
+          "options": {
+            "ordered": false
+          }
+        }
+      },
+      "outcome": {
+        "error": true,
+        "result": {
+          "deletedCount": 0,
+          "insertedCount": 2,
+          "matchedCount": 0,
+          "modifiedCount": 0,
+          "upsertedCount": 0,
+          "upsertedIds": {}
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/write/insertOne.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/write/insertOne.json
new file mode 100644
index 0000000000000000000000000000000000000000..525de75e078d1d2c8420da4a2eb05ff236a295e7
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/write/insertOne.json	
@@ -0,0 +1,39 @@
+{
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    }
+  ],
+  "tests": [
+    {
+      "description": "InsertOne with a non-existing document",
+      "operation": {
+        "name": "insertOne",
+        "arguments": {
+          "document": {
+            "_id": 2,
+            "x": 22
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "insertedId": 2
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/write/replaceOne-collation.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/write/replaceOne-collation.json
new file mode 100644
index 0000000000000000000000000000000000000000..a668fe738317751f41a8e2c01fb209cb20d9e8a5
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/write/replaceOne-collation.json	
@@ -0,0 +1,53 @@
+{
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": "ping"
+    }
+  ],
+  "minServerVersion": "3.4",
+  "tests": [
+    {
+      "description": "ReplaceOne when one document matches with collation",
+      "operation": {
+        "name": "replaceOne",
+        "arguments": {
+          "filter": {
+            "x": "PING"
+          },
+          "replacement": {
+            "_id": 2,
+            "x": "pong"
+          },
+          "collation": {
+            "locale": "en_US",
+            "strength": 2
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "matchedCount": 1,
+          "modifiedCount": 1,
+          "upsertedCount": 0
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": "pong"
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/write/replaceOne.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/write/replaceOne.json
new file mode 100644
index 0000000000000000000000000000000000000000..101af25c7c51b13de772075e81c7ef5263280298
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/write/replaceOne.json	
@@ -0,0 +1,205 @@
+{
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    },
+    {
+      "_id": 3,
+      "x": 33
+    }
+  ],
+  "minServerVersion": "2.6",
+  "tests": [
+    {
+      "description": "ReplaceOne when many documents match",
+      "operation": {
+        "name": "replaceOne",
+        "arguments": {
+          "filter": {
+            "_id": {
+              "$gt": 1
+            }
+          },
+          "replacement": {
+            "x": 111
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "matchedCount": 1,
+          "modifiedCount": 1,
+          "upsertedCount": 0
+        }
+      }
+    },
+    {
+      "description": "ReplaceOne when one document matches",
+      "operation": {
+        "name": "replaceOne",
+        "arguments": {
+          "filter": {
+            "_id": 1
+          },
+          "replacement": {
+            "_id": 1,
+            "x": 111
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "matchedCount": 1,
+          "modifiedCount": 1,
+          "upsertedCount": 0
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 111
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "ReplaceOne when no documents match",
+      "operation": {
+        "name": "replaceOne",
+        "arguments": {
+          "filter": {
+            "_id": 4
+          },
+          "replacement": {
+            "_id": 4,
+            "x": 1
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "matchedCount": 0,
+          "modifiedCount": 0,
+          "upsertedCount": 0
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "ReplaceOne with upsert when no documents match without an id specified",
+      "operation": {
+        "name": "replaceOne",
+        "arguments": {
+          "filter": {
+            "_id": 4
+          },
+          "replacement": {
+            "x": 1
+          },
+          "upsert": true
+        }
+      },
+      "outcome": {
+        "result": {
+          "matchedCount": 0,
+          "modifiedCount": 0,
+          "upsertedCount": 1,
+          "upsertedId": 4
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            },
+            {
+              "_id": 4,
+              "x": 1
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "ReplaceOne with upsert when no documents match with an id specified",
+      "operation": {
+        "name": "replaceOne",
+        "arguments": {
+          "filter": {
+            "_id": 4
+          },
+          "replacement": {
+            "_id": 4,
+            "x": 1
+          },
+          "upsert": true
+        }
+      },
+      "outcome": {
+        "result": {
+          "matchedCount": 0,
+          "modifiedCount": 0,
+          "upsertedCount": 1,
+          "upsertedId": 4
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            },
+            {
+              "_id": 4,
+              "x": 1
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/write/updateMany-arrayFilters.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/write/updateMany-arrayFilters.json
new file mode 100644
index 0000000000000000000000000000000000000000..ae4c123ea51acf659990f9fd8960c153e784c019
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/write/updateMany-arrayFilters.json	
@@ -0,0 +1,185 @@
+{
+  "data": [
+    {
+      "_id": 1,
+      "y": [
+        {
+          "b": 3
+        },
+        {
+          "b": 1
+        }
+      ]
+    },
+    {
+      "_id": 2,
+      "y": [
+        {
+          "b": 0
+        },
+        {
+          "b": 1
+        }
+      ]
+    }
+  ],
+  "minServerVersion": "3.5.6",
+  "tests": [
+    {
+      "description": "UpdateMany when no documents match arrayFilters",
+      "operation": {
+        "name": "updateMany",
+        "arguments": {
+          "filter": {},
+          "update": {
+            "$set": {
+              "y.$[i].b": 2
+            }
+          },
+          "arrayFilters": [
+            {
+              "i.b": 4
+            }
+          ]
+        }
+      },
+      "outcome": {
+        "result": {
+          "matchedCount": 2,
+          "modifiedCount": 0,
+          "upsertedCount": 0
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "y": [
+                {
+                  "b": 3
+                },
+                {
+                  "b": 1
+                }
+              ]
+            },
+            {
+              "_id": 2,
+              "y": [
+                {
+                  "b": 0
+                },
+                {
+                  "b": 1
+                }
+              ]
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "UpdateMany when one document matches arrayFilters",
+      "operation": {
+        "name": "updateMany",
+        "arguments": {
+          "filter": {},
+          "update": {
+            "$set": {
+              "y.$[i].b": 2
+            }
+          },
+          "arrayFilters": [
+            {
+              "i.b": 3
+            }
+          ]
+        }
+      },
+      "outcome": {
+        "result": {
+          "matchedCount": 2,
+          "modifiedCount": 1,
+          "upsertedCount": 0
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "y": [
+                {
+                  "b": 2
+                },
+                {
+                  "b": 1
+                }
+              ]
+            },
+            {
+              "_id": 2,
+              "y": [
+                {
+                  "b": 0
+                },
+                {
+                  "b": 1
+                }
+              ]
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "UpdateMany when multiple documents match arrayFilters",
+      "operation": {
+        "name": "updateMany",
+        "arguments": {
+          "filter": {},
+          "update": {
+            "$set": {
+              "y.$[i].b": 2
+            }
+          },
+          "arrayFilters": [
+            {
+              "i.b": 1
+            }
+          ]
+        }
+      },
+      "outcome": {
+        "result": {
+          "matchedCount": 2,
+          "modifiedCount": 2,
+          "upsertedCount": 0
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "y": [
+                {
+                  "b": 3
+                },
+                {
+                  "b": 2
+                }
+              ]
+            },
+            {
+              "_id": 2,
+              "y": [
+                {
+                  "b": 0
+                },
+                {
+                  "b": 2
+                }
+              ]
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/write/updateMany-collation.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/write/updateMany-collation.json
new file mode 100644
index 0000000000000000000000000000000000000000..3cb49f229814eafe39abea5c61d103b3606f1036
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/write/updateMany-collation.json	
@@ -0,0 +1,62 @@
+{
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": "ping"
+    },
+    {
+      "_id": 3,
+      "x": "pINg"
+    }
+  ],
+  "minServerVersion": "3.4",
+  "tests": [
+    {
+      "description": "UpdateMany when many documents match with collation",
+      "operation": {
+        "name": "updateMany",
+        "arguments": {
+          "filter": {
+            "x": "ping"
+          },
+          "update": {
+            "$set": {
+              "x": "pong"
+            }
+          },
+          "collation": {
+            "locale": "en_US",
+            "strength": 2
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "matchedCount": 2,
+          "modifiedCount": 2,
+          "upsertedCount": 0
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": "pong"
+            },
+            {
+              "_id": 3,
+              "x": "pong"
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/write/updateMany.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/write/updateMany.json
new file mode 100644
index 0000000000000000000000000000000000000000..a3c339987d934a5e9c02916ae2f1a6714952c83d
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/write/updateMany.json	
@@ -0,0 +1,183 @@
+{
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    },
+    {
+      "_id": 3,
+      "x": 33
+    }
+  ],
+  "minServerVersion": "2.6",
+  "tests": [
+    {
+      "description": "UpdateMany when many documents match",
+      "operation": {
+        "name": "updateMany",
+        "arguments": {
+          "filter": {
+            "_id": {
+              "$gt": 1
+            }
+          },
+          "update": {
+            "$inc": {
+              "x": 1
+            }
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "matchedCount": 2,
+          "modifiedCount": 2,
+          "upsertedCount": 0
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 23
+            },
+            {
+              "_id": 3,
+              "x": 34
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "UpdateMany when one document matches",
+      "operation": {
+        "name": "updateMany",
+        "arguments": {
+          "filter": {
+            "_id": 1
+          },
+          "update": {
+            "$inc": {
+              "x": 1
+            }
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "matchedCount": 1,
+          "modifiedCount": 1,
+          "upsertedCount": 0
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 12
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "UpdateMany when no documents match",
+      "operation": {
+        "name": "updateMany",
+        "arguments": {
+          "filter": {
+            "_id": 4
+          },
+          "update": {
+            "$inc": {
+              "x": 1
+            }
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "matchedCount": 0,
+          "modifiedCount": 0,
+          "upsertedCount": 0
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "UpdateMany with upsert when no documents match",
+      "operation": {
+        "name": "updateMany",
+        "arguments": {
+          "filter": {
+            "_id": 4
+          },
+          "update": {
+            "$inc": {
+              "x": 1
+            }
+          },
+          "upsert": true
+        }
+      },
+      "outcome": {
+        "result": {
+          "matchedCount": 0,
+          "modifiedCount": 0,
+          "upsertedCount": 1,
+          "upsertedId": 4
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            },
+            {
+              "_id": 4,
+              "x": 1
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/write/updateOne-arrayFilters.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/write/updateOne-arrayFilters.json
new file mode 100644
index 0000000000000000000000000000000000000000..087ed4b82fc09bbd22e4bee156cc505a4be5b142
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/write/updateOne-arrayFilters.json	
@@ -0,0 +1,395 @@
+{
+  "data": [
+    {
+      "_id": 1,
+      "y": [
+        {
+          "b": 3
+        },
+        {
+          "b": 1
+        }
+      ]
+    },
+    {
+      "_id": 2,
+      "y": [
+        {
+          "b": 0
+        },
+        {
+          "b": 1
+        }
+      ]
+    },
+    {
+      "_id": 3,
+      "y": [
+        {
+          "b": 5,
+          "c": [
+            {
+              "d": 2
+            },
+            {
+              "d": 1
+            }
+          ]
+        }
+      ]
+    }
+  ],
+  "minServerVersion": "3.5.6",
+  "tests": [
+    {
+      "description": "UpdateOne when no document matches arrayFilters",
+      "operation": {
+        "name": "updateOne",
+        "arguments": {
+          "filter": {},
+          "update": {
+            "$set": {
+              "y.$[i].b": 2
+            }
+          },
+          "arrayFilters": [
+            {
+              "i.b": 4
+            }
+          ]
+        }
+      },
+      "outcome": {
+        "result": {
+          "matchedCount": 1,
+          "modifiedCount": 0,
+          "upsertedCount": 0
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "y": [
+                {
+                  "b": 3
+                },
+                {
+                  "b": 1
+                }
+              ]
+            },
+            {
+              "_id": 2,
+              "y": [
+                {
+                  "b": 0
+                },
+                {
+                  "b": 1
+                }
+              ]
+            },
+            {
+              "_id": 3,
+              "y": [
+                {
+                  "b": 5,
+                  "c": [
+                    {
+                      "d": 2
+                    },
+                    {
+                      "d": 1
+                    }
+                  ]
+                }
+              ]
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "UpdateOne when one document matches arrayFilters",
+      "operation": {
+        "name": "updateOne",
+        "arguments": {
+          "filter": {},
+          "update": {
+            "$set": {
+              "y.$[i].b": 2
+            }
+          },
+          "arrayFilters": [
+            {
+              "i.b": 3
+            }
+          ]
+        }
+      },
+      "outcome": {
+        "result": {
+          "matchedCount": 1,
+          "modifiedCount": 1,
+          "upsertedCount": 0
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "y": [
+                {
+                  "b": 2
+                },
+                {
+                  "b": 1
+                }
+              ]
+            },
+            {
+              "_id": 2,
+              "y": [
+                {
+                  "b": 0
+                },
+                {
+                  "b": 1
+                }
+              ]
+            },
+            {
+              "_id": 3,
+              "y": [
+                {
+                  "b": 5,
+                  "c": [
+                    {
+                      "d": 2
+                    },
+                    {
+                      "d": 1
+                    }
+                  ]
+                }
+              ]
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "UpdateOne when multiple documents match arrayFilters",
+      "operation": {
+        "name": "updateOne",
+        "arguments": {
+          "filter": {},
+          "update": {
+            "$set": {
+              "y.$[i].b": 2
+            }
+          },
+          "arrayFilters": [
+            {
+              "i.b": 1
+            }
+          ]
+        }
+      },
+      "outcome": {
+        "result": {
+          "matchedCount": 1,
+          "modifiedCount": 1,
+          "upsertedCount": 0
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "y": [
+                {
+                  "b": 3
+                },
+                {
+                  "b": 2
+                }
+              ]
+            },
+            {
+              "_id": 2,
+              "y": [
+                {
+                  "b": 0
+                },
+                {
+                  "b": 1
+                }
+              ]
+            },
+            {
+              "_id": 3,
+              "y": [
+                {
+                  "b": 5,
+                  "c": [
+                    {
+                      "d": 2
+                    },
+                    {
+                      "d": 1
+                    }
+                  ]
+                }
+              ]
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "UpdateOne when no documents match multiple arrayFilters",
+      "operation": {
+        "name": "updateOne",
+        "arguments": {
+          "filter": {
+            "_id": 3
+          },
+          "update": {
+            "$set": {
+              "y.$[i].c.$[j].d": 0
+            }
+          },
+          "arrayFilters": [
+            {
+              "i.b": 5
+            },
+            {
+              "j.d": 3
+            }
+          ]
+        }
+      },
+      "outcome": {
+        "result": {
+          "matchedCount": 1,
+          "modifiedCount": 0,
+          "upsertedCount": 0
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "y": [
+                {
+                  "b": 3
+                },
+                {
+                  "b": 1
+                }
+              ]
+            },
+            {
+              "_id": 2,
+              "y": [
+                {
+                  "b": 0
+                },
+                {
+                  "b": 1
+                }
+              ]
+            },
+            {
+              "_id": 3,
+              "y": [
+                {
+                  "b": 5,
+                  "c": [
+                    {
+                      "d": 2
+                    },
+                    {
+                      "d": 1
+                    }
+                  ]
+                }
+              ]
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "UpdateOne when one document matches multiple arrayFilters",
+      "operation": {
+        "name": "updateOne",
+        "arguments": {
+          "filter": {
+            "_id": 3
+          },
+          "update": {
+            "$set": {
+              "y.$[i].c.$[j].d": 0
+            }
+          },
+          "arrayFilters": [
+            {
+              "i.b": 5
+            },
+            {
+              "j.d": 1
+            }
+          ]
+        }
+      },
+      "outcome": {
+        "result": {
+          "matchedCount": 1,
+          "modifiedCount": 1,
+          "upsertedCount": 0
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "y": [
+                {
+                  "b": 3
+                },
+                {
+                  "b": 1
+                }
+              ]
+            },
+            {
+              "_id": 2,
+              "y": [
+                {
+                  "b": 0
+                },
+                {
+                  "b": 1
+                }
+              ]
+            },
+            {
+              "_id": 3,
+              "y": [
+                {
+                  "b": 5,
+                  "c": [
+                    {
+                      "d": 2
+                    },
+                    {
+                      "d": 0
+                    }
+                  ]
+                }
+              ]
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/write/updateOne-collation.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/write/updateOne-collation.json
new file mode 100644
index 0000000000000000000000000000000000000000..c49112d519c9a499338fef54d7eccf42055d94e4
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/write/updateOne-collation.json	
@@ -0,0 +1,54 @@
+{
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": "ping"
+    }
+  ],
+  "minServerVersion": "3.4",
+  "tests": [
+    {
+      "description": "UpdateOne when one document matches with collation",
+      "operation": {
+        "name": "updateOne",
+        "arguments": {
+          "filter": {
+            "x": "PING"
+          },
+          "update": {
+            "$set": {
+              "x": "pong"
+            }
+          },
+          "collation": {
+            "locale": "en_US",
+            "strength": 2
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "matchedCount": 1,
+          "modifiedCount": 1,
+          "upsertedCount": 0
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": "pong"
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/write/updateOne.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/write/updateOne.json
new file mode 100644
index 0000000000000000000000000000000000000000..76d2086bdb934ca450f22d8f89ea7ca121f02704
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Collection/spec-tests/write/updateOne.json	
@@ -0,0 +1,167 @@
+{
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    },
+    {
+      "_id": 3,
+      "x": 33
+    }
+  ],
+  "minServerVersion": "2.6",
+  "tests": [
+    {
+      "description": "UpdateOne when many documents match",
+      "operation": {
+        "name": "updateOne",
+        "arguments": {
+          "filter": {
+            "_id": {
+              "$gt": 1
+            }
+          },
+          "update": {
+            "$inc": {
+              "x": 1
+            }
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "matchedCount": 1,
+          "modifiedCount": 1,
+          "upsertedCount": 0
+        }
+      }
+    },
+    {
+      "description": "UpdateOne when one document matches",
+      "operation": {
+        "name": "updateOne",
+        "arguments": {
+          "filter": {
+            "_id": 1
+          },
+          "update": {
+            "$inc": {
+              "x": 1
+            }
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "matchedCount": 1,
+          "modifiedCount": 1,
+          "upsertedCount": 0
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 12
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "UpdateOne when no documents match",
+      "operation": {
+        "name": "updateOne",
+        "arguments": {
+          "filter": {
+            "_id": 4
+          },
+          "update": {
+            "$inc": {
+              "x": 1
+            }
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "matchedCount": 0,
+          "modifiedCount": 0,
+          "upsertedCount": 0
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "UpdateOne with upsert when no documents match",
+      "operation": {
+        "name": "updateOne",
+        "arguments": {
+          "filter": {
+            "_id": 4
+          },
+          "update": {
+            "$inc": {
+              "x": 1
+            }
+          },
+          "upsert": true
+        }
+      },
+      "outcome": {
+        "result": {
+          "matchedCount": 0,
+          "modifiedCount": 0,
+          "upsertedCount": 1,
+          "upsertedId": 4
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            },
+            {
+              "_id": 4,
+              "x": 1
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Command/ListCollectionsTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Command/ListCollectionsTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..333152561adcc847800bc13be97a93bb0dd0280f
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Command/ListCollectionsTest.php	
@@ -0,0 +1,38 @@
+<?php
+
+namespace MongoDB\Tests\Command;
+
+use MongoDB\Command\ListCollections;
+use MongoDB\Exception\InvalidArgumentException;
+use MongoDB\Tests\TestCase;
+
+class ListCollectionsTest extends TestCase
+{
+    /**
+     * @dataProvider provideInvalidConstructorOptions
+     */
+    public function testConstructorOptionTypeChecks(array $options)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        new ListCollections($this->getDatabaseName(), $options);
+    }
+
+    public function provideInvalidConstructorOptions()
+    {
+        $options = [];
+
+        foreach ($this->getInvalidDocumentValues() as $value) {
+            $options[][] = ['filter' => $value];
+        }
+
+        foreach ($this->getInvalidIntegerValues() as $value) {
+            $options[][] = ['maxTimeMS' => $value];
+        }
+
+        foreach ($this->getInvalidSessionValues() as $value) {
+            $options[][] = ['session' => $value];
+        }
+
+        return $options;
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Command/ListDatabasesTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Command/ListDatabasesTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..d2ce9562396efe4a0951283e242b08008dd0789d
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Command/ListDatabasesTest.php	
@@ -0,0 +1,46 @@
+<?php
+
+namespace MongoDB\Tests\Command;
+
+use MongoDB\Command\ListDatabases;
+use MongoDB\Exception\InvalidArgumentException;
+use MongoDB\Tests\TestCase;
+
+class ListDatabasesTest extends TestCase
+{
+    /**
+     * @dataProvider provideInvalidConstructorOptions
+     */
+    public function testConstructorOptionTypeChecks(array $options)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        new ListDatabases($options);
+    }
+
+    public function provideInvalidConstructorOptions()
+    {
+        $options = [];
+
+        foreach ($this->getInvalidBooleanValues() as $value) {
+            $options[][] = ['authorizedDatabases' => $value];
+        }
+
+        foreach ($this->getInvalidDocumentValues() as $value) {
+            $options[][] = ['filter' => $value];
+        }
+
+        foreach ($this->getInvalidIntegerValues() as $value) {
+            $options[][] = ['maxTimeMS' => $value];
+        }
+
+        foreach ($this->getInvalidBooleanValues() as $value) {
+            $options[][] = ['nameOnly' => $value];
+        }
+
+        foreach ($this->getInvalidSessionValues() as $value) {
+            $options[][] = ['session' => $value];
+        }
+
+        return $options;
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/CommandObserver.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/CommandObserver.php
new file mode 100644
index 0000000000000000000000000000000000000000..44d0fa4ef0112e0a78e3ca9c5755e21de5de8aea
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/CommandObserver.php	
@@ -0,0 +1,58 @@
+<?php
+
+namespace MongoDB\Tests;
+
+use MongoDB\Driver\Monitoring\CommandFailedEvent;
+use MongoDB\Driver\Monitoring\CommandStartedEvent;
+use MongoDB\Driver\Monitoring\CommandSubscriber;
+use MongoDB\Driver\Monitoring\CommandSucceededEvent;
+use Throwable;
+use function call_user_func;
+use function MongoDB\Driver\Monitoring\addSubscriber;
+use function MongoDB\Driver\Monitoring\removeSubscriber;
+
+/**
+ * Observes command documents using the driver's monitoring API.
+ */
+class CommandObserver implements CommandSubscriber
+{
+    /** @var array */
+    private $commands = [];
+
+    public function observe(callable $execution, callable $commandCallback)
+    {
+        $this->commands = [];
+
+        addSubscriber($this);
+
+        try {
+            call_user_func($execution);
+        } catch (Throwable $executionException) {
+        }
+
+        removeSubscriber($this);
+
+        foreach ($this->commands as $command) {
+            call_user_func($commandCallback, $command);
+        }
+
+        if (isset($executionException)) {
+            throw $executionException;
+        }
+    }
+
+    public function commandStarted(CommandStartedEvent $event)
+    {
+        $this->commands[$event->getRequestId()]['started'] = $event;
+    }
+
+    public function commandSucceeded(CommandSucceededEvent $event)
+    {
+        $this->commands[$event->getRequestId()]['succeeded'] = $event;
+    }
+
+    public function commandFailed(CommandFailedEvent $event)
+    {
+        $this->commands[$event->getRequestId()]['failed'] = $event;
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Database/CollectionManagementFunctionalTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Database/CollectionManagementFunctionalTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..246ceebb944024fc56a6ebe74e105f518eda045a
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Database/CollectionManagementFunctionalTest.php	
@@ -0,0 +1,148 @@
+<?php
+
+namespace MongoDB\Tests\Database;
+
+use InvalidArgumentException;
+use MongoDB\Driver\BulkWrite;
+use MongoDB\Model\CollectionInfo;
+use MongoDB\Model\CollectionInfoIterator;
+use function call_user_func;
+use function is_callable;
+use function sprintf;
+
+/**
+ * Functional tests for collection management methods.
+ */
+class CollectionManagementFunctionalTest extends FunctionalTestCase
+{
+    public function testCreateCollection()
+    {
+        $that = $this;
+        $basicCollectionName = $this->getCollectionName() . '.basic';
+
+        $commandResult = $this->database->createCollection($basicCollectionName);
+        $this->assertCommandSucceeded($commandResult);
+        $this->assertCollectionExists($basicCollectionName, function (CollectionInfo $info) use ($that) {
+            $that->assertFalse($info->isCapped());
+        });
+
+        $cappedCollectionName = $this->getCollectionName() . '.capped';
+        $cappedCollectionOptions = [
+            'capped' => true,
+            'max' => 100,
+            'size' => 1048576,
+        ];
+
+        $commandResult = $this->database->createCollection($cappedCollectionName, $cappedCollectionOptions);
+        $this->assertCommandSucceeded($commandResult);
+        $this->assertCollectionExists($cappedCollectionName, function (CollectionInfo $info) use ($that) {
+            $that->assertTrue($info->isCapped());
+            $that->assertEquals(100, $info->getCappedMax());
+            $that->assertEquals(1048576, $info->getCappedSize());
+        });
+    }
+
+    public function testDropCollection()
+    {
+        $bulkWrite = new BulkWrite();
+        $bulkWrite->insert(['x' => 1]);
+
+        $writeResult = $this->manager->executeBulkWrite($this->getNamespace(), $bulkWrite);
+        $this->assertEquals(1, $writeResult->getInsertedCount());
+
+        $commandResult = $this->database->dropCollection($this->getCollectionName());
+        $this->assertCommandSucceeded($commandResult);
+        $this->assertCollectionCount($this->getNamespace(), 0);
+    }
+
+    public function testListCollections()
+    {
+        $commandResult = $this->database->createCollection($this->getCollectionName());
+        $this->assertCommandSucceeded($commandResult);
+
+        $collections = $this->database->listCollections();
+        $this->assertInstanceOf(CollectionInfoIterator::class, $collections);
+
+        foreach ($collections as $collection) {
+            $this->assertInstanceOf(CollectionInfo::class, $collection);
+        }
+    }
+
+    public function testListCollectionsWithFilter()
+    {
+        $commandResult = $this->database->createCollection($this->getCollectionName());
+        $this->assertCommandSucceeded($commandResult);
+
+        $collectionName = $this->getCollectionName();
+        $options = ['filter' => ['name' => $collectionName]];
+
+        $collections = $this->database->listCollections($options);
+        $this->assertInstanceOf(CollectionInfoIterator::class, $collections);
+
+        foreach ($collections as $collection) {
+            $this->assertInstanceOf(CollectionInfo::class, $collection);
+            $this->assertEquals($collectionName, $collection->getName());
+        }
+    }
+
+    public function testListCollectionNames()
+    {
+        $commandResult = $this->database->createCollection($this->getCollectionName());
+        $this->assertCommandSucceeded($commandResult);
+
+        $collections = $this->database->listCollectionNames();
+
+        foreach ($collections as $collection) {
+            $this->assertIsString($collection);
+        }
+    }
+
+    public function testListCollectionNamesWithFilter()
+    {
+        $commandResult = $this->database->createCollection($this->getCollectionName());
+        $this->assertCommandSucceeded($commandResult);
+
+        $collectionName = $this->getCollectionName();
+        $options = ['filter' => ['name' => $collectionName]];
+
+        $collections = $this->database->listCollectionNames($options);
+
+        foreach ($collections as $collection) {
+            $this->assertEquals($collectionName, $collection);
+        }
+    }
+
+    /**
+     * Asserts that a collection with the given name exists in the database.
+     *
+     * An optional $callback may be provided, which should take a CollectionInfo
+     * argument as its first and only parameter. If a CollectionInfo matching
+     * the given name is found, it will be passed to the callback, which may
+     * perform additional assertions.
+     *
+     * @param callable $callback
+     */
+    private function assertCollectionExists($collectionName, $callback = null)
+    {
+        if ($callback !== null && ! is_callable($callback)) {
+            throw new InvalidArgumentException('$callback is not a callable');
+        }
+
+        $collections = $this->database->listCollections();
+
+        $foundCollection = null;
+
+        foreach ($collections as $collection) {
+            if ($collection->getName() === $collectionName) {
+                $foundCollection = $collection;
+                break;
+            }
+        }
+
+        $this->assertNotNull($foundCollection, sprintf('Found %s collection in the database', $collectionName));
+
+        if ($callback !== null) {
+            call_user_func($callback, $foundCollection);
+        }
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Database/DatabaseFunctionalTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Database/DatabaseFunctionalTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..b913697b2a4b91165e774564dd37bcc7118728c9
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Database/DatabaseFunctionalTest.php	
@@ -0,0 +1,351 @@
+<?php
+
+namespace MongoDB\Tests\Database;
+
+use MongoDB\Database;
+use MongoDB\Driver\BulkWrite;
+use MongoDB\Driver\Cursor;
+use MongoDB\Driver\ReadConcern;
+use MongoDB\Driver\ReadPreference;
+use MongoDB\Driver\WriteConcern;
+use MongoDB\Exception\InvalidArgumentException;
+use MongoDB\Operation\CreateIndexes;
+use function array_key_exists;
+use function current;
+
+/**
+ * Functional tests for the Database class.
+ */
+class DatabaseFunctionalTest extends FunctionalTestCase
+{
+    /**
+     * @dataProvider provideInvalidDatabaseNames
+     */
+    public function testConstructorDatabaseNameArgument($databaseName)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        // TODO: Move to unit test once ManagerInterface can be mocked (PHPC-378)
+        new Database($this->manager, $databaseName);
+    }
+
+    public function provideInvalidDatabaseNames()
+    {
+        return [
+            [null],
+            [''],
+        ];
+    }
+
+    /**
+     * @dataProvider provideInvalidConstructorOptions
+     */
+    public function testConstructorOptionTypeChecks(array $options)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        new Database($this->manager, $this->getDatabaseName(), $options);
+    }
+
+    public function provideInvalidConstructorOptions()
+    {
+        $options = [];
+
+        foreach ($this->getInvalidReadConcernValues() as $value) {
+            $options[][] = ['readConcern' => $value];
+        }
+
+        foreach ($this->getInvalidReadPreferenceValues() as $value) {
+            $options[][] = ['readPreference' => $value];
+        }
+
+        foreach ($this->getInvalidArrayValues() as $value) {
+            $options[][] = ['typeMap' => $value];
+        }
+
+        foreach ($this->getInvalidWriteConcernValues() as $value) {
+            $options[][] = ['writeConcern' => $value];
+        }
+
+        return $options;
+    }
+
+    public function testGetManager()
+    {
+        $this->assertSame($this->manager, $this->database->getManager());
+    }
+
+    public function testToString()
+    {
+        $this->assertEquals($this->getDatabaseName(), (string) $this->database);
+    }
+
+    public function getGetDatabaseName()
+    {
+        $this->assertEquals($this->getDatabaseName(), $this->database->getDatabaseName());
+    }
+
+    public function testCommand()
+    {
+        $command = ['isMaster' => 1];
+        $options = [
+            'readPreference' => new ReadPreference(ReadPreference::RP_PRIMARY),
+        ];
+
+        $cursor = $this->database->command($command, $options);
+
+        $this->assertInstanceOf(Cursor::class, $cursor);
+        $commandResult = current($cursor->toArray());
+
+        $this->assertCommandSucceeded($commandResult);
+        $this->assertObjectHasAttribute('ismaster', $commandResult);
+        $this->assertTrue($commandResult->ismaster);
+    }
+
+    public function testCommandDoesNotInheritReadPreference()
+    {
+        if (! $this->isReplicaSet()) {
+            $this->markTestSkipped('Test only applies to replica sets');
+        }
+
+        $this->database = new Database($this->manager, $this->getDatabaseName(), ['readPreference' => new ReadPreference(ReadPreference::RP_SECONDARY)]);
+
+        $command = ['ping' => 1];
+
+        $cursor = $this->database->command($command);
+
+        $this->assertInstanceOf(Cursor::class, $cursor);
+        $this->assertTrue($cursor->getServer()->isPrimary());
+    }
+
+    public function testCommandAppliesTypeMapToCursor()
+    {
+        $command = ['isMaster' => 1];
+        $options = [
+            'readPreference' => new ReadPreference(ReadPreference::RP_PRIMARY),
+            'typeMap' => ['root' => 'array'],
+        ];
+
+        $cursor = $this->database->command($command, $options);
+
+        $this->assertInstanceOf(Cursor::class, $cursor);
+        $commandResult = current($cursor->toArray());
+
+        $this->assertCommandSucceeded($commandResult);
+        $this->assertIsArray($commandResult);
+        $this->assertArrayHasKey('ismaster', $commandResult);
+        $this->assertTrue($commandResult['ismaster']);
+    }
+
+    /**
+     * @dataProvider provideInvalidDocumentValues
+     */
+    public function testCommandCommandArgumentTypeCheck($command)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        $this->database->command($command);
+    }
+
+    public function testDrop()
+    {
+        $bulkWrite = new BulkWrite();
+        $bulkWrite->insert(['x' => 1]);
+
+        $writeResult = $this->manager->executeBulkWrite($this->getNamespace(), $bulkWrite);
+        $this->assertEquals(1, $writeResult->getInsertedCount());
+
+        $commandResult = $this->database->drop();
+        $this->assertCommandSucceeded($commandResult);
+        $this->assertCollectionCount($this->getNamespace(), 0);
+    }
+
+    public function testGetSelectsCollectionAndInheritsOptions()
+    {
+        $databaseOptions = ['writeConcern' => new WriteConcern(WriteConcern::MAJORITY)];
+
+        $database = new Database($this->manager, $this->getDatabaseName(), $databaseOptions);
+        $collection = $database->{$this->getCollectionName()};
+        $debug = $collection->__debugInfo();
+
+        $this->assertSame($this->manager, $debug['manager']);
+        $this->assertSame($this->getDatabaseName(), $debug['databaseName']);
+        $this->assertSame($this->getCollectionName(), $debug['collectionName']);
+        $this->assertInstanceOf(WriteConcern::class, $debug['writeConcern']);
+        $this->assertSame(WriteConcern::MAJORITY, $debug['writeConcern']->getW());
+    }
+
+    public function testModifyCollection()
+    {
+        $this->database->createCollection($this->getCollectionName());
+
+        $indexes = [['key' => ['lastAccess' => 1], 'expireAfterSeconds' => 3]];
+        $createIndexes = new CreateIndexes($this->getDatabaseName(), $this->getCollectionName(), $indexes);
+        $createIndexes->execute($this->getPrimaryServer());
+
+        $commandResult = $this->database->modifyCollection(
+            $this->getCollectionName(),
+            ['index' => ['keyPattern' => ['lastAccess' => 1], 'expireAfterSeconds' => 1000]],
+            ['typeMap' => ['root' => 'array', 'document' => 'array']]
+        );
+        $this->assertCommandSucceeded($commandResult);
+
+        $commandResult = (array) $commandResult;
+
+        if (array_key_exists('raw', $commandResult)) {
+            /* Sharded environment, where we only assert if a shard had a successful update. For
+             * non-primary shards that don't have chunks for the collection, the result contains a
+             * "ns does not exist" error. */
+            foreach ($commandResult['raw'] as $shard) {
+                if (array_key_exists('ok', $shard) && $shard['ok'] == 1) {
+                    $this->assertSame(3, $shard['expireAfterSeconds_old']);
+                    $this->assertSame(1000, $shard['expireAfterSeconds_new']);
+                }
+            }
+        } else {
+            $this->assertSame(3, $commandResult['expireAfterSeconds_old']);
+            $this->assertSame(1000, $commandResult['expireAfterSeconds_new']);
+        }
+    }
+
+    public function testSelectCollectionInheritsOptions()
+    {
+        $databaseOptions = [
+            'readConcern' => new ReadConcern(ReadConcern::LOCAL),
+            'readPreference' => new ReadPreference(ReadPreference::RP_SECONDARY_PREFERRED),
+            'typeMap' => ['root' => 'array'],
+            'writeConcern' => new WriteConcern(WriteConcern::MAJORITY),
+        ];
+
+        $database = new Database($this->manager, $this->getDatabaseName(), $databaseOptions);
+        $collection = $database->selectCollection($this->getCollectionName());
+        $debug = $collection->__debugInfo();
+
+        $this->assertSame($this->manager, $debug['manager']);
+        $this->assertSame($this->getDatabaseName(), $debug['databaseName']);
+        $this->assertSame($this->getCollectionName(), $debug['collectionName']);
+        $this->assertInstanceOf(ReadConcern::class, $debug['readConcern']);
+        $this->assertSame(ReadConcern::LOCAL, $debug['readConcern']->getLevel());
+        $this->assertInstanceOf(ReadPreference::class, $debug['readPreference']);
+        $this->assertSame(ReadPreference::RP_SECONDARY_PREFERRED, $debug['readPreference']->getMode());
+        $this->assertIsArray($debug['typeMap']);
+        $this->assertSame(['root' => 'array'], $debug['typeMap']);
+        $this->assertInstanceOf(WriteConcern::class, $debug['writeConcern']);
+        $this->assertSame(WriteConcern::MAJORITY, $debug['writeConcern']->getW());
+    }
+
+    public function testSelectCollectionPassesOptions()
+    {
+        $collectionOptions = [
+            'readConcern' => new ReadConcern(ReadConcern::LOCAL),
+            'readPreference' => new ReadPreference(ReadPreference::RP_SECONDARY_PREFERRED),
+            'typeMap' => ['root' => 'array'],
+            'writeConcern' => new WriteConcern(WriteConcern::MAJORITY),
+        ];
+
+        $collection = $this->database->selectCollection($this->getCollectionName(), $collectionOptions);
+        $debug = $collection->__debugInfo();
+
+        $this->assertInstanceOf(ReadConcern::class, $debug['readConcern']);
+        $this->assertSame(ReadConcern::LOCAL, $debug['readConcern']->getLevel());
+        $this->assertInstanceOf(ReadPreference::class, $debug['readPreference']);
+        $this->assertSame(ReadPreference::RP_SECONDARY_PREFERRED, $debug['readPreference']->getMode());
+        $this->assertIsArray($debug['typeMap']);
+        $this->assertSame(['root' => 'array'], $debug['typeMap']);
+        $this->assertInstanceOf(WriteConcern::class, $debug['writeConcern']);
+        $this->assertSame(WriteConcern::MAJORITY, $debug['writeConcern']->getW());
+    }
+
+    public function testSelectGridFSBucketInheritsOptions()
+    {
+        $databaseOptions = [
+            'readConcern' => new ReadConcern(ReadConcern::LOCAL),
+            'readPreference' => new ReadPreference(ReadPreference::RP_SECONDARY_PREFERRED),
+            'writeConcern' => new WriteConcern(WriteConcern::MAJORITY),
+        ];
+
+        $database = new Database($this->manager, $this->getDatabaseName(), $databaseOptions);
+        $bucket = $database->selectGridFSBucket();
+        $debug = $bucket->__debugInfo();
+
+        $this->assertSame($this->manager, $debug['manager']);
+        $this->assertSame($this->getDatabaseName(), $debug['databaseName']);
+        $this->assertSame('fs', $debug['bucketName']);
+        $this->assertSame(261120, $debug['chunkSizeBytes']);
+        $this->assertInstanceOf(ReadConcern::class, $debug['readConcern']);
+        $this->assertSame(ReadConcern::LOCAL, $debug['readConcern']->getLevel());
+        $this->assertInstanceOf(ReadPreference::class, $debug['readPreference']);
+        $this->assertSame(ReadPreference::RP_SECONDARY_PREFERRED, $debug['readPreference']->getMode());
+        $this->assertInstanceOf(WriteConcern::class, $debug['writeConcern']);
+        $this->assertSame(WriteConcern::MAJORITY, $debug['writeConcern']->getW());
+    }
+
+    public function testSelectGridFSBucketPassesOptions()
+    {
+        $bucketOptions = [
+            'bucketName' => 'custom_fs',
+            'chunkSizeBytes' => 8192,
+            'readConcern' => new ReadConcern(ReadConcern::LOCAL),
+            'readPreference' => new ReadPreference(ReadPreference::RP_SECONDARY_PREFERRED),
+            'writeConcern' => new WriteConcern(WriteConcern::MAJORITY),
+        ];
+
+        $database = new Database($this->manager, $this->getDatabaseName());
+        $bucket = $database->selectGridFSBucket($bucketOptions);
+        $debug = $bucket->__debugInfo();
+
+        $this->assertSame($this->getDatabaseName(), $debug['databaseName']);
+        $this->assertSame('custom_fs', $debug['bucketName']);
+        $this->assertSame(8192, $debug['chunkSizeBytes']);
+        $this->assertInstanceOf(ReadConcern::class, $debug['readConcern']);
+        $this->assertSame(ReadConcern::LOCAL, $debug['readConcern']->getLevel());
+        $this->assertInstanceOf(ReadPreference::class, $debug['readPreference']);
+        $this->assertSame(ReadPreference::RP_SECONDARY_PREFERRED, $debug['readPreference']->getMode());
+        $this->assertInstanceOf(WriteConcern::class, $debug['writeConcern']);
+        $this->assertSame(WriteConcern::MAJORITY, $debug['writeConcern']->getW());
+    }
+
+    public function testWithOptionsInheritsOptions()
+    {
+        $databaseOptions = [
+            'readConcern' => new ReadConcern(ReadConcern::LOCAL),
+            'readPreference' => new ReadPreference(ReadPreference::RP_SECONDARY_PREFERRED),
+            'typeMap' => ['root' => 'array'],
+            'writeConcern' => new WriteConcern(WriteConcern::MAJORITY),
+        ];
+
+        $database = new Database($this->manager, $this->getDatabaseName(), $databaseOptions);
+        $clone = $database->withOptions();
+        $debug = $clone->__debugInfo();
+
+        $this->assertSame($this->manager, $debug['manager']);
+        $this->assertSame($this->getDatabaseName(), $debug['databaseName']);
+        $this->assertInstanceOf(ReadConcern::class, $debug['readConcern']);
+        $this->assertSame(ReadConcern::LOCAL, $debug['readConcern']->getLevel());
+        $this->assertInstanceOf(ReadPreference::class, $debug['readPreference']);
+        $this->assertSame(ReadPreference::RP_SECONDARY_PREFERRED, $debug['readPreference']->getMode());
+        $this->assertIsArray($debug['typeMap']);
+        $this->assertSame(['root' => 'array'], $debug['typeMap']);
+        $this->assertInstanceOf(WriteConcern::class, $debug['writeConcern']);
+        $this->assertSame(WriteConcern::MAJORITY, $debug['writeConcern']->getW());
+    }
+
+    public function testWithOptionsPassesOptions()
+    {
+        $databaseOptions = [
+            'readConcern' => new ReadConcern(ReadConcern::LOCAL),
+            'readPreference' => new ReadPreference(ReadPreference::RP_SECONDARY_PREFERRED),
+            'typeMap' => ['root' => 'array'],
+            'writeConcern' => new WriteConcern(WriteConcern::MAJORITY),
+        ];
+
+        $clone = $this->database->withOptions($databaseOptions);
+        $debug = $clone->__debugInfo();
+
+        $this->assertInstanceOf(ReadConcern::class, $debug['readConcern']);
+        $this->assertSame(ReadConcern::LOCAL, $debug['readConcern']->getLevel());
+        $this->assertInstanceOf(ReadPreference::class, $debug['readPreference']);
+        $this->assertSame(ReadPreference::RP_SECONDARY_PREFERRED, $debug['readPreference']->getMode());
+        $this->assertIsArray($debug['typeMap']);
+        $this->assertSame(['root' => 'array'], $debug['typeMap']);
+        $this->assertInstanceOf(WriteConcern::class, $debug['writeConcern']);
+        $this->assertSame(WriteConcern::MAJORITY, $debug['writeConcern']->getW());
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Database/FunctionalTestCase.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Database/FunctionalTestCase.php
new file mode 100644
index 0000000000000000000000000000000000000000..186df2239b13712b757e6f36840c05df24ecf778
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Database/FunctionalTestCase.php	
@@ -0,0 +1,26 @@
+<?php
+
+namespace MongoDB\Tests\Database;
+
+use MongoDB\Database;
+use MongoDB\Tests\FunctionalTestCase as BaseFunctionalTestCase;
+use Symfony\Bridge\PhpUnit\SetUpTearDownTrait;
+
+/**
+ * Base class for Database functional tests.
+ */
+abstract class FunctionalTestCase extends BaseFunctionalTestCase
+{
+    use SetUpTearDownTrait;
+
+    /** @var Database */
+    protected $database;
+
+    private function doSetUp()
+    {
+        parent::setUp();
+
+        $this->database = new Database($this->manager, $this->getDatabaseName());
+        $this->database->drop();
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/DocumentationExamplesTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/DocumentationExamplesTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..c59058ce922039a517f1ac384ddaee7b16e74bbc
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/DocumentationExamplesTest.php	
@@ -0,0 +1,1635 @@
+<?php
+
+namespace MongoDB\Tests;
+
+use MongoDB\BSON\ObjectId;
+use MongoDB\BSON\UTCDateTime;
+use MongoDB\Client;
+use MongoDB\Database;
+use MongoDB\Driver\Cursor;
+use MongoDB\Driver\Exception\ConnectionTimeoutException;
+use MongoDB\Driver\ReadPreference;
+use MongoDB\Driver\WriteConcern;
+use Symfony\Bridge\PhpUnit\SetUpTearDownTrait;
+use function in_array;
+use function ob_end_clean;
+use function ob_start;
+use function var_dump;
+use function version_compare;
+
+/**
+ * Documentation examples to be parsed for inclusion in the MongoDB manual.
+ *
+ * @see https://jira.mongodb.org/browse/DRIVERS-356
+ * @see https://jira.mongodb.org/browse/DRIVERS-488
+ * @see https://jira.mongodb.org/browse/DRIVERS-547
+ */
+class DocumentationExamplesTest extends FunctionalTestCase
+{
+    use SetUpTearDownTrait;
+
+    private function doSetUp()
+    {
+        parent::setUp();
+
+        $this->dropCollection();
+    }
+
+    private function doTearDown()
+    {
+        if ($this->hasFailed()) {
+            return;
+        }
+
+        $this->dropCollection();
+
+        parent::tearDown();
+    }
+
+    public function testExample_1_2()
+    {
+        $db = new Database($this->manager, $this->getDatabaseName());
+
+        // Start Example 1
+        $insertOneResult = $db->inventory->insertOne([
+            'item' => 'canvas',
+            'qty' => 100,
+            'tags' => ['cotton'],
+            'size' => ['h' => 28, 'w' => 35.5, 'uom' => 'cm'],
+        ]);
+        // End Example 1
+
+        $this->assertSame(1, $insertOneResult->getInsertedCount());
+        $this->assertInstanceOf(ObjectId::class, $insertOneResult->getInsertedId());
+        $this->assertInventoryCount(1);
+
+        // Start Example 2
+        $cursor = $db->inventory->find(['item' => 'canvas']);
+        // End Example 2
+
+        $this->assertCursorCount(1, $cursor);
+    }
+
+    public function testExample_3()
+    {
+        $db = new Database($this->manager, $this->getDatabaseName());
+
+        // Start Example 3
+        $insertManyResult = $db->inventory->insertMany([
+            [
+                'item' => 'journal',
+                'qty' => 25,
+                'tags' => ['blank', 'red'],
+                'size' => ['h' => 14, 'w' => 21, 'uom' => 'cm'],
+            ],
+            [
+                'item' => 'mat',
+                'qty' => 85,
+                'tags' => ['gray'],
+                'size' => ['h' => 27.9, 'w' => 35.5, 'uom' => 'cm'],
+            ],
+            [
+                'item' => 'mousepad',
+                'qty' => 25,
+                'tags' => ['gel', 'blue'],
+                'size' => ['h' => 19, 'w' => 22.85, 'uom' => 'cm'],
+            ],
+        ]);
+        // End Example 3
+
+        $this->assertSame(3, $insertManyResult->getInsertedCount());
+        foreach ($insertManyResult->getInsertedIds() as $id) {
+            $this->assertInstanceOf(ObjectId::class, $id);
+        }
+        $this->assertInventoryCount(3);
+    }
+
+    public function testExample_6_13()
+    {
+        $db = new Database($this->manager, $this->getDatabaseName());
+
+        // Start Example 6
+        $insertManyResult = $db->inventory->insertMany([
+            [
+                'item' => 'journal',
+                'qty' => 25,
+                'size' => ['h' => 14, 'w' => 21, 'uom' => 'cm'],
+                'status' => 'A',
+            ],
+            [
+                'item' => 'notebook',
+                'qty' => 50,
+                'size' => ['h' => 8.5, 'w' => 11, 'uom' => 'in'],
+                'status' => 'A',
+            ],
+            [
+                'item' => 'paper',
+                'qty' => 100,
+                'size' => ['h' => 8.5, 'w' => 11, 'uom' => 'in'],
+                'status' => 'D',
+            ],
+            [
+                'item' => 'planner',
+                'qty' => 75,
+                'size' => ['h' => 22.85, 'w' => 30, 'uom' => 'cm'],
+                'status' => 'D',
+            ],
+            [
+                'item' => 'postcard',
+                'qty' => 45,
+                'size' => ['h' => 10, 'w' => 15.25, 'uom' => 'cm'],
+                'status' => 'A',
+            ],
+        ]);
+        // End Example 6
+
+        $this->assertSame(5, $insertManyResult->getInsertedCount());
+        foreach ($insertManyResult->getInsertedIds() as $id) {
+            $this->assertInstanceOf(ObjectId::class, $id);
+        }
+        $this->assertInventoryCount(5);
+
+        // Start Example 7
+        $cursor = $db->inventory->find([]);
+        // End Example 7
+
+        $this->assertCursorCount(5, $cursor);
+
+        // Start Example 8
+        $cursor = $db->inventory->find();
+        // End Example 8
+
+        $this->assertCursorCount(5, $cursor);
+
+        // Start Example 9
+        $cursor = $db->inventory->find(['status' => 'D']);
+        // End Example 9
+
+        $this->assertCursorCount(2, $cursor);
+
+        // Start Example 10
+        $cursor = $db->inventory->find(['status' => ['$in' => ['A', 'D']]]);
+        // End Example 10
+
+        $this->assertCursorCount(5, $cursor);
+
+        // Start Example 11
+        $cursor = $db->inventory->find([
+            'status' => 'A',
+            'qty' => ['$lt' => 30],
+        ]);
+        // End Example 11
+
+        $this->assertCursorCount(1, $cursor);
+
+        // Start Example 12
+        $cursor = $db->inventory->find([
+            '$or' => [
+                ['status' => 'A'],
+                ['qty' => ['$lt' => 30]],
+            ],
+        ]);
+        // End Example 12
+
+        $this->assertCursorCount(3, $cursor);
+
+        // Start Example 13
+        $cursor = $db->inventory->find([
+            'status' => 'A',
+            '$or' => [
+                ['qty' => ['$lt' => 30]],
+                // Alternatively: ['item' => new \MongoDB\BSON\Regex('^p')]
+                ['item' => ['$regex' => '^p']],
+            ],
+        ]);
+        // End Example 13
+
+        $this->assertCursorCount(2, $cursor);
+    }
+
+    public function testExample_14_19()
+    {
+        $db = new Database($this->manager, $this->getDatabaseName());
+
+        // Start Example 14
+        $insertManyResult = $db->inventory->insertMany([
+            [
+                'item' => 'journal',
+                'qty' => 25,
+                'size' => ['h' => 14, 'w' => 21, 'uom' => 'cm'],
+                'status' => 'A',
+            ],
+            [
+                'item' => 'notebook',
+                'qty' => 50,
+                'size' => ['h' => 8.5, 'w' => 11, 'uom' => 'in'],
+                'status' => 'A',
+            ],
+            [
+                'item' => 'paper',
+                'qty' => 100,
+                'size' => ['h' => 8.5, 'w' => 11, 'uom' => 'in'],
+                'status' => 'D',
+            ],
+            [
+                'item' => 'planner',
+                'qty' => 75,
+                'size' => ['h' => 22.85, 'w' => 30, 'uom' => 'cm'],
+                'status' => 'D',
+            ],
+            [
+                'item' => 'postcard',
+                'qty' => 45,
+                'size' => ['h' => 10, 'w' => 15.25, 'uom' => 'cm'],
+                'status' => 'A',
+            ],
+        ]);
+        // End Example 14
+
+        $this->assertSame(5, $insertManyResult->getInsertedCount());
+        foreach ($insertManyResult->getInsertedIds() as $id) {
+            $this->assertInstanceOf(ObjectId::class, $id);
+        }
+        $this->assertInventoryCount(5);
+
+        // Start Example 15
+        $cursor = $db->inventory->find(['size' => ['h' => 14, 'w' => 21, 'uom' => 'cm']]);
+        // End Example 15
+
+        $this->assertCursorCount(1, $cursor);
+
+        // Start Example 16
+        $cursor = $db->inventory->find(['size' => ['w' => 21, 'h' => 14, 'uom' => 'cm']]);
+        // End Example 16
+
+        $this->assertCursorCount(0, $cursor);
+
+        // Start Example 17
+        $cursor = $db->inventory->find(['size.uom' => 'in']);
+        // End Example 17
+
+        $this->assertCursorCount(2, $cursor);
+
+        // Start Example 18
+        $cursor = $db->inventory->find(['size.h' => ['$lt' => 15]]);
+        // End Example 18
+
+        $this->assertCursorCount(4, $cursor);
+
+        // Start Example 19
+        $cursor = $db->inventory->find([
+            'size.h' => ['$lt' => 15],
+            'size.uom' => 'in',
+            'status' => 'D',
+        ]);
+        // End Example 19
+
+        $this->assertCursorCount(1, $cursor);
+    }
+
+    public function testExample_20_28()
+    {
+        $db = new Database($this->manager, $this->getDatabaseName());
+
+        // Start Example 20
+        $insertManyResult = $db->inventory->insertMany([
+            [
+                'item' => 'journal',
+                'qty' => 25,
+                'tags' => ['blank', 'red'],
+                'dim_cm' => [14, 21],
+            ],
+            [
+                'item' => 'notebook',
+                'qty' => 50,
+                'tags' => ['red', 'blank'],
+                'dim_cm' => [14, 21],
+            ],
+            [
+                'item' => 'paper',
+                'qty' => 100,
+                'tags' => ['red', 'blank', 'plain'],
+                'dim_cm' => [14, 21],
+            ],
+            [
+                'item' => 'planner',
+                'qty' => 75,
+                'tags' => ['blank', 'red'],
+                'dim_cm' => [22.85, 30],
+            ],
+            [
+                'item' => 'postcard',
+                'qty' => 45,
+                'tags' => ['blue'],
+                'dim_cm' => [10, 15.25],
+            ],
+        ]);
+        // End Example 20
+
+        $this->assertSame(5, $insertManyResult->getInsertedCount());
+        foreach ($insertManyResult->getInsertedIds() as $id) {
+            $this->assertInstanceOf(ObjectId::class, $id);
+        }
+        $this->assertInventoryCount(5);
+
+        // Start Example 21
+        $cursor = $db->inventory->find(['tags' => ['red', 'blank']]);
+        // End Example 21
+
+        $this->assertCursorCount(1, $cursor);
+
+        // Start Example 22
+        $cursor = $db->inventory->find(['tags' => ['$all' => ['red', 'blank']]]);
+        // End Example 22
+
+        $this->assertCursorCount(4, $cursor);
+
+        // Start Example 23
+        $cursor = $db->inventory->find(['tags' => 'red']);
+        // End Example 23
+
+        $this->assertCursorCount(4, $cursor);
+
+        // Start Example 24
+        $cursor = $db->inventory->find(['dim_cm' => ['$gt' => 25]]);
+        // End Example 24
+
+        $this->assertCursorCount(1, $cursor);
+
+        // Start Example 25
+        $cursor = $db->inventory->find([
+            'dim_cm' => [
+                '$gt' => 15,
+                '$lt' => 20,
+            ],
+        ]);
+        // End Example 25
+
+        $this->assertCursorCount(4, $cursor);
+
+        // Start Example 26
+        $cursor = $db->inventory->find([
+            'dim_cm' => [
+                '$elemMatch' => [
+                    '$gt' => 22,
+                    '$lt' => 30,
+                ],
+            ],
+        ]);
+        // End Example 26
+
+        $this->assertCursorCount(1, $cursor);
+
+        // Start Example 27
+        $cursor = $db->inventory->find(['dim_cm.1' => ['$gt' => 25]]);
+        // End Example 27
+
+        $this->assertCursorCount(1, $cursor);
+
+        // Start Example 28
+        $cursor = $db->inventory->find(['tags' => ['$size' => 3]]);
+        // End Example 28
+
+        $this->assertCursorCount(1, $cursor);
+    }
+
+    public function testExample_29_37()
+    {
+        $db = new Database($this->manager, $this->getDatabaseName());
+
+        // Start Example 29
+        $insertManyResult = $db->inventory->insertMany([
+            [
+                'item' => 'journal',
+                'instock' => [
+                    ['warehouse' => 'A',  'qty' => 5],
+                    ['warehouse' => 'C',  'qty' => 15],
+                ],
+            ],
+            [
+                'item' => 'notebook',
+                'instock' => [
+                    ['warehouse' => 'C',  'qty' => 5],
+                ],
+            ],
+            [
+                'item' => 'paper',
+                'instock' => [
+                    ['warehouse' => 'A',  'qty' => 60],
+                    ['warehouse' => 'B',  'qty' => 15],
+                ],
+            ],
+            [
+                'item' => 'planner',
+                'instock' => [
+                    ['warehouse' => 'A',  'qty' => 40],
+                    ['warehouse' => 'B',  'qty' => 5],
+                ],
+            ],
+            [
+                'item' => 'postcard',
+                'instock' => [
+                    ['warehouse' => 'B',  'qty' => 15],
+                    ['warehouse' => 'C',  'qty' => 35],
+                ],
+            ],
+        ]);
+        // End Example 29
+
+        $this->assertSame(5, $insertManyResult->getInsertedCount());
+        foreach ($insertManyResult->getInsertedIds() as $id) {
+            $this->assertInstanceOf(ObjectId::class, $id);
+        }
+        $this->assertInventoryCount(5);
+
+        // Start Example 30
+        $cursor = $db->inventory->find(['instock' => ['warehouse' => 'A', 'qty' => 5]]);
+        // End Example 30
+
+        $this->assertCursorCount(1, $cursor);
+
+        // Start Example 31
+        $cursor = $db->inventory->find(['instock' => ['qty' => 5, 'warehouse' => 'A']]);
+        // End Example 31
+
+        $this->assertCursorCount(0, $cursor);
+
+        // Start Example 32
+        $cursor = $db->inventory->find(['instock.0.qty' => ['$lte' => 20]]);
+        // End Example 32
+
+        $this->assertCursorCount(3, $cursor);
+
+        // Start Example 33
+        $cursor = $db->inventory->find(['instock.qty' => ['$lte' => 20]]);
+        // End Example 33
+
+        $this->assertCursorCount(5, $cursor);
+
+        // Start Example 34
+        $cursor = $db->inventory->find(['instock' => ['$elemMatch' => ['qty' => 5, 'warehouse' => 'A']]]);
+        // End Example 34
+
+        $this->assertCursorCount(1, $cursor);
+
+        // Start Example 35
+        $cursor = $db->inventory->find(['instock' => ['$elemMatch' => ['qty' => ['$gt' => 10, '$lte' => 20]]]]);
+        // End Example 35
+
+        $this->assertCursorCount(3, $cursor);
+
+        // Start Example 36
+        $cursor = $db->inventory->find(['instock.qty' => ['$gt' => 10, '$lte' => 20]]);
+        // End Example 36
+
+        $this->assertCursorCount(4, $cursor);
+
+        // Start Example 37
+        $cursor = $db->inventory->find(['instock.qty' => 5, 'instock.warehouse' => 'A']);
+        // End Example 37
+
+        $this->assertCursorCount(2, $cursor);
+    }
+
+    public function testExample_38_41()
+    {
+        $db = new Database($this->manager, $this->getDatabaseName());
+
+        // Start Example 38
+        $insertManyResult = $db->inventory->insertMany([
+            ['_id' => 1, 'item' => null],
+            ['_id' => 2],
+        ]);
+        // End Example 38
+
+        $this->assertSame(2, $insertManyResult->getInsertedCount());
+        foreach ($insertManyResult->getInsertedIds() as $id) {
+            $this->assertIsInt($id);
+        }
+        $this->assertInventoryCount(2);
+
+        // Start Example 39
+        $cursor = $db->inventory->find(['item' => null]);
+        // End Example 39
+
+        $this->assertCursorCount(2, $cursor);
+
+        // Start Example 40
+        $cursor = $db->inventory->find(['item' => ['$type' => 10]]);
+        // End Example 40
+
+        $this->assertCursorCount(1, $cursor);
+
+        // Start Example 41
+        $cursor = $db->inventory->find(['item' => ['$exists' => false]]);
+        // End Example 41
+
+        $this->assertCursorCount(1, $cursor);
+    }
+
+    public function testExample_42_50()
+    {
+        $db = new Database($this->manager, $this->getDatabaseName());
+
+        // Start Example 42
+        $insertManyResult = $db->inventory->insertMany([
+            [
+                'item' => 'journal',
+                'status' => 'A',
+                'size' => ['h' => 14, 'w' => 21, 'uom' => 'cm'],
+                'instock' => [
+                    ['warehouse' => 'A', 'qty' => 5],
+                ],
+            ],
+            [
+                'item' => 'notebook',
+                'status' => 'A',
+                'size' => ['h' => 8.5, 'w' => 11, 'uom' => 'in'],
+                'instock' => [
+                    ['warehouse' => 'C', 'qty' => 5],
+                ],
+            ],
+            [
+                'item' => 'paper',
+                'status' => 'D',
+                'size' => ['h' => 8.5, 'w' => 11, 'uom' => 'in'],
+                'instock' => [
+                    ['warehouse' => 'A', 'qty' => 60],
+                ],
+            ],
+            [
+                'item' => 'planner',
+                'status' => 'D',
+                'size' => ['h' => 22.85, 'w' => 30, 'uom' => 'cm'],
+                'instock' => [
+                    ['warehouse' => 'A', 'qty' => 40],
+                ],
+            ],
+            [
+                'item' => 'postcard',
+                'status' => 'A',
+                'size' => ['h' => 10, 'w' => 15.25, 'uom' => 'cm'],
+                'instock' => [
+                    ['warehouse' => 'B', 'qty' => 15],
+                    ['warehouse' => 'C', 'qty' => 35],
+                ],
+            ],
+        ]);
+        // End Example 42
+
+        $this->assertSame(5, $insertManyResult->getInsertedCount());
+        foreach ($insertManyResult->getInsertedIds() as $id) {
+            $this->assertInstanceOf(ObjectId::class, $id);
+        }
+        $this->assertInventoryCount(5);
+
+        // Start Example 43
+        $cursor = $db->inventory->find(['status' => 'A']);
+        // End Example 43
+
+        $documents = $cursor->toArray();
+        $this->assertCount(3, $documents);
+        foreach ($documents as $document) {
+            foreach (['_id', 'item', 'status', 'size', 'instock'] as $field) {
+                $this->assertObjectHasAttribute($field, $document);
+            }
+        }
+
+        // Start Example 44
+        $cursor = $db->inventory->find(
+            ['status' => 'A'],
+            ['projection' => ['item' => 1, 'status' => 1]]
+        );
+        // End Example 44
+
+        $documents = $cursor->toArray();
+        $this->assertCount(3, $documents);
+        foreach ($documents as $document) {
+            foreach (['_id', 'item', 'status'] as $field) {
+                $this->assertObjectHasAttribute($field, $document);
+            }
+            foreach (['size', 'instock'] as $field) {
+                $this->assertObjectNotHasAttribute($field, $document);
+            }
+        }
+
+        // Start Example 45
+        $cursor = $db->inventory->find(
+            ['status' => 'A'],
+            ['projection' => ['item' => 1, 'status' => 1, '_id' => 0]]
+        );
+        // End Example 45
+
+        $documents = $cursor->toArray();
+        $this->assertCount(3, $documents);
+        foreach ($documents as $document) {
+            foreach (['item', 'status'] as $field) {
+                $this->assertObjectHasAttribute($field, $document);
+            }
+            foreach (['_id', 'size', 'instock'] as $field) {
+                $this->assertObjectNotHasAttribute($field, $document);
+            }
+        }
+
+        // Start Example 46
+        $cursor = $db->inventory->find(
+            ['status' => 'A'],
+            ['projection' => ['status' => 0, 'instock' => 0]]
+        );
+        // End Example 46
+
+        $documents = $cursor->toArray();
+        $this->assertCount(3, $documents);
+        foreach ($documents as $document) {
+            foreach (['_id', 'item', 'size'] as $field) {
+                $this->assertObjectHasAttribute($field, $document);
+            }
+            foreach (['status', 'instock'] as $field) {
+                $this->assertObjectNotHasAttribute($field, $document);
+            }
+        }
+
+        // Start Example 47
+        $cursor = $db->inventory->find(
+            ['status' => 'A'],
+            ['projection' => ['item' => 1, 'status' => 1, 'size.uom' => 1]]
+        );
+        // End Example 47
+
+        $documents = $cursor->toArray();
+        $this->assertCount(3, $documents);
+        foreach ($documents as $document) {
+            foreach (['_id', 'item', 'status', 'size'] as $field) {
+                $this->assertObjectHasAttribute($field, $document);
+            }
+            $this->assertObjectNotHasAttribute('instock', $document);
+            $this->assertObjectHasAttribute('uom', $document->size);
+            $this->assertObjectNotHasAttribute('h', $document->size);
+            $this->assertObjectNotHasAttribute('w', $document->size);
+        }
+
+        // Start Example 48
+        $cursor = $db->inventory->find(
+            ['status' => 'A'],
+            ['projection' => ['size.uom' => 0]]
+        );
+        // End Example 48
+
+        $documents = $cursor->toArray();
+        $this->assertCount(3, $documents);
+        foreach ($documents as $document) {
+            foreach (['_id', 'item', 'status', 'size', 'instock'] as $field) {
+                $this->assertObjectHasAttribute($field, $document);
+            }
+            $this->assertObjectHasAttribute('h', $document->size);
+            $this->assertObjectHasAttribute('w', $document->size);
+            $this->assertObjectNotHasAttribute('uom', $document->size);
+        }
+
+        // Start Example 49
+        $cursor = $db->inventory->find(
+            ['status' => 'A'],
+            ['projection' => ['item' => 1, 'status' => 1, 'instock.qty' => 1]]
+        );
+        // End Example 49
+
+        $documents = $cursor->toArray();
+        $this->assertCount(3, $documents);
+        foreach ($documents as $document) {
+            foreach (['_id', 'item', 'status', 'instock'] as $field) {
+                $this->assertObjectHasAttribute($field, $document);
+            }
+            $this->assertObjectNotHasAttribute('size', $document);
+            foreach ($document->instock as $instock) {
+                $this->assertObjectHasAttribute('qty', $instock);
+                $this->assertObjectNotHasAttribute('warehouse', $instock);
+            }
+        }
+
+        // Start Example 50
+        $cursor = $db->inventory->find(
+            ['status' => 'A'],
+            ['projection' => ['item' => 1, 'status' => 1, 'instock' => ['$slice' => -1]]]
+        );
+        // End Example 50
+
+        $documents = $cursor->toArray();
+        $this->assertCount(3, $documents);
+        foreach ($documents as $document) {
+            foreach (['_id', 'item', 'status', 'instock'] as $field) {
+                $this->assertObjectHasAttribute($field, $document);
+            }
+            $this->assertObjectNotHasAttribute('size', $document);
+            $this->assertCount(1, $document->instock);
+        }
+    }
+
+    public function testExample_51_54()
+    {
+        $db = new Database($this->manager, $this->getDatabaseName());
+
+        // Start Example 51
+        $insertManyResult = $db->inventory->insertMany([
+            [
+                'item' => 'canvas',
+                'qty' => 100,
+                'size' => ['h' => 28, 'w' => 35.5, 'uom' => 'cm'],
+                'status' => 'A',
+            ],
+            [
+                'item' => 'journal',
+                'qty' => 25,
+                'size' => ['h' => 14, 'w' => 21, 'uom' => 'cm'],
+                'status' => 'A',
+            ],
+            [
+                'item' => 'mat',
+                'qty' => 85,
+                'size' => ['h' => 27.9, 'w' => 35.5, 'uom' => 'cm'],
+                'status' => 'A',
+            ],
+            [
+                'item' => 'mousepad',
+                'qty' => 25,
+                'size' => ['h' => 19, 'w' => 22.85, 'uom' => 'cm'],
+                'status' => 'P',
+            ],
+            [
+                'item' => 'notebook',
+                'qty' => 50,
+                'size' => ['h' => 8.5, 'w' => 11, 'uom' => 'in'],
+                'status' => 'P',
+            ],
+            [
+                'item' => 'paper',
+                'qty' => 100,
+                'size' => ['h' => 8.5, 'w' => 11, 'uom' => 'in'],
+                'status' => 'D',
+            ],
+            [
+                'item' => 'planner',
+                'qty' => 75,
+                'size' => ['h' => 22.85, 'w' => 30, 'uom' => 'cm'],
+                'status' => 'D',
+            ],
+            [
+                'item' => 'postcard',
+                'qty' => 45,
+                'size' => ['h' => 10, 'w' => 15.25, 'uom' => 'cm'],
+                'status' => 'A',
+            ],
+            [
+                'item' => 'sketchbook',
+                'qty' => 80,
+                'size' => ['h' => 14, 'w' => 21, 'uom' => 'cm'],
+                'status' => 'A',
+            ],
+            [
+                'item' => 'sketch pad',
+                'qty' => 95,
+                'size' => ['h' => 22.85, 'w' => 30.5, 'uom' => 'cm'],
+                'status' => 'A',
+            ],
+        ]);
+        // End Example 51
+
+        $this->assertSame(10, $insertManyResult->getInsertedCount());
+        foreach ($insertManyResult->getInsertedIds() as $id) {
+            $this->assertInstanceOf(ObjectId::class, $id);
+        }
+        $this->assertInventoryCount(10);
+
+        // Start Example 52
+        $updateResult = $db->inventory->updateOne(
+            ['item' => 'paper'],
+            [
+                '$set' => ['size.uom' => 'cm', 'status' => 'P'],
+                '$currentDate' => ['lastModified' => true],
+            ]
+        );
+        // End Example 52
+
+        $this->assertSame(1, $updateResult->getMatchedCount());
+        $this->assertSame(1, $updateResult->getModifiedCount());
+        $cursor = $db->inventory->find([
+            'item' => 'paper',
+            'size.uom' => 'cm',
+            'status' => 'P',
+            'lastModified' => ['$type' => 9],
+        ]);
+        $this->assertCursorCount(1, $cursor);
+
+        // Start Example 53
+        $updateResult = $db->inventory->updateMany(
+            ['qty' => ['$lt' => 50]],
+            [
+                '$set' => ['size.uom' => 'cm', 'status' => 'P'],
+                '$currentDate' => ['lastModified' => true],
+            ]
+        );
+        // End Example 53
+
+        $this->assertSame(3, $updateResult->getMatchedCount());
+        $this->assertSame(3, $updateResult->getModifiedCount());
+        $cursor = $db->inventory->find([
+            'qty' => ['$lt' => 50],
+            'size.uom' => 'cm',
+            'status' => 'P',
+            'lastModified' => ['$type' => 9],
+        ]);
+        $this->assertCursorCount(3, $cursor);
+
+        // Start Example 54
+        $updateResult = $db->inventory->replaceOne(
+            ['item' => 'paper'],
+            [
+                'item' => 'paper',
+                'instock' => [
+                    ['warehouse' => 'A', 'qty' => 60],
+                    ['warehouse' => 'B', 'qty' => 40],
+                ],
+            ]
+        );
+        // End Example 54
+
+        $this->assertSame(1, $updateResult->getMatchedCount());
+        $this->assertSame(1, $updateResult->getModifiedCount());
+        $cursor = $db->inventory->find([
+            'item' => 'paper',
+            'instock' => [
+                ['warehouse' => 'A', 'qty' => 60],
+                ['warehouse' => 'B', 'qty' => 40],
+            ],
+        ]);
+        $this->assertCursorCount(1, $cursor);
+    }
+
+    public function testExample_55_58()
+    {
+        $db = new Database($this->manager, $this->getDatabaseName());
+
+        // Start Example 55
+        $insertManyResult = $db->inventory->insertMany([
+            [
+                'item' => 'journal',
+                'qty' => 25,
+                'size' => ['h' => 14, 'w' => 21, 'uom' => 'cm'],
+                'status' => 'A',
+            ],
+            [
+                'item' => 'notebook',
+                'qty' => 50,
+                'size' => ['h' => 8.5, 'w' => 11, 'uom' => 'in'],
+                'status' => 'P',
+            ],
+            [
+                'item' => 'paper',
+                'qty' => 100,
+                'size' => ['h' => 8.5, 'w' => 11, 'uom' => 'in'],
+                'status' => 'D',
+            ],
+            [
+                'item' => 'planner',
+                'qty' => 75,
+                'size' => ['h' => 22.85, 'w' => 30, 'uom' => 'cm'],
+                'status' => 'D',
+            ],
+            [
+                'item' => 'postcard',
+                'qty' => 45,
+                'size' => ['h' => 10, 'w' => 15.25, 'uom' => 'cm'],
+                'status' => 'A',
+            ],
+        ]);
+        // End Example 55
+
+        $this->assertSame(5, $insertManyResult->getInsertedCount());
+        foreach ($insertManyResult->getInsertedIds() as $id) {
+            $this->assertInstanceOf(ObjectId::class, $id);
+        }
+        $this->assertInventoryCount(5);
+
+        // Start Example 57
+        $deleteResult = $db->inventory->deleteMany(['status' => 'A']);
+        // End Example 57
+
+        $this->assertSame(2, $deleteResult->getDeletedCount());
+        $cursor = $db->inventory->find(['status' => 'A']);
+        $this->assertCursorCount(0, $cursor);
+
+        // Start Example 58
+        $deleteResult = $db->inventory->deleteOne(['status' => 'D']);
+        // End Example 58
+
+        $this->assertSame(1, $deleteResult->getDeletedCount());
+        $cursor = $db->inventory->find(['status' => 'D']);
+        $this->assertCursorCount(1, $cursor);
+
+        // Start Example 56
+        $deleteResult = $db->inventory->deleteMany([]);
+        // End Example 56
+
+        $this->assertSame(2, $deleteResult->getDeletedCount());
+        $this->assertInventoryCount(0);
+    }
+
+    public function testChangeStreamExample_1_4()
+    {
+        $this->skipIfChangeStreamIsNotSupported();
+
+        if ($this->isShardedCluster()) {
+            $this->markTestSkipped('Test does not apply on sharded clusters: need more than a single getMore call on the change stream.');
+        }
+
+        $db = new Database($this->manager, $this->getDatabaseName());
+        $db->dropCollection('inventory');
+        $db->createCollection('inventory');
+
+        // Start Changestream Example 1
+        $changeStream = $db->inventory->watch();
+        $changeStream->rewind();
+
+        $firstChange = $changeStream->current();
+
+        $changeStream->next();
+
+        $secondChange = $changeStream->current();
+        // End Changestream Example 1
+
+        $this->assertNull($firstChange);
+        $this->assertNull($secondChange);
+
+        // phpcs:disable SlevomatCodingStandard.Namespaces.ReferenceUsedNamesOnly
+        // Start Changestream Example 2
+        $changeStream = $db->inventory->watch([], ['fullDocument' => \MongoDB\Operation\Watch::FULL_DOCUMENT_UPDATE_LOOKUP]);
+        $changeStream->rewind();
+
+        $firstChange = $changeStream->current();
+
+        $changeStream->next();
+
+        $secondChange = $changeStream->current();
+        // End Changestream Example 2
+        // phpcs:enable
+
+        $this->assertNull($firstChange);
+        $this->assertNull($secondChange);
+
+        $insertManyResult = $db->inventory->insertMany([
+            ['_id' => 1, 'x' => 'foo'],
+            ['_id' => 2, 'x' => 'bar'],
+        ]);
+        $this->assertEquals(2, $insertManyResult->getInsertedCount());
+
+        $changeStream->next();
+        $this->assertTrue($changeStream->valid());
+        $lastChange = $changeStream->current();
+
+        $expectedChange = [
+            '_id' => $lastChange->_id,
+            'operationType' => 'insert',
+            'fullDocument' => ['_id' => 1, 'x' => 'foo'],
+            'ns' => ['db' => $this->getDatabaseName(), 'coll' => 'inventory'],
+            'documentKey' => ['_id' => 1],
+        ];
+
+        $this->assertMatchesDocument($expectedChange, $lastChange);
+
+        // phpcs:disable SlevomatCodingStandard.Namespaces.ReferenceUsedNamesOnly
+        // Start Changestream Example 3
+        $resumeToken = $changeStream->getResumeToken();
+
+        if ($resumeToken === null) {
+            throw new \Exception('Resume token was not found');
+        }
+
+        $changeStream = $db->inventory->watch([], ['resumeAfter' => $resumeToken]);
+        $changeStream->rewind();
+
+        $firstChange = $changeStream->current();
+        // End Changestream Example 3
+        // phpcs:enable
+
+        $expectedChange = [
+            '_id' => $firstChange->_id,
+            'operationType' => 'insert',
+            'fullDocument' => ['_id' => 2, 'x' => 'bar'],
+            'ns' => ['db' => $this->getDatabaseName(), 'coll' => 'inventory'],
+            'documentKey' => ['_id' => 2],
+        ];
+
+        $this->assertMatchesDocument($expectedChange, $firstChange);
+
+        // Start Changestream Example 4
+        $pipeline = [
+            ['$match' => ['fullDocument.username' => 'alice']],
+            ['$addFields' => ['newField' => 'this is an added field!']],
+        ];
+        $changeStream = $db->inventory->watch($pipeline);
+        $changeStream->rewind();
+
+        $firstChange = $changeStream->current();
+
+        $changeStream->next();
+
+        $secondChange = $changeStream->current();
+        // End Changestream Example 4
+
+        $this->assertNull($firstChange);
+        $this->assertNull($secondChange);
+    }
+
+    public function testAggregation_example_1()
+    {
+        $db = new Database($this->manager, $this->getDatabaseName());
+
+        // Start Aggregation Example 1
+        $cursor = $db->sales->aggregate([
+            ['$match' => ['items.fruit' => 'banana']],
+            ['$sort' => ['date' => 1]],
+        ]);
+        // End Aggregation Example 1
+
+        $this->assertInstanceOf(Cursor::class, $cursor);
+    }
+
+    public function testAggregation_example_2()
+    {
+        $db = new Database($this->manager, $this->getDatabaseName());
+
+        // Start Aggregation Example 2
+        $cursor = $db->sales->aggregate([
+            ['$unwind' => '$items'],
+            ['$match' => ['items.fruit' => 'banana']],
+            [
+                '$group' => [
+                    '_id' => ['day' => ['$dayOfWeek' => '$date']],
+                    'count' => ['$sum' => '$items.quantity'],
+                ],
+            ],
+            [
+                '$project' => [
+                    'dayOfWeek' => '$_id.day',
+                    'numberSold' => '$count',
+                    '_id' => 0,
+                ],
+            ],
+            ['$sort' => ['numberSold' => 1]],
+        ]);
+        // End Aggregation Example 2
+
+        $this->assertInstanceOf(Cursor::class, $cursor);
+    }
+
+    public function testAggregation_example_3()
+    {
+        $db = new Database($this->manager, $this->getDatabaseName());
+
+        // Start Aggregation Example 3
+        $cursor = $db->sales->aggregate([
+            ['$unwind' => '$items'],
+            [
+                '$group' => [
+                    '_id' => ['day' => ['$dayOfWeek' => '$date']],
+                    'items_sold' => ['$sum' => '$items.quantity'],
+                    'revenue' => [
+                        '$sum' => [
+                            '$multiply' => ['$items.quantity', '$items.price'],
+                        ],
+                    ],
+                ],
+            ],
+            [
+                '$project' => [
+                    'day' => '$_id.day',
+                    'revenue' => 1,
+                    'items_sold' => 1,
+                    'discount' => [
+                        '$cond' => [
+                            'if' => ['$lte' => ['$revenue', 250]],
+                            'then' => 25,
+                            'else' => 0,
+                        ],
+                    ],
+                ],
+            ],
+        ]);
+        // End Aggregation Example 3
+
+        $this->assertInstanceOf(Cursor::class, $cursor);
+    }
+
+    public function testAggregation_example_4()
+    {
+        if (version_compare($this->getServerVersion(), '3.6.0', '<')) {
+            $this->markTestSkipped('$lookup does not support "let" option');
+        }
+
+        $db = new Database($this->manager, $this->getDatabaseName());
+
+        // Start Aggregation Example 4
+        $cursor = $db->air_alliances->aggregate([
+            [
+                '$lookup' => [
+                    'from' => 'air_airlines',
+                    'let' => ['constituents' => '$airlines'],
+                    'pipeline' => [[
+                        '$match' => [
+                            '$expr' => ['$in' => ['$name', '$constituents']],
+                        ],
+                    ],
+                    ],
+                    'as' => 'airlines',
+                ],
+            ],
+            [
+                '$project' => [
+                    '_id' => 0,
+                    'name' => 1,
+                    'airlines' => [
+                        '$filter' => [
+                            'input' => '$airlines',
+                            'as' => 'airline',
+                            'cond' => ['$eq' => ['$$airline.country', 'Canada']],
+                        ],
+                    ],
+                ],
+            ],
+        ]);
+        // End Aggregation Example 4
+
+        $this->assertInstanceOf(Cursor::class, $cursor);
+    }
+
+    public function testRunCommand_example_1()
+    {
+        $db = new Database($this->manager, $this->getDatabaseName());
+
+        // Start runCommand Example 1
+        $cursor = $db->command(['buildInfo' => 1]);
+        $result = $cursor->toArray()[0];
+        // End runCommand Example 1
+
+        $this->assertInstanceOf(Cursor::class, $cursor);
+    }
+
+    public function testRunCommand_example_2()
+    {
+        $db = new Database($this->manager, $this->getDatabaseName());
+        $db->dropCollection('restaurants');
+        $db->createCollection('restaurants');
+
+        // Start runCommand Example 2
+        $cursor = $db->command(['collStats' => 'restaurants']);
+        $result = $cursor->toArray()[0];
+        // End runCommand Example 2
+
+        $this->assertInstanceOf(Cursor::class, $cursor);
+    }
+
+    public function testIndex_example_1()
+    {
+        $db = new Database($this->manager, $this->getDatabaseName());
+
+        // Start Index Example 1
+        $indexName = $db->records->createIndex(['score' => 1]);
+        // End Index Example 1
+
+        $this->assertEquals('score_1', $indexName);
+    }
+
+    public function testIndex_example_2()
+    {
+        $db = new Database($this->manager, $this->getDatabaseName());
+
+        // Start Index Example 2
+        $indexName = $db->restaurants->createIndex(
+            ['cuisine' => 1, 'name' => 1],
+            ['partialFilterExpression' => ['rating' => ['$gt' => 5]]]
+        );
+        // End Index Example 2
+
+        $this->assertEquals('cuisine_1_name_1', $indexName);
+    }
+
+    // phpcs:disable SlevomatCodingStandard.Namespaces.ReferenceUsedNamesOnly
+    // phpcs:disable Squiz.Commenting.FunctionComment.WrongStyle
+    // phpcs:disable Squiz.WhiteSpace.FunctionSpacing.After
+    // Start Transactions Intro Example 1
+    private function updateEmployeeInfo1(\MongoDB\Client $client, \MongoDB\Driver\Session $session)
+    {
+        $session->startTransaction([
+            'readConcern' => new \MongoDB\Driver\ReadConcern('snapshot'),
+            'writeConcern' => new \MongoDB\Driver\WriteConcern(\MongoDB\Driver\WriteConcern::MAJORITY),
+        ]);
+
+        try {
+            $client->hr->employees->updateOne(
+                ['employee' => 3],
+                ['$set' => ['status' => 'Inactive']],
+                ['session' => $session]
+            );
+            $client->reporting->events->insertOne(
+                ['employee' => 3, 'status' => [ 'new' => 'Inactive', 'old' => 'Active']],
+                ['session' => $session]
+            );
+        } catch (\MongoDB\Driver\Exception\Exception $error) {
+            echo "Caught exception during transaction, aborting.\n";
+            $session->abortTransaction();
+            throw $error;
+        }
+
+        while (true) {
+            try {
+                $session->commitTransaction();
+                echo "Transaction committed.\n";
+                break;
+            } catch (\MongoDB\Driver\Exception\CommandException $error) {
+                $resultDoc = $error->getResultDocument();
+
+                if (isset($resultDoc->errorLabels) && in_array('UnknownTransactionCommitResult', $resultDoc->errorLabels)) {
+                    echo "UnknownTransactionCommitResult, retrying commit operation ...\n";
+                    continue;
+                } else {
+                    echo "Error during commit ...\n";
+                    throw $error;
+                }
+            } catch (\MongoDB\Driver\Exception\Exception $error) {
+                echo "Error during commit ...\n";
+                throw $error;
+            }
+        }
+    }
+    // End Transactions Intro Example 1
+    // phpcs:enable
+
+    public function testTransactions_intro_example_1()
+    {
+        $this->skipIfTransactionsAreNotSupported();
+
+        $this->assertNotNull('This test intentionally performs no assertions');
+
+        $client = new Client(static::getUri());
+
+        /* The WC is required: https://docs.mongodb.com/manual/core/transactions/#transactions-and-locks */
+        $client->hr->dropCollection('employees', ['writeConcern' => new WriteConcern('majority')]);
+        $client->reporting->dropCollection('events', ['writeConcern' => new WriteConcern('majority')]);
+
+        /* Collections need to be created before a transaction starts */
+        $client->hr->createCollection('employees', ['writeConcern' => new WriteConcern('majority')]);
+        $client->reporting->createCollection('events', ['writeConcern' => new WriteConcern('majority')]);
+
+        $session = $client->startSession();
+
+        ob_start();
+        try {
+            $this->updateEmployeeInfo1($client, $session);
+        } finally {
+            ob_end_clean();
+        }
+    }
+
+    // phpcs:disable SlevomatCodingStandard.Namespaces.ReferenceUsedNamesOnly
+    // phpcs:disable Squiz.Commenting.FunctionComment.WrongStyle
+    // phpcs:disable Squiz.WhiteSpace.FunctionSpacing.After
+    // Start Transactions Retry Example 1
+    private function runTransactionWithRetry1(callable $txnFunc, \MongoDB\Client $client, \MongoDB\Driver\Session $session)
+    {
+        while (true) {
+            try {
+                $txnFunc($client, $session);  // performs transaction
+                break;
+            } catch (\MongoDB\Driver\Exception\CommandException $error) {
+                $resultDoc = $error->getResultDocument();
+                echo "Transaction aborted. Caught exception during transaction.\n";
+
+                // If transient error, retry the whole transaction
+                if (isset($resultDoc->errorLabels) && in_array('TransientTransactionError', $resultDoc->errorLabels)) {
+                    echo "TransientTransactionError, retrying transaction ...\n";
+                    continue;
+                } else {
+                    throw $error;
+                }
+            } catch (\MongoDB\Driver\Exception\Exception $error) {
+                throw $error;
+            }
+        }
+    }
+    // End Transactions Retry Example 1
+    // phpcs:enable
+
+    // phpcs:disable SlevomatCodingStandard.Namespaces.ReferenceUsedNamesOnly
+    // phpcs:disable Squiz.Commenting.FunctionComment.WrongStyle
+    // phpcs:disable Squiz.WhiteSpace.FunctionSpacing.After
+    // Start Transactions Retry Example 2
+    private function commitWithRetry2(\MongoDB\Driver\Session $session)
+    {
+        while (true) {
+            try {
+                $session->commitTransaction();
+                echo "Transaction committed.\n";
+                break;
+            } catch (\MongoDB\Driver\Exception\CommandException $error) {
+                $resultDoc = $error->getResultDocument();
+
+                if (isset($resultDoc->errorLabels) && in_array('UnknownTransactionCommitResult', $resultDoc->errorLabels)) {
+                    echo "UnknownTransactionCommitResult, retrying commit operation ...\n";
+                    continue;
+                } else {
+                    echo "Error during commit ...\n";
+                    throw $error;
+                }
+            } catch (\MongoDB\Driver\Exception\Exception $error) {
+                echo "Error during commit ...\n";
+                throw $error;
+            }
+        }
+    }
+    // End Transactions Retry Example 2
+    // phpcs:enable
+
+    // phpcs:disable SlevomatCodingStandard.Namespaces.ReferenceUsedNamesOnly
+    // phpcs:disable Squiz.Commenting.FunctionComment.WrongStyle
+    // phpcs:disable Squiz.WhiteSpace.FunctionSpacing.After
+    // Start Transactions Retry Example 3
+    private function runTransactionWithRetry3(callable $txnFunc, \MongoDB\Client $client, \MongoDB\Driver\Session $session)
+    {
+        while (true) {
+            try {
+                $txnFunc($client, $session);  // performs transaction
+                break;
+            } catch (\MongoDB\Driver\Exception\CommandException $error) {
+                $resultDoc = $error->getResultDocument();
+
+                // If transient error, retry the whole transaction
+                if (isset($resultDoc->errorLabels) && in_array('TransientTransactionError', $resultDoc->errorLabels)) {
+                    continue;
+                } else {
+                    throw $error;
+                }
+            } catch (\MongoDB\Driver\Exception\Exception $error) {
+                throw $error;
+            }
+        }
+    }
+
+    private function commitWithRetry3(\MongoDB\Driver\Session $session)
+    {
+        while (true) {
+            try {
+                $session->commitTransaction();
+                echo "Transaction committed.\n";
+                break;
+            } catch (\MongoDB\Driver\Exception\CommandException $error) {
+                $resultDoc = $error->getResultDocument();
+
+                if (isset($resultDoc->errorLabels) && in_array('UnknownTransactionCommitResult', $resultDoc->errorLabels)) {
+                    echo "UnknownTransactionCommitResult, retrying commit operation ...\n";
+                    continue;
+                } else {
+                    echo "Error during commit ...\n";
+                    throw $error;
+                }
+            } catch (\MongoDB\Driver\Exception\Exception $error) {
+                echo "Error during commit ...\n";
+                throw $error;
+            }
+        }
+    }
+
+    private function updateEmployeeInfo3(\MongoDB\Client $client, \MongoDB\Driver\Session $session)
+    {
+        $session->startTransaction([
+            'readConcern' => new \MongoDB\Driver\ReadConcern("snapshot"),
+            'readPrefernece' => new \MongoDB\Driver\ReadPreference(\MongoDB\Driver\ReadPreference::RP_PRIMARY),
+            'writeConcern' => new \MongoDB\Driver\WriteConcern(\MongoDB\Driver\WriteConcern::MAJORITY),
+        ]);
+
+        try {
+            $client->hr->employees->updateOne(
+                ['employee' => 3],
+                ['$set' => ['status' => 'Inactive']],
+                ['session' => $session]
+            );
+            $client->reporting->events->insertOne(
+                ['employee' => 3, 'status' => [ 'new' => 'Inactive', 'old' => 'Active']],
+                ['session' => $session]
+            );
+        } catch (\MongoDB\Driver\Exception\Exception $error) {
+            echo "Caught exception during transaction, aborting.\n";
+            $session->abortTransaction();
+            throw $error;
+        }
+
+        $this->commitWithRetry3($session);
+    }
+
+    private function doUpdateEmployeeInfo(\MongoDB\Client $client)
+    {
+        // Start a session.
+        $session = $client->startSession();
+
+        try {
+            $this->runTransactionWithRetry3([$this, 'updateEmployeeInfo3'], $client, $session);
+        } catch (\MongoDB\Driver\Exception\Exception $error) {
+            // Do something with error
+        }
+    }
+    // End Transactions Retry Example 3
+    // phpcs:enable
+
+    public function testTransactions_retry_example_3()
+    {
+        $this->skipIfTransactionsAreNotSupported();
+
+        $this->assertNotNull('This test intentionally performs no assertions');
+
+        $client = new Client(static::getUri());
+
+        /* The WC is required: https://docs.mongodb.com/manual/core/transactions/#transactions-and-locks */
+        $client->hr->dropCollection('employees', ['writeConcern' => new WriteConcern('majority')]);
+        $client->reporting->dropCollection('events', ['writeConcern' => new WriteConcern('majority')]);
+
+        /* Collections need to be created before a transaction starts */
+        $client->hr->createCollection('employees', ['writeConcern' => new WriteConcern('majority')]);
+        $client->reporting->createCollection('events', ['writeConcern' => new WriteConcern('majority')]);
+
+        ob_start();
+        try {
+            $this->doUpdateEmployeeInfo($client);
+        } finally {
+            ob_end_clean();
+        }
+    }
+
+    public function testCausalConsistency()
+    {
+        $this->skipIfCausalConsistencyIsNotSupported();
+
+        try {
+            $this->manager->selectServer(new ReadPreference('secondary'));
+        } catch (ConnectionTimeoutException $e) {
+            $this->markTestSkipped('Secondary is not available');
+        }
+
+        $this->assertNotNull('This test intentionally performs no assertions');
+
+        // Prep
+        $client = new Client(static::getUri());
+        $items = $client->selectDatabase(
+            'test',
+            [ 'writeConcern' => new WriteConcern(WriteConcern::MAJORITY) ]
+        )->items;
+
+        $items->drop();
+        $items->insertOne(
+            [ 'sku' => '111', 'name' => 'Peanuts', 'start' => new UTCDateTime() ]
+        );
+
+        // phpcs:disable SlevomatCodingStandard.Namespaces.ReferenceUsedNamesOnly
+        // Start Causal Consistency Example 1
+        $items = $client->selectDatabase(
+            'test',
+            [
+                'readConcern' => new \MongoDB\Driver\ReadConcern(\MongoDB\Driver\ReadConcern::MAJORITY),
+                'writeConcern' => new \MongoDB\Driver\WriteConcern(\MongoDB\Driver\WriteConcern::MAJORITY, 1000),
+            ]
+        )->items;
+
+        $s1 = $client->startSession(
+            [ 'causalConsistency' => true ]
+        );
+
+        $currentDate = new \MongoDB\BSON\UTCDateTime();
+
+        $items->updateOne(
+            [ 'sku' => '111', 'end' => [ '$exists' => false ] ],
+            [ '$set' => [ 'end' => $currentDate ] ],
+            [ 'session' => $s1 ]
+        );
+        $items->insertOne(
+            [ 'sku' => '111-nuts', 'name' => 'Pecans', 'start' => $currentDate ],
+            [ 'session' => $s1 ]
+        );
+        // End Causal Consistency Example 1
+        // phpcs:enable
+
+        ob_start();
+
+        // phpcs:disable SlevomatCodingStandard.Namespaces.ReferenceUsedNamesOnly
+        // Start Causal Consistency Example 2
+        $s2 = $client->startSession(
+            [ 'causalConsistency' => true ]
+        );
+        $s2->advanceClusterTime($s1->getClusterTime());
+        $s2->advanceOperationTime($s1->getOperationTime());
+
+        $items = $client->selectDatabase(
+            'test',
+            [
+                'readPreference' => new \MongoDB\Driver\ReadPreference(\MongoDB\Driver\ReadPreference::RP_SECONDARY),
+                'readConcern' => new \MongoDB\Driver\ReadConcern(\MongoDB\Driver\ReadConcern::MAJORITY),
+                'writeConcern' => new \MongoDB\Driver\WriteConcern(\MongoDB\Driver\WriteConcern::MAJORITY, 1000),
+            ]
+        )->items;
+
+        $result = $items->find(
+            [ 'end' => [ '$exists' => false ] ],
+            [ 'session' => $s2 ]
+        );
+        foreach ($result as $item) {
+            var_dump($item);
+        }
+        // End Causal Consistency Example 2
+        // phpcs:enable
+
+        ob_end_clean();
+    }
+
+    /**
+     * @doesNotPerformAssertions
+     */
+    public function testWithTransactionExample()
+    {
+        $this->skipIfTransactionsAreNotSupported();
+
+        $uriString = static::getUri(true);
+
+        // phpcs:disable SlevomatCodingStandard.Namespaces.ReferenceUsedNamesOnly
+        // Start Transactions withTxn API Example 1
+        /*
+         * For a replica set, include the replica set name and a seedlist of the members in the URI string; e.g.
+         * uriString = 'mongodb://mongodb0.example.com:27017,mongodb1.example.com:27017/?replicaSet=myRepl'
+         * For a sharded cluster, connect to the mongos instances; e.g.
+         * uriString = 'mongodb://mongos0.example.com:27017,mongos1.example.com:27017/'
+         */
+
+        $client = new \MongoDB\Client($uriString);
+
+        // Prerequisite: Create collections.
+        $client->selectCollection(
+            'mydb1',
+            'foo',
+            [
+                'writeConcern' => new \MongoDB\Driver\WriteConcern(\MongoDB\Driver\WriteConcern::MAJORITY, 1000),
+            ]
+        )->insertOne(['abc' => 0]);
+
+        $client->selectCollection(
+            'mydb2',
+            'bar',
+            [
+                'writeConcern' => new \MongoDB\Driver\WriteConcern(\MongoDB\Driver\WriteConcern::MAJORITY, 1000),
+            ]
+        )->insertOne(['xyz' => 0]);
+
+        // Step 1: Define the callback that specifies the sequence of operations to perform inside the transactions.
+
+        $callback = function (\MongoDB\Driver\Session $session) use ($client) {
+            $client
+                ->selectCollection('mydb1', 'foo')
+                ->insertOne(['abc' => 1], ['session' => $session]);
+
+            $client
+                ->selectCollection('mydb2', 'bar')
+                ->insertOne(['xyz' => 999], ['session' => $session]);
+        };
+
+        // Step 2: Start a client session.
+
+        $session = $client->startSession();
+
+        // Step 3: Use with_transaction to start a transaction, execute the callback, and commit (or abort on error).
+
+        $transactionOptions = [
+            'readConcern' => new \MongoDB\Driver\ReadConcern(\MongoDB\Driver\ReadConcern::LOCAL),
+            'writeConcern' => new \MongoDB\Driver\WriteConcern(\MongoDB\Driver\WriteConcern::MAJORITY, 1000),
+            'readPreference' => new \MongoDB\Driver\ReadPreference(\MongoDB\Driver\ReadPreference::RP_PRIMARY),
+        ];
+
+        \MongoDB\with_transaction($session, $callback, $transactionOptions);
+
+        // End Transactions withTxn API Example 1
+        // phpcs:enable
+    }
+
+    /**
+     * Return the test collection name.
+     *
+     * @return string
+     */
+    protected function getCollectionName()
+    {
+        return 'inventory';
+    }
+
+    private function assertCursorCount($count, Cursor $cursor)
+    {
+        $this->assertCount($count, $cursor->toArray());
+    }
+
+    private function assertInventoryCount($count)
+    {
+        $this->assertCollectionCount($this->getDatabaseName() . '.' . $this->getCollectionName(), $count);
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/FunctionalTestCase.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/FunctionalTestCase.php
new file mode 100644
index 0000000000000000000000000000000000000000..03d3896773d9f8b626784e004f0d96a6cfca16dc
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/FunctionalTestCase.php	
@@ -0,0 +1,493 @@
+<?php
+
+namespace MongoDB\Tests;
+
+use InvalidArgumentException;
+use MongoDB\BSON\ObjectId;
+use MongoDB\Driver\Command;
+use MongoDB\Driver\Exception\CommandException;
+use MongoDB\Driver\Manager;
+use MongoDB\Driver\Query;
+use MongoDB\Driver\ReadPreference;
+use MongoDB\Driver\Server;
+use MongoDB\Driver\WriteConcern;
+use MongoDB\Operation\CreateCollection;
+use MongoDB\Operation\DatabaseCommand;
+use MongoDB\Operation\DropCollection;
+use stdClass;
+use Symfony\Bridge\PhpUnit\SetUpTearDownTrait;
+use UnexpectedValueException;
+use function array_merge;
+use function count;
+use function current;
+use function explode;
+use function implode;
+use function is_array;
+use function is_object;
+use function is_string;
+use function key;
+use function ob_get_clean;
+use function ob_start;
+use function parse_url;
+use function phpinfo;
+use function preg_match;
+use function preg_quote;
+use function sprintf;
+use function version_compare;
+use const INFO_MODULES;
+
+abstract class FunctionalTestCase extends TestCase
+{
+    use SetUpTearDownTrait;
+
+    /** @var Manager */
+    protected $manager;
+
+    /** @var array */
+    private $configuredFailPoints = [];
+
+    private function doSetUp()
+    {
+        parent::setUp();
+
+        $this->manager = new Manager(static::getUri());
+        $this->configuredFailPoints = [];
+    }
+
+    private function doTearDown()
+    {
+        $this->disableFailPoints();
+
+        parent::tearDown();
+    }
+
+    public static function getUri($allowMultipleMongoses = false)
+    {
+        $uri = parent::getUri();
+
+        if ($allowMultipleMongoses) {
+            return $uri;
+        }
+
+        $urlParts = parse_url($uri);
+        if ($urlParts === false) {
+            return $uri;
+        }
+
+        // Only modify URIs using the mongodb scheme
+        if ($urlParts['scheme'] !== 'mongodb') {
+            return $uri;
+        }
+
+        $hosts = explode(',', $urlParts['host']);
+        $numHosts = count($hosts);
+        if ($numHosts === 1) {
+            return $uri;
+        }
+
+        $manager = new Manager($uri);
+        if ($manager->selectServer(new ReadPreference(ReadPreference::RP_PRIMARY))->getType() !== Server::TYPE_MONGOS) {
+            return $uri;
+        }
+
+        // Re-append port to last host
+        if (isset($urlParts['port'])) {
+            $hosts[$numHosts-1] .= ':' . $urlParts['port'];
+        }
+
+        $parts = ['mongodb://'];
+
+        if (isset($urlParts['user'], $urlParts['pass'])) {
+            $parts += [
+                $urlParts['user'],
+                ':',
+                $urlParts['pass'],
+                '@',
+            ];
+        }
+
+        $parts[] = $hosts[0];
+
+        if (isset($urlParts['path'])) {
+            $parts[] = $urlParts['path'];
+        }
+        if (isset($urlParts['query'])) {
+            $parts = array_merge($parts, [
+                '?',
+                $urlParts['query'],
+            ]);
+        }
+
+        return implode('', $parts);
+    }
+
+    protected function assertCollectionCount($namespace, $count)
+    {
+        list($databaseName, $collectionName) = explode('.', $namespace, 2);
+
+        $cursor = $this->manager->executeCommand($databaseName, new Command(['count' => $collectionName]));
+        $cursor->setTypeMap(['root' => 'array', 'document' => 'array']);
+        $document = current($cursor->toArray());
+
+        $this->assertArrayHasKey('n', $document);
+        $this->assertEquals($count, $document['n']);
+    }
+
+    protected function assertCommandSucceeded($document)
+    {
+        $document = is_object($document) ? (array) $document : $document;
+
+        $this->assertArrayHasKey('ok', $document);
+        $this->assertEquals(1, $document['ok']);
+    }
+
+    protected function assertSameObjectId($expectedObjectId, $actualObjectId)
+    {
+        $this->assertInstanceOf(ObjectId::class, $expectedObjectId);
+        $this->assertInstanceOf(ObjectId::class, $actualObjectId);
+        $this->assertEquals((string) $expectedObjectId, (string) $actualObjectId);
+    }
+
+    /**
+     * Configure a fail point for the test.
+     *
+     * The fail point will automatically be disabled during tearDown() to avoid
+     * affecting a subsequent test.
+     *
+     * @param array|stdClass $command configureFailPoint command document
+     * @throws InvalidArgumentException if $command is not a configureFailPoint command
+     */
+    public function configureFailPoint($command, Server $server = null)
+    {
+        if (! $this->isFailCommandSupported()) {
+            $this->markTestSkipped('failCommand is only supported on mongod >= 4.0.0 and mongos >= 4.1.5.');
+        }
+
+        if (! $this->isFailCommandEnabled()) {
+            $this->markTestSkipped('The enableTestCommands parameter is not enabled.');
+        }
+
+        if (is_array($command)) {
+            $command = (object) $command;
+        }
+
+        if (! $command instanceof stdClass) {
+            throw new InvalidArgumentException('$command is not an array or stdClass instance');
+        }
+
+        if (key($command) !== 'configureFailPoint') {
+            throw new InvalidArgumentException('$command is not a configureFailPoint command');
+        }
+
+        $failPointServer = $server ?: $this->getPrimaryServer();
+
+        $operation = new DatabaseCommand('admin', $command);
+        $cursor = $operation->execute($failPointServer);
+        $result = $cursor->toArray()[0];
+
+        $this->assertCommandSucceeded($result);
+
+        // Record the fail point so it can be disabled during tearDown()
+        $this->configuredFailPoints[] = [$command->configureFailPoint, $failPointServer];
+    }
+
+    /**
+     * Creates the test collection with the specified options.
+     *
+     * If the "writeConcern" option is not specified but is supported by the
+     * server, a majority write concern will be used. This is helpful for tests
+     * using transactions or secondary reads.
+     *
+     * @param array $options
+     */
+    protected function createCollection(array $options = [])
+    {
+        if (version_compare($this->getServerVersion(), '3.4.0', '>=')) {
+            $options += ['writeConcern' => new WriteConcern(WriteConcern::MAJORITY)];
+        }
+
+        $operation = new CreateCollection($this->getDatabaseName(), $this->getCollectionName(), $options);
+        $operation->execute($this->getPrimaryServer());
+    }
+
+    /**
+     * Drops the test collection with the specified options.
+     *
+     * If the "writeConcern" option is not specified but is supported by the
+     * server, a majority write concern will be used. This is helpful for tests
+     * using transactions or secondary reads.
+     *
+     * @param array $options
+     */
+    protected function dropCollection(array $options = [])
+    {
+        if (version_compare($this->getServerVersion(), '3.4.0', '>=')) {
+            $options += ['writeConcern' => new WriteConcern(WriteConcern::MAJORITY)];
+        }
+
+        $operation = new DropCollection($this->getDatabaseName(), $this->getCollectionName(), $options);
+        $operation->execute($this->getPrimaryServer());
+    }
+
+    protected function getFeatureCompatibilityVersion(ReadPreference $readPreference = null)
+    {
+        if ($this->isShardedCluster()) {
+            return $this->getServerVersion($readPreference);
+        }
+
+        if (version_compare($this->getServerVersion(), '3.4.0', '<')) {
+            return $this->getServerVersion($readPreference);
+        }
+
+        $cursor = $this->manager->executeCommand(
+            'admin',
+            new Command(['getParameter' => 1, 'featureCompatibilityVersion' => 1]),
+            $readPreference ?: new ReadPreference(ReadPreference::RP_PRIMARY)
+        );
+
+        $cursor->setTypeMap(['root' => 'array', 'document' => 'array']);
+        $document = current($cursor->toArray());
+
+        // MongoDB 3.6: featureCompatibilityVersion is an embedded document
+        if (isset($document['featureCompatibilityVersion']['version']) && is_string($document['featureCompatibilityVersion']['version'])) {
+            return $document['featureCompatibilityVersion']['version'];
+        }
+
+        // MongoDB 3.4: featureCompatibilityVersion is a string
+        if (isset($document['featureCompatibilityVersion']) && is_string($document['featureCompatibilityVersion'])) {
+            return $document['featureCompatibilityVersion'];
+        }
+
+        throw new UnexpectedValueException('Could not determine featureCompatibilityVersion');
+    }
+
+    protected function getPrimaryServer()
+    {
+        return $this->manager->selectServer(new ReadPreference(ReadPreference::RP_PRIMARY));
+    }
+
+    protected function getServerVersion(ReadPreference $readPreference = null)
+    {
+        $cursor = $this->manager->executeCommand(
+            $this->getDatabaseName(),
+            new Command(['buildInfo' => 1]),
+            $readPreference ?: new ReadPreference(ReadPreference::RP_PRIMARY)
+        );
+
+        $cursor->setTypeMap(['root' => 'array', 'document' => 'array']);
+        $document = current($cursor->toArray());
+
+        if (isset($document['version']) && is_string($document['version'])) {
+            return $document['version'];
+        }
+
+        throw new UnexpectedValueException('Could not determine server version');
+    }
+
+    protected function getServerStorageEngine(ReadPreference $readPreference = null)
+    {
+        $cursor = $this->manager->executeCommand(
+            $this->getDatabaseName(),
+            new Command(['serverStatus' => 1]),
+            $readPreference ?: new ReadPreference('primary')
+        );
+
+        $result = current($cursor->toArray());
+
+        if (isset($result->storageEngine->name) && is_string($result->storageEngine->name)) {
+            return $result->storageEngine->name;
+        }
+
+        throw new UnexpectedValueException('Could not determine server storage engine');
+    }
+
+    protected function isReplicaSet()
+    {
+        return $this->getPrimaryServer()->getType() == Server::TYPE_RS_PRIMARY;
+    }
+
+    protected function isShardedCluster()
+    {
+        return $this->getPrimaryServer()->getType() == Server::TYPE_MONGOS;
+    }
+
+    protected function isShardedClusterUsingReplicasets()
+    {
+        $cursor = $this->getPrimaryServer()->executeQuery(
+            'config.shards',
+            new Query([], ['limit' => 1])
+        );
+
+        $cursor->setTypeMap(['root' => 'array', 'document' => 'array']);
+        $document = current($cursor->toArray());
+
+        if (! $document) {
+            return false;
+        }
+
+        /**
+         * Use regular expression to distinguish between standalone or replicaset:
+         * Without a replicaset: "host" : "localhost:4100"
+         * With a replicaset: "host" : "dec6d8a7-9bc1-4c0e-960c-615f860b956f/localhost:4400,localhost:4401"
+         */
+        return preg_match('@^.*/.*:\d+@', $document['host']);
+    }
+
+    protected function skipIfChangeStreamIsNotSupported()
+    {
+        switch ($this->getPrimaryServer()->getType()) {
+            case Server::TYPE_MONGOS:
+                if (version_compare($this->getServerVersion(), '3.6.0', '<')) {
+                    $this->markTestSkipped('$changeStream is only supported on MongoDB 3.6 or higher');
+                }
+                if (! $this->isShardedClusterUsingReplicasets()) {
+                    $this->markTestSkipped('$changeStream is only supported with replicasets');
+                }
+                break;
+
+            case Server::TYPE_RS_PRIMARY:
+                if (version_compare($this->getFeatureCompatibilityVersion(), '3.6', '<')) {
+                    $this->markTestSkipped('$changeStream is only supported on FCV 3.6 or higher');
+                }
+                break;
+
+            default:
+                $this->markTestSkipped('$changeStream is not supported');
+        }
+    }
+
+    protected function skipIfCausalConsistencyIsNotSupported()
+    {
+        switch ($this->getPrimaryServer()->getType()) {
+            case Server::TYPE_MONGOS:
+                if (version_compare($this->getServerVersion(), '3.6.0', '<')) {
+                    $this->markTestSkipped('Causal Consistency is only supported on MongoDB 3.6 or higher');
+                }
+                if (! $this->isShardedClusterUsingReplicasets()) {
+                    $this->markTestSkipped('Causal Consistency is only supported with replicasets');
+                }
+                break;
+
+            case Server::TYPE_RS_PRIMARY:
+                if (version_compare($this->getFeatureCompatibilityVersion(), '3.6', '<')) {
+                    $this->markTestSkipped('Causal Consistency is only supported on FCV 3.6 or higher');
+                }
+                if ($this->getServerStorageEngine() !== 'wiredTiger') {
+                    $this->markTestSkipped('Causal Consistency requires WiredTiger storage engine');
+                }
+                break;
+
+            default:
+                $this->markTestSkipped('Causal Consistency is not supported');
+        }
+    }
+
+    protected function skipIfClientSideEncryptionIsNotSupported()
+    {
+        if (version_compare($this->getFeatureCompatibilityVersion(), '4.2', '<')) {
+            $this->markTestSkipped('Client Side Encryption only supported on FCV 4.2 or higher');
+        }
+
+        if ($this->getModuleInfo('libmongocrypt') === 'disabled') {
+            $this->markTestSkipped('Client Side Encryption is not enabled in the MongoDB extension');
+        }
+    }
+
+    protected function skipIfTransactionsAreNotSupported()
+    {
+        if ($this->getPrimaryServer()->getType() === Server::TYPE_STANDALONE) {
+            $this->markTestSkipped('Transactions are not supported on standalone servers');
+        }
+
+        if ($this->isShardedCluster()) {
+            if (! $this->isShardedClusterUsingReplicasets()) {
+                $this->markTestSkipped('Transactions are not supported on sharded clusters without replica sets');
+            }
+
+            if (version_compare($this->getFeatureCompatibilityVersion(), '4.2', '<')) {
+                $this->markTestSkipped('Transactions are only supported on FCV 4.2 or higher');
+            }
+
+            return;
+        }
+
+        if (version_compare($this->getFeatureCompatibilityVersion(), '4.0', '<')) {
+            $this->markTestSkipped('Transactions are only supported on FCV 4.0 or higher');
+        }
+
+        if ($this->getServerStorageEngine() !== 'wiredTiger') {
+            $this->markTestSkipped('Transactions require WiredTiger storage engine');
+        }
+    }
+
+    /**
+     * Disables any fail points that were configured earlier in the test.
+     *
+     * This tracks fail points set via configureFailPoint() and should be called
+     * during tearDown().
+     */
+    private function disableFailPoints()
+    {
+        if (empty($this->configuredFailPoints)) {
+            return;
+        }
+
+        foreach ($this->configuredFailPoints as list($failPoint, $server)) {
+            $operation = new DatabaseCommand('admin', ['configureFailPoint' => $failPoint, 'mode' => 'off']);
+            $operation->execute($server);
+        }
+    }
+
+    /**
+     * @param string $row
+     *
+     * @return string|null
+     */
+    private function getModuleInfo($row)
+    {
+        ob_start();
+        phpinfo(INFO_MODULES);
+        $info = ob_get_clean();
+
+        $pattern = sprintf('/^%s([\w ]+)$/m', preg_quote($row . ' => '));
+
+        if (preg_match($pattern, $info, $matches) !== 1) {
+            return null;
+        }
+
+        return $matches[1];
+    }
+
+    /**
+     * Checks if the failCommand command is supported on this server version
+     *
+     * @return bool
+     */
+    private function isFailCommandSupported()
+    {
+        $minVersion = $this->isShardedCluster() ? '4.1.5' : '4.0.0';
+
+        return version_compare($this->getServerVersion(), $minVersion, '>=');
+    }
+
+    /**
+     * Checks if the failCommand command is enabled by checking the enableTestCommands parameter
+     *
+     * @return bool
+     */
+    private function isFailCommandEnabled()
+    {
+        try {
+            $cursor = $this->manager->executeCommand(
+                'admin',
+                new Command(['getParameter' => 1, 'enableTestCommands' => 1])
+            );
+
+            $document = current($cursor->toArray());
+        } catch (CommandException $e) {
+            return false;
+        }
+
+        return isset($document->enableTestCommands) && $document->enableTestCommands === true;
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/FunctionsTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/FunctionsTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..6efba64b12d06eed49e2a7d58bd7254db60d8c15
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/FunctionsTest.php	
@@ -0,0 +1,257 @@
+<?php
+
+namespace MongoDB\Tests;
+
+use MongoDB\Exception\InvalidArgumentException;
+use MongoDB\Model\BSONArray;
+use MongoDB\Model\BSONDocument;
+use function MongoDB\apply_type_map_to_document;
+use function MongoDB\create_field_path_type_map;
+use function MongoDB\generate_index_name;
+use function MongoDB\is_first_key_operator;
+use function MongoDB\is_mapreduce_output_inline;
+use function MongoDB\is_pipeline;
+
+/**
+ * Unit tests for utility functions.
+ */
+class FunctionsTest extends TestCase
+{
+    /**
+     * @dataProvider provideDocumentAndTypeMap
+     */
+    public function testApplyTypeMapToDocument($document, array $typeMap, $expectedDocument)
+    {
+        $this->assertEquals($expectedDocument, apply_type_map_to_document($document, $typeMap));
+    }
+
+    public function provideDocumentAndTypeMap()
+    {
+        return [
+            [
+                [
+                    'x' => 1,
+                    'y' => (object) ['foo' => 'bar'],
+                    'z' => [1, 2, 3],
+                ],
+                [
+                    'root' => 'object',
+                    'document' => 'stdClass',
+                    'array' => 'array',
+                ],
+                (object) [
+                    'x' => 1,
+                    'y' => (object) ['foo' => 'bar'],
+                    'z' => [1, 2, 3],
+                ],
+            ],
+            [
+                [
+                    'x' => 1,
+                    'y' => (object) ['foo' => 'bar'],
+                    'z' => [1, 2, 3],
+                ],
+                [
+                    'root' => BSONDocument::class,
+                    'document' => BSONDocument::class,
+                    'array' => BSONArray::class,
+                ],
+                new BSONDocument([
+                    'x' => 1,
+                    'y' => new BSONDocument(['foo' => 'bar']),
+                    'z' => new BSONArray([1, 2, 3]),
+                ]),
+            ],
+            [
+                [
+                    'x' => 1,
+                    'random' => ['foo' => 'bar'],
+                    'value' => [
+                        'bar' => 'baz',
+                        'embedded' => ['foo' => 'bar'],
+                    ],
+                ],
+                [
+                    'root' => 'array',
+                    'document' => 'stdClass',
+                    'array' => 'array',
+                    'fieldPaths' => ['value' => 'array'],
+                ],
+                [
+                    'x' => 1,
+                    'random' => (object) ['foo' => 'bar'],
+                    'value' => [
+                        'bar' => 'baz',
+                        'embedded' => (object) ['foo' => 'bar'],
+                    ],
+                ],
+            ],
+        ];
+    }
+
+    /**
+     * @dataProvider provideIndexSpecificationDocumentsAndGeneratedNames
+     */
+    public function testGenerateIndexName($document, $expectedName)
+    {
+        $this->assertSame($expectedName, generate_index_name($document));
+    }
+
+    public function provideIndexSpecificationDocumentsAndGeneratedNames()
+    {
+        return [
+            [ ['x' => 1], 'x_1' ],
+            [ ['x' => -1, 'y' => 1], 'x_-1_y_1' ],
+            [ ['x' => '2dsphere', 'y' => 1 ], 'x_2dsphere_y_1' ],
+            [ (object) ['x' => 1], 'x_1' ],
+            [ new BSONDocument(['x' => 1]), 'x_1' ],
+        ];
+    }
+
+    /**
+     * @dataProvider provideInvalidDocumentValues
+     */
+    public function testGenerateIndexNameArgumentTypeCheck($document)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        generate_index_name($document);
+    }
+
+    /**
+     * @dataProvider provideIsFirstKeyOperatorDocuments
+     */
+    public function testIsFirstKeyOperator($document, $isFirstKeyOperator)
+    {
+        $this->assertSame($isFirstKeyOperator, is_first_key_operator($document));
+    }
+
+    public function provideIsFirstKeyOperatorDocuments()
+    {
+        return [
+            [ ['y' => 1], false ],
+            [ (object) ['y' => 1], false ],
+            [ new BSONDocument(['y' => 1]), false ],
+            [ ['$set' => ['y' => 1]], true ],
+            [ (object) ['$set' => ['y' => 1]], true ],
+            [ new BSONDocument(['$set' => ['y' => 1]]), true ],
+        ];
+    }
+
+    /**
+     * @dataProvider provideInvalidDocumentValues
+     */
+    public function testIsFirstKeyOperatorArgumentTypeCheck($document)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        is_first_key_operator($document);
+    }
+
+    /**
+     * @dataProvider provideMapReduceOutValues
+     */
+    public function testIsMapReduceOutputInline($out, $isInline)
+    {
+        $this->assertSame($isInline, is_mapreduce_output_inline($out));
+    }
+
+    public function provideMapReduceOutValues()
+    {
+        return [
+            [ 'collectionName', false ],
+            [ ['inline' => 1], true ],
+            [ ['inline' => 0], true ], // only the key is significant
+            [ ['replace' => 'collectionName'], false ],
+        ];
+    }
+
+    /**
+     * @dataProvider provideTypeMapValues
+     */
+    public function testCreateFieldPathTypeMap(array $expected, array $typeMap, $fieldPath = 'field')
+    {
+        $this->assertEquals($expected, create_field_path_type_map($typeMap, $fieldPath));
+    }
+
+    public function provideTypeMapValues()
+    {
+        return [
+            'No root type' => [
+                ['document' => 'array', 'root' => 'object'],
+                ['document' => 'array'],
+            ],
+            'No field path' => [
+                ['root' => 'object', 'fieldPaths' => ['field' => 'array']],
+                ['root' => 'array'],
+            ],
+            'Field path exists' => [
+                ['root' => 'object', 'fieldPaths' => ['field' => 'array', 'field.field' => 'object']],
+                ['root' => 'array', 'fieldPaths' => ['field' => 'object']],
+            ],
+            'Nested field path' => [
+                ['root' => 'object', 'fieldPaths' => ['field' => 'object', 'field.nested' => 'array']],
+                ['root' => 'object', 'fieldPaths' => ['nested' => 'array']],
+            ],
+            'Array field path converted to array' => [
+                [
+                    'root' => 'object',
+                    'array' => 'MongoDB\Model\BSONArray',
+                    'fieldPaths' => [
+                        'field' => 'array',
+                        'field.$' => 'object',
+                        'field.$.nested' => 'array',
+                    ],
+                ],
+                [
+                    'root' => 'object',
+                    'array' => 'MongoDB\Model\BSONArray',
+                    'fieldPaths' => ['nested' => 'array'],
+                ],
+                'field.$',
+            ],
+            'Array field path without root key' => [
+                [
+                    'root' => 'object',
+                    'array' => 'MongoDB\Model\BSONArray',
+                    'fieldPaths' => [
+                        'field' => 'array',
+                        'field.$.nested' => 'array',
+                    ],
+                ],
+                [
+                    'array' => 'MongoDB\Model\BSONArray',
+                    'fieldPaths' => ['nested' => 'array'],
+                ],
+                'field.$',
+            ],
+        ];
+    }
+
+    /**
+     * @dataProvider providePipelines
+     */
+    public function testIsPipeline($expected, $pipeline)
+    {
+        $this->assertSame($expected, is_pipeline($pipeline));
+    }
+
+    public function providePipelines()
+    {
+        return [
+            'Not an array' => [false, (object) []],
+            'Empty array' => [false, []],
+            'Non-sequential indexes in array' => [false, [1 => ['$group' => []]]],
+            'Update document instead of pipeline' => [false, ['$set' => ['foo' => 'bar']]],
+            'Invalid pipeline stage' => [false, [['group' => []]]],
+            'Update with DbRef' => [false, ['x' => ['$ref' => 'foo', '$id' => 'bar']]],
+            'Valid pipeline' => [
+                true,
+                [
+                    ['$match' => ['foo' => 'bar']],
+                    ['$group' => ['_id' => 1]],
+                ],
+            ],
+            'False positive with DbRef in numeric field' => [true, ['0' => ['$ref' => 'foo', '$id' => 'bar']]],
+            'DbRef in numeric field as object' => [false, (object) ['0' => ['$ref' => 'foo', '$id' => 'bar']]],
+        ];
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/GridFS/BucketFunctionalTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/GridFS/BucketFunctionalTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..069b79b9128276d789135e6a101795098363b6e2
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/GridFS/BucketFunctionalTest.php	
@@ -0,0 +1,866 @@
+<?php
+
+namespace MongoDB\Tests\GridFS;
+
+use MongoDB\BSON\Binary;
+use MongoDB\Collection;
+use MongoDB\Driver\ReadConcern;
+use MongoDB\Driver\ReadPreference;
+use MongoDB\Driver\WriteConcern;
+use MongoDB\Exception\InvalidArgumentException;
+use MongoDB\GridFS\Bucket;
+use MongoDB\GridFS\Exception\FileNotFoundException;
+use MongoDB\GridFS\Exception\StreamException;
+use MongoDB\Model\BSONDocument;
+use MongoDB\Model\IndexInfo;
+use MongoDB\Operation\ListCollections;
+use MongoDB\Operation\ListIndexes;
+use PHPUnit\Framework\Error\Warning;
+use function array_merge;
+use function call_user_func;
+use function current;
+use function exec;
+use function fclose;
+use function fopen;
+use function fread;
+use function fwrite;
+use function hash_init;
+use function implode;
+use function is_callable;
+use function min;
+use function sprintf;
+use function str_repeat;
+use function stream_get_contents;
+use function strlen;
+use function strncasecmp;
+use function substr;
+use const PHP_EOL;
+use const PHP_OS;
+use const PHP_VERSION_ID;
+
+/**
+ * Functional tests for the Bucket class.
+ */
+class BucketFunctionalTest extends FunctionalTestCase
+{
+    /**
+     * @doesNotPerformAssertions
+     */
+    public function testValidConstructorOptions()
+    {
+        new Bucket($this->manager, $this->getDatabaseName(), [
+            'bucketName' => 'test',
+            'chunkSizeBytes' => 8192,
+            'readConcern' => new ReadConcern(ReadConcern::LOCAL),
+            'readPreference' => new ReadPreference(ReadPreference::RP_PRIMARY),
+            'writeConcern' => new WriteConcern(WriteConcern::MAJORITY, 1000),
+        ]);
+    }
+
+    /**
+     * @dataProvider provideInvalidConstructorOptions
+     */
+    public function testConstructorOptionTypeChecks(array $options)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        new Bucket($this->manager, $this->getDatabaseName(), $options);
+    }
+
+    public function provideInvalidConstructorOptions()
+    {
+        $options = [];
+
+        foreach ($this->getInvalidStringValues(true) as $value) {
+            $options[][] = ['bucketName' => $value];
+        }
+
+        foreach ($this->getInvalidIntegerValues(true) as $value) {
+            $options[][] = ['chunkSizeBytes' => $value];
+        }
+
+        foreach ($this->getInvalidBooleanValues(true) as $value) {
+            $options[][] = ['disableMD5' => $value];
+        }
+
+        foreach ($this->getInvalidReadConcernValues() as $value) {
+            $options[][] = ['readConcern' => $value];
+        }
+
+        foreach ($this->getInvalidReadPreferenceValues() as $value) {
+            $options[][] = ['readPreference' => $value];
+        }
+
+        foreach ($this->getInvalidArrayValues() as $value) {
+            $options[][] = ['typeMap' => $value];
+        }
+
+        foreach ($this->getInvalidWriteConcernValues() as $value) {
+            $options[][] = ['writeConcern' => $value];
+        }
+
+        return $options;
+    }
+
+    public function testConstructorShouldRequireChunkSizeBytesOptionToBePositive()
+    {
+        $this->expectException(InvalidArgumentException::class);
+        $this->expectExceptionMessage('Expected "chunkSizeBytes" option to be >= 1, 0 given');
+        new Bucket($this->manager, $this->getDatabaseName(), ['chunkSizeBytes' => 0]);
+    }
+
+    /**
+     * @dataProvider provideInputDataAndExpectedChunks
+     */
+    public function testDelete($input, $expectedChunks)
+    {
+        $id = $this->bucket->uploadFromStream('filename', $this->createStream($input));
+
+        $this->assertCollectionCount($this->filesCollection, 1);
+        $this->assertCollectionCount($this->chunksCollection, $expectedChunks);
+
+        $this->bucket->delete($id);
+
+        $this->assertCollectionCount($this->filesCollection, 0);
+        $this->assertCollectionCount($this->chunksCollection, 0);
+    }
+
+    public function provideInputDataAndExpectedChunks()
+    {
+        return [
+            ['', 0],
+            ['foobar', 1],
+            [str_repeat('a', 261120), 1],
+            [str_repeat('a', 261121), 2],
+            [str_repeat('a', 522240), 2],
+            [str_repeat('a', 522241), 3],
+            [str_repeat('foobar', 43520), 1],
+            [str_repeat('foobar', 43521), 2],
+            [str_repeat('foobar', 87040), 2],
+            [str_repeat('foobar', 87041), 3],
+        ];
+    }
+
+    public function testDeleteShouldRequireFileToExist()
+    {
+        $this->expectException(FileNotFoundException::class);
+        $this->bucket->delete('nonexistent-id');
+    }
+
+    /**
+     * @dataProvider provideInputDataAndExpectedChunks
+     */
+    public function testDeleteStillRemovesChunksIfFileDoesNotExist($input, $expectedChunks)
+    {
+        $id = $this->bucket->uploadFromStream('filename', $this->createStream($input));
+
+        $this->assertCollectionCount($this->filesCollection, 1);
+        $this->assertCollectionCount($this->chunksCollection, $expectedChunks);
+
+        $this->filesCollection->deleteOne(['_id' => $id]);
+
+        try {
+            $this->bucket->delete($id);
+            $this->fail('FileNotFoundException was not thrown');
+        } catch (FileNotFoundException $e) {
+        }
+
+        $this->assertCollectionCount($this->chunksCollection, 0);
+    }
+
+    public function testDownloadingFileWithMissingChunk()
+    {
+        $id = $this->bucket->uploadFromStream("filename", $this->createStream("foobar"));
+
+        $this->chunksCollection->deleteOne(['files_id' => $id, 'n' => 0]);
+
+        $this->expectException(Warning::class);
+        stream_get_contents($this->bucket->openDownloadStream($id));
+    }
+
+    public function testDownloadingFileWithUnexpectedChunkIndex()
+    {
+        $id = $this->bucket->uploadFromStream("filename", $this->createStream("foobar"));
+
+        $this->chunksCollection->updateOne(
+            ['files_id' => $id, 'n' => 0],
+            ['$set' => ['n' => 1]]
+        );
+
+        $this->expectException(Warning::class);
+        stream_get_contents($this->bucket->openDownloadStream($id));
+    }
+
+    public function testDownloadingFileWithUnexpectedChunkSize()
+    {
+        $id = $this->bucket->uploadFromStream("filename", $this->createStream("foobar"));
+
+        $this->chunksCollection->updateOne(
+            ['files_id' => $id, 'n' => 0],
+            ['$set' => ['data' => new Binary('fooba', Binary::TYPE_GENERIC)]]
+        );
+
+        $this->expectException(Warning::class);
+        stream_get_contents($this->bucket->openDownloadStream($id));
+    }
+
+    /**
+     * @dataProvider provideInputDataAndExpectedChunks
+     */
+    public function testDownloadToStream($input)
+    {
+        $id = $this->bucket->uploadFromStream('filename', $this->createStream($input));
+        $destination = $this->createStream();
+        $this->bucket->downloadToStream($id, $destination);
+
+        $this->assertStreamContents($input, $destination);
+    }
+
+    /**
+     * @dataProvider provideInvalidStreamValues
+     */
+    public function testDownloadToStreamShouldRequireDestinationStream($destination)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        $this->bucket->downloadToStream('id', $destination);
+    }
+
+    public function provideInvalidStreamValues()
+    {
+        return $this->wrapValuesForDataProvider($this->getInvalidStreamValues());
+    }
+
+    public function testDownloadToStreamShouldRequireFileToExist()
+    {
+        $this->expectException(FileNotFoundException::class);
+        $this->bucket->downloadToStream('nonexistent-id', $this->createStream());
+    }
+
+    public function testDownloadToStreamByName()
+    {
+        $this->bucket->uploadFromStream('filename', $this->createStream('foo'));
+        $this->bucket->uploadFromStream('filename', $this->createStream('bar'));
+        $this->bucket->uploadFromStream('filename', $this->createStream('baz'));
+
+        $destination = $this->createStream();
+        $this->bucket->downloadToStreamByName('filename', $destination);
+        $this->assertStreamContents('baz', $destination);
+
+        $destination = $this->createStream();
+        $this->bucket->downloadToStreamByName('filename', $destination, ['revision' => -3]);
+        $this->assertStreamContents('foo', $destination);
+
+        $destination = $this->createStream();
+        $this->bucket->downloadToStreamByName('filename', $destination, ['revision' => -2]);
+        $this->assertStreamContents('bar', $destination);
+
+        $destination = $this->createStream();
+        $this->bucket->downloadToStreamByName('filename', $destination, ['revision' => -1]);
+        $this->assertStreamContents('baz', $destination);
+
+        $destination = $this->createStream();
+        $this->bucket->downloadToStreamByName('filename', $destination, ['revision' => 0]);
+        $this->assertStreamContents('foo', $destination);
+
+        $destination = $this->createStream();
+        $this->bucket->downloadToStreamByName('filename', $destination, ['revision' => 1]);
+        $this->assertStreamContents('bar', $destination);
+
+        $destination = $this->createStream();
+        $this->bucket->downloadToStreamByName('filename', $destination, ['revision' => 2]);
+        $this->assertStreamContents('baz', $destination);
+    }
+
+    /**
+     * @dataProvider provideInvalidStreamValues
+     */
+    public function testDownloadToStreamByNameShouldRequireDestinationStream($destination)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        $this->bucket->downloadToStreamByName('filename', $destination);
+    }
+
+    /**
+     * @dataProvider provideNonexistentFilenameAndRevision
+     */
+    public function testDownloadToStreamByNameShouldRequireFilenameAndRevisionToExist($filename, $revision)
+    {
+        $this->bucket->uploadFromStream('filename', $this->createStream('foo'));
+        $this->bucket->uploadFromStream('filename', $this->createStream('bar'));
+
+        $destination = $this->createStream();
+        $this->expectException(FileNotFoundException::class);
+        $this->bucket->downloadToStreamByName($filename, $destination, ['revision' => $revision]);
+    }
+
+    public function provideNonexistentFilenameAndRevision()
+    {
+        return [
+            ['filename', 2],
+            ['filename', -3],
+            ['nonexistent-filename', 0],
+            ['nonexistent-filename', -1],
+        ];
+    }
+
+    public function testDrop()
+    {
+        $this->bucket->uploadFromStream('filename', $this->createStream('foobar'));
+
+        $this->assertCollectionCount($this->filesCollection, 1);
+        $this->assertCollectionCount($this->chunksCollection, 1);
+
+        $this->bucket->drop();
+
+        $this->assertCollectionDoesNotExist($this->filesCollection->getCollectionName());
+        $this->assertCollectionDoesNotExist($this->chunksCollection->getCollectionName());
+    }
+
+    public function testFind()
+    {
+        $this->bucket->uploadFromStream('a', $this->createStream('foo'));
+        $this->bucket->uploadFromStream('b', $this->createStream('foobar'));
+        $this->bucket->uploadFromStream('c', $this->createStream('foobarbaz'));
+
+        $cursor = $this->bucket->find(
+            ['length' => ['$lte' => 6]],
+            [
+                'projection' => [
+                    'filename' => 1,
+                    'length' => 1,
+                    '_id' => 0,
+                ],
+                'sort' => ['length' => -1],
+            ]
+        );
+
+        $expected = [
+            ['filename' => 'b', 'length' => 6],
+            ['filename' => 'a', 'length' => 3],
+        ];
+
+        $this->assertSameDocuments($expected, $cursor);
+    }
+
+    public function testFindUsesTypeMap()
+    {
+        $this->bucket->uploadFromStream('a', $this->createStream('foo'));
+
+        $cursor = $this->bucket->find();
+        $fileDocument = current($cursor->toArray());
+
+        $this->assertInstanceOf(BSONDocument::class, $fileDocument);
+    }
+
+    public function testFindOne()
+    {
+        $this->bucket->uploadFromStream('a', $this->createStream('foo'));
+        $this->bucket->uploadFromStream('b', $this->createStream('foobar'));
+        $this->bucket->uploadFromStream('c', $this->createStream('foobarbaz'));
+
+        $fileDocument = $this->bucket->findOne(
+            ['length' => ['$lte' => 6]],
+            [
+                'projection' => [
+                    'filename' => 1,
+                    'length' => 1,
+                    '_id' => 0,
+                ],
+                'sort' => ['length' => -1],
+            ]
+        );
+
+        $this->assertInstanceOf(BSONDocument::class, $fileDocument);
+        $this->assertSameDocument(['filename' => 'b', 'length' => 6], $fileDocument);
+    }
+
+    public function testGetBucketNameWithCustomValue()
+    {
+        $bucket = new Bucket($this->manager, $this->getDatabaseName(), ['bucketName' => 'custom_fs']);
+
+        $this->assertEquals('custom_fs', $bucket->getBucketName());
+    }
+
+    public function testGetBucketNameWithDefaultValue()
+    {
+        $this->assertEquals('fs', $this->bucket->getBucketName());
+    }
+
+    public function testGetChunksCollection()
+    {
+        $chunksCollection = $this->bucket->getChunksCollection();
+
+        $this->assertInstanceOf(Collection::class, $chunksCollection);
+        $this->assertEquals('fs.chunks', $chunksCollection->getCollectionName());
+    }
+
+    public function testGetChunkSizeBytesWithCustomValue()
+    {
+        $bucket = new Bucket($this->manager, $this->getDatabaseName(), ['chunkSizeBytes' => 8192]);
+
+        $this->assertEquals(8192, $bucket->getChunkSizeBytes());
+    }
+
+    public function testGetChunkSizeBytesWithDefaultValue()
+    {
+        $this->assertEquals(261120, $this->bucket->getChunkSizeBytes());
+    }
+
+    public function testGetDatabaseName()
+    {
+        $this->assertEquals($this->getDatabaseName(), $this->bucket->getDatabaseName());
+    }
+
+    public function testGetFileDocumentForStreamUsesTypeMap()
+    {
+        $metadata = ['foo' => 'bar'];
+        $stream = $this->bucket->openUploadStream('filename', ['_id' => 1, 'metadata' => $metadata]);
+
+        $fileDocument = $this->bucket->getFileDocumentForStream($stream);
+
+        $this->assertInstanceOf(BSONDocument::class, $fileDocument);
+        $this->assertInstanceOf(BSONDocument::class, $fileDocument['metadata']);
+        $this->assertSame(['foo' => 'bar'], $fileDocument['metadata']->getArrayCopy());
+    }
+
+    public function testGetFileDocumentForStreamWithReadableStream()
+    {
+        $metadata = ['foo' => 'bar'];
+        $id = $this->bucket->uploadFromStream('filename', $this->createStream('foobar'), ['metadata' => $metadata]);
+        $stream = $this->bucket->openDownloadStream($id);
+
+        $fileDocument = $this->bucket->getFileDocumentForStream($stream);
+
+        $this->assertSameObjectId($id, $fileDocument->_id);
+        $this->assertSame('filename', $fileDocument->filename);
+        $this->assertSame(6, $fileDocument->length);
+        $this->assertSameDocument($metadata, $fileDocument->metadata);
+    }
+
+    public function testGetFileDocumentForStreamWithWritableStream()
+    {
+        $metadata = ['foo' => 'bar'];
+        $stream = $this->bucket->openUploadStream('filename', ['_id' => 1, 'metadata' => $metadata]);
+
+        $fileDocument = $this->bucket->getFileDocumentForStream($stream);
+
+        $this->assertEquals(1, $fileDocument->_id);
+        $this->assertSame('filename', $fileDocument->filename);
+        $this->assertSameDocument($metadata, $fileDocument->metadata);
+    }
+
+    /**
+     * @dataProvider provideInvalidGridFSStreamValues
+     */
+    public function testGetFileDocumentForStreamShouldRequireGridFSStreamResource($stream)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        $this->bucket->getFileDocumentForStream($stream);
+    }
+
+    public function provideInvalidGridFSStreamValues()
+    {
+        return $this->wrapValuesForDataProvider(array_merge($this->getInvalidStreamValues(), [$this->createStream()]));
+    }
+
+    public function testGetFileIdForStreamUsesTypeMap()
+    {
+        $stream = $this->bucket->openUploadStream('filename', ['_id' => ['x' => 1]]);
+
+        $id = $this->bucket->getFileIdForStream($stream);
+
+        $this->assertInstanceOf(BSONDocument::class, $id);
+        $this->assertSame(['x' => 1], $id->getArrayCopy());
+    }
+
+    public function testGetFileIdForStreamWithReadableStream()
+    {
+        $id = $this->bucket->uploadFromStream('filename', $this->createStream('foobar'));
+        $stream = $this->bucket->openDownloadStream($id);
+
+        $this->assertSameObjectId($id, $this->bucket->getFileIdForStream($stream));
+    }
+
+    public function testGetFileIdForStreamWithWritableStream()
+    {
+        $stream = $this->bucket->openUploadStream('filename', ['_id' => 1]);
+
+        $this->assertEquals(1, $this->bucket->getFileIdForStream($stream));
+    }
+
+    /**
+     * @dataProvider provideInvalidGridFSStreamValues
+     */
+    public function testGetFileIdForStreamShouldRequireGridFSStreamResource($stream)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        $this->bucket->getFileIdForStream($stream);
+    }
+
+    public function testGetFilesCollection()
+    {
+        $filesCollection = $this->bucket->getFilesCollection();
+
+        $this->assertInstanceOf(Collection::class, $filesCollection);
+        $this->assertEquals('fs.files', $filesCollection->getCollectionName());
+    }
+
+    /**
+     * @dataProvider provideInputDataAndExpectedChunks
+     */
+    public function testOpenDownloadStream($input)
+    {
+        $id = $this->bucket->uploadFromStream('filename', $this->createStream($input));
+
+        $this->assertStreamContents($input, $this->bucket->openDownloadStream($id));
+    }
+
+    /**
+     * @dataProvider provideInputDataAndExpectedChunks
+     */
+    public function testOpenDownloadStreamAndMultipleReadOperations($input)
+    {
+        $id = $this->bucket->uploadFromStream('filename', $this->createStream($input));
+        $stream = $this->bucket->openDownloadStream($id);
+        $buffer = '';
+
+        while (strlen($buffer) < strlen($input)) {
+            $expectedReadLength = min(4096, strlen($input) - strlen($buffer));
+            $buffer .= $read = fread($stream, 4096);
+
+            $this->assertIsString($read);
+            $this->assertEquals($expectedReadLength, strlen($read));
+        }
+
+        $this->assertTrue(fclose($stream));
+        $this->assertEquals($input, $buffer);
+    }
+
+    public function testOpenDownloadStreamShouldRequireFileToExist()
+    {
+        $this->expectException(FileNotFoundException::class);
+        $this->bucket->openDownloadStream('nonexistent-id');
+    }
+
+    public function testOpenDownloadStreamByNameShouldRequireFilenameToExist()
+    {
+        $this->expectException(FileNotFoundException::class);
+        $this->bucket->openDownloadStream('nonexistent-filename');
+    }
+
+    public function testOpenDownloadStreamByName()
+    {
+        $this->bucket->uploadFromStream('filename', $this->createStream('foo'));
+        $this->bucket->uploadFromStream('filename', $this->createStream('bar'));
+        $this->bucket->uploadFromStream('filename', $this->createStream('baz'));
+
+        $this->assertStreamContents('baz', $this->bucket->openDownloadStreamByName('filename'));
+        $this->assertStreamContents('foo', $this->bucket->openDownloadStreamByName('filename', ['revision' => -3]));
+        $this->assertStreamContents('bar', $this->bucket->openDownloadStreamByName('filename', ['revision' => -2]));
+        $this->assertStreamContents('baz', $this->bucket->openDownloadStreamByName('filename', ['revision' => -1]));
+        $this->assertStreamContents('foo', $this->bucket->openDownloadStreamByName('filename', ['revision' => 0]));
+        $this->assertStreamContents('bar', $this->bucket->openDownloadStreamByName('filename', ['revision' => 1]));
+        $this->assertStreamContents('baz', $this->bucket->openDownloadStreamByName('filename', ['revision' => 2]));
+    }
+
+    /**
+     * @dataProvider provideNonexistentFilenameAndRevision
+     */
+    public function testOpenDownloadStreamByNameShouldRequireFilenameAndRevisionToExist($filename, $revision)
+    {
+        $this->bucket->uploadFromStream('filename', $this->createStream('foo'));
+        $this->bucket->uploadFromStream('filename', $this->createStream('bar'));
+
+        $this->expectException(FileNotFoundException::class);
+        $this->bucket->openDownloadStream($filename, ['revision' => $revision]);
+    }
+
+    public function testOpenUploadStream()
+    {
+        $stream = $this->bucket->openUploadStream('filename');
+
+        fwrite($stream, 'foobar');
+        fclose($stream);
+
+        $this->assertStreamContents('foobar', $this->bucket->openDownloadStreamByName('filename'));
+    }
+
+    /**
+     * @dataProvider provideInputDataAndExpectedChunks
+     */
+    public function testOpenUploadStreamAndMultipleWriteOperations($input)
+    {
+        $stream = $this->bucket->openUploadStream('filename');
+        $offset = 0;
+
+        while ($offset < strlen($input)) {
+            $expectedWriteLength = min(4096, strlen($input) - $offset);
+            $writeLength = fwrite($stream, substr($input, $offset, 4096));
+            $offset += $writeLength;
+
+            $this->assertEquals($expectedWriteLength, $writeLength);
+        }
+
+        $this->assertTrue(fclose($stream));
+        $this->assertStreamContents($input, $this->bucket->openDownloadStreamByName('filename'));
+    }
+
+    public function testRename()
+    {
+        $id = $this->bucket->uploadFromStream('a', $this->createStream('foo'));
+        $this->bucket->rename($id, 'b');
+
+        $fileDocument = $this->filesCollection->findOne(
+            ['_id' => $id],
+            ['projection' => ['filename' => 1, '_id' => 0]]
+        );
+
+        $this->assertSameDocument(['filename' => 'b'], $fileDocument);
+        $this->assertStreamContents('foo', $this->bucket->openDownloadStreamByName('b'));
+    }
+
+    public function testRenameShouldNotRequireFileToBeModified()
+    {
+        $id = $this->bucket->uploadFromStream('a', $this->createStream('foo'));
+        $this->bucket->rename($id, 'a');
+
+        $fileDocument = $this->filesCollection->findOne(
+            ['_id' => $id],
+            ['projection' => ['filename' => 1, '_id' => 0]]
+        );
+
+        $this->assertSameDocument(['filename' => 'a'], $fileDocument);
+        $this->assertStreamContents('foo', $this->bucket->openDownloadStreamByName('a'));
+    }
+
+    public function testRenameShouldRequireFileToExist()
+    {
+        $this->expectException(FileNotFoundException::class);
+        $this->bucket->rename('nonexistent-id', 'b');
+    }
+
+    public function testUploadFromStream()
+    {
+        $options = [
+            '_id' => 'custom-id',
+            'chunkSizeBytes' => 2,
+            'metadata' => ['foo' => 'bar'],
+        ];
+
+        $id = $this->bucket->uploadFromStream('filename', $this->createStream('foobar'), $options);
+
+        $this->assertCollectionCount($this->filesCollection, 1);
+        $this->assertCollectionCount($this->chunksCollection, 3);
+        $this->assertSame('custom-id', $id);
+
+        $fileDocument = $this->filesCollection->findOne(['_id' => $id]);
+
+        $this->assertSameDocument(['foo' => 'bar'], $fileDocument['metadata']);
+    }
+
+    /**
+     * @dataProvider provideInvalidStreamValues
+     */
+    public function testUploadFromStreamShouldRequireSourceStream($source)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        $this->bucket->uploadFromStream('filename', $source);
+    }
+
+    public function testUploadingAnEmptyFile()
+    {
+        $id = $this->bucket->uploadFromStream('filename', $this->createStream(''));
+        $destination = $this->createStream();
+        $this->bucket->downloadToStream($id, $destination);
+
+        $this->assertStreamContents('', $destination);
+        $this->assertCollectionCount($this->filesCollection, 1);
+        $this->assertCollectionCount($this->chunksCollection, 0);
+
+        $fileDocument = $this->filesCollection->findOne(
+            ['_id' => $id],
+            [
+                'projection' => [
+                    'length' => 1,
+                    'md5' => 1,
+                    '_id' => 0,
+                ],
+            ]
+        );
+
+        $expected = [
+            'length' => 0,
+            'md5' => 'd41d8cd98f00b204e9800998ecf8427e',
+        ];
+
+        $this->assertSameDocument($expected, $fileDocument);
+    }
+
+    public function testUploadingFirstFileCreatesIndexes()
+    {
+        $this->bucket->uploadFromStream('filename', $this->createStream('foo'));
+
+        $this->assertIndexExists($this->filesCollection->getCollectionName(), 'filename_1_uploadDate_1');
+        $this->assertIndexExists($this->chunksCollection->getCollectionName(), 'files_id_1_n_1', function (IndexInfo $info) {
+            $this->assertTrue($info->isUnique());
+        });
+    }
+
+    public function testExistingIndexIsReused()
+    {
+        $this->filesCollection->createIndex(['filename' => 1.0, 'uploadDate' => 1], ['name' => 'test']);
+        $this->chunksCollection->createIndex(['files_id' => 1.0, 'n' => 1], ['name' => 'test', 'unique' => true]);
+
+        $this->bucket->uploadFromStream('filename', $this->createStream('foo'));
+
+        $this->assertIndexNotExists($this->filesCollection->getCollectionName(), 'filename_1_uploadDate_1');
+        $this->assertIndexNotExists($this->chunksCollection->getCollectionName(), 'files_id_1_n_1');
+    }
+
+    public function testDownloadToStreamFails()
+    {
+        $this->bucket->uploadFromStream('filename', $this->createStream('foo'), ['_id' => ['foo' => 'bar']]);
+
+        $this->expectException(StreamException::class);
+        $this->expectExceptionMessageMatches('#^Downloading file from "gridfs://.*/.*/.*" to "php://temp" failed. GridFS identifier: "{ "_id" : { "foo" : "bar" } }"$#');
+        $this->bucket->downloadToStream(['foo' => 'bar'], fopen('php://temp', 'r'));
+    }
+
+    public function testDownloadToStreamByNameFails()
+    {
+        $this->bucket->uploadFromStream('filename', $this->createStream('foo'));
+
+        $this->expectException(StreamException::class);
+        $this->expectExceptionMessageMatches('#^Downloading file from "gridfs://.*/.*/.*" to "php://temp" failed. GridFS filename: "filename"$#');
+        $this->bucket->downloadToStreamByName('filename', fopen('php://temp', 'r'));
+    }
+
+    public function testUploadFromStreamFails()
+    {
+        if (PHP_VERSION_ID < 70400) {
+            $this->markTestSkipped('Test only works on PHP 7.4 and newer');
+        }
+
+        UnusableStream::register();
+        $source = fopen('unusable://temp', 'w');
+
+        $this->expectException(StreamException::class);
+        $this->expectExceptionMessageMatches('#^Uploading file from "unusable://temp" to "gridfs://.*/.*/.*" failed. GridFS filename: "filename"$#');
+        $this->bucket->uploadFromStream('filename', $source);
+    }
+
+    public function testDanglingOpenWritableStream()
+    {
+        if (! strncasecmp(PHP_OS, 'WIN', 3)) {
+            $this->markTestSkipped('Test does not apply to Windows');
+        }
+
+        $path = __DIR__ . '/../../vendor/autoload.php';
+        $command = <<<CMD
+php -r "require '$path'; \\\$stream = (new MongoDB\Client)->test->selectGridFSBucket()->openUploadStream('filename', ['disableMD5' => true]);" 2>&1
+CMD;
+
+        @exec(
+            $command,
+            $output,
+            $return
+        );
+
+        $this->assertSame(0, $return);
+        $output = implode(PHP_EOL, $output);
+
+        $this->assertSame('', $output);
+    }
+
+    /**
+     * Asserts that a collection with the given name does not exist on the
+     * server.
+     *
+     * @param string $collectionName
+     */
+    private function assertCollectionDoesNotExist($collectionName)
+    {
+        $operation = new ListCollections($this->getDatabaseName());
+        $collections = $operation->execute($this->getPrimaryServer());
+
+        $foundCollection = null;
+
+        foreach ($collections as $collection) {
+            if ($collection->getName() === $collectionName) {
+                $foundCollection = $collection;
+                break;
+            }
+        }
+
+        $this->assertNull($foundCollection, sprintf('Collection %s exists', $collectionName));
+    }
+
+    /**
+     * Asserts that an index with the given name exists for the collection.
+     *
+     * An optional $callback may be provided, which should take an IndexInfo
+     * argument as its first and only parameter. If an IndexInfo matching the
+     * given name is found, it will be passed to the callback, which may perform
+     * additional assertions.
+     *
+     * @param string   $collectionName
+     * @param string   $indexName
+     * @param callable $callback
+     */
+    private function assertIndexExists($collectionName, $indexName, $callback = null)
+    {
+        if ($callback !== null && ! is_callable($callback)) {
+            throw new InvalidArgumentException('$callback is not a callable');
+        }
+
+        $operation = new ListIndexes($this->getDatabaseName(), $collectionName);
+        $indexes = $operation->execute($this->getPrimaryServer());
+
+        $foundIndex = null;
+
+        foreach ($indexes as $index) {
+            if ($index->getName() === $indexName) {
+                $foundIndex = $index;
+                break;
+            }
+        }
+
+        $this->assertNotNull($foundIndex, sprintf('Index %s does not exist', $indexName));
+
+        if ($callback !== null) {
+            call_user_func($callback, $foundIndex);
+        }
+    }
+
+    /**
+     * Asserts that an index with the given name does not exist for the collection.
+     *
+     * @param string $collectionName
+     * @param string $indexName
+     */
+    private function assertIndexNotExists($collectionName, $indexName)
+    {
+        $operation = new ListIndexes($this->getDatabaseName(), $collectionName);
+        $indexes = $operation->execute($this->getPrimaryServer());
+
+        $foundIndex = false;
+
+        foreach ($indexes as $index) {
+            if ($index->getName() === $indexName) {
+                $foundIndex = true;
+                break;
+            }
+        }
+
+        $this->assertFalse($foundIndex, sprintf('Index %s exists', $indexName));
+    }
+
+    /**
+     * Return a list of invalid stream values.
+     *
+     * @return array
+     */
+    private function getInvalidStreamValues()
+    {
+        return [null, 123, 'foo', [], hash_init('md5')];
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/GridFS/FunctionalTestCase.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/GridFS/FunctionalTestCase.php
new file mode 100644
index 0000000000000000000000000000000000000000..4281952847495cbccc1c219e407af303324445cb
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/GridFS/FunctionalTestCase.php	
@@ -0,0 +1,71 @@
+<?php
+
+namespace MongoDB\Tests\GridFS;
+
+use MongoDB\Collection;
+use MongoDB\GridFS\Bucket;
+use MongoDB\Tests\FunctionalTestCase as BaseFunctionalTestCase;
+use Symfony\Bridge\PhpUnit\SetUpTearDownTrait;
+use function fopen;
+use function fwrite;
+use function get_resource_type;
+use function rewind;
+use function stream_get_contents;
+
+/**
+ * Base class for GridFS functional tests.
+ */
+abstract class FunctionalTestCase extends BaseFunctionalTestCase
+{
+    use SetUpTearDownTrait;
+
+    /** @var Bucket */
+    protected $bucket;
+
+    /** @var Collection */
+    protected $chunksCollection;
+
+    /** @var Collection */
+    protected $filesCollection;
+
+    private function doSetUp()
+    {
+        parent::setUp();
+
+        $this->bucket = new Bucket($this->manager, $this->getDatabaseName());
+        $this->bucket->drop();
+
+        $this->chunksCollection = new Collection($this->manager, $this->getDatabaseName(), 'fs.chunks');
+        $this->filesCollection = new Collection($this->manager, $this->getDatabaseName(), 'fs.files');
+    }
+
+    /**
+     * Asserts that a variable is a stream containing the expected data.
+     *
+     * Note: this will seek to the beginning of the stream before reading.
+     *
+     * @param string   $expectedContents
+     * @param resource $stream
+     */
+    protected function assertStreamContents($expectedContents, $stream)
+    {
+        $this->assertIsResource($stream);
+        $this->assertSame('stream', get_resource_type($stream));
+        $this->assertEquals($expectedContents, stream_get_contents($stream, -1, 0));
+    }
+
+    /**
+     * Creates an in-memory stream with the given data.
+     *
+     * @param string $data
+     * @return resource
+     */
+    protected function createStream($data = '')
+    {
+        $stream = fopen('php://temp', 'w+b');
+        fwrite($stream, $data);
+        rewind($stream);
+
+        return $stream;
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/GridFS/ReadableStreamFunctionalTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/GridFS/ReadableStreamFunctionalTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..bdadcfa327ac38808d808e32a5de4380ac39d9e6
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/GridFS/ReadableStreamFunctionalTest.php	
@@ -0,0 +1,315 @@
+<?php
+
+namespace MongoDB\Tests\GridFS;
+
+use MongoDB\BSON\Binary;
+use MongoDB\Exception\InvalidArgumentException;
+use MongoDB\GridFS\CollectionWrapper;
+use MongoDB\GridFS\Exception\CorruptFileException;
+use MongoDB\GridFS\ReadableStream;
+use MongoDB\Tests\CommandObserver;
+use Symfony\Bridge\PhpUnit\SetUpTearDownTrait;
+use function array_filter;
+
+/**
+ * Functional tests for the internal ReadableStream class.
+ */
+class ReadableStreamFunctionalTest extends FunctionalTestCase
+{
+    use SetUpTearDownTrait;
+
+    /** @var CollectionWrapper */
+    private $collectionWrapper;
+
+    private function doSetUp()
+    {
+        parent::setUp();
+
+        $this->collectionWrapper = new CollectionWrapper($this->manager, $this->getDatabaseName(), 'fs');
+
+        $this->filesCollection->insertMany([
+            ['_id' => 'length-0', 'length' => 0, 'chunkSize' => 4],
+            ['_id' => 'length-0-with-empty-chunk', 'length' => 0, 'chunkSize' => 4],
+            ['_id' => 'length-2', 'length' => 2, 'chunkSize' => 4],
+            ['_id' => 'length-8', 'length' => 8, 'chunkSize' => 4],
+            ['_id' => 'length-10', 'length' => 10, 'chunkSize' => 4],
+        ]);
+
+        $this->chunksCollection->insertMany([
+            ['_id' => 1, 'files_id' => 'length-0-with-empty-chunk', 'n' => 0, 'data' => new Binary('', Binary::TYPE_GENERIC)],
+            ['_id' => 2, 'files_id' => 'length-2', 'n' => 0, 'data' => new Binary('ab', Binary::TYPE_GENERIC)],
+            ['_id' => 3, 'files_id' => 'length-8', 'n' => 0, 'data' => new Binary('abcd', Binary::TYPE_GENERIC)],
+            ['_id' => 4, 'files_id' => 'length-8', 'n' => 1, 'data' => new Binary('efgh', Binary::TYPE_GENERIC)],
+            ['_id' => 5, 'files_id' => 'length-10', 'n' => 0, 'data' => new Binary('abcd', Binary::TYPE_GENERIC)],
+            ['_id' => 6, 'files_id' => 'length-10', 'n' => 1, 'data' => new Binary('efgh', Binary::TYPE_GENERIC)],
+            ['_id' => 7, 'files_id' => 'length-10', 'n' => 2, 'data' => new Binary('ij', Binary::TYPE_GENERIC)],
+        ]);
+    }
+
+    public function testGetFile()
+    {
+        $fileDocument = (object) ['_id' => null, 'chunkSize' => 1, 'length' => 0];
+        $stream = new ReadableStream($this->collectionWrapper, $fileDocument);
+        $this->assertSame($fileDocument, $stream->getFile());
+    }
+
+    /**
+     * @dataProvider provideInvalidConstructorFileDocuments
+     */
+    public function testConstructorFileDocumentChecks($file)
+    {
+        $this->expectException(CorruptFileException::class);
+        new ReadableStream($this->collectionWrapper, $file);
+    }
+
+    public function provideInvalidConstructorFileDocuments()
+    {
+        $options = [];
+
+        foreach ($this->getInvalidIntegerValues() as $value) {
+            $options[][] = (object) ['_id' => 1, 'chunkSize' => $value, 'length' => 0];
+        }
+
+        foreach ($this->getInvalidIntegerValues() as $value) {
+            $options[][] = (object) ['_id' => 1, 'chunkSize' => 1, 'length' => $value];
+        }
+
+        $options[][] = (object) ['_id' => 1, 'chunkSize' => 0, 'length' => 0];
+        $options[][] = (object) ['_id' => 1, 'chunkSize' => 1, 'length' => -1];
+        $options[][] = (object) ['chunkSize' => 1, 'length' => 0];
+
+        return $options;
+    }
+
+    /**
+     * @dataProvider provideFileIdAndExpectedBytes
+     */
+    public function testReadBytes($fileId, $length, $expectedBytes)
+    {
+        $fileDocument = $this->collectionWrapper->findFileById($fileId);
+        $stream = new ReadableStream($this->collectionWrapper, $fileDocument);
+
+        $this->assertSame($expectedBytes, $stream->readBytes($length));
+    }
+
+    public function provideFileIdAndExpectedBytes()
+    {
+        return [
+            ['length-0', 0, ''],
+            ['length-0', 2, ''],
+            ['length-0-with-empty-chunk', 0, ''],
+            ['length-0-with-empty-chunk', 2, ''],
+            ['length-2', 0, ''],
+            ['length-2', 2, 'ab'],
+            ['length-2', 4, 'ab'],
+            ['length-8', 0, ''],
+            ['length-8', 2, 'ab'],
+            ['length-8', 4, 'abcd'],
+            ['length-8', 6, 'abcdef'],
+            ['length-8', 8, 'abcdefgh'],
+            ['length-8', 10, 'abcdefgh'],
+            ['length-10', 0, ''],
+            ['length-10', 2, 'ab'],
+            ['length-10', 4, 'abcd'],
+            ['length-10', 6, 'abcdef'],
+            ['length-10', 8, 'abcdefgh'],
+            ['length-10', 10, 'abcdefghij'],
+            ['length-10', 12, 'abcdefghij'],
+        ];
+    }
+
+    public function provideFilteredFileIdAndExpectedBytes()
+    {
+        return array_filter(
+            $this->provideFileIdAndExpectedBytes(),
+            function (array $args) {
+                return $args[1] > 0;
+            }
+        );
+    }
+
+    /**
+     * @dataProvider provideFilteredFileIdAndExpectedBytes
+     */
+    public function testReadBytesCalledMultipleTimes($fileId, $length, $expectedBytes)
+    {
+        $fileDocument = $this->collectionWrapper->findFileById($fileId);
+        $stream = new ReadableStream($this->collectionWrapper, $fileDocument);
+        for ($i = 0; $i < $length; $i++) {
+            $expectedByte = $expectedBytes[$i] ?? '';
+            $this->assertSame($expectedByte, $stream->readBytes(1));
+        }
+    }
+
+    public function testReadBytesWithMissingChunk()
+    {
+        $this->chunksCollection->deleteOne(['files_id' => 'length-10', 'n' => 2]);
+
+        $fileDocument = $this->collectionWrapper->findFileById('length-10');
+        $stream = new ReadableStream($this->collectionWrapper, $fileDocument);
+
+        $this->expectException(CorruptFileException::class);
+        $this->expectExceptionMessage('Chunk not found for index "2"');
+        $stream->readBytes(10);
+    }
+
+    public function testReadBytesWithUnexpectedChunkIndex()
+    {
+        $this->chunksCollection->deleteOne(['files_id' => 'length-10', 'n' => 1]);
+
+        $fileDocument = $this->collectionWrapper->findFileById('length-10');
+        $stream = new ReadableStream($this->collectionWrapper, $fileDocument);
+
+        $this->expectException(CorruptFileException::class);
+        $this->expectExceptionMessage('Expected chunk to have index "1" but found "2"');
+        $stream->readBytes(10);
+    }
+
+    public function testReadBytesWithUnexpectedChunkSize()
+    {
+        $this->chunksCollection->updateOne(
+            ['files_id' => 'length-10', 'n' => 2],
+            ['$set' => ['data' => new Binary('i', Binary::TYPE_GENERIC)]]
+        );
+
+        $fileDocument = $this->collectionWrapper->findFileById('length-10');
+        $stream = new ReadableStream($this->collectionWrapper, $fileDocument);
+
+        $this->expectException(CorruptFileException::class);
+        $this->expectExceptionMessage('Expected chunk to have size "2" but found "1"');
+        $stream->readBytes(10);
+    }
+
+    public function testReadBytesWithNegativeLength()
+    {
+        $fileDocument = $this->collectionWrapper->findFileById('length-0');
+        $stream = new ReadableStream($this->collectionWrapper, $fileDocument);
+
+        $this->expectException(InvalidArgumentException::class);
+        $stream->readBytes(-1);
+    }
+
+    public function testSeekBeforeReading()
+    {
+        $fileDocument = $this->collectionWrapper->findFileById('length-10');
+        $stream = new ReadableStream($this->collectionWrapper, $fileDocument);
+
+        $stream->seek(8);
+        $this->assertSame('ij', $stream->readBytes(2));
+    }
+
+    public function testSeekOutOfRange()
+    {
+        $fileDocument = $this->collectionWrapper->findFileById('length-10');
+        $stream = new ReadableStream($this->collectionWrapper, $fileDocument);
+
+        $this->expectException(InvalidArgumentException::class);
+        $this->expectExceptionMessage('$offset must be >= 0 and <= 10; given: 11');
+        $stream->seek(11);
+    }
+
+    /**
+     * @dataProvider providePreviousChunkSeekOffsetAndBytes
+     */
+    public function testSeekPreviousChunk($offset, $length, $expectedBytes)
+    {
+        $fileDocument = $this->collectionWrapper->findFileById('length-10');
+        $stream = new ReadableStream($this->collectionWrapper, $fileDocument);
+
+        // Read to initialize and advance the chunk iterator to the last chunk
+        $this->assertSame('abcdefghij', $stream->readBytes(10));
+
+        $commands = [];
+
+        (new CommandObserver())->observe(
+            function () use ($stream, $offset, $length, $expectedBytes) {
+                $stream->seek($offset);
+                $this->assertSame($expectedBytes, $stream->readBytes($length));
+            },
+            function (array $event) use (&$commands) {
+                $commands[] = $event['started']->getCommandName();
+            }
+        );
+
+        $this->assertSame(['find'], $commands);
+    }
+
+    public function providePreviousChunkSeekOffsetAndBytes()
+    {
+        return [
+            [0, 4, 'abcd'],
+            [2, 4, 'cdef'],
+            [4, 4, 'efgh'],
+            [6, 4, 'ghij'],
+        ];
+    }
+
+    /**
+     * @dataProvider provideSameChunkSeekOffsetAndBytes
+     */
+    public function testSeekSameChunk($offset, $length, $expectedBytes)
+    {
+        $fileDocument = $this->collectionWrapper->findFileById('length-10');
+        $stream = new ReadableStream($this->collectionWrapper, $fileDocument);
+
+        // Read to initialize and advance the chunk iterator to the middle chunk
+        $this->assertSame('abcdef', $stream->readBytes(6));
+
+        $commands = [];
+
+        (new CommandObserver())->observe(
+            function () use ($stream, $offset, $length, $expectedBytes) {
+                $stream->seek($offset);
+                $this->assertSame($expectedBytes, $stream->readBytes($length));
+            },
+            function (array $event) use (&$commands) {
+                $commands[] = $event['started']->getCommandName();
+            }
+        );
+
+        $this->assertSame([], $commands);
+    }
+
+    public function provideSameChunkSeekOffsetAndBytes()
+    {
+        return [
+            [4, 4, 'efgh'],
+            [6, 4, 'ghij'],
+        ];
+    }
+
+    /**
+     * @dataProvider provideSubsequentChunkSeekOffsetAndBytes
+     */
+    public function testSeekSubsequentChunk($offset, $length, $expectedBytes)
+    {
+        $fileDocument = $this->collectionWrapper->findFileById('length-10');
+        $stream = new ReadableStream($this->collectionWrapper, $fileDocument);
+
+        // Read to initialize the chunk iterator to the first chunk
+        $this->assertSame('a', $stream->readBytes(1));
+
+        $commands = [];
+
+        (new CommandObserver())->observe(
+            function () use ($stream, $offset, $length, $expectedBytes) {
+                $stream->seek($offset);
+                $this->assertSame($expectedBytes, $stream->readBytes($length));
+            },
+            function (array $event) use (&$commands) {
+                $commands[] = $event['started']->getCommandName();
+            }
+        );
+
+        $this->assertSame([], $commands);
+    }
+
+    public function provideSubsequentChunkSeekOffsetAndBytes()
+    {
+        return [
+            [4, 4, 'efgh'],
+            [6, 4, 'ghij'],
+            [8, 2, 'ij'],
+        ];
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/GridFS/SpecFunctionalTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/GridFS/SpecFunctionalTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..f9d42f3f8d830e97abc76204d604896faea8fd96
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/GridFS/SpecFunctionalTest.php	
@@ -0,0 +1,389 @@
+<?php
+
+namespace MongoDB\Tests\GridFS;
+
+use DateTime;
+use IteratorIterator;
+use LogicException;
+use MongoDB\BSON\Binary;
+use MongoDB\BSON\ObjectId;
+use MongoDB\BSON\UTCDateTime;
+use MongoDB\Collection;
+use MongoDB\GridFS\Exception\FileNotFoundException;
+use MongoDB\Operation\BulkWrite;
+use MultipleIterator;
+use PHPUnit\Framework\Error\Warning;
+use Symfony\Bridge\PhpUnit\SetUpTearDownTrait;
+use Throwable;
+use function array_walk;
+use function array_walk_recursive;
+use function file_get_contents;
+use function glob;
+use function hex2bin;
+use function in_array;
+use function is_array;
+use function is_string;
+use function json_decode;
+use function str_replace;
+use function stream_get_contents;
+use function strncmp;
+use function var_export;
+
+/**
+ * GridFS spec functional tests.
+ *
+ * @see https://github.com/mongodb/specifications/tree/master/source/gridfs/tests
+ */
+class SpecFunctionalTest extends FunctionalTestCase
+{
+    use SetUpTearDownTrait;
+
+    /** @var Collection */
+    private $expectedChunksCollection;
+
+    /** @var Collection */
+    private $expectedFilesCollection;
+
+    private function doSetUp()
+    {
+        parent::setUp();
+
+        $this->expectedFilesCollection = new Collection($this->manager, $this->getDatabaseName(), 'expected.files');
+        $this->expectedFilesCollection->drop();
+
+        $this->expectedChunksCollection = new Collection($this->manager, $this->getDatabaseName(), 'expected.chunks');
+        $this->expectedChunksCollection->drop();
+    }
+
+    /**
+     * @dataProvider provideSpecificationTests
+     */
+    public function testSpecification(array $initialData, array $test)
+    {
+        $this->initializeData($initialData);
+
+        if (isset($test['arrange'])) {
+            foreach ($test['arrange']['data'] as $dataModification) {
+                $this->executeDataModification($dataModification);
+            }
+        }
+
+        try {
+            $result = $this->executeAct($test['act']);
+        } catch (Throwable $e) {
+            $result = $e;
+        }
+
+        /* Per the GridFS spec: "Drivers MAY attempt to delete any orphaned
+         * chunks with files_id equal to id before raising the error." The spec
+         * tests do not expect orphaned chunks to be removed, so we manually
+         * remove those chunks from the expected collection. */
+        if ($test['act']['operation'] === 'delete' && $result instanceof FileNotFoundException) {
+            $filesId = $this->convertTypes($test['act'])['arguments']['id'];
+            $this->expectedChunksCollection->deleteMany(['files_id' => $filesId]);
+        }
+
+        if (isset($test['assert'])) {
+            $this->executeAssert($test['assert'], $result);
+        }
+    }
+
+    public function provideSpecificationTests()
+    {
+        $testArgs = [];
+
+        foreach (glob(__DIR__ . '/spec-tests/*.json') as $filename) {
+            $json = json_decode(file_get_contents($filename), true);
+
+            foreach ($json['tests'] as $test) {
+                $name = str_replace(' ', '_', $test['description']);
+                $testArgs[$name] = [$json['data'], $test];
+            }
+        }
+
+        return $testArgs;
+    }
+
+    /**
+     * Assert that the collections contain equivalent documents.
+     *
+     * This method will resolve references within the expected collection's
+     * documents before comparing documents. Occurrences of "*result" in the
+     * expected collection's documents will be replaced with the actual result.
+     * Occurrences of "*actual" in the expected collection's documents will be
+     * replaced with the corresponding value in the actual collection's document
+     * being compared.
+     *
+     * @param Collection $expectedCollection
+     * @param Collection $actualCollection
+     * @param mixed      $actualResult
+     */
+    private function assertEquivalentCollections($expectedCollection, $actualCollection, $actualResult)
+    {
+        $mi = new MultipleIterator(MultipleIterator::MIT_NEED_ANY);
+        $mi->attachIterator(new IteratorIterator($expectedCollection->find()));
+        $mi->attachIterator(new IteratorIterator($actualCollection->find()));
+
+        foreach ($mi as $documents) {
+            list($expectedDocument, $actualDocument) = $documents;
+
+            foreach ($expectedDocument as $key => $value) {
+                if (! is_string($value)) {
+                    continue;
+                }
+
+                if ($value === '*result') {
+                    $expectedDocument[$key] = $actualResult;
+                }
+
+                if (! strncmp($value, '*actual_', 8)) {
+                    $expectedDocument[$key] = $actualDocument[$key];
+                }
+            }
+
+            $this->assertSameDocument($expectedDocument, $actualDocument);
+        }
+    }
+
+    /**
+     * Convert encoded types in the array and return the modified array.
+     *
+     * Nested arrays with "$oid" and "$date" keys will be converted to ObjectId
+     * and UTCDateTime instances, respectively. Nested arrays with "$hex" keys
+     * will be converted to a string or Binary object.
+     *
+     * @param param   $data
+     * @param boolean $createBinary If true, convert "$hex" values to a Binary
+     * @return array
+     */
+    private function convertTypes(array $data, $createBinary = true)
+    {
+        /* array_walk_recursive() only visits leaf nodes within the array, so we
+         * need to manually recurse.
+         */
+        array_walk($data, function (&$value) use ($createBinary) {
+            if (! is_array($value)) {
+                return;
+            }
+
+            if (isset($value['$oid'])) {
+                $value = new ObjectId($value['$oid']);
+
+                return;
+            }
+
+            if (isset($value['$hex'])) {
+                $value = $createBinary
+                    ? new Binary(hex2bin($value['$hex']), Binary::TYPE_GENERIC)
+                    : hex2bin($value['$hex']);
+
+                return;
+            }
+
+            if (isset($value['$date'])) {
+                $value = new UTCDateTime(new DateTime($value['$date']));
+
+                return;
+            }
+
+            $value = $this->convertTypes($value, $createBinary);
+        });
+
+        return $data;
+    }
+
+    /**
+     * Executes an "act" block.
+     *
+     * @param array $act
+     * @return mixed
+     * @throws LogicException if the operation is unsupported
+     */
+    private function executeAct(array $act)
+    {
+        $act = $this->convertTypes($act, false);
+
+        switch ($act['operation']) {
+            case 'delete':
+                return $this->bucket->delete($act['arguments']['id']);
+            case 'download':
+                return stream_get_contents($this->bucket->openDownloadStream($act['arguments']['id']));
+            case 'download_by_name':
+                return stream_get_contents($this->bucket->openDownloadStreamByName(
+                    $act['arguments']['filename'],
+                    $act['arguments']['options'] ?? []
+                ));
+            case 'upload':
+                return $this->bucket->uploadFromStream(
+                    $act['arguments']['filename'],
+                    $this->createStream($act['arguments']['source']),
+                    $act['arguments']['options'] ?? []
+                );
+            default:
+                throw new LogicException('Unsupported act: ' . $act['operation']);
+        }
+    }
+
+    /**
+     * Executes an "assert" block.
+     *
+     * @param array $assert
+     * @param mixed $actualResult
+     * @return mixed
+     * @throws LogicException if the operation is unsupported
+     */
+    private function executeAssert(array $assert, $actualResult)
+    {
+        if (isset($assert['error'])) {
+            $this->assertInstanceOf($this->getExceptionClassForError($assert['error']), $actualResult);
+        }
+
+        if (isset($assert['result'])) {
+            $this->executeAssertResult($assert['result'], $actualResult);
+        }
+
+        if (! isset($assert['data'])) {
+            return;
+        }
+
+        /* Since "*actual" may be used for an expected document's "_id", append
+         * a unique value to avoid duplicate key exceptions.
+         */
+        array_walk_recursive($assert['data'], function (&$value) {
+            if ($value === '*actual') {
+                $value .= '_' . new ObjectId();
+            }
+        });
+
+        foreach ($assert['data'] as $dataModification) {
+            $this->executeDataModification($dataModification);
+        }
+
+        $this->assertEquivalentCollections($this->expectedFilesCollection, $this->filesCollection, $actualResult);
+        $this->assertEquivalentCollections($this->expectedChunksCollection, $this->chunksCollection, $actualResult);
+    }
+
+    /**
+     * Executes the "result" section of an "assert" block.
+     *
+     * @param mixed $expectedResult
+     * @param mixed $actualResult
+     * @throws LogicException if the result assertion is unsupported
+     */
+    private function executeAssertResult($expectedResult, $actualResult)
+    {
+        if ($expectedResult === 'void') {
+            return $this->assertNull($actualResult);
+        }
+
+        if ($expectedResult === '&result') {
+            // Do nothing; assertEquivalentCollections() will handle this
+            return;
+        }
+
+        if (isset($expectedResult['$hex'])) {
+            return $this->assertSame(hex2bin($expectedResult['$hex']), $actualResult);
+        }
+
+        throw new LogicException('Unsupported result assertion: ' . var_export($expectedResult, true));
+    }
+
+    /**
+     * Executes a data modification from an "arrange" or "assert" block.
+     *
+     * @param array $dataModification
+     * @return mixed
+     * @throws LogicException if the operation or collection is unsupported
+     */
+    private function executeDataModification(array $dataModification)
+    {
+        if (empty($dataModification)) {
+            throw new LogicException('Command for data modification is empty');
+        }
+
+        foreach ($dataModification as $type => $collectionName) {
+            break;
+        }
+
+        if (! in_array($collectionName, ['fs.files', 'fs.chunks', 'expected.files', 'expected.chunks'])) {
+            throw new LogicException('Unsupported collection: ' . $collectionName);
+        }
+
+        $dataModification = $this->convertTypes($dataModification);
+        $operations = [];
+
+        switch ($type) {
+            case 'delete':
+                foreach ($dataModification['deletes'] as $delete) {
+                    $operations[] = [ ($delete['limit'] === 1 ? 'deleteOne' : 'deleteMany') => [ $delete['q'] ] ];
+                }
+
+                break;
+
+            case 'insert':
+                foreach ($dataModification['documents'] as $document) {
+                    $operations[] = [ 'insertOne' => [ $document ] ];
+                }
+
+                break;
+
+            case 'update':
+                foreach ($dataModification['updates'] as $update) {
+                    $operations[] = [ 'updateOne' => [ $update['q'], $update['u'] ] ];
+                }
+
+                break;
+
+            default:
+                throw new LogicException('Unsupported arrangement: ' . $type);
+        }
+
+        $bulk = new BulkWrite($this->getDatabaseName(), $collectionName, $operations);
+
+        return $bulk->execute($this->getPrimaryServer());
+    }
+
+    /**
+     * Returns the exception class for the "error" section of an "assert" block.
+     *
+     * @param string $error
+     * @return string
+     * @throws LogicException if the error is unsupported
+     */
+    private function getExceptionClassForError($error)
+    {
+        switch ($error) {
+            case 'FileNotFound':
+            case 'RevisionNotFound':
+                return FileNotFoundException::class;
+            case 'ChunkIsMissing':
+            case 'ChunkIsWrongSize':
+                /* Although ReadableStream throws a CorruptFileException, the
+                 * stream wrapper will convert it to a PHP error of type
+                 * E_USER_WARNING. */
+                return Warning::class;
+            default:
+                throw new LogicException('Unsupported error: ' . $error);
+        }
+    }
+
+    /**
+     * Initializes data in the files and chunks collections.
+     *
+     * @param array $data
+     */
+    private function initializeData(array $data)
+    {
+        $data = $this->convertTypes($data);
+
+        if (! empty($data['files'])) {
+            $this->filesCollection->insertMany($data['files']);
+            $this->expectedFilesCollection->insertMany($data['files']);
+        }
+
+        if (! empty($data['chunks'])) {
+            $this->chunksCollection->insertMany($data['chunks']);
+            $this->expectedChunksCollection->insertMany($data['chunks']);
+        }
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/GridFS/StreamWrapperFunctionalTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/GridFS/StreamWrapperFunctionalTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..88e1bd9b87f21fa6008d8ab2c7c0277f02e05026
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/GridFS/StreamWrapperFunctionalTest.php	
@@ -0,0 +1,208 @@
+<?php
+
+namespace MongoDB\Tests\GridFS;
+
+use MongoDB\BSON\Binary;
+use MongoDB\BSON\UTCDateTime;
+use Symfony\Bridge\PhpUnit\SetUpTearDownTrait;
+use function fclose;
+use function feof;
+use function fread;
+use function fseek;
+use function fstat;
+use function fwrite;
+use const SEEK_CUR;
+use const SEEK_END;
+use const SEEK_SET;
+
+/**
+ * Functional tests for the internal StreamWrapper class.
+ */
+class StreamWrapperFunctionalTest extends FunctionalTestCase
+{
+    use SetUpTearDownTrait;
+
+    private function doSetUp()
+    {
+        parent::setUp();
+
+        $this->filesCollection->insertMany([
+            ['_id' => 'length-10', 'length' => 10, 'chunkSize' => 4, 'uploadDate' => new UTCDateTime('1484202200000')],
+        ]);
+
+        $this->chunksCollection->insertMany([
+            ['_id' => 1, 'files_id' => 'length-10', 'n' => 0, 'data' => new Binary('abcd', Binary::TYPE_GENERIC)],
+            ['_id' => 2, 'files_id' => 'length-10', 'n' => 1, 'data' => new Binary('efgh', Binary::TYPE_GENERIC)],
+            ['_id' => 3, 'files_id' => 'length-10', 'n' => 2, 'data' => new Binary('ij', Binary::TYPE_GENERIC)],
+        ]);
+    }
+
+    public function testReadableStreamClose()
+    {
+        $stream = $this->bucket->openDownloadStream('length-10');
+
+        $this->assertTrue(fclose($stream));
+    }
+
+    public function testReadableStreamEof()
+    {
+        $stream = $this->bucket->openDownloadStream('length-10');
+
+        $this->assertFalse(feof($stream));
+        $this->assertStreamContents('abcdefghij', $stream);
+        $this->assertTrue(feof($stream));
+    }
+
+    public function testReadableStreamRead()
+    {
+        $stream = $this->bucket->openDownloadStream('length-10');
+
+        $this->assertSame('abc', fread($stream, 3));
+        $this->assertSame('defghij', fread($stream, 10));
+        $this->assertSame('', fread($stream, 3));
+    }
+
+    public function testReadableStreamSeek()
+    {
+        $stream = $this->bucket->openDownloadStream('length-10');
+
+        $this->assertSame(0, fseek($stream, 2, SEEK_SET));
+        $this->assertSame('cde', fread($stream, 3));
+        $this->assertSame(0, fseek($stream, 10, SEEK_SET));
+        $this->assertSame('', fread($stream, 3));
+        $this->assertSame(-1, fseek($stream, -1, SEEK_SET));
+        $this->assertSame(-1, fseek($stream, 11, SEEK_SET));
+
+        $this->assertSame(0, fseek($stream, -5, SEEK_CUR));
+        $this->assertSame('fgh', fread($stream, 3));
+        $this->assertSame(0, fseek($stream, 1, SEEK_CUR));
+        $this->assertSame('j', fread($stream, 3));
+        $this->assertSame(-1, fseek($stream, 1, SEEK_CUR));
+        $this->assertSame(-1, fseek($stream, -11, SEEK_CUR));
+
+        $this->assertSame(0, fseek($stream, 0, SEEK_END));
+        $this->assertSame('', fread($stream, 3));
+        $this->assertSame(0, fseek($stream, -8, SEEK_END));
+        $this->assertSame('cde', fread($stream, 3));
+        $this->assertSame(-1, fseek($stream, -11, SEEK_END));
+        $this->assertSame(-1, fseek($stream, 1, SEEK_END));
+    }
+
+    public function testReadableStreamStat()
+    {
+        $stream = $this->bucket->openDownloadStream('length-10');
+
+        $stat = fstat($stream);
+        $this->assertSame(0100444, $stat[2]);
+        $this->assertSame(0100444, $stat['mode']);
+        $this->assertSame(10, $stat[7]);
+        $this->assertSame(10, $stat['size']);
+        $this->assertSame(1484202200, $stat[9]);
+        $this->assertSame(1484202200, $stat['mtime']);
+        $this->assertSame(1484202200, $stat[10]);
+        $this->assertSame(1484202200, $stat['ctime']);
+        $this->assertSame(4, $stat[11]);
+        $this->assertSame(4, $stat['blksize']);
+    }
+
+    public function testReadableStreamWrite()
+    {
+        $stream = $this->bucket->openDownloadStream('length-10');
+
+        $this->assertSame(0, fwrite($stream, 'foobar'));
+    }
+
+    public function testWritableStreamClose()
+    {
+        $stream = $this->bucket->openUploadStream('filename');
+
+        $this->assertSame(6, fwrite($stream, 'foobar'));
+        $this->assertTrue(fclose($stream));
+
+        $this->assertStreamContents('foobar', $this->bucket->openDownloadStreamByName('filename'));
+    }
+
+    public function testWritableStreamEof()
+    {
+        $stream = $this->bucket->openUploadStream('filename');
+
+        $this->assertFalse(feof($stream));
+        $this->assertSame(6, fwrite($stream, 'foobar'));
+        $this->assertFalse(feof($stream));
+    }
+
+    public function testWritableStreamRead()
+    {
+        $stream = $this->bucket->openUploadStream('filename');
+
+        $this->assertSame('', fread($stream, 8192));
+        $this->assertSame(6, fwrite($stream, 'foobar'));
+        $this->assertSame('', fread($stream, 8192));
+    }
+
+    public function testWritableStreamSeek()
+    {
+        $stream = $this->bucket->openUploadStream('filename');
+
+        $this->assertSame(6, fwrite($stream, 'foobar'));
+
+        $this->assertSame(-1, fseek($stream, 0, SEEK_SET));
+        $this->assertSame(-1, fseek($stream, 7, SEEK_SET));
+        $this->assertSame(0, fseek($stream, 6, SEEK_SET));
+
+        $this->assertSame(0, fseek($stream, 0, SEEK_CUR));
+        $this->assertSame(-1, fseek($stream, -1, SEEK_CUR));
+        $this->assertSame(-1, fseek($stream, 1, SEEK_CUR));
+
+        $this->assertSame(0, fseek($stream, 0, SEEK_END));
+        $this->assertSame(-1, fseek($stream, -1, SEEK_END));
+        $this->assertSame(-1, fseek($stream, 1, SEEK_END));
+    }
+
+    public function testWritableStreamStatBeforeSaving()
+    {
+        $stream = $this->bucket->openUploadStream('filename', ['chunkSizeBytes' => 1024]);
+
+        $stat = fstat($stream);
+        $this->assertSame(0100222, $stat[2]);
+        $this->assertSame(0100222, $stat['mode']);
+        $this->assertSame(0, $stat[7]);
+        $this->assertSame(0, $stat['size']);
+        $this->assertSame(0, $stat[9]);
+        $this->assertSame(0, $stat['mtime']);
+        $this->assertSame(0, $stat[10]);
+        $this->assertSame(0, $stat['ctime']);
+        $this->assertSame(1024, $stat[11]);
+        $this->assertSame(1024, $stat['blksize']);
+
+        $this->assertSame(6, fwrite($stream, 'foobar'));
+
+        $stat = fstat($stream);
+        $this->assertSame(6, $stat[7]);
+        $this->assertSame(6, $stat['size']);
+    }
+
+    public function testWritableStreamStatAfterSaving()
+    {
+        $stream = $this->bucket->openDownloadStream('length-10');
+
+        $stat = fstat($stream);
+        $this->assertSame(0100444, $stat[2]);
+        $this->assertSame(0100444, $stat['mode']);
+        $this->assertSame(10, $stat[7]);
+        $this->assertSame(10, $stat['size']);
+        $this->assertSame(1484202200, $stat[9]);
+        $this->assertSame(1484202200, $stat['mtime']);
+        $this->assertSame(1484202200, $stat[10]);
+        $this->assertSame(1484202200, $stat['ctime']);
+        $this->assertSame(4, $stat[11]);
+        $this->assertSame(4, $stat['blksize']);
+    }
+
+    public function testWritableStreamWrite()
+    {
+        $stream = $this->bucket->openUploadStream('filename');
+
+        $this->assertSame(6, fwrite($stream, 'foobar'));
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/GridFS/UnusableStream.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/GridFS/UnusableStream.php
new file mode 100644
index 0000000000000000000000000000000000000000..f7c7970cef34c15a9aaf2dbe3b6ae47f300bd911
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/GridFS/UnusableStream.php	
@@ -0,0 +1,61 @@
+<?php
+
+namespace MongoDB\Tests\GridFS;
+
+use function in_array;
+use function stream_get_wrappers;
+use function stream_wrapper_register;
+use function stream_wrapper_unregister;
+use const SEEK_SET;
+use const STREAM_IS_URL;
+
+final class UnusableStream
+{
+    public static function register($protocol = 'unusable')
+    {
+        if (in_array($protocol, stream_get_wrappers())) {
+            stream_wrapper_unregister($protocol);
+        }
+
+        stream_wrapper_register($protocol, static::class, STREAM_IS_URL);
+    }
+
+    public function stream_close()
+    {
+    }
+
+    public function stream_eof()
+    {
+        return true;
+    }
+
+    public function stream_open($path, $mode, $options, &$openedPath)
+    {
+        return true;
+    }
+
+    public function stream_read($length)
+    {
+        return false;
+    }
+
+    public function stream_seek($offset, $whence = SEEK_SET)
+    {
+        return true;
+    }
+
+    public function stream_stat()
+    {
+        return [];
+    }
+
+    public function stream_tell()
+    {
+        return 0;
+    }
+
+    public function stream_write($data)
+    {
+        return 0;
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/GridFS/WritableStreamFunctionalTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/GridFS/WritableStreamFunctionalTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..cadee3ad6906658e79581da646d8650f6f3d97ee
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/GridFS/WritableStreamFunctionalTest.php	
@@ -0,0 +1,119 @@
+<?php
+
+namespace MongoDB\Tests\GridFS;
+
+use MongoDB\Exception\InvalidArgumentException;
+use MongoDB\GridFS\CollectionWrapper;
+use MongoDB\GridFS\WritableStream;
+use Symfony\Bridge\PhpUnit\SetUpTearDownTrait;
+use function str_repeat;
+
+/**
+ * Functional tests for the internal WritableStream class.
+ */
+class WritableStreamFunctionalTest extends FunctionalTestCase
+{
+    use SetUpTearDownTrait;
+
+    /** @var CollectionWrapper */
+    private $collectionWrapper;
+
+    private function doSetUp()
+    {
+        parent::setUp();
+
+        $this->collectionWrapper = new CollectionWrapper($this->manager, $this->getDatabaseName(), 'fs');
+    }
+
+    /**
+     * @doesNotPerformAssertions
+     */
+    public function testValidConstructorOptions()
+    {
+        new WritableStream($this->collectionWrapper, 'filename', [
+            '_id' => 'custom-id',
+            'chunkSizeBytes' => 2,
+            'metadata' => ['foo' => 'bar'],
+        ]);
+    }
+
+    /**
+     * @dataProvider provideInvalidConstructorOptions
+     */
+    public function testConstructorOptionTypeChecks(array $options)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        new WritableStream($this->collectionWrapper, 'filename', $options);
+    }
+
+    public function provideInvalidConstructorOptions()
+    {
+        $options = [];
+
+        foreach ($this->getInvalidIntegerValues(true) as $value) {
+            $options[][] = ['chunkSizeBytes' => $value];
+        }
+
+        foreach ($this->getInvalidBooleanValues(true) as $value) {
+            $options[][] = ['disableMD5' => $value];
+        }
+
+        foreach ($this->getInvalidDocumentValues() as $value) {
+            $options[][] = ['metadata' => $value];
+        }
+
+        return $options;
+    }
+
+    public function testConstructorShouldRequireChunkSizeBytesOptionToBePositive()
+    {
+        $this->expectException(InvalidArgumentException::class);
+        $this->expectExceptionMessage('Expected "chunkSizeBytes" option to be >= 1, 0 given');
+        new WritableStream($this->collectionWrapper, 'filename', ['chunkSizeBytes' => 0]);
+    }
+
+    public function testWriteBytesAlwaysUpdatesFileSize()
+    {
+        $stream = new WritableStream($this->collectionWrapper, 'filename', ['chunkSizeBytes' => 1024]);
+
+        $this->assertSame(0, $stream->getSize());
+        $this->assertSame(512, $stream->writeBytes(str_repeat('a', 512)));
+        $this->assertSame(512, $stream->getSize());
+        $this->assertSame(512, $stream->writeBytes(str_repeat('a', 512)));
+        $this->assertSame(1024, $stream->getSize());
+        $this->assertSame(512, $stream->writeBytes(str_repeat('a', 512)));
+        $this->assertSame(1536, $stream->getSize());
+
+        $stream->close();
+        $this->assertSame(1536, $stream->getSize());
+    }
+
+    /**
+     * @dataProvider provideInputDataAndExpectedMD5
+     */
+    public function testWriteBytesCalculatesMD5($input, $expectedMD5)
+    {
+        $stream = new WritableStream($this->collectionWrapper, 'filename');
+        $stream->writeBytes($input);
+        $stream->close();
+
+        $fileDocument = $this->filesCollection->findOne(
+            ['_id' => $stream->getFile()->_id],
+            ['projection' => ['md5' => 1, '_id' => 0]]
+        );
+
+        $this->assertSameDocument(['md5' => $expectedMD5], $fileDocument);
+    }
+
+    public function provideInputDataAndExpectedMD5()
+    {
+        return [
+            ['', 'd41d8cd98f00b204e9800998ecf8427e'],
+            ['foobar', '3858f62230ac3c915f300c664312c63f'],
+            [str_repeat('foobar', 43520), '88ff0e5fcb0acb27947d736b5d69cb73'],
+            [str_repeat('foobar', 43521), '8ff86511c95a06a611842ceb555d8454'],
+            [str_repeat('foobar', 87040), '45bfa1a9ec36728ee7338d15c5a30c13'],
+            [str_repeat('foobar', 87041), '95e78f624f8e745bcfd2d11691fa601e'],
+        ];
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/GridFS/spec-tests/delete.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/GridFS/spec-tests/delete.json
new file mode 100644
index 0000000000000000000000000000000000000000..d74e49284bdfea65f6cd21ba14b63e530b417cfc
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/GridFS/spec-tests/delete.json	
@@ -0,0 +1,291 @@
+{
+  "data": {
+    "files": [
+      {
+        "_id": {
+          "$oid": "000000000000000000000001"
+        },
+        "length": 0,
+        "chunkSize": 4,
+        "uploadDate": {
+          "$date": "1970-01-01T00:00:00.000Z"
+        },
+        "md5": "d41d8cd98f00b204e9800998ecf8427e",
+        "filename": "length-0",
+        "contentType": "application/octet-stream",
+        "aliases": [],
+        "metadata": {}
+      },
+      {
+        "_id": {
+          "$oid": "000000000000000000000002"
+        },
+        "length": 0,
+        "chunkSize": 4,
+        "uploadDate": {
+          "$date": "1970-01-01T00:00:00.000Z"
+        },
+        "md5": "d41d8cd98f00b204e9800998ecf8427e",
+        "filename": "length-0-with-empty-chunk",
+        "contentType": "application/octet-stream",
+        "aliases": [],
+        "metadata": {}
+      },
+      {
+        "_id": {
+          "$oid": "000000000000000000000003"
+        },
+        "length": 2,
+        "chunkSize": 4,
+        "uploadDate": {
+          "$date": "1970-01-01T00:00:00.000Z"
+        },
+        "md5": "c700ed4fdb1d27055aa3faa2c2432283",
+        "filename": "length-2",
+        "contentType": "application/octet-stream",
+        "aliases": [],
+        "metadata": {}
+      },
+      {
+        "_id": {
+          "$oid": "000000000000000000000004"
+        },
+        "length": 8,
+        "chunkSize": 4,
+        "uploadDate": {
+          "$date": "1970-01-01T00:00:00.000Z"
+        },
+        "md5": "dd254cdc958e53abaa67da9f797125f5",
+        "filename": "length-8",
+        "contentType": "application/octet-stream",
+        "aliases": [],
+        "metadata": {}
+      }
+    ],
+    "chunks": [
+      {
+        "_id": {
+          "$oid": "000000000000000000000001"
+        },
+        "files_id": {
+          "$oid": "000000000000000000000002"
+        },
+        "n": 0,
+        "data": {
+          "$hex": ""
+        }
+      },
+      {
+        "_id": {
+          "$oid": "000000000000000000000002"
+        },
+        "files_id": {
+          "$oid": "000000000000000000000003"
+        },
+        "n": 0,
+        "data": {
+          "$hex": "1122"
+        }
+      },
+      {
+        "_id": {
+          "$oid": "000000000000000000000003"
+        },
+        "files_id": {
+          "$oid": "000000000000000000000004"
+        },
+        "n": 0,
+        "data": {
+          "$hex": "11223344"
+        }
+      },
+      {
+        "_id": {
+          "$oid": "000000000000000000000004"
+        },
+        "files_id": {
+          "$oid": "000000000000000000000004"
+        },
+        "n": 1,
+        "data": {
+          "$hex": "55667788"
+        }
+      }
+    ]
+  },
+  "tests": [
+    {
+      "description": "Delete when length is 0",
+      "act": {
+        "operation": "delete",
+        "arguments": {
+          "id": {
+            "$oid": "000000000000000000000001"
+          }
+        }
+      },
+      "assert": {
+        "result": "void",
+        "data": [
+          {
+            "delete": "expected.files",
+            "deletes": [
+              {
+                "q": {
+                  "_id": {
+                    "$oid": "000000000000000000000001"
+                  }
+                },
+                "limit": 1
+              }
+            ]
+          }
+        ]
+      }
+    },
+    {
+      "description": "Delete when length is 0 and there is one extra empty chunk",
+      "act": {
+        "operation": "delete",
+        "arguments": {
+          "id": {
+            "$oid": "000000000000000000000002"
+          }
+        }
+      },
+      "assert": {
+        "result": "void",
+        "data": [
+          {
+            "delete": "expected.files",
+            "deletes": [
+              {
+                "q": {
+                  "_id": {
+                    "$oid": "000000000000000000000002"
+                  }
+                },
+                "limit": 1
+              }
+            ]
+          },
+          {
+            "delete": "expected.chunks",
+            "deletes": [
+              {
+                "q": {
+                  "files_id": {
+                    "$oid": "000000000000000000000002"
+                  }
+                },
+                "limit": 0
+              }
+            ]
+          }
+        ]
+      }
+    },
+    {
+      "description": "Delete when length is 8",
+      "act": {
+        "operation": "delete",
+        "arguments": {
+          "id": {
+            "$oid": "000000000000000000000004"
+          }
+        }
+      },
+      "assert": {
+        "result": "void",
+        "data": [
+          {
+            "delete": "expected.files",
+            "deletes": [
+              {
+                "q": {
+                  "_id": {
+                    "$oid": "000000000000000000000004"
+                  }
+                },
+                "limit": 1
+              }
+            ]
+          },
+          {
+            "delete": "expected.chunks",
+            "deletes": [
+              {
+                "q": {
+                  "files_id": {
+                    "$oid": "000000000000000000000004"
+                  }
+                },
+                "limit": 0
+              }
+            ]
+          }
+        ]
+      }
+    },
+    {
+      "description": "Delete when files entry does not exist",
+      "act": {
+        "operation": "delete",
+        "arguments": {
+          "id": {
+            "$oid": "000000000000000000000000"
+          }
+        }
+      },
+      "assert": {
+        "error": "FileNotFound"
+      }
+    },
+    {
+      "description": "Delete when files entry does not exist and there are orphaned chunks",
+      "arrange": {
+        "data": [
+          {
+            "delete": "fs.files",
+            "deletes": [
+              {
+                "q": {
+                  "_id": {
+                    "$oid": "000000000000000000000004"
+                  }
+                },
+                "limit": 1
+              }
+            ]
+          }
+        ]
+      },
+      "act": {
+        "operation": "delete",
+        "arguments": {
+          "id": {
+            "$oid": "000000000000000000000004"
+          }
+        }
+      },
+      "assert": {
+        "error": "FileNotFound",
+        "data": [
+          {
+            "delete": "expected.files",
+            "deletes": [
+              {
+                "q": {
+                  "_id": {
+                    "$oid": "000000000000000000000004"
+                  }
+                },
+                "limit": 1
+              }
+            ]
+          }
+        ]
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/GridFS/spec-tests/download.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/GridFS/spec-tests/download.json
new file mode 100644
index 0000000000000000000000000000000000000000..5092fba981ad0e38dbf2415fa4400d8e51134491
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/GridFS/spec-tests/download.json	
@@ -0,0 +1,467 @@
+{
+  "data": {
+    "files": [
+      {
+        "_id": {
+          "$oid": "000000000000000000000001"
+        },
+        "length": 0,
+        "chunkSize": 4,
+        "uploadDate": {
+          "$date": "1970-01-01T00:00:00.000Z"
+        },
+        "md5": "d41d8cd98f00b204e9800998ecf8427e",
+        "filename": "length-0",
+        "contentType": "application/octet-stream",
+        "aliases": [],
+        "metadata": {}
+      },
+      {
+        "_id": {
+          "$oid": "000000000000000000000002"
+        },
+        "length": 0,
+        "chunkSize": 4,
+        "uploadDate": {
+          "$date": "1970-01-01T00:00:00.000Z"
+        },
+        "md5": "d41d8cd98f00b204e9800998ecf8427e",
+        "filename": "length-0-with-empty-chunk",
+        "contentType": "application/octet-stream",
+        "aliases": [],
+        "metadata": {}
+      },
+      {
+        "_id": {
+          "$oid": "000000000000000000000003"
+        },
+        "length": 2,
+        "chunkSize": 4,
+        "uploadDate": {
+          "$date": "1970-01-01T00:00:00.000Z"
+        },
+        "md5": "c700ed4fdb1d27055aa3faa2c2432283",
+        "filename": "length-2",
+        "contentType": "application/octet-stream",
+        "aliases": [],
+        "metadata": {}
+      },
+      {
+        "_id": {
+          "$oid": "000000000000000000000004"
+        },
+        "length": 8,
+        "chunkSize": 4,
+        "uploadDate": {
+          "$date": "1970-01-01T00:00:00.000Z"
+        },
+        "md5": "dd254cdc958e53abaa67da9f797125f5",
+        "filename": "length-8",
+        "contentType": "application/octet-stream",
+        "aliases": [],
+        "metadata": {}
+      },
+      {
+        "_id": {
+          "$oid": "000000000000000000000005"
+        },
+        "length": 10,
+        "chunkSize": 4,
+        "uploadDate": {
+          "$date": "1970-01-01T00:00:00.000Z"
+        },
+        "md5": "57d83cd477bfb1ccd975ab33d827a92b",
+        "filename": "length-10",
+        "contentType": "application/octet-stream",
+        "aliases": [],
+        "metadata": {}
+      },
+      {
+        "_id": {
+          "$oid": "000000000000000000000006"
+        },
+        "length": 2,
+        "chunkSize": 4,
+        "uploadDate": {
+          "$date": "1970-01-01T00:00:00.000Z"
+        },
+        "md5": "c700ed4fdb1d27055aa3faa2c2432283",
+        "contentType": "application/octet-stream",
+        "aliases": [],
+        "metadata": {}
+      }
+    ],
+    "chunks": [
+      {
+        "_id": {
+          "$oid": "000000000000000000000001"
+        },
+        "files_id": {
+          "$oid": "000000000000000000000002"
+        },
+        "n": 0,
+        "data": {
+          "$hex": ""
+        }
+      },
+      {
+        "_id": {
+          "$oid": "000000000000000000000002"
+        },
+        "files_id": {
+          "$oid": "000000000000000000000003"
+        },
+        "n": 0,
+        "data": {
+          "$hex": "1122"
+        }
+      },
+      {
+        "_id": {
+          "$oid": "000000000000000000000003"
+        },
+        "files_id": {
+          "$oid": "000000000000000000000004"
+        },
+        "n": 0,
+        "data": {
+          "$hex": "11223344"
+        }
+      },
+      {
+        "_id": {
+          "$oid": "000000000000000000000004"
+        },
+        "files_id": {
+          "$oid": "000000000000000000000004"
+        },
+        "n": 1,
+        "data": {
+          "$hex": "55667788"
+        }
+      },
+      {
+        "_id": {
+          "$oid": "000000000000000000000005"
+        },
+        "files_id": {
+          "$oid": "000000000000000000000005"
+        },
+        "n": 0,
+        "data": {
+          "$hex": "11223344"
+        }
+      },
+      {
+        "_id": {
+          "$oid": "000000000000000000000006"
+        },
+        "files_id": {
+          "$oid": "000000000000000000000005"
+        },
+        "n": 1,
+        "data": {
+          "$hex": "55667788"
+        }
+      },
+      {
+        "_id": {
+          "$oid": "000000000000000000000007"
+        },
+        "files_id": {
+          "$oid": "000000000000000000000005"
+        },
+        "n": 2,
+        "data": {
+          "$hex": "99aa"
+        }
+      },
+      {
+        "_id": {
+          "$oid": "000000000000000000000008"
+        },
+        "files_id": {
+          "$oid": "000000000000000000000006"
+        },
+        "n": 0,
+        "data": {
+          "$hex": "1122"
+        }
+      }
+    ]
+  },
+  "tests": [
+    {
+      "description": "Download when length is zero",
+      "act": {
+        "operation": "download",
+        "arguments": {
+          "id": {
+            "$oid": "000000000000000000000001"
+          },
+          "options": {}
+        }
+      },
+      "assert": {
+        "result": {
+          "$hex": ""
+        }
+      }
+    },
+    {
+      "description": "Download when length is zero and there is one empty chunk",
+      "act": {
+        "operation": "download",
+        "arguments": {
+          "id": {
+            "$oid": "000000000000000000000002"
+          },
+          "options": {}
+        }
+      },
+      "assert": {
+        "result": {
+          "$hex": ""
+        }
+      }
+    },
+    {
+      "description": "Download when there is one chunk",
+      "act": {
+        "operation": "download",
+        "arguments": {
+          "id": {
+            "$oid": "000000000000000000000003"
+          },
+          "options": {}
+        }
+      },
+      "assert": {
+        "result": {
+          "$hex": "1122"
+        }
+      }
+    },
+    {
+      "description": "Download when there are two chunks",
+      "act": {
+        "operation": "download",
+        "arguments": {
+          "id": {
+            "$oid": "000000000000000000000004"
+          },
+          "options": {}
+        }
+      },
+      "assert": {
+        "result": {
+          "$hex": "1122334455667788"
+        }
+      }
+    },
+    {
+      "description": "Download when there are three chunks",
+      "act": {
+        "operation": "download",
+        "arguments": {
+          "id": {
+            "$oid": "000000000000000000000005"
+          },
+          "options": {}
+        }
+      },
+      "assert": {
+        "result": {
+          "$hex": "112233445566778899aa"
+        }
+      }
+    },
+    {
+      "description": "Download when files entry does not exist",
+      "act": {
+        "operation": "download",
+        "arguments": {
+          "id": {
+            "$oid": "000000000000000000000000"
+          },
+          "options": {}
+        }
+      },
+      "assert": {
+        "error": "FileNotFound"
+      }
+    },
+    {
+      "description": "Download when an intermediate chunk is missing",
+      "arrange": {
+        "data": [
+          {
+            "delete": "fs.chunks",
+            "deletes": [
+              {
+                "q": {
+                  "files_id": {
+                    "$oid": "000000000000000000000005"
+                  },
+                  "n": 1
+                },
+                "limit": 1
+              }
+            ]
+          }
+        ]
+      },
+      "act": {
+        "operation": "download",
+        "arguments": {
+          "id": {
+            "$oid": "000000000000000000000005"
+          }
+        }
+      },
+      "assert": {
+        "error": "ChunkIsMissing"
+      }
+    },
+    {
+      "description": "Download when final chunk is missing",
+      "arrange": {
+        "data": [
+          {
+            "delete": "fs.chunks",
+            "deletes": [
+              {
+                "q": {
+                  "files_id": {
+                    "$oid": "000000000000000000000005"
+                  },
+                  "n": 1
+                },
+                "limit": 1
+              }
+            ]
+          }
+        ]
+      },
+      "act": {
+        "operation": "download",
+        "arguments": {
+          "id": {
+            "$oid": "000000000000000000000005"
+          }
+        }
+      },
+      "assert": {
+        "error": "ChunkIsMissing"
+      }
+    },
+    {
+      "description": "Download when an intermediate chunk is the wrong size",
+      "arrange": {
+        "data": [
+          {
+            "update": "fs.chunks",
+            "updates": [
+              {
+                "q": {
+                  "files_id": {
+                    "$oid": "000000000000000000000005"
+                  },
+                  "n": 1
+                },
+                "u": {
+                  "$set": {
+                    "data": {
+                      "$hex": "556677"
+                    }
+                  }
+                }
+              },
+              {
+                "q": {
+                  "files_id": {
+                    "$oid": "000000000000000000000005"
+                  },
+                  "n": 2
+                },
+                "u": {
+                  "$set": {
+                    "data": {
+                      "$hex": "8899aa"
+                    }
+                  }
+                }
+              }
+            ]
+          }
+        ]
+      },
+      "act": {
+        "operation": "download",
+        "arguments": {
+          "id": {
+            "$oid": "000000000000000000000005"
+          }
+        }
+      },
+      "assert": {
+        "error": "ChunkIsWrongSize"
+      }
+    },
+    {
+      "description": "Download when final chunk is the wrong size",
+      "arrange": {
+        "data": [
+          {
+            "update": "fs.chunks",
+            "updates": [
+              {
+                "q": {
+                  "files_id": {
+                    "$oid": "000000000000000000000005"
+                  },
+                  "n": 2
+                },
+                "u": {
+                  "$set": {
+                    "data": {
+                      "$hex": "99"
+                    }
+                  }
+                }
+              }
+            ]
+          }
+        ]
+      },
+      "act": {
+        "operation": "download",
+        "arguments": {
+          "id": {
+            "$oid": "000000000000000000000005"
+          }
+        }
+      },
+      "assert": {
+        "error": "ChunkIsWrongSize"
+      }
+    },
+    {
+      "description": "Download legacy file with no name",
+      "act": {
+        "operation": "download",
+        "arguments": {
+          "id": {
+            "$oid": "000000000000000000000006"
+          },
+          "options": {}
+        }
+      },
+      "assert": {
+        "result": {
+          "$hex": "1122"
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/GridFS/spec-tests/download_by_name.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/GridFS/spec-tests/download_by_name.json
new file mode 100644
index 0000000000000000000000000000000000000000..ecc8c9e2ccae2f4117f5cfde7316ecff43b5761a
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/GridFS/spec-tests/download_by_name.json	
@@ -0,0 +1,240 @@
+{
+  "data": {
+    "files": [
+      {
+        "_id": {
+          "$oid": "000000000000000000000001"
+        },
+        "length": 1,
+        "chunkSize": 4,
+        "uploadDate": {
+          "$date": "1970-01-01T00:00:00.000Z"
+        },
+        "md5": "47ed733b8d10be225eceba344d533586",
+        "filename": "abc",
+        "contentType": "application/octet-stream",
+        "aliases": [],
+        "metadata": {}
+      },
+      {
+        "_id": {
+          "$oid": "000000000000000000000002"
+        },
+        "length": 1,
+        "chunkSize": 4,
+        "uploadDate": {
+          "$date": "1970-01-02T00:00:00.000Z"
+        },
+        "md5": "b15835f133ff2e27c7cb28117bfae8f4",
+        "filename": "abc",
+        "contentType": "application/octet-stream",
+        "aliases": [],
+        "metadata": {}
+      },
+      {
+        "_id": {
+          "$oid": "000000000000000000000003"
+        },
+        "length": 1,
+        "chunkSize": 4,
+        "uploadDate": {
+          "$date": "1970-01-03T00:00:00.000Z"
+        },
+        "md5": "eccbc87e4b5ce2fe28308fd9f2a7baf3",
+        "filename": "abc",
+        "contentType": "application/octet-stream",
+        "aliases": [],
+        "metadata": {}
+      },
+      {
+        "_id": {
+          "$oid": "000000000000000000000004"
+        },
+        "length": 1,
+        "chunkSize": 4,
+        "uploadDate": {
+          "$date": "1970-01-04T00:00:00.000Z"
+        },
+        "md5": "f623e75af30e62bbd73d6df5b50bb7b5",
+        "filename": "abc",
+        "contentType": "application/octet-stream",
+        "aliases": [],
+        "metadata": {}
+      },
+      {
+        "_id": {
+          "$oid": "000000000000000000000005"
+        },
+        "length": 1,
+        "chunkSize": 4,
+        "uploadDate": {
+          "$date": "1970-01-05T00:00:00.000Z"
+        },
+        "md5": "4c614360da93c0a041b22e537de151eb",
+        "filename": "abc",
+        "contentType": "application/octet-stream",
+        "aliases": [],
+        "metadata": {}
+      }
+    ],
+    "chunks": [
+      {
+        "_id": {
+          "$oid": "000000000000000000000001"
+        },
+        "files_id": {
+          "$oid": "000000000000000000000001"
+        },
+        "n": 0,
+        "data": {
+          "$hex": "11"
+        }
+      },
+      {
+        "_id": {
+          "$oid": "000000000000000000000002"
+        },
+        "files_id": {
+          "$oid": "000000000000000000000002"
+        },
+        "n": 0,
+        "data": {
+          "$hex": "22"
+        }
+      },
+      {
+        "_id": {
+          "$oid": "000000000000000000000003"
+        },
+        "files_id": {
+          "$oid": "000000000000000000000003"
+        },
+        "n": 0,
+        "data": {
+          "$hex": "33"
+        }
+      },
+      {
+        "_id": {
+          "$oid": "000000000000000000000004"
+        },
+        "files_id": {
+          "$oid": "000000000000000000000004"
+        },
+        "n": 0,
+        "data": {
+          "$hex": "44"
+        }
+      },
+      {
+        "_id": {
+          "$oid": "000000000000000000000005"
+        },
+        "files_id": {
+          "$oid": "000000000000000000000005"
+        },
+        "n": 0,
+        "data": {
+          "$hex": "55"
+        }
+      }
+    ]
+  },
+  "tests": [
+    {
+      "description": "Download_by_name when revision is 0",
+      "act": {
+        "operation": "download_by_name",
+        "arguments": {
+          "filename": "abc",
+          "options": {
+            "revision": 0
+          }
+        }
+      },
+      "assert": {
+        "result": {
+          "$hex": "11"
+        }
+      }
+    },
+    {
+      "description": "Download_by_name when revision is 1",
+      "act": {
+        "operation": "download_by_name",
+        "arguments": {
+          "filename": "abc",
+          "options": {
+            "revision": 1
+          }
+        }
+      },
+      "assert": {
+        "result": {
+          "$hex": "22"
+        }
+      }
+    },
+    {
+      "description": "Download_by_name when revision is -2",
+      "act": {
+        "operation": "download_by_name",
+        "arguments": {
+          "filename": "abc",
+          "options": {
+            "revision": -2
+          }
+        }
+      },
+      "assert": {
+        "result": {
+          "$hex": "44"
+        }
+      }
+    },
+    {
+      "description": "Download_by_name when revision is -1",
+      "act": {
+        "operation": "download_by_name",
+        "arguments": {
+          "filename": "abc",
+          "options": {
+            "revision": -1
+          }
+        }
+      },
+      "assert": {
+        "result": {
+          "$hex": "55"
+        }
+      }
+    },
+    {
+      "description": "Download_by_name when files entry does not exist",
+      "act": {
+        "operation": "download_by_name",
+        "arguments": {
+          "filename": "xyz"
+        }
+      },
+      "assert": {
+        "error": "FileNotFound"
+      }
+    },
+    {
+      "description": "Download_by_name when revision does not exist",
+      "act": {
+        "operation": "download_by_name",
+        "arguments": {
+          "filename": "abc",
+          "options": {
+            "revision": 999
+          }
+        }
+      },
+      "assert": {
+        "error": "RevisionNotFound"
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/GridFS/spec-tests/upload.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/GridFS/spec-tests/upload.json
new file mode 100644
index 0000000000000000000000000000000000000000..ecec0c548842072518461b63cf7cf4db7204ca5f
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/GridFS/spec-tests/upload.json	
@@ -0,0 +1,466 @@
+{
+  "data": {
+    "files": [],
+    "chunks": []
+  },
+  "tests": [
+    {
+      "description": "Upload when length is 0",
+      "act": {
+        "operation": "upload",
+        "arguments": {
+          "filename": "filename",
+          "source": {
+            "$hex": ""
+          },
+          "options": {
+            "chunkSizeBytes": 4
+          }
+        }
+      },
+      "assert": {
+        "result": "&result",
+        "data": [
+          {
+            "insert": "expected.files",
+            "documents": [
+              {
+                "_id": "*result",
+                "length": 0,
+                "chunkSize": 4,
+                "uploadDate": "*actual",
+                "md5": "d41d8cd98f00b204e9800998ecf8427e",
+                "filename": "filename"
+              }
+            ]
+          }
+        ]
+      }
+    },
+    {
+      "description": "Upload when length is 1",
+      "act": {
+        "operation": "upload",
+        "arguments": {
+          "filename": "filename",
+          "source": {
+            "$hex": "11"
+          },
+          "options": {
+            "chunkSizeBytes": 4
+          }
+        }
+      },
+      "assert": {
+        "result": "&result",
+        "data": [
+          {
+            "insert": "expected.files",
+            "documents": [
+              {
+                "_id": "*result",
+                "length": 1,
+                "chunkSize": 4,
+                "uploadDate": "*actual",
+                "md5": "47ed733b8d10be225eceba344d533586",
+                "filename": "filename"
+              }
+            ]
+          },
+          {
+            "insert": "expected.chunks",
+            "documents": [
+              {
+                "_id": "*actual",
+                "files_id": "*result",
+                "n": 0,
+                "data": {
+                  "$hex": "11"
+                }
+              }
+            ]
+          }
+        ]
+      }
+    },
+    {
+      "description": "Upload when length is 3",
+      "act": {
+        "operation": "upload",
+        "arguments": {
+          "filename": "filename",
+          "source": {
+            "$hex": "112233"
+          },
+          "options": {
+            "chunkSizeBytes": 4
+          }
+        }
+      },
+      "assert": {
+        "result": "&result",
+        "data": [
+          {
+            "insert": "expected.files",
+            "documents": [
+              {
+                "_id": "*result",
+                "length": 3,
+                "chunkSize": 4,
+                "uploadDate": "*actual",
+                "md5": "bafae3a174ab91fc70db7a6aa50f4f52",
+                "filename": "filename"
+              }
+            ]
+          },
+          {
+            "insert": "expected.chunks",
+            "documents": [
+              {
+                "_id": "*actual",
+                "files_id": "*result",
+                "n": 0,
+                "data": {
+                  "$hex": "112233"
+                }
+              }
+            ]
+          }
+        ]
+      }
+    },
+    {
+      "description": "Upload when length is 4",
+      "act": {
+        "operation": "upload",
+        "arguments": {
+          "filename": "filename",
+          "source": {
+            "$hex": "11223344"
+          },
+          "options": {
+            "chunkSizeBytes": 4
+          }
+        }
+      },
+      "assert": {
+        "result": "&result",
+        "data": [
+          {
+            "insert": "expected.files",
+            "documents": [
+              {
+                "_id": "*result",
+                "length": 4,
+                "chunkSize": 4,
+                "uploadDate": "*actual",
+                "md5": "7e7c77cff5705d1f7574a25ef6662117",
+                "filename": "filename"
+              }
+            ]
+          },
+          {
+            "insert": "expected.chunks",
+            "documents": [
+              {
+                "_id": "*actual",
+                "files_id": "*result",
+                "n": 0,
+                "data": {
+                  "$hex": "11223344"
+                }
+              }
+            ]
+          }
+        ]
+      }
+    },
+    {
+      "description": "Upload when length is 5",
+      "act": {
+        "operation": "upload",
+        "arguments": {
+          "filename": "filename",
+          "source": {
+            "$hex": "1122334455"
+          },
+          "options": {
+            "chunkSizeBytes": 4
+          }
+        }
+      },
+      "assert": {
+        "result": "&result",
+        "data": [
+          {
+            "insert": "expected.files",
+            "documents": [
+              {
+                "_id": "*result",
+                "length": 5,
+                "chunkSize": 4,
+                "uploadDate": "*actual",
+                "md5": "283d4fea5dded59cf837d3047328f5af",
+                "filename": "filename"
+              }
+            ]
+          },
+          {
+            "insert": "expected.chunks",
+            "documents": [
+              {
+                "_id": "*actual",
+                "files_id": "*result",
+                "n": 0,
+                "data": {
+                  "$hex": "11223344"
+                }
+              },
+              {
+                "_id": "*actual",
+                "files_id": "*result",
+                "n": 1,
+                "data": {
+                  "$hex": "55"
+                }
+              }
+            ]
+          }
+        ]
+      }
+    },
+    {
+      "description": "Upload when length is 8",
+      "act": {
+        "operation": "upload",
+        "arguments": {
+          "filename": "filename",
+          "source": {
+            "$hex": "1122334455667788"
+          },
+          "options": {
+            "chunkSizeBytes": 4
+          }
+        }
+      },
+      "assert": {
+        "result": "&result",
+        "data": [
+          {
+            "insert": "expected.files",
+            "documents": [
+              {
+                "_id": "*result",
+                "length": 8,
+                "chunkSize": 4,
+                "uploadDate": "*actual",
+                "md5": "dd254cdc958e53abaa67da9f797125f5",
+                "filename": "filename"
+              }
+            ]
+          },
+          {
+            "insert": "expected.chunks",
+            "documents": [
+              {
+                "_id": "*actual",
+                "files_id": "*result",
+                "n": 0,
+                "data": {
+                  "$hex": "11223344"
+                }
+              },
+              {
+                "_id": "*actual",
+                "files_id": "*result",
+                "n": 1,
+                "data": {
+                  "$hex": "55667788"
+                }
+              }
+            ]
+          }
+        ]
+      }
+    },
+    {
+      "description": "Upload when contentType is provided",
+      "act": {
+        "operation": "upload",
+        "arguments": {
+          "filename": "filename",
+          "source": {
+            "$hex": "11"
+          },
+          "options": {
+            "chunkSizeBytes": 4,
+            "contentType": "image/jpeg"
+          }
+        }
+      },
+      "assert": {
+        "result": "&result",
+        "data": [
+          {
+            "insert": "expected.files",
+            "documents": [
+              {
+                "_id": "*result",
+                "length": 1,
+                "chunkSize": 4,
+                "uploadDate": "*actual",
+                "md5": "47ed733b8d10be225eceba344d533586",
+                "filename": "filename",
+                "contentType": "image/jpeg"
+              }
+            ]
+          },
+          {
+            "insert": "expected.chunks",
+            "documents": [
+              {
+                "_id": "*actual",
+                "files_id": "*result",
+                "n": 0,
+                "data": {
+                  "$hex": "11"
+                }
+              }
+            ]
+          }
+        ]
+      }
+    },
+    {
+      "description": "Upload when metadata is provided",
+      "act": {
+        "operation": "upload",
+        "arguments": {
+          "filename": "filename",
+          "source": {
+            "$hex": "11"
+          },
+          "options": {
+            "chunkSizeBytes": 4,
+            "metadata": {
+              "x": 1
+            }
+          }
+        }
+      },
+      "assert": {
+        "result": "&result",
+        "data": [
+          {
+            "insert": "expected.files",
+            "documents": [
+              {
+                "_id": "*result",
+                "length": 1,
+                "chunkSize": 4,
+                "uploadDate": "*actual",
+                "md5": "47ed733b8d10be225eceba344d533586",
+                "filename": "filename",
+                "metadata": {
+                  "x": 1
+                }
+              }
+            ]
+          },
+          {
+            "insert": "expected.chunks",
+            "documents": [
+              {
+                "_id": "*actual",
+                "files_id": "*result",
+                "n": 0,
+                "data": {
+                  "$hex": "11"
+                }
+              }
+            ]
+          }
+        ]
+      }
+    },
+    {
+      "description": "Upload when length is 0 sans MD5",
+      "act": {
+        "operation": "upload",
+        "arguments": {
+          "filename": "filename",
+          "source": {
+            "$hex": ""
+          },
+          "options": {
+            "chunkSizeBytes": 4,
+            "disableMD5": true
+          }
+        }
+      },
+      "assert": {
+        "result": "&result",
+        "data": [
+          {
+            "insert": "expected.files",
+            "documents": [
+              {
+                "_id": "*result",
+                "length": 0,
+                "chunkSize": 4,
+                "uploadDate": "*actual",
+                "filename": "filename"
+              }
+            ]
+          }
+        ]
+      }
+    },
+    {
+      "description": "Upload when length is 1 sans MD5",
+      "act": {
+        "operation": "upload",
+        "arguments": {
+          "filename": "filename",
+          "source": {
+            "$hex": "11"
+          },
+          "options": {
+            "chunkSizeBytes": 4,
+            "disableMD5": true
+          }
+        }
+      },
+      "assert": {
+        "result": "&result",
+        "data": [
+          {
+            "insert": "expected.files",
+            "documents": [
+              {
+                "_id": "*result",
+                "length": 1,
+                "chunkSize": 4,
+                "uploadDate": "*actual",
+                "filename": "filename"
+              }
+            ]
+          },
+          {
+            "insert": "expected.chunks",
+            "documents": [
+              {
+                "_id": "*actual",
+                "files_id": "*result",
+                "n": 0,
+                "data": {
+                  "$hex": "11"
+                }
+              }
+            ]
+          }
+        ]
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Model/BSONArrayTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Model/BSONArrayTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..8774d223bcfd0c4ee0ef254c5965af07c33ab182
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Model/BSONArrayTest.php	
@@ -0,0 +1,110 @@
+<?php
+
+namespace MongoDB\Tests\Model;
+
+use MongoDB\BSON\ObjectId;
+use MongoDB\Model\BSONArray;
+use MongoDB\Model\BSONDocument;
+use MongoDB\Tests\TestCase;
+use ReflectionClass;
+use stdClass;
+use function json_encode;
+
+class BSONArrayTest extends TestCase
+{
+    public function testBsonSerializeReindexesKeys()
+    {
+        $data = [0 => 'foo', 2 => 'bar'];
+
+        $array = new BSONArray($data);
+        $this->assertSame($data, $array->getArrayCopy());
+        $this->assertSame(['foo', 'bar'], $array->bsonSerialize());
+    }
+
+    public function testClone()
+    {
+        $array = new BSONArray([
+            [
+                'foo',
+                new stdClass(),
+                ['bar', new stdClass()],
+            ],
+            new BSONArray([
+                'foo',
+                new stdClass(),
+                ['bar', new stdClass()],
+            ]),
+        ]);
+        $arrayClone = clone $array;
+
+        $this->assertSameDocument($array, $arrayClone);
+        $this->assertNotSame($array, $arrayClone);
+        $this->assertNotSame($array[0][1], $arrayClone[0][1]);
+        $this->assertNotSame($array[0][2][1], $arrayClone[0][2][1]);
+        $this->assertNotSame($array[1], $arrayClone[1]);
+        $this->assertNotSame($array[1][1], $arrayClone[1][1]);
+        $this->assertNotSame($array[1][2][1], $arrayClone[1][2][1]);
+    }
+
+    public function testCloneRespectsUncloneableObjects()
+    {
+        $this->assertFalse((new ReflectionClass(UncloneableObject::class))->isCloneable());
+
+        $array = new BSONArray([
+            [new UncloneableObject()],
+            new BSONArray([new UncloneableObject()]),
+        ]);
+        $arrayClone = clone $array;
+
+        $this->assertNotSame($array, $arrayClone);
+        $this->assertSame($array[0][0], $arrayClone[0][0]);
+        $this->assertNotSame($array[1], $arrayClone[1]);
+        $this->assertSame($array[1][0], $arrayClone[1][0]);
+    }
+
+    public function testCloneSupportsBSONTypes()
+    {
+        /* Note: this test does not check that the BSON type itself is cloned,
+         * as that is not yet supported in the driver (see: PHPC-1230). */
+        $array = new BSONArray([
+            [new ObjectId()],
+            new BSONArray([new ObjectId()]),
+        ]);
+        $arrayClone = clone $array;
+
+        $this->assertNotSame($array, $arrayClone);
+        $this->assertNotSame($array[1], $arrayClone[1]);
+    }
+
+    public function testJsonSerialize()
+    {
+        $document = new BSONArray([
+            'foo',
+            new BSONArray(['foo' => 1, 'bar' => 2, 'baz' => 3]),
+            new BSONDocument(['foo' => 1, 'bar' => 2, 'baz' => 3]),
+            new BSONArray([new BSONArray([new BSONArray()])]),
+        ]);
+
+        $expectedJson = '["foo",[1,2,3],{"foo":1,"bar":2,"baz":3},[[[]]]]';
+
+        $this->assertSame($expectedJson, json_encode($document));
+    }
+
+    public function testJsonSerializeReindexesKeys()
+    {
+        $data = [0 => 'foo', 2 => 'bar'];
+
+        $array = new BSONArray($data);
+        $this->assertSame($data, $array->getArrayCopy());
+        $this->assertSame(['foo', 'bar'], $array->jsonSerialize());
+    }
+
+    public function testSetState()
+    {
+        $data = ['foo', 'bar'];
+
+        $array = BSONArray::__set_state($data);
+        $this->assertInstanceOf(BSONArray::class, $array);
+        $this->assertSame($data, $array->getArrayCopy());
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Model/BSONDocumentTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Model/BSONDocumentTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..ad095e31f31801a1438d9793c28a7fff0f0472e7
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Model/BSONDocumentTest.php	
@@ -0,0 +1,118 @@
+<?php
+
+namespace MongoDB\Tests\Model;
+
+use ArrayObject;
+use MongoDB\BSON\ObjectId;
+use MongoDB\Model\BSONArray;
+use MongoDB\Model\BSONDocument;
+use MongoDB\Tests\TestCase;
+use ReflectionClass;
+use stdClass;
+use function json_encode;
+
+class BSONDocumentTest extends TestCase
+{
+    public function testConstructorDefaultsToPropertyAccess()
+    {
+        $document = new BSONDocument(['foo' => 'bar']);
+        $this->assertEquals(ArrayObject::ARRAY_AS_PROPS, $document->getFlags());
+        $this->assertSame('bar', $document->foo);
+    }
+
+    public function testBsonSerializeCastsToObject()
+    {
+        $data = [0 => 'foo', 2 => 'bar'];
+
+        $document = new BSONDocument($data);
+        $this->assertSame($data, $document->getArrayCopy());
+        $this->assertEquals((object) [0 => 'foo', 2 => 'bar'], $document->bsonSerialize());
+    }
+
+    public function testClone()
+    {
+        $document = new BSONDocument([
+            'a' => [
+                'a' => 'foo',
+                'b' => new stdClass(),
+                'c' => ['bar', new stdClass()],
+            ],
+            'b' => new BSONDocument([
+                'a' => 'foo',
+                'b' => new stdClass(),
+                'c' => ['bar', new stdClass()],
+            ]),
+        ]);
+        $documentClone = clone $document;
+
+        $this->assertSameDocument($document, $documentClone);
+        $this->assertNotSame($document, $documentClone);
+        $this->assertNotSame($document['a']['b'], $documentClone['a']['b']);
+        $this->assertNotSame($document['a']['c'][1], $documentClone['a']['c'][1]);
+        $this->assertNotSame($document['b'], $documentClone['b']);
+        $this->assertNotSame($document['b']['b'], $documentClone['b']['b']);
+        $this->assertNotSame($document['b']['c'][1], $documentClone['b']['c'][1]);
+    }
+
+    public function testCloneRespectsUncloneableObjects()
+    {
+        $this->assertFalse((new ReflectionClass(UncloneableObject::class))->isCloneable());
+
+        $document = new BSONDocument([
+            'a' => ['a' => new UncloneableObject()],
+            'b' => new BSONDocument(['a' => new UncloneableObject()]),
+        ]);
+        $documentClone = clone $document;
+
+        $this->assertNotSame($document, $documentClone);
+        $this->assertSame($document['a']['a'], $documentClone['a']['a']);
+        $this->assertNotSame($document['b'], $documentClone['b']);
+        $this->assertSame($document['b']['a'], $documentClone['b']['a']);
+    }
+
+    public function testCloneSupportsBSONTypes()
+    {
+        /* Note: this test does not check that the BSON type itself is cloned,
+         * as that is not yet supported in the driver (see: PHPC-1230). */
+        $document = new BSONDocument([
+            'a' => ['a' => new ObjectId()],
+            'b' => new BSONDocument(['a' => new ObjectId()]),
+        ]);
+        $documentClone = clone $document;
+
+        $this->assertNotSame($document, $documentClone);
+        $this->assertNotSame($document['b'], $documentClone['b']);
+    }
+
+    public function testJsonSerialize()
+    {
+        $document = new BSONDocument([
+            'foo' => 'bar',
+            'array' => new BSONArray([1, 2, 3]),
+            'object' => new BSONDocument([1, 2, 3]),
+            'nested' => new BSONDocument([new BSONDocument([new BSONDocument()])]),
+        ]);
+
+        $expectedJson = '{"foo":"bar","array":[1,2,3],"object":{"0":1,"1":2,"2":3},"nested":{"0":{"0":{}}}}';
+
+        $this->assertSame($expectedJson, json_encode($document));
+    }
+
+    public function testJsonSerializeCastsToObject()
+    {
+        $data = [0 => 'foo', 2 => 'bar'];
+
+        $document = new BSONDocument($data);
+        $this->assertSame($data, $document->getArrayCopy());
+        $this->assertEquals((object) [0 => 'foo', 2 => 'bar'], $document->jsonSerialize());
+    }
+
+    public function testSetState()
+    {
+        $data = ['foo' => 'bar'];
+
+        $document = BSONDocument::__set_state($data);
+        $this->assertInstanceOf(BSONDocument::class, $document);
+        $this->assertSame($data, $document->getArrayCopy());
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Model/BSONIteratorTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Model/BSONIteratorTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..c48ed393df1afc6d40fa6705f0824fbbc382a50b
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Model/BSONIteratorTest.php	
@@ -0,0 +1,135 @@
+<?php
+
+namespace MongoDB\Tests\Model;
+
+use MongoDB\Exception\UnexpectedValueException;
+use MongoDB\Model\BSONIterator;
+use MongoDB\Tests\TestCase;
+use function array_map;
+use function implode;
+use function iterator_to_array;
+use function MongoDB\BSON\fromPHP;
+use function substr;
+
+class BSONIteratorTest extends TestCase
+{
+    /**
+     * @dataProvider provideTypeMapOptionsAndExpectedDocuments
+     */
+    public function testValidValues(array $typeMap = null, $binaryString, array $expectedDocuments)
+    {
+        $bsonIt = new BSONIterator($binaryString, ['typeMap' => $typeMap]);
+
+        $results = iterator_to_array($bsonIt);
+
+        $this->assertEquals($expectedDocuments, $results);
+    }
+
+    public function provideTypeMapOptionsAndExpectedDocuments()
+    {
+        return [
+            [
+                null,
+                implode(array_map(
+                    'MongoDB\BSON\fromPHP',
+                    [
+                        ['_id' => 1, 'x' => ['foo' => 'bar']],
+                        ['_id' => 3, 'x' => ['foo' => 'bar']],
+                    ]
+                )),
+                [
+                    (object) ['_id' => 1, 'x' => (object) ['foo' => 'bar']],
+                    (object) ['_id' => 3, 'x' => (object) ['foo' => 'bar']],
+                ],
+            ],
+            [
+                ['root' => 'array', 'document' => 'array'],
+                implode(array_map(
+                    'MongoDB\BSON\fromPHP',
+                    [
+                        ['_id' => 1, 'x' => ['foo' => 'bar']],
+                        ['_id' => 3, 'x' => ['foo' => 'bar']],
+                    ]
+                )),
+                [
+                    ['_id' => 1, 'x' => ['foo' => 'bar']],
+                    ['_id' => 3, 'x' => ['foo' => 'bar']],
+                ],
+            ],
+            [
+                ['root' => 'object', 'document' => 'array'],
+                implode(array_map(
+                    'MongoDB\BSON\fromPHP',
+                    [
+                        ['_id' => 1, 'x' => ['foo' => 'bar']],
+                        ['_id' => 3, 'x' => ['foo' => 'bar']],
+                    ]
+                )),
+                [
+                    (object) ['_id' => 1, 'x' => ['foo' => 'bar']],
+                    (object) ['_id' => 3, 'x' => ['foo' => 'bar']],
+                ],
+            ],
+            [
+                ['root' => 'array', 'document' => 'stdClass'],
+                implode(array_map(
+                    'MongoDB\BSON\fromPHP',
+                    [
+                        ['_id' => 1, 'x' => ['foo' => 'bar']],
+                        ['_id' => 3, 'x' => ['foo' => 'bar']],
+                    ]
+                )),
+                [
+                    ['_id' => 1, 'x' => (object) ['foo' => 'bar']],
+                    ['_id' => 3, 'x' => (object) ['foo' => 'bar']],
+                ],
+            ],
+        ];
+    }
+
+    public function testCannotReadLengthFromFirstDocument()
+    {
+        $binaryString = substr(fromPHP([]), 0, 3);
+
+        $bsonIt = new BSONIterator($binaryString);
+
+        $this->expectException(UnexpectedValueException::class);
+        $this->expectExceptionMessage('Expected at least 4 bytes; 3 remaining');
+        $bsonIt->rewind();
+    }
+
+    public function testCannotReadLengthFromSubsequentDocument()
+    {
+        $binaryString = fromPHP([]) . substr(fromPHP([]), 0, 3);
+
+        $bsonIt = new BSONIterator($binaryString);
+        $bsonIt->rewind();
+
+        $this->expectException(UnexpectedValueException::class);
+        $this->expectExceptionMessage('Expected at least 4 bytes; 3 remaining');
+        $bsonIt->next();
+    }
+
+    public function testCannotReadFirstDocument()
+    {
+        $binaryString = substr(fromPHP([]), 0, 4);
+
+        $bsonIt = new BSONIterator($binaryString);
+
+        $this->expectException(UnexpectedValueException::class);
+        $this->expectExceptionMessage('Expected 5 bytes; 4 remaining');
+        $bsonIt->rewind();
+    }
+
+    public function testCannotReadSecondDocument()
+    {
+        $binaryString = fromPHP([]) . substr(fromPHP([]), 0, 4);
+
+        $bsonIt = new BSONIterator($binaryString);
+        $bsonIt->rewind();
+
+        $this->expectException(UnexpectedValueException::class);
+        $this->expectExceptionMessage('Expected 5 bytes; 4 remaining');
+        $bsonIt->next();
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Model/CachingIteratorTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Model/CachingIteratorTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..f4d4b28bf667067b389d36faf1a0d4efb071f5ef
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Model/CachingIteratorTest.php	
@@ -0,0 +1,123 @@
+<?php
+
+namespace MongoDB\Tests\Model;
+
+use Exception;
+use MongoDB\Model\CachingIterator;
+use MongoDB\Tests\TestCase;
+use Throwable;
+use function iterator_to_array;
+
+class CachingIteratorTest extends TestCase
+{
+    public function testTraversingGeneratorConsumesIt()
+    {
+        $iterator = $this->getTraversable([1, 2, 3]);
+        $this->assertSame([1, 2, 3], iterator_to_array($iterator));
+
+        $this->expectException(Throwable::class);
+        $this->expectExceptionMessage('Cannot traverse an already closed generator');
+        iterator_to_array($iterator);
+    }
+
+    public function testConstructorRewinds()
+    {
+        $iterator = new CachingIterator($this->getTraversable([1, 2, 3]));
+
+        $this->assertTrue($iterator->valid());
+        $this->assertSame(0, $iterator->key());
+        $this->assertSame(1, $iterator->current());
+    }
+
+    public function testIteration()
+    {
+        $iterator = new CachingIterator($this->getTraversable([1, 2, 3]));
+
+        $expectedKey = 0;
+        $expectedItem = 1;
+
+        foreach ($iterator as $key => $item) {
+            $this->assertSame($expectedKey++, $key);
+            $this->assertSame($expectedItem++, $item);
+        }
+
+        $this->assertFalse($iterator->valid());
+    }
+
+    public function testIterationWithEmptySet()
+    {
+        $iterator = new CachingIterator($this->getTraversable([]));
+
+        $iterator->rewind();
+        $this->assertFalse($iterator->valid());
+    }
+
+    public function testPartialIterationDoesNotExhaust()
+    {
+        $traversable = $this->getTraversable([1, 2, new Exception()]);
+        $iterator = new CachingIterator($traversable);
+
+        $expectedKey = 0;
+        $expectedItem = 1;
+
+        foreach ($iterator as $key => $item) {
+            $this->assertSame($expectedKey++, $key);
+            $this->assertSame($expectedItem++, $item);
+
+            if ($key === 1) {
+                break;
+            }
+        }
+
+        $this->assertTrue($iterator->valid());
+    }
+
+    public function testRewindAfterPartialIteration()
+    {
+        $iterator = new CachingIterator($this->getTraversable([1, 2, 3]));
+
+        $iterator->rewind();
+        $this->assertTrue($iterator->valid());
+        $this->assertSame(0, $iterator->key());
+        $this->assertSame(1, $iterator->current());
+
+        $iterator->next();
+        $this->assertSame([1, 2, 3], iterator_to_array($iterator));
+    }
+
+    public function testCount()
+    {
+        $iterator = new CachingIterator($this->getTraversable([1, 2, 3]));
+        $this->assertCount(3, $iterator);
+    }
+
+    public function testCountAfterPartialIteration()
+    {
+        $iterator = new CachingIterator($this->getTraversable([1, 2, 3]));
+
+        $iterator->rewind();
+        $this->assertTrue($iterator->valid());
+        $this->assertSame(0, $iterator->key());
+        $this->assertSame(1, $iterator->current());
+
+        $iterator->next();
+        $this->assertCount(3, $iterator);
+    }
+
+    public function testCountWithEmptySet()
+    {
+        $iterator = new CachingIterator($this->getTraversable([]));
+        $this->assertCount(0, $iterator);
+    }
+
+    private function getTraversable($items)
+    {
+        foreach ($items as $item) {
+            if ($item instanceof Exception) {
+                throw $item;
+            } else {
+                yield $item;
+            }
+        }
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Model/ChangeStreamIteratorTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Model/ChangeStreamIteratorTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..954ec4efc796f792eb411688d8a259f1bc3460d9
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Model/ChangeStreamIteratorTest.php	
@@ -0,0 +1,167 @@
+<?php
+
+namespace MongoDB\Tests\Model;
+
+use MongoDB\Collection;
+use MongoDB\Driver\Exception\LogicException;
+use MongoDB\Exception\InvalidArgumentException;
+use MongoDB\Model\ChangeStreamIterator;
+use MongoDB\Operation\CreateCollection;
+use MongoDB\Operation\DropCollection;
+use MongoDB\Operation\Find;
+use MongoDB\Tests\CommandObserver;
+use MongoDB\Tests\FunctionalTestCase;
+use Symfony\Bridge\PhpUnit\SetUpTearDownTrait;
+use function array_merge;
+use function sprintf;
+
+class ChangeStreamIteratorTest extends FunctionalTestCase
+{
+    use SetUpTearDownTrait;
+
+    /** @var Collection */
+    private $collection;
+
+    private function doSetUp()
+    {
+        parent::setUp();
+
+        $operation = new DropCollection($this->getDatabaseName(), $this->getCollectionName());
+        $operation->execute($this->getPrimaryServer());
+
+        $operation = new CreateCollection($this->getDatabaseName(), $this->getCollectionName(), ['capped' => true, 'size' => 8192]);
+        $operation->execute($this->getPrimaryServer());
+
+        $this->collection = new Collection($this->manager, $this->getDatabaseName(), $this->getCollectionName());
+    }
+
+    /**
+     * @dataProvider provideInvalidIntegerValues
+     */
+    public function testFirstBatchArgumentTypeCheck($firstBatchSize)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        new ChangeStreamIterator($this->collection->find(), $firstBatchSize, null, null);
+    }
+
+    public function provideInvalidIntegerValues()
+    {
+        return $this->wrapValuesForDataProvider($this->getInvalidIntegerValues());
+    }
+
+    public function testInitialResumeToken()
+    {
+        $iterator = new ChangeStreamIterator($this->collection->find(), 0, null, null);
+        $this->assertNull($iterator->getResumeToken());
+
+        $iterator = new ChangeStreamIterator($this->collection->find(), 0, ['resumeToken' => 1], null);
+        $this->assertSameDocument(['resumeToken' => 1], $iterator->getResumeToken());
+
+        $iterator = new ChangeStreamIterator($this->collection->find(), 0, (object) ['resumeToken' => 2], null);
+        $this->assertSameDocument((object) ['resumeToken' => 2], $iterator->getResumeToken());
+    }
+
+    /**
+     * @dataProvider provideInvalidDocumentValues
+     */
+    public function testInitialResumeTokenArgumentTypeCheck($initialResumeToken)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        new ChangeStreamIterator($this->collection->find(), 0, $initialResumeToken, null);
+    }
+
+    /**
+     * @dataProvider provideInvalidObjectValues
+     */
+    public function testPostBatchResumeTokenArgumentTypeCheck($postBatchResumeToken)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        new ChangeStreamIterator($this->collection->find(), 0, null, $postBatchResumeToken);
+    }
+
+    public function provideInvalidObjectValues()
+    {
+        return $this->wrapValuesForDataProvider(array_merge($this->getInvalidDocumentValues(), [[]]));
+    }
+
+    public function testPostBatchResumeTokenIsReturnedForLastElementInFirstBatch()
+    {
+        $this->collection->insertOne(['_id' => ['resumeToken' => 1], 'x' => 1]);
+        $this->collection->insertOne(['_id' => ['resumeToken' => 2], 'x' => 2]);
+        $postBatchResumeToken = (object) ['resumeToken' => 'pb'];
+
+        $cursor = $this->collection->find([], ['cursorType' => Find::TAILABLE]);
+        $iterator = new ChangeStreamIterator($cursor, 2, null, $postBatchResumeToken);
+
+        $this->assertNoCommandExecuted(function () use ($iterator) {
+            $iterator->rewind();
+        });
+        $this->assertTrue($iterator->valid());
+        $this->assertSameDocument(['resumeToken' => 1], $iterator->getResumeToken());
+        $this->assertSameDocument(['_id' => ['resumeToken' => 1], 'x' => 1], $iterator->current());
+
+        $iterator->next();
+        $this->assertTrue($iterator->valid());
+        $this->assertSameDocument($postBatchResumeToken, $iterator->getResumeToken());
+        $this->assertSameDocument(['_id' => ['resumeToken' => 2], 'x' => 2], $iterator->current());
+    }
+
+    public function testRewindIsNopWhenFirstBatchIsEmpty()
+    {
+        $this->collection->insertOne(['_id' => ['resumeToken' => 1], 'x' => 1]);
+
+        $cursor = $this->collection->find(['x' => ['$gt' => 1]], ['cursorType' => Find::TAILABLE]);
+        $iterator = new ChangeStreamIterator($cursor, 0, null, null);
+
+        $this->assertNoCommandExecuted(function () use ($iterator) {
+            $iterator->rewind();
+        });
+        $this->assertFalse($iterator->valid());
+
+        $this->collection->insertOne(['_id' => ['resumeToken' => 2], 'x' => 2]);
+
+        $iterator->next();
+        $this->assertTrue($iterator->valid());
+        $this->assertSameDocument(['_id' => ['resumeToken' => 2], 'x' => 2], $iterator->current());
+
+        $this->expectException(LogicException::class);
+        $iterator->rewind();
+    }
+
+    public function testRewindAdvancesWhenFirstBatchIsNotEmpty()
+    {
+        $this->collection->insertOne(['_id' => ['resumeToken' => 1], 'x' => 1]);
+
+        $cursor = $this->collection->find([], ['cursorType' => Find::TAILABLE]);
+        $iterator = new ChangeStreamIterator($cursor, 1, null, null);
+
+        $this->assertNoCommandExecuted(function () use ($iterator) {
+            $iterator->rewind();
+        });
+        $this->assertTrue($iterator->valid());
+        $this->assertSameDocument(['_id' => ['resumeToken' => 1], 'x' => 1], $iterator->current());
+
+        $this->collection->insertOne(['_id' => ['resumeToken' => 2], 'x' => 2]);
+
+        $iterator->next();
+        $this->assertTrue($iterator->valid());
+        $this->assertSameDocument(['_id' => ['resumeToken' => 2], 'x' => 2], $iterator->current());
+
+        $this->expectException(LogicException::class);
+        $iterator->rewind();
+    }
+
+    private function assertNoCommandExecuted(callable $callable)
+    {
+        $commands = [];
+
+        (new CommandObserver())->observe(
+            $callable,
+            function (array $event) use (&$commands) {
+                $this->fail(sprintf('"%s" command was executed', $event['started']->getCommandName()));
+            }
+        );
+
+        $this->assertEmpty($commands);
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Model/CollectionInfoTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Model/CollectionInfoTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..4320e7df107e3cdccf8edf370fedbf48c2cc2ada
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Model/CollectionInfoTest.php	
@@ -0,0 +1,78 @@
+<?php
+
+namespace MongoDB\Tests\Model;
+
+use MongoDB\Exception\BadMethodCallException;
+use MongoDB\Model\CollectionInfo;
+use MongoDB\Tests\TestCase;
+
+class CollectionInfoTest extends TestCase
+{
+    public function testGetName()
+    {
+        $info = new CollectionInfo(['name' => 'foo']);
+        $this->assertSame('foo', $info->getName());
+    }
+
+    public function testGetOptions()
+    {
+        $info = new CollectionInfo(['name' => 'foo']);
+        $this->assertSame([], $info->getOptions());
+
+        $info = new CollectionInfo(['name' => 'foo', 'options' => ['capped' => true, 'size' => 1048576]]);
+        $this->assertSame(['capped' => true, 'size' => 1048576], $info->getOptions());
+    }
+
+    public function testCappedCollectionMethods()
+    {
+        $info = new CollectionInfo(['name' => 'foo']);
+        $this->assertFalse($info->isCapped());
+        $this->assertNull($info->getCappedMax());
+        $this->assertNull($info->getCappedSize());
+
+        $info = new CollectionInfo(['name' => 'foo', 'options' => ['capped' => true, 'size' => 1048576]]);
+        $this->assertTrue($info->isCapped());
+        $this->assertNull($info->getCappedMax());
+        $this->assertSame(1048576, $info->getCappedSize());
+
+        $info = new CollectionInfo(['name' => 'foo', 'options' => ['capped' => true, 'size' => 1048576, 'max' => 100]]);
+        $this->assertTrue($info->isCapped());
+        $this->assertSame(100, $info->getCappedMax());
+        $this->assertSame(1048576, $info->getCappedSize());
+    }
+
+    public function testDebugInfo()
+    {
+        $expectedInfo = [
+            'name' => 'foo',
+            'options' => ['capped' => true, 'size' => 1048576],
+        ];
+
+        $info = new CollectionInfo($expectedInfo);
+        $this->assertSame($expectedInfo, $info->__debugInfo());
+    }
+
+    public function testImplementsArrayAccess()
+    {
+        $info = new CollectionInfo(['name' => 'foo']);
+        $this->assertInstanceOf('ArrayAccess', $info);
+        $this->assertArrayHasKey('name', $info);
+        $this->assertSame('foo', $info['name']);
+    }
+
+    public function testOffsetSetCannotBeCalled()
+    {
+        $info = new CollectionInfo(['name' => 'foo', 'options' => ['capped' => true, 'size' => 1048576]]);
+        $this->expectException(BadMethodCallException::class);
+        $this->expectExceptionMessage(CollectionInfo::class . ' is immutable');
+        $info['options'] = ['capped' => false];
+    }
+
+    public function testOffsetUnsetCannotBeCalled()
+    {
+        $info = new CollectionInfo(['name' => 'foo', 'options' => ['capped' => true, 'size' => 1048576]]);
+        $this->expectException(BadMethodCallException::class);
+        $this->expectExceptionMessage(CollectionInfo::class . ' is immutable');
+        unset($info['options']);
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Model/DatabaseInfoTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Model/DatabaseInfoTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..2c9819ee6471fb15c752d5163984529db416c6ba
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Model/DatabaseInfoTest.php	
@@ -0,0 +1,67 @@
+<?php
+
+namespace MongoDB\Tests\Model;
+
+use MongoDB\Exception\BadMethodCallException;
+use MongoDB\Model\DatabaseInfo;
+use MongoDB\Tests\TestCase;
+
+class DatabaseInfoTest extends TestCase
+{
+    public function testGetName()
+    {
+        $info = new DatabaseInfo(['name' => 'foo']);
+        $this->assertSame('foo', $info->getName());
+    }
+
+    public function testGetSizeOnDisk()
+    {
+        $info = new DatabaseInfo(['sizeOnDisk' => 1048576]);
+        $this->assertSame(1048576, $info->getSizeOnDisk());
+    }
+
+    public function testIsEmpty()
+    {
+        $info = new DatabaseInfo(['empty' => false]);
+        $this->assertFalse($info->isEmpty());
+
+        $info = new DatabaseInfo(['empty' => true]);
+        $this->assertTrue($info->isEmpty());
+    }
+
+    public function testDebugInfo()
+    {
+        $expectedInfo = [
+            'name' => 'foo',
+            'sizeOnDisk' => 1048576,
+            'empty' => false,
+        ];
+
+        $info = new DatabaseInfo($expectedInfo);
+        $this->assertSame($expectedInfo, $info->__debugInfo());
+    }
+
+    public function testImplementsArrayAccess()
+    {
+        $info = new DatabaseInfo(['name' => 'foo']);
+        $this->assertInstanceOf('ArrayAccess', $info);
+        $this->assertArrayHasKey('name', $info);
+        $this->assertSame('foo', $info['name']);
+    }
+
+    public function testOffsetSetCannotBeCalled()
+    {
+        $info = new DatabaseInfo(['name' => 'foo', 'sizeOnDisk' => 1048576, 'empty' => false]);
+        $this->expectException(BadMethodCallException::class);
+        $this->expectExceptionMessage(DatabaseInfo::class . ' is immutable');
+        $info['empty'] = true;
+    }
+
+    public function testOffsetUnsetCannotBeCalled()
+    {
+        $info = new DatabaseInfo(['name' => 'foo', 'sizeOnDisk' => 1048576, 'empty' => false]);
+        $this->expectException(BadMethodCallException::class);
+        $this->expectExceptionMessage(DatabaseInfo::class . ' is immutable');
+        unset($info['empty']);
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Model/IndexInfoFunctionalTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Model/IndexInfoFunctionalTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..d97a3ca23e2269c97c9a0b5cfde577bd1397d240
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Model/IndexInfoFunctionalTest.php	
@@ -0,0 +1,85 @@
+<?php
+
+namespace MongoDB\Tests\Model;
+
+use MongoDB\Collection;
+use MongoDB\Tests\FunctionalTestCase;
+use Symfony\Bridge\PhpUnit\SetUpTearDownTrait;
+use function version_compare;
+
+class IndexInfoFunctionalTest extends FunctionalTestCase
+{
+    use SetUpTearDownTrait;
+
+    /** @var Collection */
+    private $collection;
+
+    private function doSetUp()
+    {
+        parent::setUp();
+
+        $this->collection = new Collection($this->manager, $this->getDatabaseName(), $this->getCollectionName());
+        $this->collection->drop();
+    }
+
+    private function doTearDown()
+    {
+        if ($this->hasFailed()) {
+            return;
+        }
+
+        $this->collection->drop();
+
+        parent::tearDown();
+    }
+
+    public function testIs2dSphere()
+    {
+        $indexName = $this->collection->createIndex(['pos' => '2dsphere']);
+        $result = $this->collection->listIndexes();
+
+        $result->rewind();
+        $result->next();
+        $index = $result->current();
+
+        $this->assertEquals($indexName, $index->getName());
+        $this->assertTrue($index->is2dSphere());
+
+        $expectedVersion = version_compare($this->getServerVersion(), '3.2.0', '<') ? 2 : 3;
+        $this->assertEquals($expectedVersion, $index['2dsphereIndexVersion']);
+    }
+
+    public function testIsGeoHaystack()
+    {
+        $indexName = $this->collection->createIndex(['pos' => 'geoHaystack', 'x' => 1], ['bucketSize' => 5]);
+        $result = $this->collection->listIndexes();
+
+        $result->rewind();
+        $result->next();
+        $index = $result->current();
+
+        $this->assertEquals($indexName, $index->getName());
+        $this->assertTrue($index->isGeoHaystack());
+        $this->assertEquals(5, $index['bucketSize']);
+    }
+
+    public function testIsText()
+    {
+        $indexName = $this->collection->createIndex(['x' => 'text']);
+        $result = $this->collection->listIndexes();
+
+        $result->rewind();
+        $result->next();
+        $index = $result->current();
+
+        $this->assertEquals($indexName, $index->getName());
+        $this->assertTrue($index->isText());
+        $this->assertEquals('english', $index['default_language']);
+        $this->assertEquals('language', $index['language_override']);
+
+        $expectedVersion = version_compare($this->getServerVersion(), '3.2.0', '<') ? 2 : 3;
+        $this->assertEquals($expectedVersion, $index['textIndexVersion']);
+
+        $this->assertSameDocument(['x' => 1], $index['weights']);
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Model/IndexInfoTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Model/IndexInfoTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..33cfcda5208fd2cb3417a5a12da933271fbf18e5
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Model/IndexInfoTest.php	
@@ -0,0 +1,217 @@
+<?php
+
+namespace MongoDB\Tests\Model;
+
+use MongoDB\Exception\BadMethodCallException;
+use MongoDB\Model\IndexInfo;
+use MongoDB\Tests\TestCase;
+
+class IndexInfoTest extends TestCase
+{
+    public function testBasicIndex()
+    {
+        $info = new IndexInfo([
+            'v' => 1,
+            'key' => ['x' => 1],
+            'name' => 'x_1',
+            'ns' => 'foo.bar',
+        ]);
+
+        $this->assertSame(1, $info->getVersion());
+        $this->assertSame(['x' => 1], $info->getKey());
+        $this->assertSame('x_1', $info->getName());
+        $this->assertSame('foo.bar', $info->getNamespace());
+        $this->assertFalse($info->is2dSphere());
+        $this->assertFalse($info->isGeoHaystack());
+        $this->assertFalse($info->isSparse());
+        $this->assertFalse($info->isText());
+        $this->assertFalse($info->isTtl());
+        $this->assertFalse($info->isUnique());
+    }
+
+    public function testSparseIndex()
+    {
+        $info = new IndexInfo([
+            'v' => 1,
+            'key' => ['y' => 1],
+            'name' => 'y_sparse',
+            'ns' => 'foo.bar',
+            'sparse' => true,
+        ]);
+
+        $this->assertSame(1, $info->getVersion());
+        $this->assertSame(['y' => 1], $info->getKey());
+        $this->assertSame('y_sparse', $info->getName());
+        $this->assertSame('foo.bar', $info->getNamespace());
+        $this->assertFalse($info->is2dSphere());
+        $this->assertFalse($info->isGeoHaystack());
+        $this->assertTrue($info->isSparse());
+        $this->assertFalse($info->isText());
+        $this->assertFalse($info->isTtl());
+        $this->assertFalse($info->isUnique());
+    }
+
+    public function testUniqueIndex()
+    {
+        $info = new IndexInfo([
+            'v' => 1,
+            'key' => ['z' => 1],
+            'name' => 'z_unique',
+            'ns' => 'foo.bar',
+            'unique' => true,
+        ]);
+
+        $this->assertSame(1, $info->getVersion());
+        $this->assertSame(['z' => 1], $info->getKey());
+        $this->assertSame('z_unique', $info->getName());
+        $this->assertSame('foo.bar', $info->getNamespace());
+        $this->assertFalse($info->is2dSphere());
+        $this->assertFalse($info->isGeoHaystack());
+        $this->assertFalse($info->isSparse());
+        $this->assertFalse($info->isText());
+        $this->assertFalse($info->isTtl());
+        $this->assertTrue($info->isUnique());
+    }
+
+    public function testTtlIndex()
+    {
+        $info = new IndexInfo([
+            'v' => 1,
+            'key' => ['z' => 1],
+            'name' => 'z_unique',
+            'ns' => 'foo.bar',
+            'expireAfterSeconds' => 100,
+        ]);
+
+        $this->assertSame(1, $info->getVersion());
+        $this->assertSame(['z' => 1], $info->getKey());
+        $this->assertSame('z_unique', $info->getName());
+        $this->assertSame('foo.bar', $info->getNamespace());
+        $this->assertFalse($info->is2dSphere());
+        $this->assertFalse($info->isGeoHaystack());
+        $this->assertFalse($info->isSparse());
+        $this->assertFalse($info->isText());
+        $this->assertTrue($info->isTtl());
+        $this->assertFalse($info->isUnique());
+        $this->assertArrayHasKey('expireAfterSeconds', $info);
+        $this->assertSame(100, $info['expireAfterSeconds']);
+    }
+
+    public function testDebugInfo()
+    {
+        $expectedInfo = [
+            'v' => 1,
+            'key' => ['x' => 1],
+            'name' => 'x_1',
+            'ns' => 'foo.bar',
+        ];
+
+        $info = new IndexInfo($expectedInfo);
+        $this->assertSame($expectedInfo, $info->__debugInfo());
+    }
+
+    public function testImplementsArrayAccess()
+    {
+        $info = new IndexInfo([
+            'v' => 1,
+            'key' => ['x' => 1],
+            'name' => 'x_1',
+            'ns' => 'foo.bar',
+        ]);
+
+        $this->assertInstanceOf('ArrayAccess', $info);
+        $this->assertArrayHasKey('name', $info);
+        $this->assertSame('x_1', $info['name']);
+    }
+
+    public function testOffsetSetCannotBeCalled()
+    {
+        $info = new IndexInfo([
+            'v' => 1,
+            'key' => ['x' => 1],
+            'name' => 'x_1',
+            'ns' => 'foo.bar',
+        ]);
+
+        $this->expectException(BadMethodCallException::class);
+        $this->expectExceptionMessage(IndexInfo::class . ' is immutable');
+        $info['v'] = 2;
+    }
+
+    public function testOffsetUnsetCannotBeCalled()
+    {
+        $info = new IndexInfo([
+            'v' => 1,
+            'key' => ['x' => 1],
+            'name' => 'x_1',
+            'ns' => 'foo.bar',
+        ]);
+
+        $this->expectException(BadMethodCallException::class);
+        $this->expectExceptionMessage(IndexInfo::class . ' is immutable');
+        unset($info['v']);
+    }
+
+    public function testIs2dSphere()
+    {
+        $info = new IndexInfo([
+            'v' => 2,
+            'key' => ['pos' => '2dsphere'],
+            'name' => 'pos_2dsphere',
+            'ns' => 'foo.bar',
+        ]);
+
+        $this->assertSame(2, $info->getVersion());
+        $this->assertSame(['pos' => '2dsphere'], $info->getKey());
+        $this->assertSame('pos_2dsphere', $info->getName());
+        $this->assertSame('foo.bar', $info->getNamespace());
+        $this->assertTrue($info->is2dSphere());
+        $this->assertFalse($info->isGeoHaystack());
+        $this->assertFalse($info->isSparse());
+        $this->assertFalse($info->isText());
+        $this->assertFalse($info->isTtl());
+        $this->assertFalse($info->isUnique());
+    }
+
+    public function testIsGeoHaystack()
+    {
+        $info = new IndexInfo([
+            'v' => 2,
+            'key' => ['pos2' => 'geoHaystack', 'x' => 1],
+            'name' => 'pos2_geoHaystack_x_1',
+            'ns' => 'foo.bar',
+        ]);
+
+        $this->assertSame(2, $info->getVersion());
+        $this->assertSame(['pos2' => 'geoHaystack', 'x' => 1], $info->getKey());
+        $this->assertSame('pos2_geoHaystack_x_1', $info->getName());
+        $this->assertSame('foo.bar', $info->getNamespace());
+        $this->assertFalse($info->is2dSphere());
+        $this->assertTrue($info->isGeoHaystack());
+        $this->assertFalse($info->isSparse());
+        $this->assertFalse($info->isText());
+        $this->assertFalse($info->isTtl());
+        $this->assertFalse($info->isUnique());
+    }
+
+    public function testIsText()
+    {
+        $info = new IndexInfo([
+            'v' => 2,
+            'key' => ['_fts' => 'text', '_ftsx' => 1],
+            'name' => 'title_text_description_text',
+            'ns' => 'foo.bar',
+        ]);
+
+        $this->assertSame(2, $info->getVersion());
+        $this->assertSame(['_fts' => 'text', '_ftsx' => 1], $info->getKey());
+        $this->assertSame('title_text_description_text', $info->getName());
+        $this->assertSame('foo.bar', $info->getNamespace());
+        $this->assertFalse($info->is2dSphere());
+        $this->assertFalse($info->isGeoHaystack());
+        $this->assertFalse($info->isSparse());
+        $this->assertTrue($info->isText());
+        $this->assertFalse($info->isTtl());
+        $this->assertFalse($info->isUnique());
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Model/IndexInputTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Model/IndexInputTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..da6876169c15a94b84c0af3db465b960ef67df18
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Model/IndexInputTest.php	
@@ -0,0 +1,80 @@
+<?php
+
+namespace MongoDB\Tests\Model;
+
+use MongoDB\BSON\Serializable;
+use MongoDB\Exception\InvalidArgumentException;
+use MongoDB\Model\IndexInput;
+use MongoDB\Tests\TestCase;
+use stdClass;
+
+class IndexInputTest extends TestCase
+{
+    public function testConstructorShouldRequireKey()
+    {
+        $this->expectException(InvalidArgumentException::class);
+        new IndexInput([]);
+    }
+
+    public function testConstructorShouldRequireKeyToBeArrayOrObject()
+    {
+        $this->expectException(InvalidArgumentException::class);
+        new IndexInput(['key' => 'foo']);
+    }
+
+    /**
+     * @dataProvider provideInvalidFieldOrderValues
+     */
+    public function testConstructorShouldRequireKeyFieldOrderToBeNumericOrString($order)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        new IndexInput(['key' => ['x' => $order]]);
+    }
+
+    public function provideInvalidFieldOrderValues()
+    {
+        return $this->wrapValuesForDataProvider([true, [], new stdClass()]);
+    }
+
+    public function testConstructorShouldRequireNameToBeString()
+    {
+        $this->expectException(InvalidArgumentException::class);
+        new IndexInput(['key' => ['x' => 1], 'name' => 1]);
+    }
+
+    /**
+     * @dataProvider provideExpectedNameAndKey
+     */
+    public function testNameGeneration($expectedName, array $key)
+    {
+        $this->assertSame($expectedName, (string) new IndexInput(['key' => $key]));
+    }
+
+    public function provideExpectedNameAndKey()
+    {
+        return [
+            ['x_1', ['x' => 1]],
+            ['x_1_y_-1', ['x' => 1, 'y' => -1]],
+            ['loc_2dsphere', ['loc' => '2dsphere']],
+            ['loc_2dsphere_x_1', ['loc' => '2dsphere', 'x' => 1]],
+            ['doc_text', ['doc' => 'text']],
+        ];
+    }
+
+    public function testBsonSerialization()
+    {
+        $expected = [
+            'key' => ['x' => 1],
+            'unique' => true,
+            'name' => 'x_1',
+        ];
+
+        $indexInput = new IndexInput([
+            'key' => ['x' => 1],
+            'unique' => true,
+        ]);
+
+        $this->assertInstanceOf(Serializable::class, $indexInput);
+        $this->assertSame($expected, $indexInput->bsonSerialize());
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Model/UncloneableObject.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Model/UncloneableObject.php
new file mode 100644
index 0000000000000000000000000000000000000000..380d30e64ce96e977e88795a966cb8dea15a48db
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Model/UncloneableObject.php	
@@ -0,0 +1,13 @@
+<?php
+
+namespace MongoDB\Tests\Model;
+
+/**
+ * This class is used by the BSONArray and BSONDocument clone tests.
+ */
+class UncloneableObject
+{
+    private function __clone()
+    {
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/AggregateFunctionalTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/AggregateFunctionalTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..64e53f1b73c3183bc57913b2053522ab0aa51757
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/AggregateFunctionalTest.php	
@@ -0,0 +1,384 @@
+<?php
+
+namespace MongoDB\Tests\Operation;
+
+use ArrayIterator;
+use MongoDB\Collection;
+use MongoDB\Driver\BulkWrite;
+use MongoDB\Driver\Exception\RuntimeException;
+use MongoDB\Driver\ReadPreference;
+use MongoDB\Driver\WriteConcern;
+use MongoDB\Operation\Aggregate;
+use MongoDB\Tests\CommandObserver;
+use stdClass;
+use function current;
+use function iterator_to_array;
+use function version_compare;
+
+class AggregateFunctionalTest extends FunctionalTestCase
+{
+    public function testBatchSizeIsIgnoredIfPipelineIncludesOutStage()
+    {
+        (new CommandObserver())->observe(
+            function () {
+                $operation = new Aggregate(
+                    $this->getDatabaseName(),
+                    $this->getCollectionName(),
+                    [['$out' => $this->getCollectionName() . '.output']],
+                    ['batchSize' => 0]
+                );
+
+                $operation->execute($this->getPrimaryServer());
+            },
+            function (array $event) {
+                $this->assertEquals(new stdClass(), $event['started']->getCommand()->cursor);
+            }
+        );
+
+        $outCollection = new Collection($this->manager, $this->getDatabaseName(), $this->getCollectionName() . '.output');
+        $outCollection->drop();
+    }
+
+    public function testCurrentOpCommand()
+    {
+        if (version_compare($this->getServerVersion(), '3.6.0', '<')) {
+            $this->markTestSkipped('$currentOp is not supported');
+        }
+
+        (new CommandObserver())->observe(
+            function () {
+                $operation = new Aggregate(
+                    'admin',
+                    null,
+                    [['$currentOp' => (object) []]]
+                );
+
+                $operation->execute($this->getPrimaryServer());
+            },
+            function (array $event) {
+                $this->assertSame(1, $event['started']->getCommand()->aggregate);
+            }
+        );
+    }
+
+    public function testDefaultReadConcernIsOmitted()
+    {
+        (new CommandObserver())->observe(
+            function () {
+                $operation = new Aggregate(
+                    $this->getDatabaseName(),
+                    $this->getCollectionName(),
+                    [['$match' => ['x' => 1]]],
+                    ['readConcern' => $this->createDefaultReadConcern()]
+                );
+
+                $operation->execute($this->getPrimaryServer());
+            },
+            function (array $event) {
+                $this->assertObjectNotHasAttribute('readConcern', $event['started']->getCommand());
+            }
+        );
+    }
+
+    public function testDefaultWriteConcernIsOmitted()
+    {
+        (new CommandObserver())->observe(
+            function () {
+                $operation = new Aggregate(
+                    $this->getDatabaseName(),
+                    $this->getCollectionName(),
+                    [['$out' => $this->getCollectionName() . '.output']],
+                    ['writeConcern' => $this->createDefaultWriteConcern()]
+                );
+
+                $operation->execute($this->getPrimaryServer());
+            },
+            function (array $event) {
+                $this->assertObjectNotHasAttribute('writeConcern', $event['started']->getCommand());
+            }
+        );
+
+        $outCollection = new Collection($this->manager, $this->getDatabaseName(), $this->getCollectionName() . '.output');
+        $outCollection->drop();
+    }
+
+    public function testEmptyPipelineReturnsAllDocuments()
+    {
+        $this->createFixtures(3);
+
+        $operation = new Aggregate($this->getDatabaseName(), $this->getCollectionName(), []);
+        $results = iterator_to_array($operation->execute($this->getPrimaryServer()));
+
+        $expectedDocuments = [
+            (object) ['_id' => 1, 'x' => (object) ['foo' => 'bar']],
+            (object) ['_id' => 2, 'x' => (object) ['foo' => 'bar']],
+            (object) ['_id' => 3, 'x' => (object) ['foo' => 'bar']],
+        ];
+
+        $this->assertEquals($expectedDocuments, $results);
+    }
+
+    public function testUnrecognizedPipelineState()
+    {
+        $operation = new Aggregate($this->getDatabaseName(), $this->getCollectionName(), [['$foo' => 1]]);
+        $this->expectException(RuntimeException::class);
+        $operation->execute($this->getPrimaryServer());
+    }
+
+    public function testSessionOption()
+    {
+        if (version_compare($this->getServerVersion(), '3.6.0', '<')) {
+            $this->markTestSkipped('Sessions are not supported');
+        }
+
+        (new CommandObserver())->observe(
+            function () {
+                $operation = new Aggregate(
+                    $this->getDatabaseName(),
+                    $this->getCollectionName(),
+                    [],
+                    ['session' => $this->createSession()]
+                );
+
+                $operation->execute($this->getPrimaryServer());
+            },
+            function (array $event) {
+                $this->assertObjectHasAttribute('lsid', $event['started']->getCommand());
+            }
+        );
+    }
+
+    /**
+     * @dataProvider provideTypeMapOptionsAndExpectedDocuments
+     */
+    public function testTypeMapOption(array $typeMap = null, array $expectedDocuments)
+    {
+        $this->createFixtures(3);
+
+        $pipeline = [['$match' => ['_id' => ['$ne' => 2]]]];
+
+        $operation = new Aggregate($this->getDatabaseName(), $this->getCollectionName(), $pipeline, ['typeMap' => $typeMap]);
+        $results = iterator_to_array($operation->execute($this->getPrimaryServer()));
+
+        $this->assertEquals($expectedDocuments, $results);
+    }
+
+    /**
+     * @dataProvider provideTypeMapOptionsAndExpectedDocuments
+     */
+    public function testTypeMapOptionWithoutCursor(array $typeMap = null, array $expectedDocuments)
+    {
+        if (version_compare($this->getServerVersion(), '3.6.0', '>=')) {
+            $this->markTestSkipped('Aggregations with useCursor == false are not supported');
+        }
+
+        $this->createFixtures(3);
+
+        $pipeline = [['$match' => ['_id' => ['$ne' => 2]]]];
+
+        $operation = new Aggregate($this->getDatabaseName(), $this->getCollectionName(), $pipeline, ['typeMap' => $typeMap, 'useCursor' => false]);
+        $results = $operation->execute($this->getPrimaryServer());
+
+        $this->assertInstanceOf(ArrayIterator::class, $results);
+        $this->assertEquals($expectedDocuments, iterator_to_array($results));
+    }
+
+    public function testExplainOption()
+    {
+        $this->createFixtures(3);
+
+        $pipeline = [['$match' => ['_id' => ['$ne' => 2]]]];
+        $operation = new Aggregate($this->getDatabaseName(), $this->getCollectionName(), $pipeline, ['explain' => true, 'typeMap' => ['root' => 'array']]);
+        $results = iterator_to_array($operation->execute($this->getPrimaryServer()));
+
+        $this->assertCount(1, $results);
+
+        /* MongoDB 4.2 may optimize aggregate pipelines into queries, which can
+         * result in different explain output (see: SERVER-24860) */
+        $this->assertThat($results[0], $this->logicalOr(
+            $this->arrayHasKey('stages'),
+            $this->arrayHasKey('queryPlanner')
+        ));
+    }
+
+    public function testExplainOptionWithWriteConcern()
+    {
+        if (version_compare($this->getServerVersion(), '3.4.0', '<')) {
+            $this->markTestSkipped('The writeConcern option is not supported');
+        }
+
+        $this->createFixtures(3);
+
+        $pipeline = [['$match' => ['_id' => ['$ne' => 2]]], ['$out' => $this->getCollectionName() . '.output']];
+        $options = ['explain' => true, 'writeConcern' => new WriteConcern(1)];
+
+        (new CommandObserver())->observe(
+            function () use ($pipeline, $options) {
+                $operation = new Aggregate($this->getDatabaseName(), $this->getCollectionName(), $pipeline, $options);
+
+                $results = iterator_to_array($operation->execute($this->getPrimaryServer()));
+
+                $this->assertCount(1, $results);
+                $result = current($results);
+
+                if (isset($result->shards)) {
+                    foreach ($result->shards as $shard) {
+                        $this->assertObjectHasAttribute('stages', $shard);
+                    }
+                } else {
+                    $this->assertObjectHasAttribute('stages', $result);
+                }
+            },
+            function (array $event) {
+                $this->assertObjectNotHasAttribute('writeConcern', $event['started']->getCommand());
+            }
+        );
+
+        $this->assertCollectionCount($this->getCollectionName() . '.output', 0);
+    }
+
+    public function testBypassDocumentValidationSetWhenTrue()
+    {
+        if (version_compare($this->getServerVersion(), '3.2.0', '<')) {
+            $this->markTestSkipped('bypassDocumentValidation is not supported');
+        }
+
+        (new CommandObserver())->observe(
+            function () {
+                $operation = new Aggregate(
+                    $this->getDatabaseName(),
+                    $this->getCollectionName(),
+                    [['$match' => ['x' => 1]]],
+                    ['bypassDocumentValidation' => true]
+                );
+
+                $operation->execute($this->getPrimaryServer());
+            },
+            function (array $event) {
+                $this->assertObjectHasAttribute('bypassDocumentValidation', $event['started']->getCommand());
+                $this->assertEquals(true, $event['started']->getCommand()->bypassDocumentValidation);
+            }
+        );
+    }
+
+    public function testBypassDocumentValidationUnsetWhenFalse()
+    {
+        if (version_compare($this->getServerVersion(), '3.2.0', '<')) {
+            $this->markTestSkipped('bypassDocumentValidation is not supported');
+        }
+
+        (new CommandObserver())->observe(
+            function () {
+                $operation = new Aggregate(
+                    $this->getDatabaseName(),
+                    $this->getCollectionName(),
+                    [['$match' => ['x' => 1]]],
+                    ['bypassDocumentValidation' => false]
+                );
+
+                $operation->execute($this->getPrimaryServer());
+            },
+            function (array $event) {
+                $this->assertObjectNotHasAttribute('bypassDocumentValidation', $event['started']->getCommand());
+            }
+        );
+    }
+
+    public function provideTypeMapOptionsAndExpectedDocuments()
+    {
+        return [
+            [
+                null,
+                [
+                    (object) ['_id' => 1, 'x' => (object) ['foo' => 'bar']],
+                    (object) ['_id' => 3, 'x' => (object) ['foo' => 'bar']],
+                ],
+            ],
+            [
+                ['root' => 'array', 'document' => 'array'],
+                [
+                    ['_id' => 1, 'x' => ['foo' => 'bar']],
+                    ['_id' => 3, 'x' => ['foo' => 'bar']],
+                ],
+            ],
+            [
+                ['root' => 'object', 'document' => 'array'],
+                [
+                    (object) ['_id' => 1, 'x' => ['foo' => 'bar']],
+                    (object) ['_id' => 3, 'x' => ['foo' => 'bar']],
+                ],
+            ],
+            [
+                ['root' => 'array', 'document' => 'stdClass'],
+                [
+                    ['_id' => 1, 'x' => (object) ['foo' => 'bar']],
+                    ['_id' => 3, 'x' => (object) ['foo' => 'bar']],
+                ],
+            ],
+            [
+                ['root' => 'array', 'document' => 'stdClass', 'fieldPaths' => ['x' => 'array']],
+                [
+                    ['_id' => 1, 'x' => ['foo' => 'bar']],
+                    ['_id' => 3, 'x' => ['foo' => 'bar']],
+                ],
+            ],
+        ];
+    }
+
+    public function testReadPreferenceWithinTransaction()
+    {
+        $this->skipIfTransactionsAreNotSupported();
+
+        // Collection must be created before the transaction starts
+        $this->createCollection();
+
+        $session = $this->manager->startSession();
+        $session->startTransaction();
+
+        try {
+            $this->createFixtures(3, ['session' => $session]);
+
+            $pipeline = [['$match' => ['_id' => ['$lt' => 3]]]];
+            $options = [
+                'readPreference' => new ReadPreference('primary'),
+                'session' => $session,
+            ];
+
+            $operation = new Aggregate($this->getDatabaseName(), $this->getCollectionName(), $pipeline, $options);
+            $cursor = $operation->execute($this->getPrimaryServer());
+
+            $expected = [
+                ['_id' => 1, 'x' => ['foo' => 'bar']],
+                ['_id' => 2, 'x' => ['foo' => 'bar']],
+            ];
+
+            $this->assertSameDocuments($expected, $cursor);
+
+            $session->commitTransaction();
+        } finally {
+            $session->endSession();
+        }
+    }
+
+    /**
+     * Create data fixtures.
+     *
+     * @param integer $n
+     * @param array   $executeBulkWriteOptions
+     */
+    private function createFixtures($n, array $executeBulkWriteOptions = [])
+    {
+        $bulkWrite = new BulkWrite(['ordered' => true]);
+
+        for ($i = 1; $i <= $n; $i++) {
+            $bulkWrite->insert([
+                '_id' => $i,
+                'x' => (object) ['foo' => 'bar'],
+            ]);
+        }
+
+        $result = $this->manager->executeBulkWrite($this->getNamespace(), $bulkWrite, $executeBulkWriteOptions);
+
+        $this->assertEquals($n, $result->getInsertedCount());
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/AggregateTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/AggregateTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..d8898b3211fa0e37f9f03d2d6105a98ca7d25d62
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/AggregateTest.php	
@@ -0,0 +1,109 @@
+<?php
+
+namespace MongoDB\Tests\Operation;
+
+use MongoDB\Exception\InvalidArgumentException;
+use MongoDB\Operation\Aggregate;
+
+class AggregateTest extends TestCase
+{
+    public function testConstructorPipelineArgumentMustBeAList()
+    {
+        $this->expectException(InvalidArgumentException::class);
+        $this->expectExceptionMessage('$pipeline is not a list (unexpected index: "1")');
+        new Aggregate($this->getDatabaseName(), $this->getCollectionName(), [1 => ['$match' => ['x' => 1]]]);
+    }
+
+    /**
+     * @dataProvider provideInvalidConstructorOptions
+     */
+    public function testConstructorOptionTypeChecks(array $options)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        new Aggregate($this->getDatabaseName(), $this->getCollectionName(), [['$match' => ['x' => 1]]], $options);
+    }
+
+    public function provideInvalidConstructorOptions()
+    {
+        $options = [];
+
+        foreach ($this->getInvalidBooleanValues(true) as $value) {
+            $options[][] = ['allowDiskUse' => $value];
+        }
+
+        foreach ($this->getInvalidIntegerValues() as $value) {
+            $options[][] = ['batchSize' => $value];
+        }
+
+        foreach ($this->getInvalidBooleanValues() as $value) {
+            $options[][] = ['bypassDocumentValidation' => $value];
+        }
+
+        foreach ($this->getInvalidDocumentValues() as $value) {
+            $options[][] = ['collation' => $value];
+        }
+
+        foreach ($this->getInvalidStringValues() as $value) {
+            $options[][] = ['comment' => $value];
+        }
+
+        foreach ($this->getInvalidHintValues() as $value) {
+            $options[][] = ['hint' => $value];
+        }
+
+        foreach ($this->getInvalidBooleanValues() as $value) {
+            $options[][] = ['explain' => $value];
+        }
+
+        foreach ($this->getInvalidIntegerValues() as $value) {
+            $options[][] = ['maxAwaitTimeMS' => $value];
+        }
+
+        foreach ($this->getInvalidIntegerValues() as $value) {
+            $options[][] = ['maxTimeMS' => $value];
+        }
+
+        foreach ($this->getInvalidReadConcernValues() as $value) {
+            $options[][] = ['readConcern' => $value];
+        }
+
+        foreach ($this->getInvalidReadPreferenceValues() as $value) {
+            $options[][] = ['readPreference' => $value];
+        }
+
+        foreach ($this->getInvalidSessionValues() as $value) {
+            $options[][] = ['session' => $value];
+        }
+
+        foreach ($this->getInvalidArrayValues() as $value) {
+            $options[][] = ['typeMap' => $value];
+        }
+
+        foreach ($this->getInvalidBooleanValues(true) as $value) {
+            $options[][] = ['useCursor' => $value];
+        }
+
+        foreach ($this->getInvalidWriteConcernValues() as $value) {
+            $options[][] = ['writeConcern' => $value];
+        }
+
+        return $options;
+    }
+
+    public function testConstructorBatchSizeOptionRequiresUseCursor()
+    {
+        $this->expectException(InvalidArgumentException::class);
+        $this->expectExceptionMessage('"batchSize" option should not be used if "useCursor" is false');
+        new Aggregate(
+            $this->getDatabaseName(),
+            $this->getCollectionName(),
+            [['$match' => ['x' => 1]]],
+            ['batchSize' => 100, 'useCursor' => false]
+        );
+    }
+
+    private function getInvalidHintValues()
+    {
+        return [123, 3.14, true];
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/BulkWriteFunctionalTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/BulkWriteFunctionalTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..d2de54d5e1974ef176ea73387016fc373078c0be
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/BulkWriteFunctionalTest.php	
@@ -0,0 +1,348 @@
+<?php
+
+namespace MongoDB\Tests\Operation;
+
+use MongoDB\BSON\ObjectId;
+use MongoDB\BulkWriteResult;
+use MongoDB\Collection;
+use MongoDB\Driver\BulkWrite as Bulk;
+use MongoDB\Driver\WriteConcern;
+use MongoDB\Exception\BadMethodCallException;
+use MongoDB\Model\BSONDocument;
+use MongoDB\Operation\BulkWrite;
+use MongoDB\Tests\CommandObserver;
+use Symfony\Bridge\PhpUnit\SetUpTearDownTrait;
+use function version_compare;
+
+class BulkWriteFunctionalTest extends FunctionalTestCase
+{
+    use SetUpTearDownTrait;
+
+    /** @var Collection */
+    private $collection;
+
+    private function doSetUp()
+    {
+        parent::setUp();
+
+        $this->collection = new Collection($this->manager, $this->getDatabaseName(), $this->getCollectionName());
+    }
+
+    public function testInserts()
+    {
+        $ops = [
+            ['insertOne' => [['_id' => 1, 'x' => 11]]],
+            ['insertOne' => [['x' => 22]]],
+            ['insertOne' => [(object) ['_id' => 'foo', 'x' => 33]]],
+            ['insertOne' => [new BSONDocument(['_id' => 'bar', 'x' => 44])]],
+        ];
+
+        $operation = new BulkWrite($this->getDatabaseName(), $this->getCollectionName(), $ops);
+        $result = $operation->execute($this->getPrimaryServer());
+
+        $this->assertInstanceOf(BulkWriteResult::class, $result);
+        $this->assertSame(4, $result->getInsertedCount());
+
+        $insertedIds = $result->getInsertedIds();
+        $this->assertSame(1, $insertedIds[0]);
+        $this->assertInstanceOf(ObjectId::class, $insertedIds[1]);
+        $this->assertSame('foo', $insertedIds[2]);
+        $this->assertSame('bar', $insertedIds[3]);
+
+        $expected = [
+            ['_id' => 1, 'x' => 11],
+            ['_id' => $insertedIds[1], 'x' => 22],
+            ['_id' => 'foo', 'x' => 33],
+            ['_id' => 'bar', 'x' => 44],
+        ];
+
+        $this->assertSameDocuments($expected, $this->collection->find());
+    }
+
+    public function testUpdates()
+    {
+        $this->createFixtures(4);
+
+        $ops = [
+            ['updateOne' => [['_id' => 2], ['$inc' => ['x' => 1]]]],
+            ['updateMany' => [['_id' => ['$gt' => 2]], ['$inc' => ['x' => -1]]]],
+            ['updateOne' => [['_id' => 5], ['$set' => ['x' => 55]], ['upsert' => true]]],
+            ['updateOne' => [['x' => 66], ['$set' => ['x' => 66]], ['upsert' => true]]],
+            ['updateMany' => [['x' => ['$gt' => 50]], ['$inc' => ['x' => 1]]]],
+        ];
+
+        $operation = new BulkWrite($this->getDatabaseName(), $this->getCollectionName(), $ops);
+        $result = $operation->execute($this->getPrimaryServer());
+
+        $this->assertInstanceOf(BulkWriteResult::class, $result);
+        $this->assertSame(5, $result->getMatchedCount());
+        $this->assertSame(5, $result->getModifiedCount());
+        $this->assertSame(2, $result->getUpsertedCount());
+
+        $upsertedIds = $result->getUpsertedIds();
+        $this->assertSame(5, $upsertedIds[2]);
+        $this->assertInstanceOf(ObjectId::class, $upsertedIds[3]);
+
+        $expected = [
+            ['_id' => 1, 'x' => 11],
+            ['_id' => 2, 'x' => 23],
+            ['_id' => 3, 'x' => 32],
+            ['_id' => 4, 'x' => 43],
+            ['_id' => 5, 'x' => 56],
+            ['_id' => $upsertedIds[3], 'x' => 67],
+        ];
+
+        $this->assertSameDocuments($expected, $this->collection->find());
+    }
+
+    public function testDeletes()
+    {
+        $this->createFixtures(4);
+
+        $ops = [
+            ['deleteOne' => [['_id' => 1]]],
+            ['deleteMany' => [['_id' => ['$gt' => 2]]]],
+        ];
+
+        $operation = new BulkWrite($this->getDatabaseName(), $this->getCollectionName(), $ops);
+        $result = $operation->execute($this->getPrimaryServer());
+
+        $this->assertInstanceOf(BulkWriteResult::class, $result);
+        $this->assertSame(3, $result->getDeletedCount());
+
+        $expected = [
+            ['_id' => 2, 'x' => 22],
+        ];
+
+        $this->assertSameDocuments($expected, $this->collection->find());
+    }
+
+    public function testMixedOrderedOperations()
+    {
+        $this->createFixtures(3);
+
+        $ops = [
+            ['updateOne' => [['_id' => ['$gt' => 1]], ['$inc' => ['x' => 1]]]],
+            ['updateMany' => [['_id' => ['$gt' => 1]], ['$inc' => ['x' => 1]]]],
+            ['insertOne' => [['_id' => 4, 'x' => 44]]],
+            ['deleteMany' => [['x' => ['$nin' => [24, 34]]]]],
+            ['replaceOne' => [['_id' => 4], ['_id' => 4, 'x' => 44], ['upsert' => true]]],
+        ];
+
+        $operation = new BulkWrite($this->getDatabaseName(), $this->getCollectionName(), $ops);
+        $result = $operation->execute($this->getPrimaryServer());
+
+        $this->assertInstanceOf(BulkWriteResult::class, $result);
+
+        $this->assertSame(1, $result->getInsertedCount());
+        $this->assertSame([2 => 4], $result->getInsertedIds());
+
+        $this->assertSame(3, $result->getMatchedCount());
+        $this->assertSame(3, $result->getModifiedCount());
+        $this->assertSame(1, $result->getUpsertedCount());
+        $this->assertSame([4 => 4], $result->getUpsertedIds());
+
+        $this->assertSame(2, $result->getDeletedCount());
+
+        $expected = [
+            ['_id' => 2, 'x' => 24],
+            ['_id' => 3, 'x' => 34],
+            ['_id' => 4, 'x' => 44],
+        ];
+
+        $this->assertSameDocuments($expected, $this->collection->find());
+    }
+
+    public function testUnacknowledgedWriteConcern()
+    {
+        $ops = [['insertOne' => [['_id' => 1]]]];
+        $options = ['writeConcern' => new WriteConcern(0)];
+        $operation = new BulkWrite($this->getDatabaseName(), $this->getCollectionName(), $ops, $options);
+        $result = $operation->execute($this->getPrimaryServer());
+
+        $this->assertFalse($result->isAcknowledged());
+
+        return $result;
+    }
+
+    /**
+     * @depends testUnacknowledgedWriteConcern
+     */
+    public function testUnacknowledgedWriteConcernAccessesDeletedCount(BulkWriteResult $result)
+    {
+        $this->expectException(BadMethodCallException::class);
+        $this->expectExceptionMessageMatches('/[\w:\\\\]+ should not be called for an unacknowledged write result/');
+        $result->getDeletedCount();
+    }
+
+    /**
+     * @depends testUnacknowledgedWriteConcern
+     */
+    public function testUnacknowledgedWriteConcernAccessesInsertCount(BulkWriteResult $result)
+    {
+        $this->expectException(BadMethodCallException::class);
+        $this->expectExceptionMessageMatches('/[\w:\\\\]+ should not be called for an unacknowledged write result/');
+        $result->getInsertedCount();
+    }
+
+    /**
+     * @depends testUnacknowledgedWriteConcern
+     */
+    public function testUnacknowledgedWriteConcernAccessesMatchedCount(BulkWriteResult $result)
+    {
+        $this->expectException(BadMethodCallException::class);
+        $this->expectExceptionMessageMatches('/[\w:\\\\]+ should not be called for an unacknowledged write result/');
+        $result->getMatchedCount();
+    }
+
+    /**
+     * @depends testUnacknowledgedWriteConcern
+     */
+    public function testUnacknowledgedWriteConcernAccessesModifiedCount(BulkWriteResult $result)
+    {
+        $this->expectException(BadMethodCallException::class);
+        $this->expectExceptionMessageMatches('/[\w:\\\\]+ should not be called for an unacknowledged write result/');
+        $result->getModifiedCount();
+    }
+
+    /**
+     * @depends testUnacknowledgedWriteConcern
+     */
+    public function testUnacknowledgedWriteConcernAccessesUpsertedCount(BulkWriteResult $result)
+    {
+        $this->expectException(BadMethodCallException::class);
+        $this->expectExceptionMessageMatches('/[\w:\\\\]+ should not be called for an unacknowledged write result/');
+        $result->getUpsertedCount();
+    }
+
+    /**
+     * @depends testUnacknowledgedWriteConcern
+     */
+    public function testUnacknowledgedWriteConcernAccessesUpsertedIds(BulkWriteResult $result)
+    {
+        $this->expectException(BadMethodCallException::class);
+        $this->expectExceptionMessageMatches('/[\w:\\\\]+ should not be called for an unacknowledged write result/');
+        $result->getUpsertedIds();
+    }
+
+    public function testSessionOption()
+    {
+        if (version_compare($this->getServerVersion(), '3.6.0', '<')) {
+            $this->markTestSkipped('Sessions are not supported');
+        }
+
+        (new CommandObserver())->observe(
+            function () {
+                $operation = new BulkWrite(
+                    $this->getDatabaseName(),
+                    $this->getCollectionName(),
+                    [['insertOne' => [['_id' => 1]]]],
+                    ['session' => $this->createSession()]
+                );
+
+                $operation->execute($this->getPrimaryServer());
+            },
+            function (array $event) {
+                $this->assertObjectHasAttribute('lsid', $event['started']->getCommand());
+            }
+        );
+    }
+
+    public function testBypassDocumentValidationSetWhenTrue()
+    {
+        if (version_compare($this->getServerVersion(), '3.2.0', '<')) {
+            $this->markTestSkipped('bypassDocumentValidation is not supported');
+        }
+
+        (new CommandObserver())->observe(
+            function () {
+                $operation = new BulkWrite(
+                    $this->getDatabaseName(),
+                    $this->getCollectionName(),
+                    [['insertOne' => [['_id' => 1]]]],
+                    ['bypassDocumentValidation' => true]
+                );
+
+                $operation->execute($this->getPrimaryServer());
+            },
+            function (array $event) {
+                $this->assertObjectHasAttribute('bypassDocumentValidation', $event['started']->getCommand());
+                $this->assertEquals(true, $event['started']->getCommand()->bypassDocumentValidation);
+            }
+        );
+    }
+
+    public function testBypassDocumentValidationUnsetWhenFalse()
+    {
+        if (version_compare($this->getServerVersion(), '3.2.0', '<')) {
+            $this->markTestSkipped('bypassDocumentValidation is not supported');
+        }
+
+        (new CommandObserver())->observe(
+            function () {
+                $operation = new BulkWrite(
+                    $this->getDatabaseName(),
+                    $this->getCollectionName(),
+                    [['insertOne' => [['_id' => 1]]]],
+                    ['bypassDocumentValidation' => false]
+                );
+
+                $operation->execute($this->getPrimaryServer());
+            },
+            function (array $event) {
+                $this->assertObjectNotHasAttribute('bypassDocumentValidation', $event['started']->getCommand());
+            }
+        );
+    }
+
+    public function testBulkWriteWithPipelineUpdates()
+    {
+        if (version_compare($this->getServerVersion(), '4.2.0', '<')) {
+            $this->markTestSkipped('Pipeline-style updates are not supported');
+        }
+
+        $this->createFixtures(4);
+
+        $ops = [
+            ['updateOne' => [['_id' => 2], [['$addFields' => ['y' => 2]]]]],
+            ['updateMany' => [['_id' => ['$gt' => 2]], [['$addFields' => ['y' => '$_id']]]]],
+        ];
+
+        $operation = new BulkWrite($this->getDatabaseName(), $this->getCollectionName(), $ops);
+        $result = $operation->execute($this->getPrimaryServer());
+
+        $this->assertInstanceOf(BulkWriteResult::class, $result);
+        $this->assertSame(3, $result->getMatchedCount());
+        $this->assertSame(3, $result->getModifiedCount());
+
+        $expected = [
+            ['_id' => 1, 'x' => 11],
+            ['_id' => 2, 'x' => 22, 'y' => 2],
+            ['_id' => 3, 'x' => 33, 'y' => 3],
+            ['_id' => 4, 'x' => 44, 'y' => 4],
+        ];
+
+        $this->assertSameDocuments($expected, $this->collection->find());
+    }
+
+    /**
+     * Create data fixtures.
+     *
+     * @param integer $n
+     */
+    private function createFixtures($n)
+    {
+        $bulkWrite = new Bulk(['ordered' => true]);
+
+        for ($i = 1; $i <= $n; $i++) {
+            $bulkWrite->insert([
+                '_id' => $i,
+                'x' => (integer) ($i . $i),
+            ]);
+        }
+
+        $result = $this->manager->executeBulkWrite($this->getNamespace(), $bulkWrite);
+
+        $this->assertEquals($n, $result->getInsertedCount());
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/BulkWriteTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/BulkWriteTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..7beb01f4d440b339567e0cd8073c4f0241a4cb41
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/BulkWriteTest.php	
@@ -0,0 +1,429 @@
+<?php
+
+namespace MongoDB\Tests\Operation;
+
+use MongoDB\Exception\InvalidArgumentException;
+use MongoDB\Operation\BulkWrite;
+
+class BulkWriteTest extends TestCase
+{
+    public function testOperationsMustNotBeEmpty()
+    {
+        $this->expectException(InvalidArgumentException::class);
+        $this->expectExceptionMessage('$operations is empty');
+        new BulkWrite($this->getDatabaseName(), $this->getCollectionName(), []);
+    }
+
+    public function testOperationsMustBeAList()
+    {
+        $this->expectException(InvalidArgumentException::class);
+        $this->expectExceptionMessage('$operations is not a list (unexpected index: "1")');
+        new BulkWrite($this->getDatabaseName(), $this->getCollectionName(), [
+            1 => [BulkWrite::INSERT_ONE => [['x' => 1]]],
+        ]);
+    }
+
+    public function testMultipleOperationsInOneElement()
+    {
+        $this->expectException(InvalidArgumentException::class);
+        $this->expectExceptionMessage('Expected one element in $operation[0], actually: 2');
+        new BulkWrite($this->getDatabaseName(), $this->getCollectionName(), [
+            [
+                BulkWrite::INSERT_ONE => [['x' => 1]],
+                BulkWrite::DELETE_ONE => [['x' => 1]],
+            ],
+        ]);
+    }
+
+    public function testUnknownOperation()
+    {
+        $this->expectException(InvalidArgumentException::class);
+        $this->expectExceptionMessage('Unknown operation type "foo" in $operations[0]');
+        new BulkWrite($this->getDatabaseName(), $this->getCollectionName(), [
+            ['foo' => [['_id' => 1]]],
+        ]);
+    }
+
+    public function testInsertOneDocumentArgumentMissing()
+    {
+        $this->expectException(InvalidArgumentException::class);
+        $this->expectExceptionMessage('Missing first argument for $operations[0]["insertOne"]');
+        new BulkWrite($this->getDatabaseName(), $this->getCollectionName(), [
+            [BulkWrite::INSERT_ONE => []],
+        ]);
+    }
+
+    /**
+     * @dataProvider provideInvalidDocumentValues
+     */
+    public function testInsertOneDocumentArgumentTypeCheck($document)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        $this->expectExceptionMessageMatches('/Expected \$operations\[0\]\["insertOne"\]\[0\] to have type "array or object" but found "[\w ]+"/');
+        new BulkWrite($this->getDatabaseName(), $this->getCollectionName(), [
+            [BulkWrite::INSERT_ONE => [$document]],
+        ]);
+    }
+
+    public function testDeleteManyFilterArgumentMissing()
+    {
+        $this->expectException(InvalidArgumentException::class);
+        $this->expectExceptionMessage('Missing first argument for $operations[0]["deleteMany"]');
+        new BulkWrite($this->getDatabaseName(), $this->getCollectionName(), [
+            [BulkWrite::DELETE_MANY => []],
+        ]);
+    }
+
+    /**
+     * @dataProvider provideInvalidDocumentValues
+     */
+    public function testDeleteManyFilterArgumentTypeCheck($document)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        $this->expectExceptionMessageMatches('/Expected \$operations\[0\]\["deleteMany"\]\[0\] to have type "array or object" but found "[\w ]+"/');
+        new BulkWrite($this->getDatabaseName(), $this->getCollectionName(), [
+            [BulkWrite::DELETE_MANY => [$document]],
+        ]);
+    }
+
+    /**
+     * @dataProvider provideInvalidDocumentValues
+     */
+    public function testDeleteManyCollationOptionTypeCheck($collation)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        $this->expectExceptionMessageMatches('/Expected \$operations\[0\]\["deleteMany"\]\[1\]\["collation"\] to have type "array or object" but found "[\w ]+"/');
+        new BulkWrite($this->getDatabaseName(), $this->getCollectionName(), [
+            [BulkWrite::DELETE_MANY => [['x' => 1], ['collation' => $collation]]],
+        ]);
+    }
+
+    public function provideInvalidDocumentValues()
+    {
+        return $this->wrapValuesForDataProvider($this->getInvalidDocumentValues());
+    }
+
+    public function testDeleteOneFilterArgumentMissing()
+    {
+        $this->expectException(InvalidArgumentException::class);
+        $this->expectExceptionMessage('Missing first argument for $operations[0]["deleteOne"]');
+        new BulkWrite($this->getDatabaseName(), $this->getCollectionName(), [
+            [BulkWrite::DELETE_ONE => []],
+        ]);
+    }
+
+    /**
+     * @dataProvider provideInvalidDocumentValues
+     */
+    public function testDeleteOneFilterArgumentTypeCheck($document)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        $this->expectExceptionMessageMatches('/Expected \$operations\[0\]\["deleteOne"\]\[0\] to have type "array or object" but found "[\w ]+"/');
+        new BulkWrite($this->getDatabaseName(), $this->getCollectionName(), [
+            [BulkWrite::DELETE_ONE => [$document]],
+        ]);
+    }
+
+    /**
+     * @dataProvider provideInvalidDocumentValues
+     */
+    public function testDeleteOneCollationOptionTypeCheck($collation)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        $this->expectExceptionMessageMatches('/Expected \$operations\[0\]\["deleteOne"\]\[1\]\["collation"\] to have type "array or object" but found "[\w ]+"/');
+        new BulkWrite($this->getDatabaseName(), $this->getCollectionName(), [
+            [BulkWrite::DELETE_ONE => [['x' => 1], ['collation' => $collation]]],
+        ]);
+    }
+
+    public function testReplaceOneFilterArgumentMissing()
+    {
+        $this->expectException(InvalidArgumentException::class);
+        $this->expectExceptionMessage('Missing first argument for $operations[0]["replaceOne"]');
+        new BulkWrite($this->getDatabaseName(), $this->getCollectionName(), [
+            [BulkWrite::REPLACE_ONE => []],
+        ]);
+    }
+
+    /**
+     * @dataProvider provideInvalidDocumentValues
+     */
+    public function testReplaceOneFilterArgumentTypeCheck($filter)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        $this->expectExceptionMessageMatches('/Expected \$operations\[0\]\["replaceOne"\]\[0\] to have type "array or object" but found "[\w ]+"/');
+        new BulkWrite($this->getDatabaseName(), $this->getCollectionName(), [
+            [BulkWrite::REPLACE_ONE => [$filter, ['y' => 1]]],
+        ]);
+    }
+
+    public function testReplaceOneReplacementArgumentMissing()
+    {
+        $this->expectException(InvalidArgumentException::class);
+        $this->expectExceptionMessage('Missing second argument for $operations[0]["replaceOne"]');
+        new BulkWrite($this->getDatabaseName(), $this->getCollectionName(), [
+            [BulkWrite::REPLACE_ONE => [['x' => 1]]],
+        ]);
+    }
+
+    /**
+     * @dataProvider provideInvalidDocumentValues
+     */
+    public function testReplaceOneReplacementArgumentTypeCheck($replacement)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        $this->expectExceptionMessageMatches('/Expected \$operations\[0\]\["replaceOne"\]\[1\] to have type "array or object" but found "[\w ]+"/');
+        new BulkWrite($this->getDatabaseName(), $this->getCollectionName(), [
+            [BulkWrite::REPLACE_ONE => [['x' => 1], $replacement]],
+        ]);
+    }
+
+    public function testReplaceOneReplacementArgumentRequiresNoOperators()
+    {
+        $this->expectException(InvalidArgumentException::class);
+        $this->expectExceptionMessage('First key in $operations[0]["replaceOne"][1] is an update operator');
+        new BulkWrite($this->getDatabaseName(), $this->getCollectionName(), [
+            [BulkWrite::REPLACE_ONE => [['_id' => 1], ['$inc' => ['x' => 1]]]],
+        ]);
+    }
+
+    /**
+     * @dataProvider provideInvalidDocumentValues
+     */
+    public function testReplaceOneCollationOptionTypeCheck($collation)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        $this->expectExceptionMessageMatches('/Expected \$operations\[0\]\["replaceOne"\]\[2\]\["collation"\] to have type "array or object" but found "[\w ]+"/');
+        new BulkWrite($this->getDatabaseName(), $this->getCollectionName(), [
+            [BulkWrite::REPLACE_ONE => [['x' => 1], ['y' => 1], ['collation' => $collation]]],
+        ]);
+    }
+
+    /**
+     * @dataProvider provideInvalidBooleanValues
+     */
+    public function testReplaceOneUpsertOptionTypeCheck($upsert)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        $this->expectExceptionMessageMatches('/Expected \$operations\[0\]\["replaceOne"\]\[2\]\["upsert"\] to have type "boolean" but found "[\w ]+"/');
+        new BulkWrite($this->getDatabaseName(), $this->getCollectionName(), [
+            [BulkWrite::REPLACE_ONE => [['x' => 1], ['y' => 1], ['upsert' => $upsert]]],
+        ]);
+    }
+
+    public function provideInvalidBooleanValues()
+    {
+        return $this->wrapValuesForDataProvider($this->getInvalidBooleanValues());
+    }
+
+    public function testUpdateManyFilterArgumentMissing()
+    {
+        $this->expectException(InvalidArgumentException::class);
+        $this->expectExceptionMessage('Missing first argument for $operations[0]["updateMany"]');
+        new BulkWrite($this->getDatabaseName(), $this->getCollectionName(), [
+            [BulkWrite::UPDATE_MANY => []],
+        ]);
+    }
+
+    /**
+     * @dataProvider provideInvalidDocumentValues
+     */
+    public function testUpdateManyFilterArgumentTypeCheck($filter)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        $this->expectExceptionMessageMatches('/Expected \$operations\[0\]\["updateMany"\]\[0\] to have type "array or object" but found "[\w ]+"/');
+        new BulkWrite($this->getDatabaseName(), $this->getCollectionName(), [
+            [BulkWrite::UPDATE_MANY => [$filter, ['$set' => ['x' => 1]]]],
+        ]);
+    }
+
+    public function testUpdateManyUpdateArgumentMissing()
+    {
+        $this->expectException(InvalidArgumentException::class);
+        $this->expectExceptionMessage('Missing second argument for $operations[0]["updateMany"]');
+        new BulkWrite($this->getDatabaseName(), $this->getCollectionName(), [
+            [BulkWrite::UPDATE_MANY => [['x' => 1]]],
+        ]);
+    }
+
+    /**
+     * @dataProvider provideInvalidDocumentValues
+     */
+    public function testUpdateManyUpdateArgumentTypeCheck($update)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        $this->expectExceptionMessageMatches('/Expected \$operations\[0\]\["updateMany"\]\[1\] to have type "array or object" but found "[\w ]+"/');
+        new BulkWrite($this->getDatabaseName(), $this->getCollectionName(), [
+            [BulkWrite::UPDATE_MANY => [['x' => 1], $update]],
+        ]);
+    }
+
+    public function testUpdateManyUpdateArgumentRequiresOperatorsOrPipeline()
+    {
+        $this->expectException(InvalidArgumentException::class);
+        $this->expectExceptionMessage('First key in $operations[0]["updateMany"][1] is neither an update operator nor a pipeline');
+        new BulkWrite($this->getDatabaseName(), $this->getCollectionName(), [
+            [BulkWrite::UPDATE_MANY => [['_id' => ['$gt' => 1]], ['x' => 1]]],
+        ]);
+    }
+
+    /**
+     * @dataProvider provideInvalidArrayValues
+     */
+    public function testUpdateManyArrayFiltersOptionTypeCheck($arrayFilters)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        $this->expectExceptionMessageMatches('/Expected \$operations\[0\]\["updateMany"\]\[2\]\["arrayFilters"\] to have type "array" but found "[\w ]+"/');
+        new BulkWrite($this->getDatabaseName(), $this->getCollectionName(), [
+            [BulkWrite::UPDATE_MANY => [['x' => 1], ['$set' => ['x' => 1]], ['arrayFilters' => $arrayFilters]]],
+        ]);
+    }
+
+    /**
+     * @dataProvider provideInvalidDocumentValues
+     */
+    public function testUpdateManyCollationOptionTypeCheck($collation)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        $this->expectExceptionMessageMatches('/Expected \$operations\[0\]\["updateMany"\]\[2\]\["collation"\] to have type "array or object" but found "[\w ]+"/');
+        new BulkWrite($this->getDatabaseName(), $this->getCollectionName(), [
+            [BulkWrite::UPDATE_MANY => [['x' => 1], ['$set' => ['x' => 1]], ['collation' => $collation]]],
+        ]);
+    }
+
+    /**
+     * @dataProvider provideInvalidBooleanValues
+     */
+    public function testUpdateManyUpsertOptionTypeCheck($upsert)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        $this->expectExceptionMessageMatches('/Expected \$operations\[0\]\["updateMany"\]\[2\]\["upsert"\] to have type "boolean" but found "[\w ]+"/');
+        new BulkWrite($this->getDatabaseName(), $this->getCollectionName(), [
+            [BulkWrite::UPDATE_MANY => [['x' => 1], ['$set' => ['x' => 1]], ['upsert' => $upsert]]],
+        ]);
+    }
+
+    public function testUpdateOneFilterArgumentMissing()
+    {
+        $this->expectException(InvalidArgumentException::class);
+        $this->expectExceptionMessage('Missing first argument for $operations[0]["updateOne"]');
+        new BulkWrite($this->getDatabaseName(), $this->getCollectionName(), [
+            [BulkWrite::UPDATE_ONE => []],
+        ]);
+    }
+
+    /**
+     * @dataProvider provideInvalidDocumentValues
+     */
+    public function testUpdateOneFilterArgumentTypeCheck($filter)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        $this->expectExceptionMessageMatches('/Expected \$operations\[0\]\["updateOne"\]\[0\] to have type "array or object" but found "[\w ]+"/');
+        new BulkWrite($this->getDatabaseName(), $this->getCollectionName(), [
+            [BulkWrite::UPDATE_ONE => [$filter, ['$set' => ['x' => 1]]]],
+        ]);
+    }
+
+    public function testUpdateOneUpdateArgumentMissing()
+    {
+        $this->expectException(InvalidArgumentException::class);
+        $this->expectExceptionMessage('Missing second argument for $operations[0]["updateOne"]');
+        new BulkWrite($this->getDatabaseName(), $this->getCollectionName(), [
+            [BulkWrite::UPDATE_ONE => [['x' => 1]]],
+        ]);
+    }
+
+    /**
+     * @dataProvider provideInvalidDocumentValues
+     */
+    public function testUpdateOneUpdateArgumentTypeCheck($update)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        $this->expectExceptionMessageMatches('/Expected \$operations\[0\]\["updateOne"\]\[1\] to have type "array or object" but found "[\w ]+"/');
+        new BulkWrite($this->getDatabaseName(), $this->getCollectionName(), [
+            [BulkWrite::UPDATE_ONE => [['x' => 1], $update]],
+        ]);
+    }
+
+    public function testUpdateOneUpdateArgumentRequiresOperatorsOrPipeline()
+    {
+        $this->expectException(InvalidArgumentException::class);
+        $this->expectExceptionMessage('First key in $operations[0]["updateOne"][1] is neither an update operator nor a pipeline');
+        new BulkWrite($this->getDatabaseName(), $this->getCollectionName(), [
+            [BulkWrite::UPDATE_ONE => [['_id' => 1], ['x' => 1]]],
+        ]);
+    }
+
+    /**
+     * @dataProvider provideInvalidArrayValues
+     */
+    public function testUpdateOneArrayFiltersOptionTypeCheck($arrayFilters)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        $this->expectExceptionMessageMatches('/Expected \$operations\[0\]\["updateOne"\]\[2\]\["arrayFilters"\] to have type "array" but found "[\w ]+"/');
+        new BulkWrite($this->getDatabaseName(), $this->getCollectionName(), [
+            [BulkWrite::UPDATE_ONE => [['x' => 1], ['$set' => ['x' => 1]], ['arrayFilters' => $arrayFilters]]],
+        ]);
+    }
+
+    /**
+     * @dataProvider provideInvalidDocumentValues
+     */
+    public function testUpdateOneCollationOptionTypeCheck($collation)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        $this->expectExceptionMessageMatches('/Expected \$operations\[0\]\["updateOne"\]\[2\]\["collation"\] to have type "array or object" but found "[\w ]+"/');
+        new BulkWrite($this->getDatabaseName(), $this->getCollectionName(), [
+            [BulkWrite::UPDATE_ONE => [['x' => 1], ['$set' => ['x' => 1]], ['collation' => $collation]]],
+        ]);
+    }
+
+    /**
+     * @dataProvider provideInvalidBooleanValues
+     */
+    public function testUpdateOneUpsertOptionTypeCheck($upsert)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        $this->expectExceptionMessageMatches('/Expected \$operations\[0\]\["updateOne"\]\[2\]\["upsert"\] to have type "boolean" but found "[\w ]+"/');
+        new BulkWrite($this->getDatabaseName(), $this->getCollectionName(), [
+            [BulkWrite::UPDATE_ONE => [['x' => 1], ['$set' => ['x' => 1]], ['upsert' => $upsert]]],
+        ]);
+    }
+
+    /**
+     * @dataProvider provideInvalidConstructorOptions
+     */
+    public function testConstructorOptionTypeChecks(array $options)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        new BulkWrite(
+            $this->getDatabaseName(),
+            $this->getCollectionName(),
+            [[BulkWrite::INSERT_ONE => [['x' => 1]]]],
+            $options
+        );
+    }
+
+    public function provideInvalidConstructorOptions()
+    {
+        $options = [];
+
+        foreach ($this->getInvalidBooleanValues() as $value) {
+            $options[][] = ['bypassDocumentValidation' => $value];
+        }
+
+        foreach ($this->getInvalidBooleanValues(true) as $value) {
+            $options[][] = ['ordered' => $value];
+        }
+
+        foreach ($this->getInvalidSessionValues() as $value) {
+            $options[][] = ['session' => $value];
+        }
+
+        foreach ($this->getInvalidWriteConcernValues() as $value) {
+            $options[][] = ['writeConcern' => $value];
+        }
+
+        return $options;
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/CountDocumentsFunctionalTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/CountDocumentsFunctionalTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..23bba406c0106280b21c365b7fa0993aa8b67b55
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/CountDocumentsFunctionalTest.php	
@@ -0,0 +1,29 @@
+<?php
+
+namespace MongoDB\Tests\Operation;
+
+use MongoDB\Operation\CountDocuments;
+use MongoDB\Operation\InsertMany;
+
+class CountDocumentsFunctionalTest extends FunctionalTestCase
+{
+    public function testEmptyCollection()
+    {
+        $operation = new CountDocuments($this->getDatabaseName(), $this->getCollectionName(), []);
+        $this->assertSame(0, $operation->execute($this->getPrimaryServer()));
+    }
+
+    public function testNonEmptyCollection()
+    {
+        $insertMany = new InsertMany($this->getDatabaseName(), $this->getCollectionName(), [
+            ['x' => 1],
+            ['x' => 2],
+            ['y' => 3],
+            ['z' => 4],
+        ]);
+        $insertMany->execute($this->getPrimaryServer());
+
+        $operation = new CountDocuments($this->getDatabaseName(), $this->getCollectionName(), []);
+        $this->assertSame(4, $operation->execute($this->getPrimaryServer()));
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/CountDocumentsTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/CountDocumentsTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..55fe0bfb87d63fc8f720c4bb1fd4f65eb12ff4d0
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/CountDocumentsTest.php	
@@ -0,0 +1,71 @@
+<?php
+
+namespace MongoDB\Tests\Operation;
+
+use MongoDB\Exception\InvalidArgumentException;
+use MongoDB\Operation\CountDocuments;
+
+class CountDocumentsTest extends TestCase
+{
+    /**
+     * @dataProvider provideInvalidDocumentValues
+     */
+    public function testConstructorFilterArgumentTypeCheck($filter)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        new CountDocuments($this->getDatabaseName(), $this->getCollectionName(), $filter);
+    }
+
+    /**
+     * @dataProvider provideInvalidConstructorOptions
+     */
+    public function testConstructorOptionTypeChecks(array $options)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        new CountDocuments($this->getDatabaseName(), $this->getCollectionName(), [], $options);
+    }
+
+    public function provideInvalidConstructorOptions()
+    {
+        $options = [];
+
+        foreach ($this->getInvalidDocumentValues() as $value) {
+            $options[][] = ['collation' => $value];
+        }
+
+        foreach ($this->getInvalidHintValues() as $value) {
+            $options[][] = ['hint' => $value];
+        }
+
+        foreach ($this->getInvalidIntegerValues() as $value) {
+            $options[][] = ['limit' => $value];
+        }
+
+        foreach ($this->getInvalidIntegerValues() as $value) {
+            $options[][] = ['maxTimeMS' => $value];
+        }
+
+        foreach ($this->getInvalidReadConcernValues() as $value) {
+            $options[][] = ['readConcern' => $value];
+        }
+
+        foreach ($this->getInvalidReadPreferenceValues() as $value) {
+            $options[][] = ['readPreference' => $value];
+        }
+
+        foreach ($this->getInvalidSessionValues() as $value) {
+            $options[][] = ['session' => $value];
+        }
+
+        foreach ($this->getInvalidIntegerValues() as $value) {
+            $options[][] = ['skip' => $value];
+        }
+
+        return $options;
+    }
+
+    private function getInvalidHintValues()
+    {
+        return [123, 3.14, true];
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/CountFunctionalTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/CountFunctionalTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..245cfdd2e4727b608ae5daa535f2de995bae2cc0
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/CountFunctionalTest.php	
@@ -0,0 +1,95 @@
+<?php
+
+namespace MongoDB\Tests\Operation;
+
+use MongoDB\Operation\Count;
+use MongoDB\Operation\CreateIndexes;
+use MongoDB\Operation\InsertMany;
+use MongoDB\Tests\CommandObserver;
+use function version_compare;
+
+class CountFunctionalTest extends FunctionalTestCase
+{
+    public function testDefaultReadConcernIsOmitted()
+    {
+        (new CommandObserver())->observe(
+            function () {
+                $operation = new Count(
+                    $this->getDatabaseName(),
+                    $this->getCollectionName(),
+                    [],
+                    ['readConcern' => $this->createDefaultReadConcern()]
+                );
+
+                $operation->execute($this->getPrimaryServer());
+            },
+            function (array $event) {
+                $this->assertObjectNotHasAttribute('readConcern', $event['started']->getCommand());
+            }
+        );
+    }
+
+    public function testHintOption()
+    {
+        $insertMany = new InsertMany($this->getDatabaseName(), $this->getCollectionName(), [
+            ['x' => 1],
+            ['x' => 2],
+            ['y' => 3],
+        ]);
+        $insertMany->execute($this->getPrimaryServer());
+
+        $createIndexes = new CreateIndexes($this->getDatabaseName(), $this->getCollectionName(), [
+            ['key' => ['x' => 1], 'sparse' => true, 'name' => 'sparse_x'],
+            ['key' => ['y' => 1]],
+        ]);
+        $createIndexes->execute($this->getPrimaryServer());
+
+        $hintsUsingSparseIndex = [
+            ['x' => 1],
+            'sparse_x',
+        ];
+
+        /* Per SERVER-22041, the count command in server versions before 3.3.2
+         * may ignore the hint option if its query predicate is empty. */
+        $filter = ['_id' => ['$exists' => true]];
+
+        foreach ($hintsUsingSparseIndex as $hint) {
+            $operation = new Count($this->getDatabaseName(), $this->getCollectionName(), $filter, ['hint' => $hint]);
+            $this->assertSame(2, $operation->execute($this->getPrimaryServer()));
+        }
+
+        $hintsNotUsingSparseIndex = [
+            ['_id' => 1],
+            ['y' => 1],
+            'y_1',
+        ];
+
+        foreach ($hintsNotUsingSparseIndex as $hint) {
+            $operation = new Count($this->getDatabaseName(), $this->getCollectionName(), $filter, ['hint' => $hint]);
+            $this->assertSame(3, $operation->execute($this->getPrimaryServer()));
+        }
+    }
+
+    public function testSessionOption()
+    {
+        if (version_compare($this->getServerVersion(), '3.6.0', '<')) {
+            $this->markTestSkipped('Sessions are not supported');
+        }
+
+        (new CommandObserver())->observe(
+            function () {
+                $operation = new Count(
+                    $this->getDatabaseName(),
+                    $this->getCollectionName(),
+                    [],
+                    ['session' => $this->createSession()]
+                );
+
+                $operation->execute($this->getPrimaryServer());
+            },
+            function (array $event) {
+                $this->assertObjectHasAttribute('lsid', $event['started']->getCommand());
+            }
+        );
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/CountTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/CountTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..06be7d4e3ec2113fdacee93f7180efbf76ad5768
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/CountTest.php	
@@ -0,0 +1,71 @@
+<?php
+
+namespace MongoDB\Tests\Operation;
+
+use MongoDB\Exception\InvalidArgumentException;
+use MongoDB\Operation\Count;
+
+class CountTest extends TestCase
+{
+    /**
+     * @dataProvider provideInvalidDocumentValues
+     */
+    public function testConstructorFilterArgumentTypeCheck($filter)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        new Count($this->getDatabaseName(), $this->getCollectionName(), $filter);
+    }
+
+    /**
+     * @dataProvider provideInvalidConstructorOptions
+     */
+    public function testConstructorOptionTypeChecks(array $options)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        new Count($this->getDatabaseName(), $this->getCollectionName(), [], $options);
+    }
+
+    public function provideInvalidConstructorOptions()
+    {
+        $options = [];
+
+        foreach ($this->getInvalidDocumentValues() as $value) {
+            $options[][] = ['collation' => $value];
+        }
+
+        foreach ($this->getInvalidHintValues() as $value) {
+            $options[][] = ['hint' => $value];
+        }
+
+        foreach ($this->getInvalidIntegerValues() as $value) {
+            $options[][] = ['limit' => $value];
+        }
+
+        foreach ($this->getInvalidIntegerValues() as $value) {
+            $options[][] = ['maxTimeMS' => $value];
+        }
+
+        foreach ($this->getInvalidReadConcernValues() as $value) {
+            $options[][] = ['readConcern' => $value];
+        }
+
+        foreach ($this->getInvalidReadPreferenceValues() as $value) {
+            $options[][] = ['readPreference' => $value];
+        }
+
+        foreach ($this->getInvalidSessionValues() as $value) {
+            $options[][] = ['session' => $value];
+        }
+
+        foreach ($this->getInvalidIntegerValues() as $value) {
+            $options[][] = ['skip' => $value];
+        }
+
+        return $options;
+    }
+
+    private function getInvalidHintValues()
+    {
+        return [123, 3.14, true];
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/CreateCollectionFunctionalTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/CreateCollectionFunctionalTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..6874ed7367e64965100d00d4c7ee5a677eb4dcd5
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/CreateCollectionFunctionalTest.php	
@@ -0,0 +1,50 @@
+<?php
+
+namespace MongoDB\Tests\Operation;
+
+use MongoDB\Operation\CreateCollection;
+use MongoDB\Tests\CommandObserver;
+use function version_compare;
+
+class CreateCollectionFunctionalTest extends FunctionalTestCase
+{
+    public function testDefaultWriteConcernIsOmitted()
+    {
+        (new CommandObserver())->observe(
+            function () {
+                $operation = new CreateCollection(
+                    $this->getDatabaseName(),
+                    $this->getCollectionName(),
+                    ['writeConcern' => $this->createDefaultWriteConcern()]
+                );
+
+                $operation->execute($this->getPrimaryServer());
+            },
+            function (array $event) {
+                $this->assertObjectNotHasAttribute('writeConcern', $event['started']->getCommand());
+            }
+        );
+    }
+
+    public function testSessionOption()
+    {
+        if (version_compare($this->getServerVersion(), '3.6.0', '<')) {
+            $this->markTestSkipped('Sessions are not supported');
+        }
+
+        (new CommandObserver())->observe(
+            function () {
+                $operation = new CreateCollection(
+                    $this->getDatabaseName(),
+                    $this->getCollectionName(),
+                    ['session' => $this->createSession()]
+                );
+
+                $operation->execute($this->getPrimaryServer());
+            },
+            function (array $event) {
+                $this->assertObjectHasAttribute('lsid', $event['started']->getCommand());
+            }
+        );
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/CreateCollectionTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/CreateCollectionTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..da158eed500fa10610d45670c8986568682889b5
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/CreateCollectionTest.php	
@@ -0,0 +1,96 @@
+<?php
+
+namespace MongoDB\Tests\Operation;
+
+use MongoDB\Exception\InvalidArgumentException;
+use MongoDB\Operation\CreateCollection;
+
+class CreateCollectionTest extends TestCase
+{
+    /**
+     * @dataProvider provideInvalidConstructorOptions
+     */
+    public function testConstructorOptionTypeChecks(array $options)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        new CreateCollection($this->getDatabaseName(), $this->getCollectionName(), $options);
+    }
+
+    public function provideInvalidConstructorOptions()
+    {
+        $options = [];
+
+        foreach ($this->getInvalidBooleanValues() as $value) {
+            $options[][] = ['autoIndexId' => $value];
+        }
+
+        foreach ($this->getInvalidBooleanValues() as $value) {
+            $options[][] = ['capped' => $value];
+        }
+
+        foreach ($this->getInvalidDocumentValues() as $value) {
+            $options[][] = ['collation' => $value];
+        }
+
+        foreach ($this->getInvalidIntegerValues() as $value) {
+            $options[][] = ['flags' => $value];
+        }
+
+        foreach ($this->getInvalidDocumentValues() as $value) {
+            $options[][] = ['indexOptionDefaults' => $value];
+        }
+
+        foreach ($this->getInvalidIntegerValues() as $value) {
+            $options[][] = ['max' => $value];
+        }
+
+        foreach ($this->getInvalidIntegerValues() as $value) {
+            $options[][] = ['maxTimeMS' => $value];
+        }
+
+        foreach ($this->getInvalidSessionValues() as $value) {
+            $options[][] = ['session' => $value];
+        }
+
+        foreach ($this->getInvalidIntegerValues() as $value) {
+            $options[][] = ['size' => $value];
+        }
+
+        foreach ($this->getInvalidDocumentValues() as $value) {
+            $options[][] = ['storageEngine' => $value];
+        }
+
+        foreach ($this->getInvalidArrayValues() as $value) {
+            $options[][] = ['typeMap' => $value];
+        }
+
+        foreach ($this->getInvalidStringValues() as $value) {
+            $options[][] = ['validationAction' => $value];
+        }
+
+        foreach ($this->getInvalidStringValues() as $value) {
+            $options[][] = ['validationLevel' => $value];
+        }
+
+        foreach ($this->getInvalidDocumentValues() as $value) {
+            $options[][] = ['validator' => $value];
+        }
+
+        foreach ($this->getInvalidWriteConcernValues() as $value) {
+            $options[][] = ['writeConcern' => $value];
+        }
+
+        return $options;
+    }
+
+    public function testAutoIndexIdOptionIsDeprecated()
+    {
+        $this->assertDeprecated(function () {
+            new CreateCollection($this->getDatabaseName(), $this->getCollectionName(), ['autoIndexId' => true]);
+        });
+
+        $this->assertDeprecated(function () {
+            new CreateCollection($this->getDatabaseName(), $this->getCollectionName(), ['autoIndexId' => false]);
+        });
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/CreateIndexesFunctionalTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/CreateIndexesFunctionalTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..6f06c6c6435e02c5fc677b4f04515b2553828d49
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/CreateIndexesFunctionalTest.php	
@@ -0,0 +1,257 @@
+<?php
+
+namespace MongoDB\Tests\Operation;
+
+use InvalidArgumentException;
+use MongoDB\Driver\Exception\RuntimeException;
+use MongoDB\Driver\Server;
+use MongoDB\Exception\UnsupportedException;
+use MongoDB\Model\IndexInfo;
+use MongoDB\Operation\CreateIndexes;
+use MongoDB\Operation\ListIndexes;
+use MongoDB\Tests\CommandObserver;
+use function call_user_func;
+use function is_callable;
+use function sprintf;
+use function version_compare;
+
+class CreateIndexesFunctionalTest extends FunctionalTestCase
+{
+    public function testCreateSparseUniqueIndex()
+    {
+        $indexes = [['key' => ['x' => 1], 'sparse' => true, 'unique' => true]];
+
+        $operation = new CreateIndexes($this->getDatabaseName(), $this->getCollectionName(), $indexes);
+        $createdIndexNames = $operation->execute($this->getPrimaryServer());
+
+        $this->assertSame('x_1', $createdIndexNames[0]);
+        $this->assertIndexExists('x_1', function (IndexInfo $info) {
+            $this->assertTrue($info->isSparse());
+            $this->assertTrue($info->isUnique());
+            $this->assertFalse($info->isTtl());
+        });
+    }
+
+    public function testCreateCompoundIndex()
+    {
+        $indexes = [['key' => ['y' => -1, 'z' => 1]]];
+
+        $operation = new CreateIndexes($this->getDatabaseName(), $this->getCollectionName(), $indexes);
+        $createdIndexNames = $operation->execute($this->getPrimaryServer());
+
+        $this->assertSame('y_-1_z_1', $createdIndexNames[0]);
+        $this->assertIndexExists('y_-1_z_1', function (IndexInfo $info) {
+            $this->assertFalse($info->isSparse());
+            $this->assertFalse($info->isUnique());
+            $this->assertFalse($info->isTtl());
+        });
+    }
+
+    public function testCreateGeospatialIndex()
+    {
+        $indexes = [['key' => ['g' => '2dsphere', 'z' => 1]]];
+
+        $operation = new CreateIndexes($this->getDatabaseName(), $this->getCollectionName(), $indexes);
+        $createdIndexNames = $operation->execute($this->getPrimaryServer());
+
+        $this->assertSame('g_2dsphere_z_1', $createdIndexNames[0]);
+        $this->assertIndexExists('g_2dsphere_z_1', function (IndexInfo $info) {
+            $this->assertFalse($info->isSparse());
+            $this->assertFalse($info->isUnique());
+            $this->assertFalse($info->isTtl());
+        });
+    }
+
+    public function testCreateTTLIndex()
+    {
+        $indexes = [['key' => ['t' => 1], 'expireAfterSeconds' => 0, 'name' => 'my_ttl']];
+
+        $operation = new CreateIndexes($this->getDatabaseName(), $this->getCollectionName(), $indexes);
+        $createdIndexNames = $operation->execute($this->getPrimaryServer());
+
+        $this->assertSame('my_ttl', $createdIndexNames[0]);
+        $this->assertIndexExists('my_ttl', function (IndexInfo $info) {
+            $this->assertFalse($info->isSparse());
+            $this->assertFalse($info->isUnique());
+            $this->assertTrue($info->isTtl());
+        });
+    }
+
+    public function testCreateIndexes()
+    {
+        $expectedNames = ['x_1', 'y_-1_z_1', 'g_2dsphere_z_1', 'my_ttl'];
+
+        $indexes = [
+            ['key' => ['x' => 1], 'sparse' => true, 'unique' => true],
+            ['key' => ['y' => -1, 'z' => 1]],
+            ['key' => ['g' => '2dsphere', 'z' => 1]],
+            ['key' => ['t' => 1], 'expireAfterSeconds' => 0, 'name' => 'my_ttl'],
+        ];
+
+        $operation = new CreateIndexes($this->getDatabaseName(), $this->getCollectionName(), $indexes);
+        $createdIndexNames = $operation->execute($this->getPrimaryServer());
+
+        $this->assertSame($expectedNames, $createdIndexNames);
+
+        $this->assertIndexExists('x_1', function (IndexInfo $info) {
+            $this->assertTrue($info->isSparse());
+            $this->assertTrue($info->isUnique());
+            $this->assertFalse($info->isTtl());
+        });
+
+        $this->assertIndexExists('y_-1_z_1', function (IndexInfo $info) {
+            $this->assertFalse($info->isSparse());
+            $this->assertFalse($info->isUnique());
+            $this->assertFalse($info->isTtl());
+        });
+
+        $this->assertIndexExists('g_2dsphere_z_1', function (IndexInfo $info) {
+            $this->assertFalse($info->isSparse());
+            $this->assertFalse($info->isUnique());
+            $this->assertFalse($info->isTtl());
+        });
+
+        $this->assertIndexExists('my_ttl', function (IndexInfo $info) {
+            $this->assertFalse($info->isSparse());
+            $this->assertFalse($info->isUnique());
+            $this->assertTrue($info->isTtl());
+        });
+    }
+
+    public function testCreateConflictingIndexesWithCommand()
+    {
+        $indexes = [
+            ['key' => ['x' => 1], 'sparse' => true, 'unique' => false],
+            ['key' => ['x' => 1], 'sparse' => false, 'unique' => true],
+        ];
+
+        $operation = new CreateIndexes($this->getDatabaseName(), $this->getCollectionName(), $indexes);
+
+        $this->expectException(RuntimeException::class);
+        $operation->execute($this->getPrimaryServer());
+    }
+
+    public function testDefaultWriteConcernIsOmitted()
+    {
+        (new CommandObserver())->observe(
+            function () {
+                $operation = new CreateIndexes(
+                    $this->getDatabaseName(),
+                    $this->getCollectionName(),
+                    [['key' => ['x' => 1]]],
+                    ['writeConcern' => $this->createDefaultWriteConcern()]
+                );
+
+                $operation->execute($this->getPrimaryServer());
+            },
+            function (array $event) {
+                $this->assertObjectNotHasAttribute('writeConcern', $event['started']->getCommand());
+            }
+        );
+    }
+
+    public function testSessionOption()
+    {
+        if (version_compare($this->getServerVersion(), '3.6.0', '<')) {
+            $this->markTestSkipped('Sessions are not supported');
+        }
+
+        (new CommandObserver())->observe(
+            function () {
+                $operation = new CreateIndexes(
+                    $this->getDatabaseName(),
+                    $this->getCollectionName(),
+                    [['key' => ['x' => 1]]],
+                    ['session' => $this->createSession()]
+                );
+
+                $operation->execute($this->getPrimaryServer());
+            },
+            function (array $event) {
+                $this->assertObjectHasAttribute('lsid', $event['started']->getCommand());
+            }
+        );
+    }
+
+    public function testCommitQuorumOption()
+    {
+        if (version_compare($this->getServerVersion(), '4.3.4', '<')) {
+            $this->markTestSkipped('commitQuorum is not supported');
+        }
+
+        if ($this->getPrimaryServer()->getType() !== Server::TYPE_RS_PRIMARY) {
+            $this->markTestSkipped('commitQuorum is only supported on replica sets');
+        }
+
+        (new CommandObserver())->observe(
+            function () {
+                $operation = new CreateIndexes(
+                    $this->getDatabaseName(),
+                    $this->getCollectionName(),
+                    [['key' => ['x' => 1]]],
+                    ['commitQuorum' => 'majority']
+                );
+
+                $operation->execute($this->getPrimaryServer());
+            },
+            function (array $event) {
+                $this->assertObjectHasAttribute('commitQuorum', $event['started']->getCommand());
+            }
+        );
+    }
+
+    public function testCommitQuorumUnsupported()
+    {
+        if (version_compare($this->getServerVersion(), '4.3.4', '>=')) {
+            $this->markTestSkipped('commitQuorum is supported');
+        }
+
+        $operation = new CreateIndexes(
+            $this->getDatabaseName(),
+            $this->getCollectionName(),
+            [['key' => ['x' => 1]]],
+            ['commitQuorum' => 'majority']
+        );
+
+        $this->expectException(UnsupportedException::class);
+        $this->expectExceptionMessage('The "commitQuorum" option is not supported by the server executing this operation');
+
+        $operation->execute($this->getPrimaryServer());
+    }
+
+    /**
+     * Asserts that an index with the given name exists for the collection.
+     *
+     * An optional $callback may be provided, which should take an IndexInfo
+     * argument as its first and only parameter. If an IndexInfo matching the
+     * given name is found, it will be passed to the callback, which may perform
+     * additional assertions.
+     *
+     * @param string   $indexName
+     * @param callable $callback
+     */
+    private function assertIndexExists($indexName, $callback = null)
+    {
+        if ($callback !== null && ! is_callable($callback)) {
+            throw new InvalidArgumentException('$callback is not a callable');
+        }
+
+        $operation = new ListIndexes($this->getDatabaseName(), $this->getCollectionName());
+        $indexes = $operation->execute($this->getPrimaryServer());
+
+        $foundIndex = null;
+
+        foreach ($indexes as $index) {
+            if ($index->getName() === $indexName) {
+                $foundIndex = $index;
+                break;
+            }
+        }
+
+        $this->assertNotNull($foundIndex, sprintf('Index %s does not exist', $indexName));
+
+        if ($callback !== null) {
+            call_user_func($callback, $foundIndex);
+        }
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/CreateIndexesTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/CreateIndexesTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..9ee0258a45892e33c81062b24724894b7700246c
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/CreateIndexesTest.php	
@@ -0,0 +1,70 @@
+<?php
+
+namespace MongoDB\Tests\Operation;
+
+use MongoDB\Exception\InvalidArgumentException;
+use MongoDB\Operation\CreateIndexes;
+use stdClass;
+
+class CreateIndexesTest extends TestCase
+{
+    public function testConstructorIndexesArgumentMustBeAList()
+    {
+        $this->expectException(InvalidArgumentException::class);
+        $this->expectExceptionMessage('$indexes is not a list (unexpected index: "1")');
+        new CreateIndexes($this->getDatabaseName(), $this->getCollectionName(), [1 => ['key' => ['x' => 1]]]);
+    }
+
+    /**
+     * @dataProvider provideInvalidConstructorOptions
+     */
+    public function testConstructorOptionTypeChecks(array $options)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        new CreateIndexes($this->getDatabaseName(), $this->getCollectionName(), [['key' => ['x' => 1]]], $options);
+    }
+
+    public function provideInvalidConstructorOptions()
+    {
+        $options = [];
+
+        foreach ([3.14, true, [], new stdClass()] as $value) {
+            $options[][] = ['commitQuorum' => $value];
+        }
+
+        foreach ($this->getInvalidIntegerValues() as $value) {
+            $options[][] = ['maxTimeMS' => $value];
+        }
+
+        foreach ($this->getInvalidSessionValues() as $value) {
+            $options[][] = ['session' => $value];
+        }
+
+        foreach ($this->getInvalidWriteConcernValues() as $value) {
+            $options[][] = ['writeConcern' => $value];
+        }
+
+        return $options;
+    }
+
+    public function testConstructorRequiresAtLeastOneIndex()
+    {
+        $this->expectException(InvalidArgumentException::class);
+        $this->expectExceptionMessage('$indexes is empty');
+        new CreateIndexes($this->getDatabaseName(), $this->getCollectionName(), []);
+    }
+
+    /**
+     * @dataProvider provideInvalidIndexSpecificationTypes
+     */
+    public function testConstructorRequiresIndexSpecificationsToBeAnArray($index)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        new CreateIndexes($this->getDatabaseName(), $this->getCollectionName(), [$index]);
+    }
+
+    public function provideInvalidIndexSpecificationTypes()
+    {
+        return $this->wrapValuesForDataProvider($this->getInvalidArrayValues());
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/DatabaseCommandFunctionalTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/DatabaseCommandFunctionalTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..0d8d2ec2878a7fddc5459903bd0c563fe6e78835
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/DatabaseCommandFunctionalTest.php	
@@ -0,0 +1,32 @@
+<?php
+
+namespace MongoDB\Tests\Operation;
+
+use MongoDB\Operation\DatabaseCommand;
+use MongoDB\Tests\CommandObserver;
+use function version_compare;
+
+class DatabaseCommandFunctionalTest extends FunctionalTestCase
+{
+    public function testSessionOption()
+    {
+        if (version_compare($this->getServerVersion(), '3.6.0', '<')) {
+            $this->markTestSkipped('Sessions are not supported');
+        }
+
+        (new CommandObserver())->observe(
+            function () {
+                $operation = new DatabaseCommand(
+                    $this->getDatabaseName(),
+                    ['ping' => 1],
+                    ['session' => $this->createSession()]
+                );
+
+                $operation->execute($this->getPrimaryServer());
+            },
+            function (array $event) {
+                $this->assertObjectHasAttribute('lsid', $event['started']->getCommand());
+            }
+        );
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/DatabaseCommandTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/DatabaseCommandTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..e4f82c63c56699a61dbbb9fd9212147c8eafcb0a
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/DatabaseCommandTest.php	
@@ -0,0 +1,46 @@
+<?php
+
+namespace MongoDB\Tests\Operation;
+
+use MongoDB\Exception\InvalidArgumentException;
+use MongoDB\Operation\DatabaseCommand;
+
+class DatabaseCommandTest extends TestCase
+{
+    /**
+     * @dataProvider provideInvalidDocumentValues
+     */
+    public function testConstructorCommandArgumentTypeCheck($command)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        new DatabaseCommand($this->getDatabaseName(), $command);
+    }
+
+    /**
+     * @dataProvider provideInvalidConstructorOptions
+     */
+    public function testConstructorOptionTypeChecks(array $options)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        new DatabaseCommand($this->getDatabaseName(), ['ping' => 1], $options);
+    }
+
+    public function provideInvalidConstructorOptions()
+    {
+        $options = [];
+
+        foreach ($this->getInvalidReadPreferenceValues() as $value) {
+            $options[][] = ['readPreference' => $value];
+        }
+
+        foreach ($this->getInvalidSessionValues() as $value) {
+            $options[][] = ['session' => $value];
+        }
+
+        foreach ($this->getInvalidArrayValues() as $value) {
+            $options[][] = ['typeMap' => $value];
+        }
+
+        return $options;
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/DeleteFunctionalTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/DeleteFunctionalTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..a11846cafaa0c6162e05611cfc4878a9a34509d6
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/DeleteFunctionalTest.php	
@@ -0,0 +1,135 @@
+<?php
+
+namespace MongoDB\Tests\Operation;
+
+use MongoDB\Collection;
+use MongoDB\DeleteResult;
+use MongoDB\Driver\BulkWrite;
+use MongoDB\Driver\WriteConcern;
+use MongoDB\Exception\BadMethodCallException;
+use MongoDB\Operation\Delete;
+use MongoDB\Tests\CommandObserver;
+use Symfony\Bridge\PhpUnit\SetUpTearDownTrait;
+use function version_compare;
+
+class DeleteFunctionalTest extends FunctionalTestCase
+{
+    use SetUpTearDownTrait;
+
+    /** @var Collection */
+    private $collection;
+
+    private function doSetUp()
+    {
+        parent::setUp();
+
+        $this->collection = new Collection($this->manager, $this->getDatabaseName(), $this->getCollectionName());
+    }
+
+    public function testDeleteOne()
+    {
+        $this->createFixtures(3);
+
+        $filter = ['_id' => 1];
+
+        $operation = new Delete($this->getDatabaseName(), $this->getCollectionName(), $filter, 1);
+        $result = $operation->execute($this->getPrimaryServer());
+
+        $this->assertInstanceOf(DeleteResult::class, $result);
+        $this->assertSame(1, $result->getDeletedCount());
+
+        $expected = [
+            ['_id' => 2, 'x' => 22],
+            ['_id' => 3, 'x' => 33],
+        ];
+
+        $this->assertSameDocuments($expected, $this->collection->find());
+    }
+
+    public function testDeleteMany()
+    {
+        $this->createFixtures(3);
+
+        $filter = ['_id' => ['$gt' => 1]];
+
+        $operation = new Delete($this->getDatabaseName(), $this->getCollectionName(), $filter, 0);
+        $result = $operation->execute($this->getPrimaryServer());
+
+        $this->assertInstanceOf(DeleteResult::class, $result);
+        $this->assertSame(2, $result->getDeletedCount());
+
+        $expected = [
+            ['_id' => 1, 'x' => 11],
+        ];
+
+        $this->assertSameDocuments($expected, $this->collection->find());
+    }
+
+    public function testSessionOption()
+    {
+        if (version_compare($this->getServerVersion(), '3.6.0', '<')) {
+            $this->markTestSkipped('Sessions are not supported');
+        }
+
+        (new CommandObserver())->observe(
+            function () {
+                $operation = new Delete(
+                    $this->getDatabaseName(),
+                    $this->getCollectionName(),
+                    [],
+                    0,
+                    ['session' => $this->createSession()]
+                );
+
+                $operation->execute($this->getPrimaryServer());
+            },
+            function (array $event) {
+                $this->assertObjectHasAttribute('lsid', $event['started']->getCommand());
+            }
+        );
+    }
+
+    public function testUnacknowledgedWriteConcern()
+    {
+        $filter = ['_id' => 1];
+        $options = ['writeConcern' => new WriteConcern(0)];
+
+        $operation = new Delete($this->getDatabaseName(), $this->getCollectionName(), $filter, 0, $options);
+        $result = $operation->execute($this->getPrimaryServer());
+
+        $this->assertFalse($result->isAcknowledged());
+
+        return $result;
+    }
+
+    /**
+     * @depends testUnacknowledgedWriteConcern
+     */
+    public function testUnacknowledgedWriteConcernAccessesDeletedCount(DeleteResult $result)
+    {
+        $this->expectException(BadMethodCallException::class);
+        $this->expectExceptionMessageMatches('/[\w:\\\\]+ should not be called for an unacknowledged write result/');
+        $result->getDeletedCount();
+    }
+
+    /**
+     * Create data fixtures.
+     *
+     * @param integer $n
+     */
+    private function createFixtures($n)
+    {
+        $bulkWrite = new BulkWrite(['ordered' => true]);
+
+        for ($i = 1; $i <= $n; $i++) {
+            $bulkWrite->insert([
+                '_id' => $i,
+                'x' => (integer) ($i . $i),
+            ]);
+        }
+
+        $result = $this->manager->executeBulkWrite($this->getNamespace(), $bulkWrite);
+
+        $this->assertEquals($n, $result->getInsertedCount());
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/DeleteTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/DeleteTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..c22a28801d0a1c1ee7ec5a379feb6184dc87f6ce
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/DeleteTest.php	
@@ -0,0 +1,62 @@
+<?php
+
+namespace MongoDB\Tests\Operation;
+
+use MongoDB\Exception\InvalidArgumentException;
+use MongoDB\Operation\Delete;
+use function array_merge;
+
+class DeleteTest extends TestCase
+{
+    /**
+     * @dataProvider provideInvalidDocumentValues
+     */
+    public function testConstructorFilterArgumentTypeCheck($filter)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        new Delete($this->getDatabaseName(), $this->getCollectionName(), $filter, 0);
+    }
+
+    /**
+     * @dataProvider provideInvalidLimitValues
+     */
+    public function testConstructorLimitArgumentMustBeOneOrZero($limit)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        $this->expectExceptionMessage('$limit must be 0 or 1');
+        new Delete($this->getDatabaseName(), $this->getCollectionName(), [], $limit);
+    }
+
+    public function provideInvalidLimitValues()
+    {
+        return $this->wrapValuesForDataProvider(array_merge($this->getInvalidIntegerValues(), [-1, 2]));
+    }
+
+    /**
+     * @dataProvider provideInvalidConstructorOptions
+     */
+    public function testConstructorOptionTypeChecks(array $options)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        new Delete($this->getDatabaseName(), $this->getCollectionName(), [], 1, $options);
+    }
+
+    public function provideInvalidConstructorOptions()
+    {
+        $options = [];
+
+        foreach ($this->getInvalidDocumentValues() as $value) {
+            $options[][] = ['collation' => $value];
+        }
+
+        foreach ($this->getInvalidSessionValues() as $value) {
+            $options[][] = ['session' => $value];
+        }
+
+        foreach ($this->getInvalidWriteConcernValues() as $value) {
+            $options[][] = ['writeConcern' => $value];
+        }
+
+        return $options;
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/DistinctFunctionalTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/DistinctFunctionalTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..f47f61faf54db7d702e4c45619c9f1752e4e91aa
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/DistinctFunctionalTest.php	
@@ -0,0 +1,141 @@
+<?php
+
+namespace MongoDB\Tests\Operation;
+
+use MongoDB\Driver\BulkWrite;
+use MongoDB\Operation\Distinct;
+use MongoDB\Tests\CommandObserver;
+use function is_scalar;
+use function json_encode;
+use function usort;
+use function version_compare;
+
+class DistinctFunctionalTest extends FunctionalTestCase
+{
+    public function testDefaultReadConcernIsOmitted()
+    {
+        (new CommandObserver())->observe(
+            function () {
+                $operation = new Distinct(
+                    $this->getDatabaseName(),
+                    $this->getCollectionName(),
+                    'x',
+                    [],
+                    ['readConcern' => $this->createDefaultReadConcern()]
+                );
+
+                $operation->execute($this->getPrimaryServer());
+            },
+            function (array $event) {
+                $this->assertObjectNotHasAttribute('readConcern', $event['started']->getCommand());
+            }
+        );
+    }
+
+    public function testSessionOption()
+    {
+        if (version_compare($this->getServerVersion(), '3.6.0', '<')) {
+            $this->markTestSkipped('Sessions are not supported');
+        }
+
+        (new CommandObserver())->observe(
+            function () {
+                $operation = new Distinct(
+                    $this->getDatabaseName(),
+                    $this->getCollectionName(),
+                    'x',
+                    [],
+                    ['session' => $this->createSession()]
+                );
+
+                $operation->execute($this->getPrimaryServer());
+            },
+            function (array $event) {
+                $this->assertObjectHasAttribute('lsid', $event['started']->getCommand());
+            }
+        );
+    }
+
+    /**
+     * @dataProvider provideTypeMapOptionsAndExpectedDocuments
+     */
+    public function testTypeMapOption(array $typeMap, array $expectedDocuments)
+    {
+        $bulkWrite = new BulkWrite(['ordered' => true]);
+        $bulkWrite->insert([
+            'x' => (object) ['foo' => 'bar'],
+        ]);
+        $bulkWrite->insert(['x' => 4]);
+        $bulkWrite->insert([
+            'x' => (object) ['foo' => ['foo' => 'bar']],
+        ]);
+        $this->manager->executeBulkWrite($this->getNamespace(), $bulkWrite);
+
+        $distinct = new Distinct($this->getDatabaseName(), $this->getCollectionName(), 'x', [], ['typeMap' => $typeMap]);
+        $values = $distinct->execute($this->getPrimaryServer());
+
+        /* This sort callable sorts all scalars to the front of the list. All
+         * non-scalar values are sorted by running json_encode on them and
+         * comparing their string representations.
+         */
+        $sort = function ($a, $b) {
+            if (is_scalar($a) && ! is_scalar($b)) {
+                return -1;
+            }
+
+            if (! is_scalar($a)) {
+                if (is_scalar($b)) {
+                    return 1;
+                }
+
+                $a = json_encode($a);
+                $b = json_encode($b);
+            }
+
+            return $a < $b ? -1 : 1;
+        };
+
+        usort($expectedDocuments, $sort);
+        usort($values, $sort);
+
+        $this->assertEquals($expectedDocuments, $values);
+    }
+
+    public function provideTypeMapOptionsAndExpectedDocuments()
+    {
+        return [
+            'No type map' => [
+                ['root' => 'array', 'document' => 'array'],
+                [
+                    ['foo' => 'bar'],
+                    4,
+                    ['foo' => ['foo' => 'bar']],
+                ],
+            ],
+            'array/array' => [
+                ['root' => 'array', 'document' => 'array'],
+                [
+                    ['foo' => 'bar'],
+                    4,
+                    ['foo' => ['foo' => 'bar']],
+                ],
+            ],
+            'object/array' => [
+                ['root' => 'object', 'document' => 'array'],
+                [
+                    (object) ['foo' => 'bar'],
+                    4,
+                    (object) ['foo' => ['foo' => 'bar']],
+                ],
+            ],
+            'array/stdClass' => [
+                ['root' => 'array', 'document' => 'stdClass'],
+                [
+                    ['foo' => 'bar'],
+                    4,
+                    ['foo' => (object) ['foo' => 'bar']],
+                ],
+            ],
+        ];
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/DistinctTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/DistinctTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..95ea2537a44db1270f1d4894e2349f6c2e3e45d1
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/DistinctTest.php	
@@ -0,0 +1,58 @@
+<?php
+
+namespace MongoDB\Tests\Operation;
+
+use MongoDB\Exception\InvalidArgumentException;
+use MongoDB\Operation\Distinct;
+
+class DistinctTest extends TestCase
+{
+    /**
+     * @dataProvider provideInvalidDocumentValues
+     */
+    public function testConstructorFilterArgumentTypeCheck($filter)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        new Distinct($this->getDatabaseName(), $this->getCollectionName(), 'x', $filter);
+    }
+
+    /**
+     * @dataProvider provideInvalidConstructorOptions
+     */
+    public function testConstructorOptionTypeChecks(array $options)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        new Distinct($this->getDatabaseName(), $this->getCollectionName(), 'x', [], $options);
+    }
+
+    public function provideInvalidConstructorOptions()
+    {
+        $options = [];
+
+        foreach ($this->getInvalidDocumentValues() as $value) {
+            $options[][] = ['collation' => $value];
+        }
+
+        foreach ($this->getInvalidIntegerValues() as $value) {
+            $options[][] = ['maxTimeMS' => $value];
+        }
+
+        foreach ($this->getInvalidReadConcernValues() as $value) {
+            $options[][] = ['readConcern' => $value];
+        }
+
+        foreach ($this->getInvalidReadPreferenceValues() as $value) {
+            $options[][] = ['readPreference' => $value];
+        }
+
+        foreach ($this->getInvalidSessionValues() as $value) {
+            $options[][] = ['session' => $value];
+        }
+
+        foreach ($this->getInvalidArrayValues() as $value) {
+            $options[][] = ['typeMap' => $value];
+        }
+
+        return $options;
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/DropCollectionFunctionalTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/DropCollectionFunctionalTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..a52a7c3ba5fbb0da145fb21398f77689f52f6bf2
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/DropCollectionFunctionalTest.php	
@@ -0,0 +1,106 @@
+<?php
+
+namespace MongoDB\Tests\Operation;
+
+use MongoDB\Operation\DropCollection;
+use MongoDB\Operation\InsertOne;
+use MongoDB\Operation\ListCollections;
+use MongoDB\Tests\CommandObserver;
+use function sprintf;
+use function version_compare;
+
+class DropCollectionFunctionalTest extends FunctionalTestCase
+{
+    public function testDefaultWriteConcernIsOmitted()
+    {
+        (new CommandObserver())->observe(
+            function () {
+                $operation = new DropCollection(
+                    $this->getDatabaseName(),
+                    $this->getCollectionName(),
+                    ['writeConcern' => $this->createDefaultWriteConcern()]
+                );
+
+                $operation->execute($this->getPrimaryServer());
+            },
+            function (array $event) {
+                $this->assertObjectNotHasAttribute('writeConcern', $event['started']->getCommand());
+            }
+        );
+    }
+
+    public function testDropExistingCollection()
+    {
+        $server = $this->getPrimaryServer();
+
+        $insertOne = new InsertOne($this->getDatabaseName(), $this->getCollectionName(), ['x' => 1]);
+        $writeResult = $insertOne->execute($server);
+        $this->assertEquals(1, $writeResult->getInsertedCount());
+
+        $operation = new DropCollection($this->getDatabaseName(), $this->getCollectionName());
+        $commandResult = $operation->execute($server);
+
+        $this->assertCommandSucceeded($commandResult);
+        $this->assertCollectionDoesNotExist($this->getCollectionName());
+    }
+
+    /**
+     * @depends testDropExistingCollection
+     */
+    public function testDropNonexistentCollection()
+    {
+        $this->assertCollectionDoesNotExist($this->getCollectionName());
+
+        $operation = new DropCollection($this->getDatabaseName(), $this->getCollectionName());
+        $commandResult = $operation->execute($this->getPrimaryServer());
+
+        /* Avoid inspecting the result document as mongos returns {ok:1.0},
+         * which is inconsistent from the expected mongod response of {ok:0}. */
+        $this->assertIsObject($commandResult);
+    }
+
+    public function testSessionOption()
+    {
+        if (version_compare($this->getServerVersion(), '3.6.0', '<')) {
+            $this->markTestSkipped('Sessions are not supported');
+        }
+
+        (new CommandObserver())->observe(
+            function () {
+                $operation = new DropCollection(
+                    $this->getDatabaseName(),
+                    $this->getCollectionName(),
+                    ['session' => $this->createSession()]
+                );
+
+                $operation->execute($this->getPrimaryServer());
+            },
+            function (array $event) {
+                $this->assertObjectHasAttribute('lsid', $event['started']->getCommand());
+            }
+        );
+    }
+
+    /**
+     * Asserts that a collection with the given name does not exist on the
+     * server.
+     *
+     * @param string $collectionName
+     */
+    private function assertCollectionDoesNotExist($collectionName)
+    {
+        $operation = new ListCollections($this->getDatabaseName());
+        $collections = $operation->execute($this->getPrimaryServer());
+
+        $foundCollection = null;
+
+        foreach ($collections as $collection) {
+            if ($collection->getName() === $collectionName) {
+                $foundCollection = $collection;
+                break;
+            }
+        }
+
+        $this->assertNull($foundCollection, sprintf('Collection %s exists', $collectionName));
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/DropCollectionTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/DropCollectionTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..61d9359fa466b362801c70b488f59445b2f56329
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/DropCollectionTest.php	
@@ -0,0 +1,37 @@
+<?php
+
+namespace MongoDB\Tests\Operation;
+
+use MongoDB\Exception\InvalidArgumentException;
+use MongoDB\Operation\DropCollection;
+
+class DropCollectionTest extends TestCase
+{
+    /**
+     * @dataProvider provideInvalidConstructorOptions
+     */
+    public function testConstructorOptionTypeChecks(array $options)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        new DropCollection($this->getDatabaseName(), $this->getCollectionName(), $options);
+    }
+
+    public function provideInvalidConstructorOptions()
+    {
+        $options = [];
+
+        foreach ($this->getInvalidSessionValues() as $value) {
+            $options[][] = ['session' => $value];
+        }
+
+        foreach ($this->getInvalidArrayValues() as $value) {
+            $options[][] = ['typeMap' => $value];
+        }
+
+        foreach ($this->getInvalidWriteConcernValues() as $value) {
+            $options[][] = ['writeConcern' => $value];
+        }
+
+        return $options;
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/DropDatabaseFunctionalTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/DropDatabaseFunctionalTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..fab1cbdcdf6e1c0917a27c7c3c3a0b0316ea7c4a
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/DropDatabaseFunctionalTest.php	
@@ -0,0 +1,105 @@
+<?php
+
+namespace MongoDB\Tests\Operation;
+
+use MongoDB\Driver\Server;
+use MongoDB\Operation\DropDatabase;
+use MongoDB\Operation\InsertOne;
+use MongoDB\Operation\ListDatabases;
+use MongoDB\Tests\CommandObserver;
+use function sprintf;
+use function version_compare;
+
+class DropDatabaseFunctionalTest extends FunctionalTestCase
+{
+    public function testDefaultWriteConcernIsOmitted()
+    {
+        (new CommandObserver())->observe(
+            function () {
+                $operation = new DropDatabase(
+                    $this->getDatabaseName(),
+                    ['writeConcern' => $this->createDefaultWriteConcern()]
+                );
+
+                $operation->execute($this->getPrimaryServer());
+            },
+            function (array $event) {
+                $this->assertObjectNotHasAttribute('writeConcern', $event['started']->getCommand());
+            }
+        );
+    }
+
+    public function testDropExistingDatabase()
+    {
+        $server = $this->getPrimaryServer();
+
+        $insertOne = new InsertOne($this->getDatabaseName(), $this->getCollectionName(), ['x' => 1]);
+        $writeResult = $insertOne->execute($server);
+        $this->assertEquals(1, $writeResult->getInsertedCount());
+
+        $operation = new DropDatabase($this->getDatabaseName());
+        $operation->execute($server);
+
+        $this->assertDatabaseDoesNotExist($server, $this->getDatabaseName());
+    }
+
+    /**
+     * @depends testDropExistingDatabase
+     */
+    public function testDropNonexistentDatabase()
+    {
+        $server = $this->getPrimaryServer();
+
+        $operation = new DropDatabase($this->getDatabaseName());
+        $operation->execute($server);
+
+        $this->assertDatabaseDoesNotExist($server, $this->getDatabaseName());
+
+        $operation = new DropDatabase($this->getDatabaseName());
+        $operation->execute($server);
+    }
+
+    public function testSessionOption()
+    {
+        if (version_compare($this->getServerVersion(), '3.6.0', '<')) {
+            $this->markTestSkipped('Sessions are not supported');
+        }
+
+        (new CommandObserver())->observe(
+            function () {
+                $operation = new DropDatabase(
+                    $this->getDatabaseName(),
+                    ['session' => $this->createSession()]
+                );
+
+                $operation->execute($this->getPrimaryServer());
+            },
+            function (array $event) {
+                $this->assertObjectHasAttribute('lsid', $event['started']->getCommand());
+            }
+        );
+    }
+
+    /**
+     * Asserts that a database with the given name does not exist on the server.
+     *
+     * @param Server $server
+     * @param string $databaseName
+     */
+    private function assertDatabaseDoesNotExist(Server $server, $databaseName)
+    {
+        $operation = new ListDatabases();
+        $databases = $operation->execute($server);
+
+        $foundDatabase = null;
+
+        foreach ($databases as $database) {
+            if ($database->getName() === $databaseName) {
+                $foundDatabase = $database;
+                break;
+            }
+        }
+
+        $this->assertNull($foundDatabase, sprintf('Database %s exists on the server', $databaseName));
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/DropDatabaseTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/DropDatabaseTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..45d159b0b1e404ab65f3c6e67d812a277dc1b3a0
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/DropDatabaseTest.php	
@@ -0,0 +1,37 @@
+<?php
+
+namespace MongoDB\Tests\Operation;
+
+use MongoDB\Exception\InvalidArgumentException;
+use MongoDB\Operation\DropDatabase;
+
+class DropDatabaseTest extends TestCase
+{
+    /**
+     * @dataProvider provideInvalidConstructorOptions
+     */
+    public function testConstructorOptionTypeChecks(array $options)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        new DropDatabase($this->getDatabaseName(), $options);
+    }
+
+    public function provideInvalidConstructorOptions()
+    {
+        $options = [];
+
+        foreach ($this->getInvalidSessionValues() as $value) {
+            $options[][] = ['session' => $value];
+        }
+
+        foreach ($this->getInvalidArrayValues() as $value) {
+            $options[][] = ['typeMap' => $value];
+        }
+
+        foreach ($this->getInvalidWriteConcernValues() as $value) {
+            $options[][] = ['writeConcern' => $value];
+        }
+
+        return $options;
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/DropIndexesFunctionalTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/DropIndexesFunctionalTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..b9d104c14b9f36d35a671a7607c42dbf7fe050a1
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/DropIndexesFunctionalTest.php	
@@ -0,0 +1,183 @@
+<?php
+
+namespace MongoDB\Tests\Operation;
+
+use InvalidArgumentException;
+use MongoDB\Model\IndexInfo;
+use MongoDB\Operation\CreateIndexes;
+use MongoDB\Operation\DropIndexes;
+use MongoDB\Operation\ListIndexes;
+use MongoDB\Tests\CommandObserver;
+use function call_user_func;
+use function is_callable;
+use function sprintf;
+use function version_compare;
+
+class DropIndexesFunctionalTest extends FunctionalTestCase
+{
+    public function testDefaultWriteConcernIsOmitted()
+    {
+        $operation = new CreateIndexes($this->getDatabaseName(), $this->getCollectionName(), [['key' => ['x' => 1]]]);
+        $operation->execute($this->getPrimaryServer());
+
+        (new CommandObserver())->observe(
+            function () {
+                $operation = new DropIndexes(
+                    $this->getDatabaseName(),
+                    $this->getCollectionName(),
+                    'x_1',
+                    ['writeConcern' => $this->createDefaultWriteConcern()]
+                );
+
+                $operation->execute($this->getPrimaryServer());
+            },
+            function (array $event) {
+                $this->assertObjectNotHasAttribute('writeConcern', $event['started']->getCommand());
+            }
+        );
+    }
+
+    public function testDropOneIndexByName()
+    {
+        $indexes = [['key' => ['x' => 1]]];
+
+        $operation = new CreateIndexes($this->getDatabaseName(), $this->getCollectionName(), $indexes);
+        $createdIndexNames = $operation->execute($this->getPrimaryServer());
+
+        $this->assertSame('x_1', $createdIndexNames[0]);
+        $this->assertIndexExists('x_1');
+
+        $operation = new DropIndexes($this->getDatabaseName(), $this->getCollectionName(), 'x_1');
+        $this->assertCommandSucceeded($operation->execute($this->getPrimaryServer()));
+
+        $operation = new ListIndexes($this->getDatabaseName(), $this->getCollectionName());
+        $indexes = $operation->execute($this->getPrimaryServer());
+
+        foreach ($indexes as $index) {
+            if ($index->getName() === 'x_1') {
+                $this->fail('The "x_1" index should have been deleted');
+            }
+        }
+    }
+
+    public function testDropAllIndexesByWildcard()
+    {
+        $indexes = [
+            ['key' => ['x' => 1]],
+            ['key' => ['y' => 1]],
+        ];
+
+        $operation = new CreateIndexes($this->getDatabaseName(), $this->getCollectionName(), $indexes);
+        $createdIndexNames = $operation->execute($this->getPrimaryServer());
+
+        $this->assertSame('x_1', $createdIndexNames[0]);
+        $this->assertSame('y_1', $createdIndexNames[1]);
+        $this->assertIndexExists('x_1');
+        $this->assertIndexExists('y_1');
+
+        $operation = new DropIndexes($this->getDatabaseName(), $this->getCollectionName(), '*');
+        $this->assertCommandSucceeded($operation->execute($this->getPrimaryServer()));
+
+        $operation = new ListIndexes($this->getDatabaseName(), $this->getCollectionName());
+        $indexes = $operation->execute($this->getPrimaryServer());
+
+        foreach ($indexes as $index) {
+            if ($index->getName() === 'x_1') {
+                $this->fail('The "x_1" index should have been deleted');
+            }
+
+            if ($index->getName() === 'y_1') {
+                $this->fail('The "y_1" index should have been deleted');
+            }
+        }
+    }
+
+    public function testDropByIndexInfo()
+    {
+        $info = new IndexInfo([
+            'v' => 1,
+            'key' => ['x' => 1],
+            'name' => 'x_1',
+            'ns' => 'foo.bar',
+        ]);
+
+        $operation = new CreateIndexes($this->getDatabaseName(), $this->getCollectionName(), [['key' => ['x' => 1]]]);
+        $createdIndexNames = $operation->execute($this->getPrimaryServer());
+
+        $this->assertSame('x_1', $createdIndexNames[0]);
+        $this->assertIndexExists('x_1');
+
+        $operation = new DropIndexes($this->getDatabaseName(), $this->getCollectionName(), $info);
+        $this->assertCommandSucceeded($operation->execute($this->getPrimaryServer()));
+
+        $operation = new ListIndexes($this->getDatabaseName(), $this->getCollectionName());
+        $indexes = $operation->execute($this->getPrimaryServer());
+
+        foreach ($indexes as $index) {
+            if ($index->getName() === 'x_1') {
+                $this->fail('The "x_1" index should have been deleted');
+            }
+        }
+    }
+
+    public function testSessionOption()
+    {
+        if (version_compare($this->getServerVersion(), '3.6.0', '<')) {
+            $this->markTestSkipped('Sessions are not supported');
+        }
+
+        $operation = new CreateIndexes($this->getDatabaseName(), $this->getCollectionName(), [['key' => ['x' => 1]]]);
+        $operation->execute($this->getPrimaryServer());
+
+        (new CommandObserver())->observe(
+            function () {
+                $operation = new DropIndexes(
+                    $this->getDatabaseName(),
+                    $this->getCollectionName(),
+                    '*',
+                    ['session' => $this->createSession()]
+                );
+
+                $operation->execute($this->getPrimaryServer());
+            },
+            function (array $event) {
+                $this->assertObjectHasAttribute('lsid', $event['started']->getCommand());
+            }
+        );
+    }
+
+    /**
+     * Asserts that an index with the given name exists for the collection.
+     *
+     * An optional $callback may be provided, which should take an IndexInfo
+     * argument as its first and only parameter. If an IndexInfo matching the
+     * given name is found, it will be passed to the callback, which may perform
+     * additional assertions.
+     *
+     * @param callable $callback
+     */
+    private function assertIndexExists($indexName, $callback = null)
+    {
+        if ($callback !== null && ! is_callable($callback)) {
+            throw new InvalidArgumentException('$callback is not a callable');
+        }
+
+        $operation = new ListIndexes($this->getDatabaseName(), $this->getCollectionName());
+        $indexes = $operation->execute($this->getPrimaryServer());
+
+        $foundIndex = null;
+
+        foreach ($indexes as $index) {
+            if ($index->getName() === $indexName) {
+                $foundIndex = $index;
+                break;
+            }
+        }
+
+        $this->assertNotNull($foundIndex, sprintf('Found %s index for the collection', $indexName));
+
+        if ($callback !== null) {
+            call_user_func($callback, $foundIndex);
+        }
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/DropIndexesTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/DropIndexesTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..bf947f86258bab966abbd9313249178f40cf3adb
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/DropIndexesTest.php	
@@ -0,0 +1,47 @@
+<?php
+
+namespace MongoDB\Tests\Operation;
+
+use MongoDB\Exception\InvalidArgumentException;
+use MongoDB\Operation\DropIndexes;
+
+class DropIndexesTest extends TestCase
+{
+    public function testDropIndexShouldNotAllowEmptyIndexName()
+    {
+        $this->expectException(InvalidArgumentException::class);
+        new DropIndexes($this->getDatabaseName(), $this->getCollectionName(), '');
+    }
+
+    /**
+     * @dataProvider provideInvalidConstructorOptions
+     */
+    public function testConstructorOptionTypeChecks(array $options)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        new DropIndexes($this->getDatabaseName(), $this->getCollectionName(), '*', $options);
+    }
+
+    public function provideInvalidConstructorOptions()
+    {
+        $options = [];
+
+        foreach ($this->getInvalidIntegerValues() as $value) {
+            $options[][] = ['maxTimeMS' => $value];
+        }
+
+        foreach ($this->getInvalidSessionValues() as $value) {
+            $options[][] = ['session' => $value];
+        }
+
+        foreach ($this->getInvalidArrayValues() as $value) {
+            $options[][] = ['typeMap' => $value];
+        }
+
+        foreach ($this->getInvalidWriteConcernValues() as $value) {
+            $options[][] = ['writeConcern' => $value];
+        }
+
+        return $options;
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/EstimatedDocumentCountTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/EstimatedDocumentCountTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..ea8231a26fbb4dbe5c0fa60e9969fa6b54d3b63a
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/EstimatedDocumentCountTest.php	
@@ -0,0 +1,41 @@
+<?php
+
+namespace MongoDB\Tests\Operation;
+
+use MongoDB\Exception\InvalidArgumentException;
+use MongoDB\Operation\EstimatedDocumentCount;
+
+class EstimatedDocumentCountTest extends TestCase
+{
+    /**
+     * @dataProvider provideInvalidConstructorOptions
+     */
+    public function testConstructorOptionTypeChecks(array $options)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        new EstimatedDocumentCount($this->getDatabaseName(), $this->getCollectionName(), $options);
+    }
+
+    public function provideInvalidConstructorOptions()
+    {
+        $options = [];
+
+        foreach ($this->getInvalidIntegerValues() as $value) {
+            $options[][] = ['maxTimeMS' => $value];
+        }
+
+        foreach ($this->getInvalidReadConcernValues() as $value) {
+            $options[][] = ['readConcern' => $value];
+        }
+
+        foreach ($this->getInvalidReadPreferenceValues() as $value) {
+            $options[][] = ['readPreference' => $value];
+        }
+
+        foreach ($this->getInvalidSessionValues() as $value) {
+            $options[][] = ['session' => $value];
+        }
+
+        return $options;
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/ExplainFunctionalTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/ExplainFunctionalTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..e10c5157dd031e28998c8df29b9de21959c53f16
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/ExplainFunctionalTest.php	
@@ -0,0 +1,477 @@
+<?php
+
+namespace MongoDB\Tests\Operation;
+
+use MongoDB\Driver\BulkWrite;
+use MongoDB\Operation\Aggregate;
+use MongoDB\Operation\Count;
+use MongoDB\Operation\CreateCollection;
+use MongoDB\Operation\Delete;
+use MongoDB\Operation\DeleteMany;
+use MongoDB\Operation\DeleteOne;
+use MongoDB\Operation\Distinct;
+use MongoDB\Operation\Explain;
+use MongoDB\Operation\Find;
+use MongoDB\Operation\FindAndModify;
+use MongoDB\Operation\FindOne;
+use MongoDB\Operation\FindOneAndDelete;
+use MongoDB\Operation\FindOneAndReplace;
+use MongoDB\Operation\FindOneAndUpdate;
+use MongoDB\Operation\Update;
+use MongoDB\Operation\UpdateMany;
+use MongoDB\Operation\UpdateOne;
+use MongoDB\Tests\CommandObserver;
+use function version_compare;
+
+class ExplainFunctionalTest extends FunctionalTestCase
+{
+    /**
+     * @dataProvider provideVerbosityInformation
+     */
+    public function testCount($verbosity, $executionStatsExpected, $allPlansExecutionExpected)
+    {
+        $this->createFixtures(3);
+
+        $operation = new Count($this->getDatabaseName(), $this->getCollectionName(), ['x' => ['$gte' => 1]], []);
+
+        $explainOperation = new Explain($this->getDatabaseName(), $operation, ['verbosity' => $verbosity, 'typeMap' => ['root' => 'array', 'document' => 'array']]);
+        $result = $explainOperation->execute($this->getPrimaryServer());
+
+        $this->assertExplainResult($result, $executionStatsExpected, $allPlansExecutionExpected);
+    }
+
+    /**
+     * @dataProvider provideVerbosityInformation
+     */
+    public function testDelete($verbosity, $executionStatsExpected, $allPlansExecutionExpected)
+    {
+        $this->createFixtures(3);
+
+        $filter = ['_id' => 1];
+
+        $operation = new Delete($this->getDatabaseName(), $this->getCollectionName(), $filter, 1);
+
+        $explainOperation = new Explain($this->getDatabaseName(), $operation, ['verbosity' => $verbosity, 'typeMap' => ['root' => 'array', 'document' => 'array']]);
+        $result = $explainOperation->execute($this->getPrimaryServer());
+
+        $this->assertExplainResult($result, $executionStatsExpected, $allPlansExecutionExpected);
+    }
+
+    /**
+     * @dataProvider provideVerbosityInformation
+     */
+    public function testDeleteMany($verbosity, $executionStatsExpected, $allPlansExecutionExpected)
+    {
+        $this->createFixtures(3);
+
+        $filter = ['_id' => ['$gt' => 1]];
+
+        $operation = new DeleteMany($this->getDatabaseName(), $this->getCollectionName(), $filter);
+
+        $explainOperation = new Explain($this->getDatabaseName(), $operation, ['verbosity' => $verbosity, 'typeMap' => ['root' => 'array', 'document' => 'array']]);
+        $result = $explainOperation->execute($this->getPrimaryServer());
+
+        $this->assertExplainResult($result, $executionStatsExpected, $allPlansExecutionExpected);
+    }
+
+    /**
+     * @dataProvider provideVerbosityInformation
+     */
+    public function testDeleteOne($verbosity, $executionStatsExpected, $allPlansExecutionExpected)
+    {
+        $this->createFixtures(3);
+
+        $filter = ['_id' => 1];
+
+        $operation = new DeleteOne($this->getDatabaseName(), $this->getCollectionName(), $filter);
+
+        $explainOperation = new Explain($this->getDatabaseName(), $operation, ['verbosity' => $verbosity, 'typeMap' => ['root' => 'array', 'document' => 'array']]);
+        $result = $explainOperation->execute($this->getPrimaryServer());
+
+        $this->assertExplainResult($result, $executionStatsExpected, $allPlansExecutionExpected);
+    }
+
+    /**
+     * @dataProvider provideVerbosityInformation
+     */
+    public function testDistinct($verbosity, $executionStatsExpected, $allPlansExecutionExpected)
+    {
+        if (version_compare($this->getServerVersion(), '3.2.0', '<')) {
+            $this->markTestSkipped('Explaining distinct command requires server version >= 3.2');
+        }
+
+        $operation = new Distinct($this->getDatabaseName(), $this->getCollectionName(), 'x', []);
+
+        $explainOperation = new Explain($this->getDatabaseName(), $operation, ['verbosity' => $verbosity, 'typeMap' => ['root' => 'array', 'document' => 'array']]);
+        $result = $explainOperation->execute($this->getPrimaryServer());
+
+        $this->assertExplainResult($result, $executionStatsExpected, $allPlansExecutionExpected);
+    }
+
+    /**
+     * @dataProvider provideVerbosityInformation
+     */
+    public function testFindAndModify($verbosity, $executionStatsExpected, $allPlansExecutionExpected)
+    {
+        if (version_compare($this->getServerVersion(), '3.2.0', '<')) {
+            $this->markTestSkipped('Explaining findAndModify command requires server version >= 3.2');
+        }
+
+        $operation = new FindAndModify($this->getDatabaseName(), $this->getCollectionName(), ['remove' => true]);
+
+        $explainOperation = new Explain($this->getDatabaseName(), $operation, ['verbosity' => $verbosity, 'typeMap' => ['root' => 'array', 'document' => 'array']]);
+        $result = $explainOperation->execute($this->getPrimaryServer());
+
+        $this->assertExplainResult($result, $executionStatsExpected, $allPlansExecutionExpected);
+    }
+
+    /**
+     * @dataProvider provideVerbosityInformation
+     */
+    public function testFind($verbosity, $executionStatsExpected, $allPlansExecutionExpected)
+    {
+        $this->createFixtures(3);
+
+        $operation = new Find($this->getDatabaseName(), $this->getCollectionName(), []);
+
+        $explainOperation = new Explain($this->getDatabaseName(), $operation, ['verbosity' => $verbosity, 'typeMap' => ['root' => 'array', 'document' => 'array']]);
+        $result = $explainOperation->execute($this->getPrimaryServer());
+
+        $this->assertExplainResult($result, $executionStatsExpected, $allPlansExecutionExpected);
+    }
+
+    public function testFindMaxAwait()
+    {
+        if (version_compare($this->getServerVersion(), '3.2.0', '<')) {
+            $this->markTestSkipped('maxAwaitTimeMS option is not supported');
+        }
+
+        $maxAwaitTimeMS = 100;
+
+        /* Calculate an approximate pivot to use for time assertions. We will
+         * assert that the duration of blocking responses is greater than this
+         * value, and vice versa. */
+        $pivot = $maxAwaitTimeMS * 0.001 * 0.9;
+
+        // Create a capped collection.
+        $databaseName = $this->getDatabaseName();
+        $cappedCollectionName = $this->getCollectionName();
+        $cappedCollectionOptions = [
+            'capped' => true,
+            'max' => 100,
+            'size' => 1048576,
+        ];
+
+        $operation = new CreateCollection($databaseName, $cappedCollectionName, $cappedCollectionOptions);
+        $operation->execute($this->getPrimaryServer());
+
+        $this->createFixtures(2);
+
+        $operation = new Find($databaseName, $cappedCollectionName, [], ['cursorType' => Find::TAILABLE_AWAIT, 'maxAwaitTimeMS' => $maxAwaitTimeMS]);
+
+        (new CommandObserver())->observe(
+            function () use ($operation) {
+                $explainOperation = new Explain($this->getDatabaseName(), $operation, ['typeMap' => ['root' => 'array', 'document' => 'array']]);
+                $explainOperation->execute($this->getPrimaryServer());
+            },
+            function (array $event) {
+                $command = $event['started']->getCommand();
+                $this->assertObjectNotHasAttribute('maxAwaitTimeMS', $command->explain);
+                $this->assertObjectHasAttribute('tailable', $command->explain);
+                $this->assertObjectHasAttribute('awaitData', $command->explain);
+            }
+        );
+    }
+
+    public function testFindModifiers()
+    {
+        $this->createFixtures(3);
+
+        $operation = new Find(
+            $this->getDatabaseName(),
+            $this->getCollectionName(),
+            [],
+            ['modifiers' => ['$orderby' => ['_id' => 1]]]
+        );
+
+        (new CommandObserver())->observe(
+            function () use ($operation) {
+                $explainOperation = new Explain($this->getDatabaseName(), $operation, ['typeMap' => ['root' => 'array', 'document' => 'array']]);
+                $explainOperation->execute($this->getPrimaryServer());
+            },
+            function (array $event) {
+                $command = $event['started']->getCommand();
+                $this->assertObjectHasAttribute('sort', $command->explain);
+                $this->assertObjectNotHasAttribute('modifiers', $command->explain);
+            }
+        );
+    }
+
+    /**
+     * @dataProvider provideVerbosityInformation
+     */
+    public function testFindOne($verbosity, $executionStatsExpected, $allPlansExecutionExpected)
+    {
+        $this->createFixtures(1);
+
+        $operation = new FindOne($this->getDatabaseName(), $this->getCollectionName(), []);
+
+        $explainOperation = new Explain($this->getDatabaseName(), $operation, ['verbosity' => $verbosity, 'typeMap' => ['root' => 'array', 'document' => 'array']]);
+        $result = $explainOperation->execute($this->getPrimaryServer());
+
+        $this->assertExplainResult($result, $executionStatsExpected, $allPlansExecutionExpected);
+    }
+
+    /**
+     * @dataProvider provideVerbosityInformation
+     */
+    public function testFindOneAndDelete($verbosity, $executionStatsExpected, $allPlansExecutionExpected)
+    {
+        if (version_compare($this->getServerVersion(), '3.2.0', '<')) {
+            $this->markTestSkipped('Explaining findOneAndDelete command requires server version >= 3.2');
+        }
+
+        $operation = new FindOneAndDelete($this->getDatabaseName(), $this->getCollectionName(), []);
+
+        $explainOperation = new Explain($this->getDatabaseName(), $operation, ['verbosity' => $verbosity, 'typeMap' => ['root' => 'array', 'document' => 'array']]);
+        $result = $explainOperation->execute($this->getPrimaryServer());
+
+        $this->assertExplainResult($result, $executionStatsExpected, $allPlansExecutionExpected);
+    }
+
+    /**
+     * @dataProvider provideVerbosityInformation
+     */
+    public function testFindOneAndReplace($verbosity, $executionStatsExpected, $allPlansExecutionExpected)
+    {
+        if (version_compare($this->getServerVersion(), '3.2.0', '<')) {
+            $this->markTestSkipped('Explaining findOneAndReplace command requires server version >= 3.2');
+        }
+
+        $operation = new FindOneAndReplace($this->getDatabaseName(), $this->getCollectionName(), ['x' => 1.1], ['x' => 5]);
+
+        $explainOperation = new Explain($this->getDatabaseName(), $operation, ['verbosity' => $verbosity, 'typeMap' => ['root' => 'array', 'document' => 'array']]);
+        $result = $explainOperation->execute($this->getPrimaryServer());
+
+        $this->assertExplainResult($result, $executionStatsExpected, $allPlansExecutionExpected);
+    }
+
+    /**
+     * @dataProvider provideVerbosityInformation
+     */
+    public function testFindOneAndUpdate($verbosity, $executionStatsExpected, $allPlansExecutionExpected)
+    {
+        if (version_compare($this->getServerVersion(), '3.2.0', '<')) {
+            $this->markTestSkipped('Explaining findOneAndUpdate command requires server version >= 3.2');
+        }
+
+        $operation = new FindOneAndUpdate($this->getDatabaseName(), $this->getCollectionName(), [], ['$rename' => ['x' => 'y']]);
+
+        $explainOperation = new Explain($this->getDatabaseName(), $operation, ['verbosity' => $verbosity, 'typeMap' => ['root' => 'array', 'document' => 'array']]);
+        $result = $explainOperation->execute($this->getPrimaryServer());
+
+        $this->assertExplainResult($result, $executionStatsExpected, $allPlansExecutionExpected);
+    }
+
+    /**
+     * @dataProvider provideVerbosityInformation
+     */
+    public function testUpdate($verbosity, $executionStatsExpected, $allPlansExecutionExpected)
+    {
+        $this->createFixtures(3);
+
+        $filter = ['_id' => ['$gt' => 1]];
+        $update = ['$inc' => ['x' => 1]];
+
+        $operation = new Update($this->getDatabaseName(), $this->getCollectionName(), $filter, $update);
+
+        $explainOperation = new Explain($this->getDatabaseName(), $operation, ['verbosity' => $verbosity, 'typeMap' => ['root' => 'array', 'document' => 'array']]);
+        $result = $explainOperation->execute($this->getPrimaryServer());
+
+        $this->assertExplainResult($result, $executionStatsExpected, $allPlansExecutionExpected);
+    }
+
+    public function testUpdateBypassDocumentValidationSetWhenTrue()
+    {
+        if (version_compare($this->getServerVersion(), '3.2.0', '<')) {
+            $this->markTestSkipped('bypassDocumentValidation is not supported');
+        }
+
+        $this->createFixtures(3);
+
+        (new CommandObserver())->observe(
+            function () {
+                $operation = new Update(
+                    $this->getDatabaseName(),
+                    $this->getCollectionName(),
+                    ['_id' => ['$gt' => 1]],
+                    ['$inc' => ['x' => 1]],
+                    ['bypassDocumentValidation' => true]
+                );
+
+                $explainOperation = new Explain($this->getDatabaseName(), $operation);
+                $result = $explainOperation->execute($this->getPrimaryServer());
+            },
+            function (array $event) {
+                $this->assertObjectHasAttribute(
+                    'bypassDocumentValidation',
+                    $event['started']->getCommand()->explain
+                );
+                $this->assertEquals(true, $event['started']->getCommand()->explain->bypassDocumentValidation);
+            }
+        );
+    }
+
+    public function testUpdateBypassDocumentValidationUnsetWhenFalse()
+    {
+        if (version_compare($this->getServerVersion(), '3.2.0', '<')) {
+            $this->markTestSkipped('bypassDocumentValidation is not supported');
+        }
+
+        $this->createFixtures(3);
+
+        (new CommandObserver())->observe(
+            function () {
+                $operation = new Update(
+                    $this->getDatabaseName(),
+                    $this->getCollectionName(),
+                    ['_id' => ['$gt' => 1]],
+                    ['$inc' => ['x' => 1]],
+                    ['bypassDocumentValidation' => false]
+                );
+
+                $explainOperation = new Explain($this->getDatabaseName(), $operation);
+                $result = $explainOperation->execute($this->getPrimaryServer());
+            },
+            function (array $event) {
+                $this->assertObjectNotHasAttribute(
+                    'bypassDocumentValidation',
+                    $event['started']->getCommand()->explain
+                );
+            }
+        );
+    }
+
+    /**
+     * @dataProvider provideVerbosityInformation
+     */
+    public function testUpdateMany($verbosity, $executionStatsExpected, $allPlansExecutionExpected)
+    {
+        $this->createFixtures(3);
+
+        $filter = ['_id' => ['$gt' => 1]];
+        $update = ['$inc' => ['x' => 1]];
+
+        $operation = new UpdateMany($this->getDatabaseName(), $this->getCollectionName(), $filter, $update);
+
+        $explainOperation = new Explain($this->getDatabaseName(), $operation, ['verbosity' => $verbosity, 'typeMap' => ['root' => 'array', 'document' => 'array']]);
+        $result = $explainOperation->execute($this->getPrimaryServer());
+
+        $this->assertExplainResult($result, $executionStatsExpected, $allPlansExecutionExpected);
+    }
+
+    /**
+     * @dataProvider provideVerbosityInformation
+     */
+    public function testUpdateOne($verbosity, $executionStatsExpected, $allPlansExecutionExpected)
+    {
+        $this->createFixtures(3);
+
+        $filter = ['_id' => ['$lte' => 1]];
+        $update = ['$inc' => ['x' => 1]];
+
+        $operation = new UpdateOne($this->getDatabaseName(), $this->getCollectionName(), $filter, $update);
+
+        $explainOperation = new Explain($this->getDatabaseName(), $operation, ['verbosity' => $verbosity, 'typeMap' => ['root' => 'array', 'document' => 'array']]);
+        $result = $explainOperation->execute($this->getPrimaryServer());
+
+        $this->assertExplainResult($result, $executionStatsExpected, $allPlansExecutionExpected);
+    }
+
+    public function testAggregate()
+    {
+        if (version_compare($this->getServerVersion(), '4.0.0', '<')) {
+            $this->markTestSkipped('Explaining aggregate command requires server version >= 4.0');
+        }
+
+        $this->createFixtures(3);
+
+        $pipeline = [['$group' => ['_id' => null]]];
+        $operation = new Aggregate($this->getDatabaseName(), $this->getCollectionName(), $pipeline);
+
+        $explainOperation = new Explain($this->getDatabaseName(), $operation, ['verbosity' => Explain::VERBOSITY_QUERY, 'typeMap' => ['root' => 'array', 'document' => 'array']]);
+        $result = $explainOperation->execute($this->getPrimaryServer());
+
+        $this->assertExplainResult($result, false, false, true);
+    }
+
+    /**
+     * @dataProvider provideVerbosityInformation
+     */
+    public function testAggregateOptimizedToQuery($verbosity, $executionStatsExpected, $allPlansExecutionExpected)
+    {
+        if (version_compare($this->getServerVersion(), '4.2.0', '<')) {
+            $this->markTestSkipped('MongoDB < 4.2 does not optimize simple aggregation pipelines');
+        }
+
+        $this->createFixtures(3);
+
+        $pipeline = [['$match' => ['_id' => ['$ne' => 2]]]];
+        $operation = new Aggregate($this->getDatabaseName(), $this->getCollectionName(), $pipeline);
+
+        $explainOperation = new Explain($this->getDatabaseName(), $operation, ['verbosity' => $verbosity, 'typeMap' => ['root' => 'array', 'document' => 'array']]);
+        $result = $explainOperation->execute($this->getPrimaryServer());
+
+        $this->assertExplainResult($result, $executionStatsExpected, $allPlansExecutionExpected);
+    }
+
+    public function provideVerbosityInformation()
+    {
+        return [
+            [Explain::VERBOSITY_ALL_PLANS, true, true],
+            [Explain::VERBOSITY_EXEC_STATS, true, false],
+            [Explain::VERBOSITY_QUERY, false, false],
+        ];
+    }
+
+    private function assertExplainResult($result, $executionStatsExpected, $allPlansExecutionExpected, $stagesExpected = false)
+    {
+        if ($stagesExpected) {
+            $this->assertArrayHasKey('stages', $result);
+        } else {
+            $this->assertArrayHasKey('queryPlanner', $result);
+        }
+
+        if ($executionStatsExpected) {
+            $this->assertArrayHasKey('executionStats', $result);
+            if ($allPlansExecutionExpected) {
+                $this->assertArrayHasKey('allPlansExecution', $result['executionStats']);
+            } else {
+                $this->assertArrayNotHasKey('allPlansExecution', $result['executionStats']);
+            }
+        } else {
+            $this->assertArrayNotHasKey('executionStats', $result);
+        }
+    }
+
+    /**
+     * Create data fixtures.
+     *
+     * @param integer $n
+     */
+    private function createFixtures($n)
+    {
+        $bulkWrite = new BulkWrite(['ordered' => true]);
+
+        for ($i = 1; $i <= $n; $i++) {
+            $bulkWrite->insert([
+                '_id' => $i,
+                'x' => (integer) ($i . $i),
+            ]);
+        }
+
+        $result = $this->manager->executeBulkWrite($this->getNamespace(), $bulkWrite);
+
+        $this->assertEquals($n, $result->getInsertedCount());
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/ExplainTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/ExplainTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..945e300a4974d654dd21c0658de2c77e63f73f5d
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/ExplainTest.php	
@@ -0,0 +1,43 @@
+<?php
+
+namespace MongoDB\Tests\Operation;
+
+use MongoDB\Exception\InvalidArgumentException;
+use MongoDB\Operation\Explain;
+use MongoDB\Operation\Explainable;
+
+class ExplainTest extends TestCase
+{
+    /**
+     * @dataProvider provideInvalidConstructorOptions
+     */
+    public function testConstructorOptionTypeChecks(array $options)
+    {
+        $explainable = $this->getMockBuilder(Explainable::class)->getMock();
+        $this->expectException(InvalidArgumentException::class);
+        new Explain($this->getDatabaseName(), $explainable, $options);
+    }
+
+    public function provideInvalidConstructorOptions()
+    {
+        $options = [];
+
+        foreach ($this->getInvalidReadPreferenceValues() as $value) {
+            $options[][] = ['readPreference' => $value];
+        }
+
+        foreach ($this->getInvalidSessionValues() as $value) {
+            $options[][] = ['session' => $value];
+        }
+
+        foreach ($this->getInvalidStringValues() as $value) {
+            $options[][] = ['verbosity' => $value];
+        }
+
+        foreach ($this->getInvalidArrayValues() as $value) {
+            $options[][] = ['typeMap' => $value];
+        }
+
+        return $options;
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/FindAndModifyFunctionalTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/FindAndModifyFunctionalTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..d402f4717939f64dd324428f735135ca80c07656
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/FindAndModifyFunctionalTest.php	
@@ -0,0 +1,194 @@
+<?php
+
+namespace MongoDB\Tests\Operation;
+
+use MongoDB\Driver\BulkWrite;
+use MongoDB\Driver\Manager;
+use MongoDB\Driver\ReadPreference;
+use MongoDB\Model\BSONDocument;
+use MongoDB\Operation\FindAndModify;
+use MongoDB\Tests\CommandObserver;
+use function version_compare;
+
+class FindAndModifyFunctionalTest extends FunctionalTestCase
+{
+    /**
+     * @see https://jira.mongodb.org/browse/PHPLIB-344
+     */
+    public function testManagerReadConcernIsOmitted()
+    {
+        $manager = new Manager(static::getUri(), ['readConcernLevel' => 'majority']);
+        $server = $manager->selectServer(new ReadPreference(ReadPreference::RP_PRIMARY));
+
+        (new CommandObserver())->observe(
+            function () use ($server) {
+                $operation = new FindAndModify(
+                    $this->getDatabaseName(),
+                    $this->getCollectionName(),
+                    ['remove' => true]
+                );
+
+                $operation->execute($server);
+            },
+            function (array $event) {
+                $this->assertObjectNotHasAttribute('readConcern', $event['started']->getCommand());
+            }
+        );
+    }
+
+    public function testDefaultWriteConcernIsOmitted()
+    {
+        (new CommandObserver())->observe(
+            function () {
+                $operation = new FindAndModify(
+                    $this->getDatabaseName(),
+                    $this->getCollectionName(),
+                    ['remove' => true, 'writeConcern' => $this->createDefaultWriteConcern()]
+                );
+
+                $operation->execute($this->getPrimaryServer());
+            },
+            function (array $event) {
+                $this->assertObjectNotHasAttribute('writeConcern', $event['started']->getCommand());
+            }
+        );
+    }
+
+    public function testSessionOption()
+    {
+        if (version_compare($this->getServerVersion(), '3.6.0', '<')) {
+            $this->markTestSkipped('Sessions are not supported');
+        }
+
+        (new CommandObserver())->observe(
+            function () {
+                $operation = new FindAndModify(
+                    $this->getDatabaseName(),
+                    $this->getCollectionName(),
+                    ['remove' => true, 'session' => $this->createSession()]
+                );
+
+                $operation->execute($this->getPrimaryServer());
+            },
+            function (array $event) {
+                $this->assertObjectHasAttribute('lsid', $event['started']->getCommand());
+            }
+        );
+    }
+
+    public function testBypassDocumentValidationSetWhenTrue()
+    {
+        if (version_compare($this->getServerVersion(), '3.2.0', '<')) {
+            $this->markTestSkipped('bypassDocumentValidation is not supported');
+        }
+
+        (new CommandObserver())->observe(
+            function () {
+                $operation = new FindAndModify(
+                    $this->getDatabaseName(),
+                    $this->getCollectionName(),
+                    ['remove' => true, 'bypassDocumentValidation' => true]
+                );
+
+                $operation->execute($this->getPrimaryServer());
+            },
+            function (array $event) {
+                $this->assertObjectHasAttribute('bypassDocumentValidation', $event['started']->getCommand());
+                $this->assertEquals(true, $event['started']->getCommand()->bypassDocumentValidation);
+            }
+        );
+    }
+
+    public function testBypassDocumentValidationUnsetWhenFalse()
+    {
+        if (version_compare($this->getServerVersion(), '3.2.0', '<')) {
+            $this->markTestSkipped('bypassDocumentValidation is not supported');
+        }
+
+        (new CommandObserver())->observe(
+            function () {
+                $operation = new FindAndModify(
+                    $this->getDatabaseName(),
+                    $this->getCollectionName(),
+                    ['remove' => true, 'bypassDocumentValidation' => false]
+                );
+
+                $operation->execute($this->getPrimaryServer());
+            },
+            function (array $event) {
+                $this->assertObjectNotHasAttribute('bypassDocumentValidation', $event['started']->getCommand());
+            }
+        );
+    }
+
+    /**
+     * @dataProvider provideTypeMapOptionsAndExpectedDocument
+     */
+    public function testTypeMapOption(array $typeMap = null, $expectedDocument)
+    {
+        $this->createFixtures(1);
+
+        $operation = new FindAndModify(
+            $this->getDatabaseName(),
+            $this->getCollectionName(),
+            [
+                'remove' => true,
+                'typeMap' => $typeMap,
+            ]
+        );
+        $document = $operation->execute($this->getPrimaryServer());
+
+        $this->assertEquals($expectedDocument, $document);
+    }
+
+    public function provideTypeMapOptionsAndExpectedDocument()
+    {
+        return [
+            [
+                null,
+                (object) ['_id' => 1, 'x' => (object) ['foo' => 'bar']],
+            ],
+            [
+                ['root' => 'array', 'document' => 'array'],
+                ['_id' => 1, 'x' => ['foo' => 'bar']],
+            ],
+            [
+                ['root' => 'object', 'document' => 'array'],
+                (object) ['_id' => 1, 'x' => ['foo' => 'bar']],
+            ],
+            [
+                ['root' => 'array', 'document' => 'stdClass'],
+                ['_id' => 1, 'x' => (object) ['foo' => 'bar']],
+            ],
+            [
+                ['root' => BSONDocument::class, 'document' => 'object'],
+                new BSONDocument(['_id' => 1, 'x' => (object) ['foo' => 'bar']]),
+            ],
+            [
+                ['root' => 'array', 'document' => 'stdClass', 'fieldPaths' => ['x' => 'array']],
+                ['_id' => 1, 'x' => ['foo' => 'bar']],
+            ],
+        ];
+    }
+
+    /**
+     * Create data fixtures.
+     *
+     * @param integer $n
+     */
+    private function createFixtures($n)
+    {
+        $bulkWrite = new BulkWrite(['ordered' => true]);
+
+        for ($i = 1; $i <= $n; $i++) {
+            $bulkWrite->insert([
+                '_id' => $i,
+                'x' => (object) ['foo' => 'bar'],
+            ]);
+        }
+
+        $result = $this->manager->executeBulkWrite($this->getNamespace(), $bulkWrite);
+
+        $this->assertEquals($n, $result->getInsertedCount());
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/FindAndModifyTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/FindAndModifyTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..7f5cb99cc996b1ded7f5df827070fdb0e613c5af
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/FindAndModifyTest.php	
@@ -0,0 +1,88 @@
+<?php
+
+namespace MongoDB\Tests\Operation;
+
+use MongoDB\Exception\InvalidArgumentException;
+use MongoDB\Operation\FindAndModify;
+
+class FindAndModifyTest extends TestCase
+{
+    /**
+     * @dataProvider provideInvalidConstructorOptions
+     */
+    public function testConstructorOptionTypeChecks(array $options)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        new FindAndModify($this->getDatabaseName(), $this->getCollectionName(), $options);
+    }
+
+    public function provideInvalidConstructorOptions()
+    {
+        $options = [];
+
+        foreach ($this->getInvalidArrayValues() as $value) {
+            $options[][] = ['arrayFilters' => $value];
+        }
+
+        foreach ($this->getInvalidBooleanValues() as $value) {
+            $options[][] = ['bypassDocumentValidation' => $value];
+        }
+
+        foreach ($this->getInvalidDocumentValues() as $value) {
+            $options[][] = ['collation' => $value];
+        }
+
+        foreach ($this->getInvalidDocumentValues() as $value) {
+            $options[][] = ['fields' => $value];
+        }
+
+        foreach ($this->getInvalidIntegerValues() as $value) {
+            $options[][] = ['maxTimeMS' => $value];
+        }
+
+        foreach ($this->getInvalidBooleanValues(true) as $value) {
+            $options[][] = ['new' => $value];
+        }
+
+        foreach ($this->getInvalidDocumentValues() as $value) {
+            $options[][] = ['query' => $value];
+        }
+
+        foreach ($this->getInvalidBooleanValues(true) as $value) {
+            $options[][] = ['remove' => $value];
+        }
+
+        foreach ($this->getInvalidSessionValues() as $value) {
+            $options[][] = ['session' => $value];
+        }
+
+        foreach ($this->getInvalidDocumentValues() as $value) {
+            $options[][] = ['sort' => $value];
+        }
+
+        foreach ($this->getInvalidArrayValues() as $value) {
+            $options[][] = ['typeMap' => $value];
+        }
+
+        foreach ($this->getInvalidDocumentValues() as $value) {
+            $options[][] = ['update' => $value];
+        }
+
+        foreach ($this->getInvalidBooleanValues(true) as $value) {
+            $options[][] = ['upsert' => $value];
+        }
+
+        foreach ($this->getInvalidWriteConcernValues() as $value) {
+            $options[][] = ['writeConcern' => $value];
+        }
+
+        return $options;
+    }
+
+    public function testConstructorUpdateAndRemoveOptionsAreMutuallyExclusive()
+    {
+        $this->expectException(InvalidArgumentException::class);
+        $this->expectExceptionMessage('The "remove" option must be true or an "update" document must be specified, but not both');
+        new FindAndModify($this->getDatabaseName(), $this->getCollectionName(), ['remove' => true, 'update' => []]);
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/FindFunctionalTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/FindFunctionalTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..1aff69e50a97ed96817e08c570de326740f5a5e7
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/FindFunctionalTest.php	
@@ -0,0 +1,278 @@
+<?php
+
+namespace MongoDB\Tests\Operation;
+
+use IteratorIterator;
+use MongoDB\Driver\BulkWrite;
+use MongoDB\Driver\ReadPreference;
+use MongoDB\Operation\CreateCollection;
+use MongoDB\Operation\CreateIndexes;
+use MongoDB\Operation\Find;
+use MongoDB\Tests\CommandObserver;
+use function microtime;
+use function version_compare;
+
+class FindFunctionalTest extends FunctionalTestCase
+{
+    public function testDefaultReadConcernIsOmitted()
+    {
+        (new CommandObserver())->observe(
+            function () {
+                $operation = new Find(
+                    $this->getDatabaseName(),
+                    $this->getCollectionName(),
+                    [],
+                    ['readConcern' => $this->createDefaultReadConcern()]
+                );
+
+                $operation->execute($this->getPrimaryServer());
+            },
+            function (array $event) {
+                $this->assertObjectNotHasAttribute('readConcern', $event['started']->getCommand());
+            }
+        );
+    }
+
+    public function testHintOption()
+    {
+        $bulkWrite = new BulkWrite();
+        $bulkWrite->insert(['_id' => 1, 'x' => 1]);
+        $bulkWrite->insert(['_id' => 2, 'x' => 2]);
+        $bulkWrite->insert(['_id' => 3, 'y' => 3]);
+        $this->manager->executeBulkWrite($this->getNamespace(), $bulkWrite);
+
+        $createIndexes = new CreateIndexes($this->getDatabaseName(), $this->getCollectionName(), [
+            ['key' => ['x' => 1], 'sparse' => true, 'name' => 'sparse_x'],
+            ['key' => ['y' => 1]],
+        ]);
+        $createIndexes->execute($this->getPrimaryServer());
+
+        $hintsUsingSparseIndex = [
+            ['x' => 1],
+            'sparse_x',
+        ];
+
+        foreach ($hintsUsingSparseIndex as $hint) {
+            $operation = new Find($this->getDatabaseName(), $this->getCollectionName(), [], ['hint' => $hint]);
+            $cursor = $operation->execute($this->getPrimaryServer());
+
+            $expectedDocuments = [
+                (object) ['_id' => 1, 'x' => 1],
+                (object) ['_id' => 2, 'x' => 2],
+            ];
+
+            $this->assertEquals($expectedDocuments, $cursor->toArray());
+        }
+
+        $hintsNotUsingSparseIndex = [
+            ['_id' => 1],
+            ['y' => 1],
+            'y_1',
+        ];
+
+        foreach ($hintsNotUsingSparseIndex as $hint) {
+            $operation = new Find($this->getDatabaseName(), $this->getCollectionName(), [], ['hint' => $hint]);
+            $cursor = $operation->execute($this->getPrimaryServer());
+
+            $expectedDocuments = [
+                (object) ['_id' => 1, 'x' => 1],
+                (object) ['_id' => 2, 'x' => 2],
+                (object) ['_id' => 3, 'y' => 3],
+            ];
+
+            $this->assertEquals($expectedDocuments, $cursor->toArray());
+        }
+    }
+
+    public function testSessionOption()
+    {
+        if (version_compare($this->getServerVersion(), '3.6.0', '<')) {
+            $this->markTestSkipped('Sessions are not supported');
+        }
+
+        (new CommandObserver())->observe(
+            function () {
+                $operation = new Find(
+                    $this->getDatabaseName(),
+                    $this->getCollectionName(),
+                    [],
+                    ['session' => $this->createSession()]
+                );
+
+                $operation->execute($this->getPrimaryServer());
+            },
+            function (array $event) {
+                $this->assertObjectHasAttribute('lsid', $event['started']->getCommand());
+            }
+        );
+    }
+
+    /**
+     * @dataProvider provideTypeMapOptionsAndExpectedDocuments
+     */
+    public function testTypeMapOption(array $typeMap, array $expectedDocuments)
+    {
+        $this->createFixtures(3);
+
+        $operation = new Find($this->getDatabaseName(), $this->getCollectionName(), [], ['typeMap' => $typeMap]);
+        $cursor = $operation->execute($this->getPrimaryServer());
+
+        $this->assertEquals($expectedDocuments, $cursor->toArray());
+    }
+
+    public function provideTypeMapOptionsAndExpectedDocuments()
+    {
+        return [
+            [
+                ['root' => 'array', 'document' => 'array'],
+                [
+                    ['_id' => 1, 'x' => ['foo' => 'bar']],
+                    ['_id' => 2, 'x' => ['foo' => 'bar']],
+                    ['_id' => 3, 'x' => ['foo' => 'bar']],
+                ],
+            ],
+            [
+                ['root' => 'object', 'document' => 'array'],
+                [
+                    (object) ['_id' => 1, 'x' => ['foo' => 'bar']],
+                    (object) ['_id' => 2, 'x' => ['foo' => 'bar']],
+                    (object) ['_id' => 3, 'x' => ['foo' => 'bar']],
+                ],
+            ],
+            [
+                ['root' => 'array', 'document' => 'stdClass'],
+                [
+                    ['_id' => 1, 'x' => (object) ['foo' => 'bar']],
+                    ['_id' => 2, 'x' => (object) ['foo' => 'bar']],
+                    ['_id' => 3, 'x' => (object) ['foo' => 'bar']],
+                ],
+            ],
+        ];
+    }
+
+    public function testMaxAwaitTimeMS()
+    {
+        if (version_compare($this->getServerVersion(), '3.2.0', '<')) {
+            $this->markTestSkipped('maxAwaitTimeMS option is not supported');
+        }
+
+        $maxAwaitTimeMS = 100;
+
+        /* Calculate an approximate pivot to use for time assertions. We will
+         * assert that the duration of blocking responses is greater than this
+         * value, and vice versa. */
+        $pivot = $maxAwaitTimeMS * 0.001 * 0.9;
+
+        // Create a capped collection.
+        $databaseName = $this->getDatabaseName();
+        $cappedCollectionName = $this->getCollectionName();
+        $cappedCollectionOptions = [
+            'capped' => true,
+            'max' => 100,
+            'size' => 1048576,
+        ];
+
+        $operation = new CreateCollection($databaseName, $cappedCollectionName, $cappedCollectionOptions);
+        $operation->execute($this->getPrimaryServer());
+
+        // Insert documents into the capped collection.
+        $bulkWrite = new BulkWrite(['ordered' => true]);
+        $bulkWrite->insert(['_id' => 1]);
+        $bulkWrite->insert(['_id' => 2]);
+        $result = $this->manager->executeBulkWrite($this->getNamespace(), $bulkWrite);
+
+        $operation = new Find($databaseName, $cappedCollectionName, [], ['cursorType' => Find::TAILABLE_AWAIT, 'maxAwaitTimeMS' => $maxAwaitTimeMS]);
+        $cursor = $operation->execute($this->getPrimaryServer());
+        $it = new IteratorIterator($cursor);
+
+        /* The initial query includes the one and only document in its result
+         * batch, so we should not expect a delay. */
+        $startTime = microtime(true);
+        $it->rewind();
+        $duration = microtime(true) - $startTime;
+        $this->assertLessThan($pivot, $duration);
+
+        $this->assertTrue($it->valid());
+        $this->assertSameDocument(['_id' => 1], $it->current());
+
+        /* Advancing again takes us to the last document of the result batch,
+         * but still should not issue a getMore */
+        $startTime = microtime(true);
+        $it->next();
+        $duration = microtime(true) - $startTime;
+        $this->assertLessThan($pivot, $duration);
+
+        $this->assertTrue($it->valid());
+        $this->assertSameDocument(['_id' => 2], $it->current());
+
+        /* Now that we've reached the end of the initial result batch, advancing
+         * again will issue a getMore. Expect to wait at least maxAwaitTimeMS,
+         * since no new documents should be inserted to wake up the server's
+         * query thread. Also ensure we don't wait too long (server default is
+         * one second). */
+        $startTime = microtime(true);
+        $it->next();
+        $duration = microtime(true) - $startTime;
+        $this->assertGreaterThan($pivot, $duration);
+        $this->assertLessThan(0.5, $duration);
+
+        $this->assertFalse($it->valid());
+    }
+
+    public function testReadPreferenceWithinTransaction()
+    {
+        $this->skipIfTransactionsAreNotSupported();
+
+        // Collection must be created before the transaction starts
+        $this->createCollection();
+
+        $session = $this->manager->startSession();
+        $session->startTransaction();
+
+        try {
+            $this->createFixtures(3, ['session' => $session]);
+
+            $filter = ['_id' => ['$lt' => 3]];
+            $options = [
+                'readPreference' => new ReadPreference('primary'),
+                'session' => $session,
+            ];
+
+            $operation = new Find($this->getDatabaseName(), $this->getCollectionName(), $filter, $options);
+            $cursor = $operation->execute($this->getPrimaryServer());
+
+            $expected = [
+                ['_id' => 1, 'x' => ['foo' => 'bar']],
+                ['_id' => 2, 'x' => ['foo' => 'bar']],
+            ];
+
+            $this->assertSameDocuments($expected, $cursor);
+
+            $session->commitTransaction();
+        } finally {
+            $session->endSession();
+        }
+    }
+
+    /**
+     * Create data fixtures.
+     *
+     * @param integer $n
+     * @param array   $executeBulkWriteOptions
+     */
+    private function createFixtures($n, array $executeBulkWriteOptions = [])
+    {
+        $bulkWrite = new BulkWrite(['ordered' => true]);
+
+        for ($i = 1; $i <= $n; $i++) {
+            $bulkWrite->insert([
+                '_id' => $i,
+                'x' => (object) ['foo' => 'bar'],
+            ]);
+        }
+
+        $result = $this->manager->executeBulkWrite($this->getNamespace(), $bulkWrite, $executeBulkWriteOptions);
+
+        $this->assertEquals($n, $result->getInsertedCount());
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/FindOneAndDeleteTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/FindOneAndDeleteTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..306ec3568c92203de328e6531c8b8915bf463ba4
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/FindOneAndDeleteTest.php	
@@ -0,0 +1,38 @@
+<?php
+
+namespace MongoDB\Tests\Operation;
+
+use MongoDB\Exception\InvalidArgumentException;
+use MongoDB\Operation\FindOneAndDelete;
+
+class FindOneAndDeleteTest extends TestCase
+{
+    /**
+     * @dataProvider provideInvalidDocumentValues
+     */
+    public function testConstructorFilterArgumentTypeCheck($filter)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        new FindOneAndDelete($this->getDatabaseName(), $this->getCollectionName(), $filter);
+    }
+
+    /**
+     * @dataProvider provideInvalidConstructorOptions
+     */
+    public function testConstructorOptionTypeChecks(array $options)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        new FindOneAndDelete($this->getDatabaseName(), $this->getCollectionName(), [], $options);
+    }
+
+    public function provideInvalidConstructorOptions()
+    {
+        $options = [];
+
+        foreach ($this->getInvalidDocumentValues() as $value) {
+            $options[][] = ['projection' => $value];
+        }
+
+        return $options;
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/FindOneAndReplaceTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/FindOneAndReplaceTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..974d413a3d355a06b39e8d12d968133a9359fe00
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/FindOneAndReplaceTest.php	
@@ -0,0 +1,72 @@
+<?php
+
+namespace MongoDB\Tests\Operation;
+
+use MongoDB\Exception\InvalidArgumentException;
+use MongoDB\Operation\FindOneAndReplace;
+
+class FindOneAndReplaceTest extends TestCase
+{
+    /**
+     * @dataProvider provideInvalidDocumentValues
+     */
+    public function testConstructorFilterArgumentTypeCheck($filter)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        new FindOneAndReplace($this->getDatabaseName(), $this->getCollectionName(), $filter, []);
+    }
+
+    /**
+     * @dataProvider provideInvalidDocumentValues
+     */
+    public function testConstructorReplacementArgumentTypeCheck($replacement)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        new FindOneAndReplace($this->getDatabaseName(), $this->getCollectionName(), [], $replacement);
+    }
+
+    public function testConstructorReplacementArgumentRequiresNoOperators()
+    {
+        $this->expectException(InvalidArgumentException::class);
+        $this->expectExceptionMessage('First key in $replacement argument is an update operator');
+        new FindOneAndReplace($this->getDatabaseName(), $this->getCollectionName(), [], ['$set' => ['x' => 1]]);
+    }
+
+    /**
+     * @dataProvider provideInvalidConstructorOptions
+     */
+    public function testConstructorOptionTypeChecks(array $options)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        new FindOneAndReplace($this->getDatabaseName(), $this->getCollectionName(), [], [], $options);
+    }
+
+    public function provideInvalidConstructorOptions()
+    {
+        $options = [];
+
+        foreach ($this->getInvalidDocumentValues() as $value) {
+            $options[][] = ['projection' => $value];
+        }
+
+        foreach ($this->getInvalidIntegerValues(true) as $value) {
+            $options[][] = ['returnDocument' => $value];
+        }
+
+        return $options;
+    }
+
+    /**
+     * @dataProvider provideInvalidConstructorReturnDocumentOptions
+     */
+    public function testConstructorReturnDocumentOption($returnDocument)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        new FindOneAndReplace($this->getDatabaseName(), $this->getCollectionName(), [], [], ['returnDocument' => $returnDocument]);
+    }
+
+    public function provideInvalidConstructorReturnDocumentOptions()
+    {
+        return $this->wrapValuesForDataProvider([-1, 0, 3]);
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/FindOneAndUpdateTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/FindOneAndUpdateTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..1391b7623a4167676e152b22e64627b8cc6af179
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/FindOneAndUpdateTest.php	
@@ -0,0 +1,72 @@
+<?php
+
+namespace MongoDB\Tests\Operation;
+
+use MongoDB\Exception\InvalidArgumentException;
+use MongoDB\Operation\FindOneAndUpdate;
+
+class FindOneAndUpdateTest extends TestCase
+{
+    /**
+     * @dataProvider provideInvalidDocumentValues
+     */
+    public function testConstructorFilterArgumentTypeCheck($filter)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        new FindOneAndUpdate($this->getDatabaseName(), $this->getCollectionName(), $filter, []);
+    }
+
+    /**
+     * @dataProvider provideInvalidDocumentValues
+     */
+    public function testConstructorUpdateArgumentTypeCheck($update)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        new FindOneAndUpdate($this->getDatabaseName(), $this->getCollectionName(), [], $update);
+    }
+
+    public function testConstructorUpdateArgumentRequiresOperatorsOrPipeline()
+    {
+        $this->expectException(InvalidArgumentException::class);
+        $this->expectExceptionMessage('Expected an update document with operator as first key or a pipeline');
+        new FindOneAndUpdate($this->getDatabaseName(), $this->getCollectionName(), [], []);
+    }
+
+    /**
+     * @dataProvider provideInvalidConstructorOptions
+     */
+    public function testConstructorOptionTypeChecks(array $options)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        new FindOneAndUpdate($this->getDatabaseName(), $this->getCollectionName(), [], ['$set' => ['x' => 1]], $options);
+    }
+
+    public function provideInvalidConstructorOptions()
+    {
+        $options = [];
+
+        foreach ($this->getInvalidDocumentValues() as $value) {
+            $options[][] = ['projection' => $value];
+        }
+
+        foreach ($this->getInvalidIntegerValues(true) as $value) {
+            $options[][] = ['returnDocument' => $value];
+        }
+
+        return $options;
+    }
+
+    /**
+     * @dataProvider provideInvalidConstructorReturnDocumentOptions
+     */
+    public function testConstructorReturnDocumentOption($returnDocument)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        new FindOneAndUpdate($this->getDatabaseName(), $this->getCollectionName(), [], [], ['returnDocument' => $returnDocument]);
+    }
+
+    public function provideInvalidConstructorReturnDocumentOptions()
+    {
+        return $this->wrapValuesForDataProvider([-1, 0, 3]);
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/FindOneFunctionalTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/FindOneFunctionalTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..62fac82871b19db609ff510b847d614c16d67574
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/FindOneFunctionalTest.php	
@@ -0,0 +1,61 @@
+<?php
+
+namespace MongoDB\Tests\Operation;
+
+use MongoDB\Driver\BulkWrite;
+use MongoDB\Operation\FindOne;
+
+class FindOneFunctionalTest extends FunctionalTestCase
+{
+    /**
+     * @dataProvider provideTypeMapOptionsAndExpectedDocument
+     */
+    public function testTypeMapOption(array $typeMap, $expectedDocument)
+    {
+        $this->createFixtures(1);
+
+        $operation = new FindOne($this->getDatabaseName(), $this->getCollectionName(), [], ['typeMap' => $typeMap]);
+        $document = $operation->execute($this->getPrimaryServer());
+
+        $this->assertEquals($expectedDocument, $document);
+    }
+
+    public function provideTypeMapOptionsAndExpectedDocument()
+    {
+        return [
+            [
+                ['root' => 'array', 'document' => 'array'],
+                ['_id' => 1, 'x' => ['foo' => 'bar']],
+            ],
+            [
+                ['root' => 'object', 'document' => 'array'],
+                (object) ['_id' => 1, 'x' => ['foo' => 'bar']],
+            ],
+            [
+                ['root' => 'array', 'document' => 'stdClass'],
+                ['_id' => 1, 'x' => (object) ['foo' => 'bar']],
+            ],
+        ];
+    }
+
+    /**
+     * Create data fixtures.
+     *
+     * @param integer $n
+     */
+    private function createFixtures($n)
+    {
+        $bulkWrite = new BulkWrite(['ordered' => true]);
+
+        for ($i = 1; $i <= $n; $i++) {
+            $bulkWrite->insert([
+                '_id' => $i,
+                'x' => (object) ['foo' => 'bar'],
+            ]);
+        }
+
+        $result = $this->manager->executeBulkWrite($this->getNamespace(), $bulkWrite);
+
+        $this->assertEquals($n, $result->getInsertedCount());
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/FindTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/FindTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..4464ea5a89872ea5146cf48a93585aac2270bc69
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/FindTest.php	
@@ -0,0 +1,167 @@
+<?php
+
+namespace MongoDB\Tests\Operation;
+
+use MongoDB\Exception\InvalidArgumentException;
+use MongoDB\Operation\Find;
+
+class FindTest extends TestCase
+{
+    /**
+     * @dataProvider provideInvalidDocumentValues
+     */
+    public function testConstructorFilterArgumentTypeCheck($filter)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        new Find($this->getDatabaseName(), $this->getCollectionName(), $filter);
+    }
+
+    /**
+     * @dataProvider provideInvalidConstructorOptions
+     */
+    public function testConstructorOptionTypeChecks(array $options)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        new Find($this->getDatabaseName(), $this->getCollectionName(), [], $options);
+    }
+
+    public function provideInvalidConstructorOptions()
+    {
+        $options = [];
+
+        foreach ($this->getInvalidBooleanValues() as $value) {
+            $options[][] = ['allowPartialResults' => $value];
+        }
+
+        foreach ($this->getInvalidIntegerValues() as $value) {
+            $options[][] = ['batchSize' => $value];
+        }
+
+        foreach ($this->getInvalidDocumentValues() as $value) {
+            $options[][] = ['collation' => $value];
+        }
+
+        foreach ($this->getInvalidStringValues() as $value) {
+            $options[][] = ['comment' => $value];
+        }
+
+        foreach ($this->getInvalidIntegerValues() as $value) {
+            $options[][] = ['cursorType' => $value];
+        }
+
+        foreach ($this->getInvalidHintValues() as $value) {
+            $options[][] = ['hint' => $value];
+        }
+
+        foreach ($this->getInvalidIntegerValues() as $value) {
+            $options[][] = ['limit' => $value];
+        }
+
+        foreach ($this->getInvalidDocumentValues() as $value) {
+            $options[][] = ['max' => $value];
+        }
+
+        foreach ($this->getInvalidIntegerValues() as $value) {
+            $options[][] = ['maxAwaitTimeMS' => $value];
+        }
+
+        foreach ($this->getInvalidIntegerValues() as $value) {
+            $options[][] = ['maxScan' => $value];
+        }
+
+        foreach ($this->getInvalidIntegerValues() as $value) {
+            $options[][] = ['maxTimeMS' => $value];
+        }
+
+        foreach ($this->getInvalidDocumentValues() as $value) {
+            $options[][] = ['min' => $value];
+        }
+
+        foreach ($this->getInvalidDocumentValues() as $value) {
+            $options[][] = ['modifiers' => $value];
+        }
+
+        foreach ($this->getInvalidBooleanValues() as $value) {
+            $options[][] = ['oplogReplay' => $value];
+        }
+
+        foreach ($this->getInvalidDocumentValues() as $value) {
+            $options[][] = ['projection' => $value];
+        }
+
+        foreach ($this->getInvalidReadConcernValues() as $value) {
+            $options[][] = ['readConcern' => $value];
+        }
+
+        foreach ($this->getInvalidReadPreferenceValues() as $value) {
+            $options[][] = ['readPreference' => $value];
+        }
+
+        foreach ($this->getInvalidBooleanValues() as $value) {
+            $options[][] = ['returnKey' => $value];
+        }
+
+        foreach ($this->getInvalidSessionValues() as $value) {
+            $options[][] = ['session' => $value];
+        }
+
+        foreach ($this->getInvalidBooleanValues() as $value) {
+            $options[][] = ['showRecordId' => $value];
+        }
+
+        foreach ($this->getInvalidIntegerValues() as $value) {
+            $options[][] = ['skip' => $value];
+        }
+
+        foreach ($this->getInvalidBooleanValues() as $value) {
+            $options[][] = ['snapshot' => $value];
+        }
+
+        foreach ($this->getInvalidDocumentValues() as $value) {
+            $options[][] = ['sort' => $value];
+        }
+
+        foreach ($this->getInvalidArrayValues() as $value) {
+            $options[][] = ['typeMap' => $value];
+        }
+
+        return $options;
+    }
+
+    public function testSnapshotOptionIsDeprecated()
+    {
+        $this->assertDeprecated(function () {
+            new Find($this->getDatabaseName(), $this->getCollectionName(), [], ['snapshot' => true]);
+        });
+
+        $this->assertDeprecated(function () {
+            new Find($this->getDatabaseName(), $this->getCollectionName(), [], ['snapshot' => false]);
+        });
+    }
+
+    public function testMaxScanOptionIsDeprecated()
+    {
+        $this->assertDeprecated(function () {
+            new Find($this->getDatabaseName(), $this->getCollectionName(), [], ['maxScan' => 1]);
+        });
+    }
+
+    private function getInvalidHintValues()
+    {
+        return [123, 3.14, true];
+    }
+
+    /**
+     * @dataProvider provideInvalidConstructorCursorTypeOptions
+     */
+    public function testConstructorCursorTypeOption($cursorType)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        new Find($this->getDatabaseName(), $this->getCollectionName(), [], ['cursorType' => $cursorType]);
+    }
+
+    public function provideInvalidConstructorCursorTypeOptions()
+    {
+        return $this->wrapValuesForDataProvider([-1, 0, 4]);
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/FunctionalTestCase.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/FunctionalTestCase.php
new file mode 100644
index 0000000000000000000000000000000000000000..ef4e76b7c8a3dd54240792ce11937bb4c83b5173
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/FunctionalTestCase.php	
@@ -0,0 +1,49 @@
+<?php
+
+namespace MongoDB\Tests\Operation;
+
+use MongoDB\Driver\ReadConcern;
+use MongoDB\Driver\WriteConcern;
+use MongoDB\Tests\FunctionalTestCase as BaseFunctionalTestCase;
+use Symfony\Bridge\PhpUnit\SetUpTearDownTrait;
+
+/**
+ * Base class for Operation functional tests.
+ */
+abstract class FunctionalTestCase extends BaseFunctionalTestCase
+{
+    use SetUpTearDownTrait;
+
+    private function doSetUp()
+    {
+        parent::setUp();
+
+        $this->dropCollection();
+    }
+
+    private function doTearDown()
+    {
+        if ($this->hasFailed()) {
+            return;
+        }
+
+        $this->dropCollection();
+
+        parent::tearDown();
+    }
+
+    protected function createDefaultReadConcern()
+    {
+        return new ReadConcern();
+    }
+
+    protected function createDefaultWriteConcern()
+    {
+        return new WriteConcern(-2);
+    }
+
+    protected function createSession()
+    {
+        return $this->manager->startSession();
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/InsertManyFunctionalTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/InsertManyFunctionalTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..d8f105d64f052291f4a3c4854fad5be2f4ccc3e1
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/InsertManyFunctionalTest.php	
@@ -0,0 +1,161 @@
+<?php
+
+namespace MongoDB\Tests\Operation;
+
+use MongoDB\BSON\ObjectId;
+use MongoDB\Collection;
+use MongoDB\Driver\WriteConcern;
+use MongoDB\Exception\BadMethodCallException;
+use MongoDB\InsertManyResult;
+use MongoDB\Model\BSONDocument;
+use MongoDB\Operation\InsertMany;
+use MongoDB\Tests\CommandObserver;
+use Symfony\Bridge\PhpUnit\SetUpTearDownTrait;
+use function version_compare;
+
+class InsertManyFunctionalTest extends FunctionalTestCase
+{
+    use SetUpTearDownTrait;
+
+    /** @var Collection */
+    private $collection;
+
+    private function doSetUp()
+    {
+        parent::setUp();
+
+        $this->collection = new Collection($this->manager, $this->getDatabaseName(), $this->getCollectionName());
+    }
+
+    public function testInsertMany()
+    {
+        $documents = [
+            ['_id' => 'foo', 'x' => 11],
+            ['x' => 22],
+            (object) ['_id' => 'bar', 'x' => 33],
+            new BSONDocument(['_id' => 'baz', 'x' => 44]),
+        ];
+
+        $operation = new InsertMany($this->getDatabaseName(), $this->getCollectionName(), $documents);
+        $result = $operation->execute($this->getPrimaryServer());
+
+        $this->assertInstanceOf(InsertManyResult::class, $result);
+        $this->assertSame(4, $result->getInsertedCount());
+
+        $insertedIds = $result->getInsertedIds();
+        $this->assertSame('foo', $insertedIds[0]);
+        $this->assertInstanceOf(ObjectId::class, $insertedIds[1]);
+        $this->assertSame('bar', $insertedIds[2]);
+        $this->assertSame('baz', $insertedIds[3]);
+
+        $expected = [
+            ['_id' => 'foo', 'x' => 11],
+            ['_id' => $insertedIds[1], 'x' => 22],
+            ['_id' => 'bar', 'x' => 33],
+            ['_id' => 'baz', 'x' => 44],
+        ];
+
+        $this->assertSameDocuments($expected, $this->collection->find());
+    }
+
+    public function testSessionOption()
+    {
+        if (version_compare($this->getServerVersion(), '3.6.0', '<')) {
+            $this->markTestSkipped('Sessions are not supported');
+        }
+
+        (new CommandObserver())->observe(
+            function () {
+                $operation = new InsertMany(
+                    $this->getDatabaseName(),
+                    $this->getCollectionName(),
+                    [['_id' => 1], ['_id' => 2]],
+                    ['session' => $this->createSession()]
+                );
+
+                $operation->execute($this->getPrimaryServer());
+            },
+            function (array $event) {
+                $this->assertObjectHasAttribute('lsid', $event['started']->getCommand());
+            }
+        );
+    }
+
+    public function testBypassDocumentValidationSetWhenTrue()
+    {
+        if (version_compare($this->getServerVersion(), '3.2.0', '<')) {
+            $this->markTestSkipped('bypassDocumentValidation is not supported');
+        }
+
+        (new CommandObserver())->observe(
+            function () {
+                $operation = new InsertMany(
+                    $this->getDatabaseName(),
+                    $this->getCollectionName(),
+                    [['_id' => 1], ['_id' => 2]],
+                    ['bypassDocumentValidation' => true]
+                );
+
+                $operation->execute($this->getPrimaryServer());
+            },
+            function (array $event) {
+                $this->assertObjectHasAttribute('bypassDocumentValidation', $event['started']->getCommand());
+                $this->assertEquals(true, $event['started']->getCommand()->bypassDocumentValidation);
+            }
+        );
+    }
+
+    public function testBypassDocumentValidationUnsetWhenFalse()
+    {
+        if (version_compare($this->getServerVersion(), '3.2.0', '<')) {
+            $this->markTestSkipped('bypassDocumentValidation is not supported');
+        }
+
+        (new CommandObserver())->observe(
+            function () {
+                $operation = new InsertMany(
+                    $this->getDatabaseName(),
+                    $this->getCollectionName(),
+                    [['_id' => 1], ['_id' => 2]],
+                    ['bypassDocumentValidation' => false]
+                );
+
+                $operation->execute($this->getPrimaryServer());
+            },
+            function (array $event) {
+                $this->assertObjectNotHasAttribute('bypassDocumentValidation', $event['started']->getCommand());
+            }
+        );
+    }
+
+    public function testUnacknowledgedWriteConcern()
+    {
+        $documents = [['x' => 11]];
+        $options = ['writeConcern' => new WriteConcern(0)];
+
+        $operation = new InsertMany($this->getDatabaseName(), $this->getCollectionName(), $documents, $options);
+        $result = $operation->execute($this->getPrimaryServer());
+
+        $this->assertFalse($result->isAcknowledged());
+
+        return $result;
+    }
+
+    /**
+     * @depends testUnacknowledgedWriteConcern
+     */
+    public function testUnacknowledgedWriteConcernAccessesInsertedCount(InsertManyResult $result)
+    {
+        $this->expectException(BadMethodCallException::class);
+        $this->expectExceptionMessageMatches('/[\w:\\\\]+ should not be called for an unacknowledged write result/');
+        $result->getInsertedCount();
+    }
+
+    /**
+     * @depends testUnacknowledgedWriteConcern
+     */
+    public function testUnacknowledgedWriteConcernAccessesInsertedId(InsertManyResult $result)
+    {
+        $this->assertInstanceOf(ObjectId::class, $result->getInsertedIds()[0]);
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/InsertManyTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/InsertManyTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..38955fd588b7486f90fcfcbd8893dca81b9637ad
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/InsertManyTest.php	
@@ -0,0 +1,65 @@
+<?php
+
+namespace MongoDB\Tests\Operation;
+
+use MongoDB\Exception\InvalidArgumentException;
+use MongoDB\Operation\InsertMany;
+
+class InsertManyTest extends TestCase
+{
+    public function testConstructorDocumentsMustNotBeEmpty()
+    {
+        $this->expectException(InvalidArgumentException::class);
+        $this->expectExceptionMessage('$documents is empty');
+        new InsertMany($this->getDatabaseName(), $this->getCollectionName(), []);
+    }
+
+    public function testConstructorDocumentsMustBeAList()
+    {
+        $this->expectException(InvalidArgumentException::class);
+        $this->expectExceptionMessage('$documents is not a list (unexpected index: "1")');
+        new InsertMany($this->getDatabaseName(), $this->getCollectionName(), [1 => ['x' => 1]]);
+    }
+
+    /**
+     * @dataProvider provideInvalidDocumentValues
+     */
+    public function testConstructorDocumentsArgumentElementTypeChecks($document)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        $this->expectExceptionMessageMatches('/Expected \$documents[0\] to have type "array or object" but found "[\w ]+"/');
+        new InsertMany($this->getDatabaseName(), $this->getCollectionName(), [$document]);
+    }
+
+    /**
+     * @dataProvider provideInvalidConstructorOptions
+     */
+    public function testConstructorOptionTypeChecks(array $options)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        new InsertMany($this->getDatabaseName(), $this->getCollectionName(), [['x' => 1]], $options);
+    }
+
+    public function provideInvalidConstructorOptions()
+    {
+        $options = [];
+
+        foreach ($this->getInvalidBooleanValues() as $value) {
+            $options[][] = ['bypassDocumentValidation' => $value];
+        }
+
+        foreach ($this->getInvalidBooleanValues(true) as $value) {
+            $options[][] = ['ordered' => $value];
+        }
+
+        foreach ($this->getInvalidSessionValues() as $value) {
+            $options[][] = ['session' => $value];
+        }
+
+        foreach ($this->getInvalidWriteConcernValues() as $value) {
+            $options[][] = ['writeConcern' => $value];
+        }
+
+        return $options;
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/InsertOneFunctionalTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/InsertOneFunctionalTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..b0eefded90262734c4e39c04ef3c24664919ade7
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/InsertOneFunctionalTest.php	
@@ -0,0 +1,176 @@
+<?php
+
+namespace MongoDB\Tests\Operation;
+
+use MongoDB\BSON\ObjectId;
+use MongoDB\Collection;
+use MongoDB\Driver\WriteConcern;
+use MongoDB\Exception\BadMethodCallException;
+use MongoDB\InsertOneResult;
+use MongoDB\Model\BSONDocument;
+use MongoDB\Operation\InsertOne;
+use MongoDB\Tests\CommandObserver;
+use Symfony\Bridge\PhpUnit\SetUpTearDownTrait;
+use function version_compare;
+
+class InsertOneFunctionalTest extends FunctionalTestCase
+{
+    use SetUpTearDownTrait;
+
+    /** @var Collection */
+    private $collection;
+
+    private function doSetUp()
+    {
+        parent::setUp();
+
+        $this->collection = new Collection($this->manager, $this->getDatabaseName(), $this->getCollectionName());
+    }
+
+    /**
+     * @dataProvider provideDocumentWithExistingId
+     */
+    public function testInsertOneWithExistingId($document)
+    {
+        $operation = new InsertOne($this->getDatabaseName(), $this->getCollectionName(), $document);
+        $result = $operation->execute($this->getPrimaryServer());
+
+        $this->assertInstanceOf(InsertOneResult::class, $result);
+        $this->assertSame(1, $result->getInsertedCount());
+        $this->assertSame('foo', $result->getInsertedId());
+
+        $expected = [
+            ['_id' => 'foo', 'x' => 11],
+        ];
+
+        $this->assertSameDocuments($expected, $this->collection->find());
+    }
+
+    public function provideDocumentWithExistingId()
+    {
+        return [
+            [['_id' => 'foo', 'x' => 11]],
+            [(object) ['_id' => 'foo', 'x' => 11]],
+            [new BSONDocument(['_id' => 'foo', 'x' => 11])],
+        ];
+    }
+
+    public function testInsertOneWithGeneratedId()
+    {
+        $document = ['x' => 11];
+
+        $operation = new InsertOne($this->getDatabaseName(), $this->getCollectionName(), $document);
+        $result = $operation->execute($this->getPrimaryServer());
+
+        $this->assertInstanceOf(InsertOneResult::class, $result);
+        $this->assertSame(1, $result->getInsertedCount());
+        $this->assertInstanceOf(ObjectId::class, $result->getInsertedId());
+
+        $expected = [
+            ['_id' => $result->getInsertedId(), 'x' => 11],
+        ];
+
+        $this->assertSameDocuments($expected, $this->collection->find());
+    }
+
+    public function testSessionOption()
+    {
+        if (version_compare($this->getServerVersion(), '3.6.0', '<')) {
+            $this->markTestSkipped('Sessions are not supported');
+        }
+
+        (new CommandObserver())->observe(
+            function () {
+                $operation = new InsertOne(
+                    $this->getDatabaseName(),
+                    $this->getCollectionName(),
+                    ['_id' => 1],
+                    ['session' => $this->createSession()]
+                );
+
+                $operation->execute($this->getPrimaryServer());
+            },
+            function (array $event) {
+                $this->assertObjectHasAttribute('lsid', $event['started']->getCommand());
+            }
+        );
+    }
+
+    public function testBypassDocumentValidationSetWhenTrue()
+    {
+        if (version_compare($this->getServerVersion(), '3.2.0', '<')) {
+            $this->markTestSkipped('bypassDocumentValidation is not supported');
+        }
+
+        (new CommandObserver())->observe(
+            function () {
+                $operation = new InsertOne(
+                    $this->getDatabaseName(),
+                    $this->getCollectionName(),
+                    ['_id' => 1],
+                    ['bypassDocumentValidation' => true]
+                );
+
+                $operation->execute($this->getPrimaryServer());
+            },
+            function (array $event) {
+                $this->assertObjectHasAttribute('bypassDocumentValidation', $event['started']->getCommand());
+                $this->assertEquals(true, $event['started']->getCommand()->bypassDocumentValidation);
+            }
+        );
+    }
+
+    public function testBypassDocumentValidationUnsetWhenFalse()
+    {
+        if (version_compare($this->getServerVersion(), '3.2.0', '<')) {
+            $this->markTestSkipped('bypassDocumentValidation is not supported');
+        }
+
+        (new CommandObserver())->observe(
+            function () {
+                $operation = new InsertOne(
+                    $this->getDatabaseName(),
+                    $this->getCollectionName(),
+                    ['_id' => 1],
+                    ['bypassDocumentValidation' => false]
+                );
+
+                $operation->execute($this->getPrimaryServer());
+            },
+            function (array $event) {
+                $this->assertObjectNotHasAttribute('bypassDocumentValidation', $event['started']->getCommand());
+            }
+        );
+    }
+
+    public function testUnacknowledgedWriteConcern()
+    {
+        $document = ['x' => 11];
+        $options = ['writeConcern' => new WriteConcern(0)];
+
+        $operation = new InsertOne($this->getDatabaseName(), $this->getCollectionName(), $document, $options);
+        $result = $operation->execute($this->getPrimaryServer());
+
+        $this->assertFalse($result->isAcknowledged());
+
+        return $result;
+    }
+
+    /**
+     * @depends testUnacknowledgedWriteConcern
+     */
+    public function testUnacknowledgedWriteConcernAccessesInsertedCount(InsertOneResult $result)
+    {
+        $this->expectException(BadMethodCallException::class);
+        $this->expectExceptionMessageMatches('/[\w:\\\\]+ should not be called for an unacknowledged write result/');
+        $result->getInsertedCount();
+    }
+
+    /**
+     * @depends testUnacknowledgedWriteConcern
+     */
+    public function testUnacknowledgedWriteConcernAccessesInsertedId(InsertOneResult $result)
+    {
+        $this->assertInstanceOf(ObjectId::class, $result->getInsertedId());
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/InsertOneTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/InsertOneTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..2a91f8cc0871c0b1d7b437f5be8528f66e919a59
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/InsertOneTest.php	
@@ -0,0 +1,46 @@
+<?php
+
+namespace MongoDB\Tests\Operation;
+
+use MongoDB\Exception\InvalidArgumentException;
+use MongoDB\Operation\InsertOne;
+
+class InsertOneTest extends TestCase
+{
+    /**
+     * @dataProvider provideInvalidDocumentValues
+     */
+    public function testConstructorDocumentArgumentTypeCheck($document)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        new InsertOne($this->getDatabaseName(), $this->getCollectionName(), $document);
+    }
+
+    /**
+     * @dataProvider provideInvalidConstructorOptions
+     */
+    public function testConstructorOptionTypeChecks(array $options)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        new InsertOne($this->getDatabaseName(), $this->getCollectionName(), ['x' => 1], $options);
+    }
+
+    public function provideInvalidConstructorOptions()
+    {
+        $options = [];
+
+        foreach ($this->getInvalidBooleanValues() as $value) {
+            $options[][] = ['bypassDocumentValidation' => $value];
+        }
+
+        foreach ($this->getInvalidSessionValues() as $value) {
+            $options[][] = ['session' => $value];
+        }
+
+        foreach ($this->getInvalidWriteConcernValues() as $value) {
+            $options[][] = ['writeConcern' => $value];
+        }
+
+        return $options;
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/ListCollectionNamesFunctionalTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/ListCollectionNamesFunctionalTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..dbb111ab748ee0ba27c57acc1219f697b1f4ce14
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/ListCollectionNamesFunctionalTest.php	
@@ -0,0 +1,53 @@
+<?php
+
+namespace MongoDB\Tests\Operation;
+
+use MongoDB\Operation\DropDatabase;
+use MongoDB\Operation\InsertOne;
+use MongoDB\Operation\ListCollectionNames;
+use MongoDB\Tests\CommandObserver;
+use function version_compare;
+
+class ListCollectionNamesFunctionalTest extends FunctionalTestCase
+{
+    public function testListCollectionNamesForNewlyCreatedDatabase()
+    {
+        $server = $this->getPrimaryServer();
+
+        $operation = new DropDatabase($this->getDatabaseName());
+        $operation->execute($server);
+
+        $insertOne = new InsertOne($this->getDatabaseName(), $this->getCollectionName(), ['x' => 1]);
+        $writeResult = $insertOne->execute($server);
+        $this->assertEquals(1, $writeResult->getInsertedCount());
+
+        $operation = new ListCollectionNames($this->getDatabaseName(), ['filter' => ['name' => $this->getCollectionName()]]);
+        $names = $operation->execute($server);
+        $this->assertCount(1, $names);
+
+        foreach ($names as $collection) {
+            $this->assertSame($this->getCollectionName(), $collection);
+        }
+    }
+
+    public function testSessionOption()
+    {
+        if (version_compare($this->getServerVersion(), '3.6.0', '<')) {
+            $this->markTestSkipped('Sessions are not supported');
+        }
+
+        (new CommandObserver())->observe(
+            function () {
+                $operation = new ListCollectionNames(
+                    $this->getDatabaseName(),
+                    ['session' => $this->createSession()]
+                );
+
+                $operation->execute($this->getPrimaryServer());
+            },
+            function (array $event) {
+                $this->assertObjectHasAttribute('lsid', $event['started']->getCommand());
+            }
+        );
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/ListCollectionsFunctionalTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/ListCollectionsFunctionalTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..5d3228da7e6579e9b259ddead6b0a100f121e2b2
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/ListCollectionsFunctionalTest.php	
@@ -0,0 +1,96 @@
+<?php
+
+namespace MongoDB\Tests\Operation;
+
+use MongoDB\Model\CollectionInfo;
+use MongoDB\Model\CollectionInfoIterator;
+use MongoDB\Operation\DropDatabase;
+use MongoDB\Operation\InsertOne;
+use MongoDB\Operation\ListCollections;
+use MongoDB\Tests\CommandObserver;
+use function version_compare;
+
+class ListCollectionsFunctionalTest extends FunctionalTestCase
+{
+    public function testListCollectionsForNewlyCreatedDatabase()
+    {
+        $server = $this->getPrimaryServer();
+
+        $operation = new DropDatabase($this->getDatabaseName());
+        $operation->execute($server);
+
+        $insertOne = new InsertOne($this->getDatabaseName(), $this->getCollectionName(), ['x' => 1]);
+        $writeResult = $insertOne->execute($server);
+        $this->assertEquals(1, $writeResult->getInsertedCount());
+
+        $operation = new ListCollections($this->getDatabaseName(), ['filter' => ['name' => $this->getCollectionName()]]);
+        $collections = $operation->execute($server);
+
+        $this->assertInstanceOf(CollectionInfoIterator::class, $collections);
+
+        $this->assertCount(1, $collections);
+
+        foreach ($collections as $collection) {
+            $this->assertInstanceOf(CollectionInfo::class, $collection);
+            $this->assertEquals($this->getCollectionName(), $collection->getName());
+        }
+    }
+
+    public function testIdIndexAndInfo()
+    {
+        if (version_compare($this->getServerVersion(), '3.4.0', '<')) {
+            $this->markTestSkipped('idIndex and info are not supported');
+        }
+
+        $server = $this->getPrimaryServer();
+
+        $insertOne = new InsertOne($this->getDatabaseName(), $this->getCollectionName(), ['x' => 1]);
+        $writeResult = $insertOne->execute($server);
+        $this->assertEquals(1, $writeResult->getInsertedCount());
+
+        $operation = new ListCollections($this->getDatabaseName(), ['filter' => ['name' => $this->getCollectionName()]]);
+        $collections = $operation->execute($server);
+
+        $this->assertInstanceOf(CollectionInfoIterator::class, $collections);
+
+        foreach ($collections as $collection) {
+            $this->assertInstanceOf(CollectionInfo::class, $collection);
+            $this->assertArrayHasKey('readOnly', $collection['info']);
+            $this->assertEquals(['v' => 2, 'key' => ['_id' => 1], 'name' => '_id_', 'ns' => $this->getNamespace()], $collection['idIndex']);
+        }
+    }
+
+    public function testListCollectionsForNonexistentDatabase()
+    {
+        $server = $this->getPrimaryServer();
+
+        $operation = new DropDatabase($this->getDatabaseName());
+        $operation->execute($server);
+
+        $operation = new ListCollections($this->getDatabaseName());
+        $collections = $operation->execute($server);
+
+        $this->assertCount(0, $collections);
+    }
+
+    public function testSessionOption()
+    {
+        if (version_compare($this->getServerVersion(), '3.6.0', '<')) {
+            $this->markTestSkipped('Sessions are not supported');
+        }
+
+        (new CommandObserver())->observe(
+            function () {
+                $operation = new ListCollections(
+                    $this->getDatabaseName(),
+                    ['session' => $this->createSession()]
+                );
+
+                $operation->execute($this->getPrimaryServer());
+            },
+            function (array $event) {
+                $this->assertObjectHasAttribute('lsid', $event['started']->getCommand());
+            }
+        );
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/ListDatabaseNamesFunctionalTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/ListDatabaseNamesFunctionalTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..2553c81fa4ccd2987c05cb237ca6723bd15bc4b5
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/ListDatabaseNamesFunctionalTest.php	
@@ -0,0 +1,95 @@
+<?php
+
+namespace MongoDB\Tests\Operation;
+
+use MongoDB\Operation\InsertOne;
+use MongoDB\Operation\ListDatabaseNames;
+use MongoDB\Tests\CommandObserver;
+use function version_compare;
+
+class ListDatabaseNamesFunctionalTest extends FunctionalTestCase
+{
+    public function testListDatabaseNames()
+    {
+        $server = $this->getPrimaryServer();
+
+        $insertOne = new InsertOne($this->getDatabaseName(), $this->getCollectionName(), ['x' => 1]);
+        $writeResult = $insertOne->execute($server);
+        $this->assertEquals(1, $writeResult->getInsertedCount());
+
+        $databases = null;
+        (new CommandObserver())->observe(
+            function () use (&$databases, $server) {
+                $operation = new ListDatabaseNames();
+
+                $databases = $operation->execute($server);
+            },
+            function (array $event) {
+                $this->assertObjectNotHasAttribute('authorizedDatabases', $event['started']->getCommand());
+                $this->assertSame(true, $event['started']->getCommand()->nameOnly);
+            }
+        );
+
+        foreach ($databases as $database) {
+            $this->assertIsString($database);
+        }
+    }
+
+    public function testAuthorizedDatabasesOption()
+    {
+        (new CommandObserver())->observe(
+            function () {
+                $operation = new ListDatabaseNames(
+                    ['authorizedDatabases' => true]
+                );
+
+                $operation->execute($this->getPrimaryServer());
+            },
+            function (array $event) {
+                $this->assertObjectHasAttribute('authorizedDatabases', $event['started']->getCommand());
+                $this->assertSame(true, $event['started']->getCommand()->nameOnly);
+            }
+        );
+    }
+
+    public function testFilterOption()
+    {
+        if (version_compare($this->getServerVersion(), '3.6.0', '<')) {
+            $this->markTestSkipped('listDatabase command "filter" option is not supported');
+        }
+
+        $server = $this->getPrimaryServer();
+
+        $insertOne = new InsertOne($this->getDatabaseName(), $this->getCollectionName(), ['x' => 1]);
+        $writeResult = $insertOne->execute($server);
+        $this->assertEquals(1, $writeResult->getInsertedCount());
+
+        $operation = new ListDatabaseNames(['filter' => ['name' => $this->getDatabaseName()]]);
+        $names = $operation->execute($server);
+        $this->assertCount(1, $names);
+
+        foreach ($names as $database) {
+            $this->assertSame($this->getDatabaseName(), $database);
+        }
+    }
+
+    public function testSessionOption()
+    {
+        if (version_compare($this->getServerVersion(), '3.6.0', '<')) {
+            $this->markTestSkipped('Sessions are not supported');
+        }
+
+        (new CommandObserver())->observe(
+            function () {
+                $operation = new ListDatabaseNames(
+                    ['session' => $this->createSession()]
+                );
+
+                $operation->execute($this->getPrimaryServer());
+            },
+            function (array $event) {
+                $this->assertObjectHasAttribute('lsid', $event['started']->getCommand());
+            }
+        );
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/ListDatabasesFunctionalTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/ListDatabasesFunctionalTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..6e9bb1e58928233cbf355d83a5976a1dad1ecffd
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/ListDatabasesFunctionalTest.php	
@@ -0,0 +1,101 @@
+<?php
+
+namespace MongoDB\Tests\Operation;
+
+use MongoDB\Model\DatabaseInfo;
+use MongoDB\Model\DatabaseInfoIterator;
+use MongoDB\Operation\InsertOne;
+use MongoDB\Operation\ListDatabases;
+use MongoDB\Tests\CommandObserver;
+use function version_compare;
+
+class ListDatabasesFunctionalTest extends FunctionalTestCase
+{
+    public function testListDatabases()
+    {
+        $server = $this->getPrimaryServer();
+
+        $insertOne = new InsertOne($this->getDatabaseName(), $this->getCollectionName(), ['x' => 1]);
+        $writeResult = $insertOne->execute($server);
+        $this->assertEquals(1, $writeResult->getInsertedCount());
+
+        $databases = null;
+        (new CommandObserver())->observe(
+            function () use (&$databases, $server) {
+                $operation = new ListDatabases();
+
+                $databases = $operation->execute($server);
+            },
+            function (array $event) {
+                $this->assertObjectNotHasAttribute('authorizedDatabases', $event['started']->getCommand());
+            }
+        );
+
+        $this->assertInstanceOf(DatabaseInfoIterator::class, $databases);
+
+        foreach ($databases as $database) {
+            $this->assertInstanceOf(DatabaseInfo::class, $database);
+        }
+    }
+
+    public function testAuthorizedDatabasesOption()
+    {
+        (new CommandObserver())->observe(
+            function () {
+                $operation = new ListDatabases(
+                    ['authorizedDatabases' => true]
+                );
+
+                $operation->execute($this->getPrimaryServer());
+            },
+            function (array $event) {
+                $this->assertObjectHasAttribute('authorizedDatabases', $event['started']->getCommand());
+            }
+        );
+    }
+
+    public function testFilterOption()
+    {
+        if (version_compare($this->getServerVersion(), '3.6.0', '<')) {
+            $this->markTestSkipped('listDatabase command "filter" option is not supported');
+        }
+
+        $server = $this->getPrimaryServer();
+
+        $insertOne = new InsertOne($this->getDatabaseName(), $this->getCollectionName(), ['x' => 1]);
+        $writeResult = $insertOne->execute($server);
+        $this->assertEquals(1, $writeResult->getInsertedCount());
+
+        $operation = new ListDatabases(['filter' => ['name' => $this->getDatabaseName()]]);
+        $databases = $operation->execute($server);
+
+        $this->assertInstanceOf(DatabaseInfoIterator::class, $databases);
+
+        $this->assertCount(1, $databases);
+
+        foreach ($databases as $database) {
+            $this->assertInstanceOf(DatabaseInfo::class, $database);
+            $this->assertEquals($this->getDatabaseName(), $database->getName());
+        }
+    }
+
+    public function testSessionOption()
+    {
+        if (version_compare($this->getServerVersion(), '3.6.0', '<')) {
+            $this->markTestSkipped('Sessions are not supported');
+        }
+
+        (new CommandObserver())->observe(
+            function () {
+                $operation = new ListDatabases(
+                    ['session' => $this->createSession()]
+                );
+
+                $operation->execute($this->getPrimaryServer());
+            },
+            function (array $event) {
+                $this->assertObjectHasAttribute('lsid', $event['started']->getCommand());
+            }
+        );
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/ListIndexesFunctionalTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/ListIndexesFunctionalTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..7c5fb822208ce6dbdee0e8f3c1ff73c4e8a55dfb
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/ListIndexesFunctionalTest.php	
@@ -0,0 +1,70 @@
+<?php
+
+namespace MongoDB\Tests\Operation;
+
+use MongoDB\Model\IndexInfo;
+use MongoDB\Model\IndexInfoIterator;
+use MongoDB\Operation\DropCollection;
+use MongoDB\Operation\InsertOne;
+use MongoDB\Operation\ListIndexes;
+use MongoDB\Tests\CommandObserver;
+use function version_compare;
+
+class ListIndexesFunctionalTest extends FunctionalTestCase
+{
+    public function testListIndexesForNewlyCreatedCollection()
+    {
+        $operation = new DropCollection($this->getDatabaseName(), $this->getCollectionName());
+        $operation->execute($this->getPrimaryServer());
+
+        $insertOne = new InsertOne($this->getDatabaseName(), $this->getCollectionName(), ['x' => 1]);
+        $writeResult = $insertOne->execute($this->getPrimaryServer());
+        $this->assertEquals(1, $writeResult->getInsertedCount());
+
+        $operation = new ListIndexes($this->getDatabaseName(), $this->getCollectionName());
+        $indexes = $operation->execute($this->getPrimaryServer());
+
+        $this->assertInstanceOf(IndexInfoIterator::class, $indexes);
+
+        $this->assertCount(1, $indexes);
+
+        foreach ($indexes as $index) {
+            $this->assertInstanceOf(IndexInfo::class, $index);
+            $this->assertEquals(['_id' => 1], $index->getKey());
+            $this->assertSame($this->getNamespace(), $index->getNamespace());
+        }
+    }
+
+    public function testListIndexesForNonexistentCollection()
+    {
+        $operation = new DropCollection($this->getDatabaseName(), $this->getCollectionName());
+        $operation->execute($this->getPrimaryServer());
+
+        $operation = new ListIndexes($this->getDatabaseName(), $this->getCollectionName());
+        $indexes = $operation->execute($this->getPrimaryServer());
+
+        $this->assertCount(0, $indexes);
+    }
+
+    public function testSessionOption()
+    {
+        if (version_compare($this->getServerVersion(), '3.6.0', '<')) {
+            $this->markTestSkipped('Sessions are not supported');
+        }
+
+        (new CommandObserver())->observe(
+            function () {
+                $operation = new ListIndexes(
+                    $this->getDatabaseName(),
+                    $this->getCollectionName(),
+                    ['session' => $this->createSession()]
+                );
+
+                $operation->execute($this->getPrimaryServer());
+            },
+            function (array $event) {
+                $this->assertObjectHasAttribute('lsid', $event['started']->getCommand());
+            }
+        );
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/ListIndexesTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/ListIndexesTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..c8b8450805ab982fc9f66a99874e8077c4ae3776
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/ListIndexesTest.php	
@@ -0,0 +1,33 @@
+<?php
+
+namespace MongoDB\Tests\Operation;
+
+use MongoDB\Exception\InvalidArgumentException;
+use MongoDB\Operation\ListIndexes;
+
+class ListIndexesTest extends TestCase
+{
+    /**
+     * @dataProvider provideInvalidConstructorOptions
+     */
+    public function testConstructorOptionTypeChecks(array $options)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        new ListIndexes($this->getDatabaseName(), $this->getCollectionName(), $options);
+    }
+
+    public function provideInvalidConstructorOptions()
+    {
+        $options = [];
+
+        foreach ($this->getInvalidIntegerValues() as $value) {
+            $options[][] = ['maxTimeMS' => $value];
+        }
+
+        foreach ($this->getInvalidSessionValues() as $value) {
+            $options[][] = ['session' => $value];
+        }
+
+        return $options;
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/MapReduceFunctionalTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/MapReduceFunctionalTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..ddce2a9630a182dea956f5211faf3692b7fb2948
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/MapReduceFunctionalTest.php	
@@ -0,0 +1,333 @@
+<?php
+
+namespace MongoDB\Tests\Operation;
+
+use MongoDB\BSON\Javascript;
+use MongoDB\Driver\BulkWrite;
+use MongoDB\MapReduceResult;
+use MongoDB\Operation\DropCollection;
+use MongoDB\Operation\Find;
+use MongoDB\Operation\MapReduce;
+use MongoDB\Tests\CommandObserver;
+use function is_object;
+use function iterator_to_array;
+use function usort;
+use function version_compare;
+
+class MapReduceFunctionalTest extends FunctionalTestCase
+{
+    public function testDefaultReadConcernIsOmitted()
+    {
+        // Collection must exist for mapReduce command
+        $this->createCollection();
+
+        (new CommandObserver())->observe(
+            function () {
+                $operation = new MapReduce(
+                    $this->getDatabaseName(),
+                    $this->getCollectionName(),
+                    new Javascript('function() { emit(this.x, this.y); }'),
+                    new Javascript('function(key, values) { return Array.sum(values); }'),
+                    ['inline' => 1],
+                    ['readConcern' => $this->createDefaultReadConcern()]
+                );
+
+                $operation->execute($this->getPrimaryServer());
+            },
+            function (array $event) {
+                $this->assertObjectNotHasAttribute('readConcern', $event['started']->getCommand());
+            }
+        );
+    }
+
+    public function testDefaultWriteConcernIsOmitted()
+    {
+        // Collection must exist for mapReduce command
+        $this->createCollection();
+
+        (new CommandObserver())->observe(
+            function () {
+                $operation = new MapReduce(
+                    $this->getDatabaseName(),
+                    $this->getCollectionName(),
+                    new Javascript('function() { emit(this.x, this.y); }'),
+                    new Javascript('function(key, values) { return Array.sum(values); }'),
+                    $this->getCollectionName() . '.output',
+                    ['writeConcern' => $this->createDefaultWriteConcern()]
+                );
+
+                $operation->execute($this->getPrimaryServer());
+            },
+            function (array $event) {
+                $this->assertObjectNotHasAttribute('writeConcern', $event['started']->getCommand());
+            }
+        );
+
+        $operation = new DropCollection($this->getDatabaseName(), $this->getCollectionName() . '.output');
+        $operation->execute($this->getPrimaryServer());
+    }
+
+    public function testFinalize()
+    {
+        $this->createFixtures(3);
+
+        $map = new Javascript('function() { emit(this.x, this.y); }');
+        $reduce = new Javascript('function(key, values) { return Array.sum(values); }');
+        $out = ['inline' => 1];
+        $finalize = new Javascript('function(key, reducedValue) { return reducedValue; }');
+
+        $operation = new MapReduce($this->getDatabaseName(), $this->getCollectionName(), $map, $reduce, $out, ['finalize' => $finalize]);
+        $result = $operation->execute($this->getPrimaryServer());
+
+        $this->assertNotNull($result);
+    }
+
+    public function testResult()
+    {
+        $this->createFixtures(3);
+
+        $map = new Javascript('function() { emit(this.x, this.y); }');
+        $reduce = new Javascript('function(key, values) { return Array.sum(values); }');
+        $out = ['inline' => 1];
+
+        $operation = new MapReduce($this->getDatabaseName(), $this->getCollectionName(), $map, $reduce, $out);
+        $result = $operation->execute($this->getPrimaryServer());
+
+        $this->assertInstanceOf(MapReduceResult::class, $result);
+
+        if (version_compare($this->getServerVersion(), '4.3.0', '<')) {
+            $this->assertGreaterThanOrEqual(0, $result->getExecutionTimeMS());
+            $this->assertNotEmpty($result->getCounts());
+        }
+    }
+
+    public function testResultIncludesTimingWithVerboseOption()
+    {
+        if (version_compare($this->getServerVersion(), '4.3.0', '>=')) {
+            $this->markTestSkipped('mapReduce statistics are no longer exposed');
+        }
+
+        $this->createFixtures(3);
+
+        $map = new Javascript('function() { emit(this.x, this.y); }');
+        $reduce = new Javascript('function(key, values) { return Array.sum(values); }');
+        $out = ['inline' => 1];
+
+        $operation = new MapReduce($this->getDatabaseName(), $this->getCollectionName(), $map, $reduce, $out, ['verbose' => true]);
+        $result = $operation->execute($this->getPrimaryServer());
+
+        $this->assertInstanceOf(MapReduceResult::class, $result);
+        $this->assertGreaterThanOrEqual(0, $result->getExecutionTimeMS());
+        $this->assertNotEmpty($result->getCounts());
+        $this->assertNotEmpty($result->getTiming());
+    }
+
+    public function testResultDoesNotIncludeTimingWithoutVerboseOption()
+    {
+        if (version_compare($this->getServerVersion(), '4.3.0', '>=')) {
+            $this->markTestSkipped('mapReduce statistics are no longer exposed');
+        }
+
+        $this->createFixtures(3);
+
+        $map = new Javascript('function() { emit(this.x, this.y); }');
+        $reduce = new Javascript('function(key, values) { return Array.sum(values); }');
+        $out = ['inline' => 1];
+
+        $operation = new MapReduce($this->getDatabaseName(), $this->getCollectionName(), $map, $reduce, $out, ['verbose' => false]);
+        $result = $operation->execute($this->getPrimaryServer());
+
+        $this->assertInstanceOf(MapReduceResult::class, $result);
+        $this->assertGreaterThanOrEqual(0, $result->getExecutionTimeMS());
+        $this->assertNotEmpty($result->getCounts());
+        $this->assertEmpty($result->getTiming());
+    }
+
+    public function testSessionOption()
+    {
+        if (version_compare($this->getServerVersion(), '3.6.0', '<')) {
+            $this->markTestSkipped('Sessions are not supported');
+        }
+
+        $this->createFixtures(3);
+
+        (new CommandObserver())->observe(
+            function () {
+                $operation = new MapReduce(
+                    $this->getDatabaseName(),
+                    $this->getCollectionName(),
+                    new Javascript('function() { emit(this.x, this.y); }'),
+                    new Javascript('function(key, values) { return Array.sum(values); }'),
+                    ['inline' => 1],
+                    ['session' => $this->createSession()]
+                );
+
+                $operation->execute($this->getPrimaryServer());
+            },
+            function (array $event) {
+                $this->assertObjectHasAttribute('lsid', $event['started']->getCommand());
+            }
+        );
+    }
+
+    public function testBypassDocumentValidationSetWhenTrue()
+    {
+        if (version_compare($this->getServerVersion(), '3.2.0', '<')) {
+            $this->markTestSkipped('bypassDocumentValidation is not supported');
+        }
+
+        $this->createFixtures(1);
+
+        (new CommandObserver())->observe(
+            function () {
+                $operation = new MapReduce(
+                    $this->getDatabaseName(),
+                    $this->getCollectionName(),
+                    new Javascript('function() { emit(this.x, this.y); }'),
+                    new Javascript('function(key, values) { return Array.sum(values); }'),
+                    ['inline' => 1],
+                    ['bypassDocumentValidation' => true]
+                );
+
+                $operation->execute($this->getPrimaryServer());
+            },
+            function (array $event) {
+                $this->assertObjectHasAttribute('bypassDocumentValidation', $event['started']->getCommand());
+                $this->assertEquals(true, $event['started']->getCommand()->bypassDocumentValidation);
+            }
+        );
+    }
+
+    public function testBypassDocumentValidationUnsetWhenFalse()
+    {
+        if (version_compare($this->getServerVersion(), '3.2.0', '<')) {
+            $this->markTestSkipped('bypassDocumentValidation is not supported');
+        }
+
+        $this->createFixtures(1);
+
+        (new CommandObserver())->observe(
+            function () {
+                $operation = new MapReduce(
+                    $this->getDatabaseName(),
+                    $this->getCollectionName(),
+                    new Javascript('function() { emit(this.x, this.y); }'),
+                    new Javascript('function(key, values) { return Array.sum(values); }'),
+                    ['inline' => 1],
+                    ['bypassDocumentValidation' => false]
+                );
+
+                $operation->execute($this->getPrimaryServer());
+            },
+            function (array $event) {
+                $this->assertObjectNotHasAttribute('bypassDocumentValidation', $event['started']->getCommand());
+            }
+        );
+    }
+
+    /**
+     * @dataProvider provideTypeMapOptionsAndExpectedDocuments
+     */
+    public function testTypeMapOptionWithInlineResults(array $typeMap = null, array $expectedDocuments)
+    {
+        $this->createFixtures(3);
+
+        $map = new Javascript('function() { emit(this.x, this.y); }');
+        $reduce = new Javascript('function(key, values) { return Array.sum(values); }');
+        $out = ['inline' => 1];
+
+        $operation = new MapReduce($this->getDatabaseName(), $this->getCollectionName(), $map, $reduce, $out, ['typeMap' => $typeMap]);
+        $results = iterator_to_array($operation->execute($this->getPrimaryServer()));
+
+        $this->assertEquals($this->sortResults($expectedDocuments), $this->sortResults($results));
+    }
+
+    public function provideTypeMapOptionsAndExpectedDocuments()
+    {
+        return [
+            [
+                null,
+                [
+                    (object) ['_id' => 1, 'value' => 3],
+                    (object) ['_id' => 2, 'value' => 6],
+                    (object) ['_id' => 3, 'value' => 9],
+                ],
+            ],
+            [
+                ['root' => 'array'],
+                [
+                    ['_id' => 1, 'value' => 3],
+                    ['_id' => 2, 'value' => 6],
+                    ['_id' => 3, 'value' => 9],
+                ],
+            ],
+            [
+                ['root' => 'object'],
+                [
+                    (object) ['_id' => 1, 'value' => 3],
+                    (object) ['_id' => 2, 'value' => 6],
+                    (object) ['_id' => 3, 'value' => 9],
+                ],
+            ],
+        ];
+    }
+
+    /**
+     * @dataProvider provideTypeMapOptionsAndExpectedDocuments
+     */
+    public function testTypeMapOptionWithOutputCollection(array $typeMap = null, array $expectedDocuments)
+    {
+        $this->createFixtures(3);
+
+        $map = new Javascript('function() { emit(this.x, this.y); }');
+        $reduce = new Javascript('function(key, values) { return Array.sum(values); }');
+        $out = $this->getCollectionName() . '.output';
+
+        $operation = new MapReduce($this->getDatabaseName(), $this->getCollectionName(), $map, $reduce, $out, ['typeMap' => $typeMap]);
+        $results = iterator_to_array($operation->execute($this->getPrimaryServer()));
+
+        $this->assertEquals($this->sortResults($expectedDocuments), $this->sortResults($results));
+
+        $operation = new Find($this->getDatabaseName(), $out, [], ['typeMap' => $typeMap]);
+        $cursor = $operation->execute($this->getPrimaryServer());
+
+        $this->assertEquals($this->sortResults($expectedDocuments), $this->sortResults(iterator_to_array($cursor)));
+
+        $operation = new DropCollection($this->getDatabaseName(), $out);
+        $operation->execute($this->getPrimaryServer());
+    }
+
+    /**
+     * Create data fixtures.
+     *
+     * @param integer $n
+     */
+    private function createFixtures($n)
+    {
+        $bulkWrite = new BulkWrite(['ordered' => true]);
+
+        for ($i = 1; $i <= $n; $i++) {
+            $bulkWrite->insert(['x' => $i, 'y' => $i]);
+            $bulkWrite->insert(['x' => $i, 'y' => $i * 2]);
+        }
+
+        $result = $this->manager->executeBulkWrite($this->getNamespace(), $bulkWrite);
+
+        $this->assertEquals($n * 2, $result->getInsertedCount());
+    }
+
+    private function sortResults(array $results) : array
+    {
+        $sortFunction = static function ($resultA, $resultB) : int {
+            $idA = is_object($resultA) ? $resultA->_id : $resultA['_id'];
+            $idB = is_object($resultB) ? $resultB->_id : $resultB['_id'];
+
+            return $idA <=> $idB;
+        };
+
+        $sortedResults = $results;
+        usort($sortedResults, $sortFunction);
+
+        return $sortedResults;
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/MapReduceTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/MapReduceTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..635dffb067f8638a2c7dacab940a9f4033d73c03
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/MapReduceTest.php	
@@ -0,0 +1,114 @@
+<?php
+
+namespace MongoDB\Tests\Operation;
+
+use MongoDB\BSON\Javascript;
+use MongoDB\BSON\ObjectId;
+use MongoDB\Exception\InvalidArgumentException;
+use MongoDB\Operation\MapReduce;
+use stdClass;
+
+class MapReduceTest extends TestCase
+{
+    /**
+     * @dataProvider provideInvalidOutValues
+     */
+    public function testConstructorOutArgumentTypeCheck($out)
+    {
+        $map = new Javascript('function() { emit(this.x, this.y); }');
+        $reduce = new Javascript('function(key, values) { return Array.sum(values); }');
+
+        $this->expectException(InvalidArgumentException::class);
+        new MapReduce($this->getDatabaseName(), $this->getCollectionName(), $map, $reduce, $out);
+    }
+
+    public function provideInvalidOutValues()
+    {
+        return $this->wrapValuesForDataProvider([123, 3.14, true]);
+    }
+
+    /**
+     * @dataProvider provideInvalidConstructorOptions
+     */
+    public function testConstructorOptionTypeChecks(array $options)
+    {
+        $map = new Javascript('function() { emit(this.x, this.y); }');
+        $reduce = new Javascript('function(key, values) { return Array.sum(values); }');
+        $out = ['inline' => 1];
+
+        $this->expectException(InvalidArgumentException::class);
+        new MapReduce($this->getDatabaseName(), $this->getCollectionName(), $map, $reduce, $out, $options);
+    }
+
+    public function provideInvalidConstructorOptions()
+    {
+        $options = [];
+
+        foreach ($this->getInvalidBooleanValues() as $value) {
+            $options[][] = ['bypassDocumentValidation' => $value];
+        }
+
+        foreach ($this->getInvalidDocumentValues() as $value) {
+            $options[][] = ['collation' => $value];
+        }
+
+        foreach ($this->getInvalidJavascriptValues() as $value) {
+            $options[][] = ['finalize' => $value];
+        }
+
+        foreach ($this->getInvalidBooleanValues() as $value) {
+            $options[][] = ['jsMode' => $value];
+        }
+
+        foreach ($this->getInvalidIntegerValues() as $value) {
+            $options[][] = ['limit' => $value];
+        }
+
+        foreach ($this->getInvalidIntegerValues() as $value) {
+            $options[][] = ['maxTimeMS' => $value];
+        }
+
+        foreach ($this->getInvalidDocumentValues() as $value) {
+            $options[][] = ['query' => $value];
+        }
+
+        foreach ($this->getInvalidReadConcernValues() as $value) {
+            $options[][] = ['readConcern' => $value];
+        }
+
+        foreach ($this->getInvalidReadPreferenceValues() as $value) {
+            $options[][] = ['readPreference' => $value];
+        }
+
+        foreach ($this->getInvalidDocumentValues() as $value) {
+            $options[][] = ['scope' => $value];
+        }
+
+        foreach ($this->getInvalidSessionValues() as $value) {
+            $options[][] = ['session' => $value];
+        }
+
+        foreach ($this->getInvalidDocumentValues() as $value) {
+            $options[][] = ['sort' => $value];
+        }
+
+        foreach ($this->getInvalidArrayValues() as $value) {
+            $options[][] = ['typeMap' => $value];
+        }
+
+        foreach ($this->getInvalidBooleanValues() as $value) {
+            $options[][] = ['verbose' => $value];
+        }
+
+        foreach ($this->getInvalidWriteConcernValues() as $value) {
+            $options[][] = ['writeConcern' => $value];
+        }
+
+        return $options;
+    }
+
+    private function getInvalidJavascriptValues()
+    {
+        return [123, 3.14, 'foo', true, [], new stdClass(), new ObjectId()];
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/ModifyCollectionFunctionalTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/ModifyCollectionFunctionalTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..0fd22aa6c32c8276ceaa7e5162a35b70c2feccc2
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/ModifyCollectionFunctionalTest.php	
@@ -0,0 +1,42 @@
+<?php
+
+namespace MongoDB\Tests\Operation;
+
+use MongoDB\Operation\CreateIndexes;
+use MongoDB\Operation\ModifyCollection;
+use function array_key_exists;
+
+class ModifyCollectionFunctionalTest extends FunctionalTestCase
+{
+    public function testCollMod()
+    {
+        $this->createCollection();
+
+        $indexes = [['key' => ['lastAccess' => 1], 'expireAfterSeconds' => 3]];
+        $createIndexes = new CreateIndexes($this->getDatabaseName(), $this->getCollectionName(), $indexes);
+        $createIndexes->execute($this->getPrimaryServer());
+
+        $modifyCollection = new ModifyCollection(
+            $this->getDatabaseName(),
+            $this->getCollectionName(),
+            ['index' => ['keyPattern' => ['lastAccess' => 1], 'expireAfterSeconds' => 1000]],
+            ['typeMap' => ['root' => 'array', 'document' => 'array']]
+        );
+        $result = $modifyCollection->execute($this->getPrimaryServer());
+
+        if (array_key_exists('raw', $result)) {
+            /* Sharded environment, where we only assert if a shard had a successful update. For
+             * non-primary shards that don't have chunks for the collection, the result contains a
+             * "ns does not exist" error. */
+            foreach ($result['raw'] as $shard) {
+                if (array_key_exists('ok', $shard) && $shard['ok'] == 1) {
+                    $this->assertSame(3, $shard['expireAfterSeconds_old']);
+                    $this->assertSame(1000, $shard['expireAfterSeconds_new']);
+                }
+            }
+        } else {
+            $this->assertSame(3, $result['expireAfterSeconds_old']);
+            $this->assertSame(1000, $result['expireAfterSeconds_new']);
+        }
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/ModifyCollectionTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/ModifyCollectionTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..48a48d39da065c7c450471cd06dc1584629407b8
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/ModifyCollectionTest.php	
@@ -0,0 +1,44 @@
+<?php
+
+namespace MongoDB\Tests\Operation;
+
+use MongoDB\Exception\InvalidArgumentException;
+use MongoDB\Operation\ModifyCollection;
+
+class ModifyCollectionTest extends TestCase
+{
+    public function testConstructorEmptyCollectionOptions()
+    {
+        $this->expectException(InvalidArgumentException::class);
+        $this->expectExceptionMessage('$collectionOptions is empty');
+        new ModifyCollection($this->getDatabaseName(), $this->getCollectionName(), []);
+    }
+
+    /**
+     * @dataProvider provideInvalidConstructorOptions
+     */
+    public function testConstructorOptionTypeChecks(array $options)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        new ModifyCollection($this->getDatabaseName(), $this->getCollectionName(), [], $options);
+    }
+
+    public function provideInvalidConstructorOptions()
+    {
+        $options = [];
+
+        foreach ($this->getInvalidSessionValues() as $value) {
+            $options[][] = ['session' => $value];
+        }
+
+        foreach ($this->getInvalidArrayValues() as $value) {
+            $options[][] = ['typeMap' => $value];
+        }
+
+        foreach ($this->getInvalidWriteConcernValues() as $value) {
+            $options[][] = ['writeConcern' => $value];
+        }
+
+        return $options;
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/ReplaceOneTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/ReplaceOneTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..a639e22521f57d5fa0b111c65de6aa98069c9aac
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/ReplaceOneTest.php	
@@ -0,0 +1,65 @@
+<?php
+
+namespace MongoDB\Tests\Operation;
+
+use MongoDB\Exception\InvalidArgumentException;
+use MongoDB\Model\BSONDocument;
+use MongoDB\Operation\ReplaceOne;
+
+class ReplaceOneTest extends TestCase
+{
+    /**
+     * @dataProvider provideInvalidDocumentValues
+     */
+    public function testConstructorFilterArgumentTypeCheck($filter)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        new ReplaceOne($this->getDatabaseName(), $this->getCollectionName(), $filter, ['y' => 1]);
+    }
+
+    /**
+     * @dataProvider provideInvalidDocumentValues
+     */
+    public function testConstructorReplacementArgumentTypeCheck($replacement)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        new ReplaceOne($this->getDatabaseName(), $this->getCollectionName(), ['x' => 1], $replacement);
+    }
+
+    /**
+     * @dataProvider provideReplacementDocuments
+     * @doesNotPerformAssertions
+     */
+    public function testConstructorReplacementArgument($replacement)
+    {
+        new ReplaceOne($this->getDatabaseName(), $this->getCollectionName(), ['x' => 1], $replacement);
+    }
+
+    /**
+     * @dataProvider provideUpdateDocuments
+     */
+    public function testConstructorReplacementArgumentRequiresNoOperators($replacement)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        $this->expectExceptionMessage('First key in $replacement argument is an update operator');
+        new ReplaceOne($this->getDatabaseName(), $this->getCollectionName(), ['x' => 1], $replacement);
+    }
+
+    public function provideReplacementDocuments()
+    {
+        return $this->wrapValuesForDataProvider([
+            ['y' => 1],
+            (object) ['y' => 1],
+            new BSONDocument(['y' => 1]),
+        ]);
+    }
+
+    public function provideUpdateDocuments()
+    {
+        return $this->wrapValuesForDataProvider([
+            ['$set' => ['y' => 1]],
+            (object) ['$set' => ['y' => 1]],
+            new BSONDocument(['$set' => ['y' => 1]]),
+        ]);
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/TestCase.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/TestCase.php
new file mode 100644
index 0000000000000000000000000000000000000000..2de8b0e6853c7878a2a687f05b0603a14b62c979
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/TestCase.php	
@@ -0,0 +1,12 @@
+<?php
+
+namespace MongoDB\Tests\Operation;
+
+use MongoDB\Tests\TestCase as BaseTestCase;
+
+/**
+ * Base class for Operation unit tests.
+ */
+abstract class TestCase extends BaseTestCase
+{
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/UpdateFunctionalTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/UpdateFunctionalTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..fc0c1552d74336ad72919e0b61cfbec874cf28ab
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/UpdateFunctionalTest.php	
@@ -0,0 +1,281 @@
+<?php
+
+namespace MongoDB\Tests\Operation;
+
+use MongoDB\BSON\ObjectId;
+use MongoDB\Collection;
+use MongoDB\Driver\BulkWrite;
+use MongoDB\Driver\WriteConcern;
+use MongoDB\Exception\BadMethodCallException;
+use MongoDB\Operation\Update;
+use MongoDB\Tests\CommandObserver;
+use MongoDB\UpdateResult;
+use Symfony\Bridge\PhpUnit\SetUpTearDownTrait;
+use function version_compare;
+
+class UpdateFunctionalTest extends FunctionalTestCase
+{
+    use SetUpTearDownTrait;
+
+    /** @var Collection */
+    private $collection;
+
+    private function doSetUp()
+    {
+        parent::setUp();
+
+        $this->collection = new Collection($this->manager, $this->getDatabaseName(), $this->getCollectionName());
+    }
+
+    public function testSessionOption()
+    {
+        if (version_compare($this->getServerVersion(), '3.6.0', '<')) {
+            $this->markTestSkipped('Sessions are not supported');
+        }
+
+        (new CommandObserver())->observe(
+            function () {
+                $operation = new Update(
+                    $this->getDatabaseName(),
+                    $this->getCollectionName(),
+                    ['_id' => 1],
+                    ['$inc' => ['x' => 1]],
+                    ['session' => $this->createSession()]
+                );
+
+                $operation->execute($this->getPrimaryServer());
+            },
+            function (array $event) {
+                $this->assertObjectHasAttribute('lsid', $event['started']->getCommand());
+            }
+        );
+    }
+
+    public function testBypassDocumentValidationSetWhenTrue()
+    {
+        if (version_compare($this->getServerVersion(), '3.2.0', '<')) {
+            $this->markTestSkipped('bypassDocumentValidation is not supported');
+        }
+
+        (new CommandObserver())->observe(
+            function () {
+                $operation = new Update(
+                    $this->getDatabaseName(),
+                    $this->getCollectionName(),
+                    ['_id' => 1],
+                    ['$inc' => ['x' => 1]],
+                    ['bypassDocumentValidation' => true]
+                );
+
+                $operation->execute($this->getPrimaryServer());
+            },
+            function (array $event) {
+                $this->assertObjectHasAttribute('bypassDocumentValidation', $event['started']->getCommand());
+                $this->assertEquals(true, $event['started']->getCommand()->bypassDocumentValidation);
+            }
+        );
+    }
+
+    public function testBypassDocumentValidationUnsetWhenFalse()
+    {
+        if (version_compare($this->getServerVersion(), '3.2.0', '<')) {
+            $this->markTestSkipped('bypassDocumentValidation is not supported');
+        }
+
+        (new CommandObserver())->observe(
+            function () {
+                $operation = new Update(
+                    $this->getDatabaseName(),
+                    $this->getCollectionName(),
+                    ['_id' => 1],
+                    ['$inc' => ['x' => 1]],
+                    ['bypassDocumentValidation' => false]
+                );
+
+                $operation->execute($this->getPrimaryServer());
+            },
+            function (array $event) {
+                $this->assertObjectNotHasAttribute('bypassDocumentValidation', $event['started']->getCommand());
+            }
+        );
+    }
+
+    public function testUpdateOne()
+    {
+        $this->createFixtures(3);
+
+        $filter = ['_id' => ['$gt' => 1]];
+        $update = ['$inc' => ['x' => 1]];
+
+        $operation = new Update($this->getDatabaseName(), $this->getCollectionName(), $filter, $update);
+        $result = $operation->execute($this->getPrimaryServer());
+
+        $this->assertInstanceOf(UpdateResult::class, $result);
+        $this->assertSame(1, $result->getMatchedCount());
+        $this->assertSame(1, $result->getModifiedCount());
+        $this->assertSame(0, $result->getUpsertedCount());
+        $this->assertNull($result->getUpsertedId());
+
+        $expected = [
+            ['_id' => 1, 'x' => 11],
+            ['_id' => 2, 'x' => 23],
+            ['_id' => 3, 'x' => 33],
+        ];
+
+        $this->assertSameDocuments($expected, $this->collection->find());
+    }
+
+    public function testUpdateMany()
+    {
+        $this->createFixtures(3);
+
+        $filter = ['_id' => ['$gt' => 1]];
+        $update = ['$inc' => ['x' => 1]];
+        $options = ['multi' => true];
+
+        $operation = new Update($this->getDatabaseName(), $this->getCollectionName(), $filter, $update, $options);
+        $result = $operation->execute($this->getPrimaryServer());
+
+        $this->assertInstanceOf(UpdateResult::class, $result);
+        $this->assertSame(2, $result->getMatchedCount());
+        $this->assertSame(2, $result->getModifiedCount());
+        $this->assertSame(0, $result->getUpsertedCount());
+        $this->assertNull($result->getUpsertedId());
+
+        $expected = [
+            ['_id' => 1, 'x' => 11],
+            ['_id' => 2, 'x' => 23],
+            ['_id' => 3, 'x' => 34],
+        ];
+
+        $this->assertSameDocuments($expected, $this->collection->find());
+    }
+
+    public function testUpdateManyWithExistingId()
+    {
+        $this->createFixtures(3);
+
+        $filter = ['_id' => 5];
+        $update = ['$set' => ['x' => 55]];
+        $options = ['upsert' => true];
+
+        $operation = new Update($this->getDatabaseName(), $this->getCollectionName(), $filter, $update, $options);
+        $result = $operation->execute($this->getPrimaryServer());
+
+        $this->assertInstanceOf(UpdateResult::class, $result);
+        $this->assertSame(0, $result->getMatchedCount());
+        $this->assertSame(0, $result->getModifiedCount());
+        $this->assertSame(1, $result->getUpsertedCount());
+        $this->assertSame(5, $result->getUpsertedId());
+
+        $expected = [
+            ['_id' => 1, 'x' => 11],
+            ['_id' => 2, 'x' => 22],
+            ['_id' => 3, 'x' => 33],
+            ['_id' => 5, 'x' => 55],
+        ];
+
+        $this->assertSameDocuments($expected, $this->collection->find());
+    }
+
+    public function testUpdateManyWithGeneratedId()
+    {
+        $this->createFixtures(3);
+
+        $filter = ['x' => 66];
+        $update = ['$set' => ['x' => 66]];
+        $options = ['upsert' => true];
+
+        $operation = new Update($this->getDatabaseName(), $this->getCollectionName(), $filter, $update, $options);
+        $result = $operation->execute($this->getPrimaryServer());
+
+        $this->assertInstanceOf(UpdateResult::class, $result);
+        $this->assertSame(0, $result->getMatchedCount());
+        $this->assertSame(0, $result->getModifiedCount());
+        $this->assertSame(1, $result->getUpsertedCount());
+        $this->assertInstanceOf(ObjectId::class, $result->getUpsertedId());
+
+        $expected = [
+            ['_id' => 1, 'x' => 11],
+            ['_id' => 2, 'x' => 22],
+            ['_id' => 3, 'x' => 33],
+            ['_id' => $result->getUpsertedId(), 'x' => 66],
+        ];
+
+        $this->assertSameDocuments($expected, $this->collection->find());
+    }
+
+    public function testUnacknowledgedWriteConcern()
+    {
+        $filter = ['_id' => 1];
+        $update = ['$set' => ['x' => 1]];
+        $options = ['writeConcern' => new WriteConcern(0)];
+        $operation = new Update($this->getDatabaseName(), $this->getCollectionName(), $filter, $update, $options);
+        $result = $operation->execute($this->getPrimaryServer());
+
+        $this->assertFalse($result->isAcknowledged());
+
+        return $result;
+    }
+
+    /**
+     * @depends testUnacknowledgedWriteConcern
+     */
+    public function testUnacknowledgedWriteConcernAccessesMatchedCount(UpdateResult $result)
+    {
+        $this->expectException(BadMethodCallException::class);
+        $this->expectExceptionMessageMatches('/[\w:\\\\]+ should not be called for an unacknowledged write result/');
+        $result->getMatchedCount();
+    }
+
+    /**
+     * @depends testUnacknowledgedWriteConcern
+     */
+    public function testUnacknowledgedWriteConcernAccessesModifiedCount(UpdateResult $result)
+    {
+        $this->expectException(BadMethodCallException::class);
+        $this->expectExceptionMessageMatches('/[\w:\\\\]+ should not be called for an unacknowledged write result/');
+        $result->getModifiedCount();
+    }
+
+    /**
+     * @depends testUnacknowledgedWriteConcern
+     */
+    public function testUnacknowledgedWriteConcernAccessesUpsertedCount(UpdateResult $result)
+    {
+        $this->expectException(BadMethodCallException::class);
+        $this->expectExceptionMessageMatches('/[\w:\\\\]+ should not be called for an unacknowledged write result/');
+        $result->getUpsertedCount();
+    }
+
+    /**
+     * @depends testUnacknowledgedWriteConcern
+     */
+    public function testUnacknowledgedWriteConcernAccessesUpsertedId(UpdateResult $result)
+    {
+        $this->expectException(BadMethodCallException::class);
+        $this->expectExceptionMessageMatches('/[\w:\\\\]+ should not be called for an unacknowledged write result/');
+        $result->getUpsertedId();
+    }
+
+    /**
+     * Create data fixtures.
+     *
+     * @param integer $n
+     */
+    private function createFixtures($n)
+    {
+        $bulkWrite = new BulkWrite(['ordered' => true]);
+
+        for ($i = 1; $i <= $n; $i++) {
+            $bulkWrite->insert([
+                '_id' => $i,
+                'x' => (integer) ($i . $i),
+            ]);
+        }
+
+        $result = $this->manager->executeBulkWrite($this->getNamespace(), $bulkWrite);
+
+        $this->assertEquals($n, $result->getInsertedCount());
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/UpdateManyTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/UpdateManyTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..70537c0bc6b8715e72f17db5f00d2713e016e55c
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/UpdateManyTest.php	
@@ -0,0 +1,65 @@
+<?php
+
+namespace MongoDB\Tests\Operation;
+
+use MongoDB\Exception\InvalidArgumentException;
+use MongoDB\Model\BSONDocument;
+use MongoDB\Operation\UpdateMany;
+
+class UpdateManyTest extends TestCase
+{
+    /**
+     * @dataProvider provideInvalidDocumentValues
+     */
+    public function testConstructorFilterArgumentTypeCheck($filter)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        new UpdateMany($this->getDatabaseName(), $this->getCollectionName(), $filter, ['$set' => ['x' => 1]]);
+    }
+
+    /**
+     * @dataProvider provideInvalidDocumentValues
+     */
+    public function testConstructorUpdateArgumentTypeCheck($update)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        new UpdateMany($this->getDatabaseName(), $this->getCollectionName(), ['x' => 1], $update);
+    }
+
+    /**
+     * @dataProvider provideUpdateDocuments
+     * @doesNotPerformAssertions
+     */
+    public function testConstructorUpdateArgument($update)
+    {
+        new UpdateMany($this->getDatabaseName(), $this->getCollectionName(), ['x' => 1], $update);
+    }
+
+    /**
+     * @dataProvider provideReplacementDocuments
+     */
+    public function testConstructorUpdateArgumentRequiresOperators($replacement)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        $this->expectExceptionMessage('Expected an update document with operator as first key or a pipeline');
+        new UpdateMany($this->getDatabaseName(), $this->getCollectionName(), ['x' => 1], $replacement);
+    }
+
+    public function provideReplacementDocuments()
+    {
+        return $this->wrapValuesForDataProvider([
+            ['y' => 1],
+            (object) ['y' => 1],
+            new BSONDocument(['y' => 1]),
+        ]);
+    }
+
+    public function provideUpdateDocuments()
+    {
+        return $this->wrapValuesForDataProvider([
+            ['$set' => ['y' => 1]],
+            (object) ['$set' => ['y' => 1]],
+            new BSONDocument(['$set' => ['y' => 1]]),
+        ]);
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/UpdateOneTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/UpdateOneTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..6aec7a5ba8f964857d6a2855b9ff4fbbc81e4d99
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/UpdateOneTest.php	
@@ -0,0 +1,65 @@
+<?php
+
+namespace MongoDB\Tests\Operation;
+
+use MongoDB\Exception\InvalidArgumentException;
+use MongoDB\Model\BSONDocument;
+use MongoDB\Operation\UpdateOne;
+
+class UpdateOneTest extends TestCase
+{
+    /**
+     * @dataProvider provideInvalidDocumentValues
+     */
+    public function testConstructorFilterArgumentTypeCheck($filter)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        new UpdateOne($this->getDatabaseName(), $this->getCollectionName(), $filter, ['$set' => ['x' => 1]]);
+    }
+
+    /**
+     * @dataProvider provideInvalidDocumentValues
+     */
+    public function testConstructorUpdateArgumentTypeCheck($update)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        new UpdateOne($this->getDatabaseName(), $this->getCollectionName(), ['x' => 1], $update);
+    }
+
+    /**
+     * @dataProvider provideUpdateDocuments
+     * @doesNotPerformAssertions
+     */
+    public function testConstructorUpdateArgument($update)
+    {
+        new UpdateOne($this->getDatabaseName(), $this->getCollectionName(), ['x' => 1], $update);
+    }
+
+    /**
+     * @dataProvider provideReplacementDocuments
+     */
+    public function testConstructorUpdateArgumentRequiresOperators($replacement)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        $this->expectExceptionMessage('Expected an update document with operator as first key or a pipeline');
+        new UpdateOne($this->getDatabaseName(), $this->getCollectionName(), ['x' => 1], $replacement);
+    }
+
+    public function provideReplacementDocuments()
+    {
+        return $this->wrapValuesForDataProvider([
+            ['y' => 1],
+            (object) ['y' => 1],
+            new BSONDocument(['y' => 1]),
+        ]);
+    }
+
+    public function provideUpdateDocuments()
+    {
+        return $this->wrapValuesForDataProvider([
+            ['$set' => ['y' => 1]],
+            (object) ['$set' => ['y' => 1]],
+            new BSONDocument(['$set' => ['y' => 1]]),
+        ]);
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/UpdateTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/UpdateTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..ddb61a17509d19b87c7f5712c69d40730fb07b83
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/UpdateTest.php	
@@ -0,0 +1,73 @@
+<?php
+
+namespace MongoDB\Tests\Operation;
+
+use MongoDB\Exception\InvalidArgumentException;
+use MongoDB\Operation\Update;
+
+class UpdateTest extends TestCase
+{
+    /**
+     * @dataProvider provideInvalidDocumentValues
+     */
+    public function testConstructorFilterArgumentTypeCheck($filter)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        $this->expectExceptionMessageMatches('/Expected \$filter to have type "array or object" but found "[\w ]+"/');
+        new Update($this->getDatabaseName(), $this->getCollectionName(), $filter, ['$set' => ['x' => 1]]);
+    }
+
+    /**
+     * @dataProvider provideInvalidDocumentValues
+     */
+    public function testConstructorUpdateArgumentTypeCheck($update)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        $this->expectExceptionMessageMatches('/Expected \$update to have type "array or object" but found "[\w ]+"/');
+        new Update($this->getDatabaseName(), $this->getCollectionName(), ['x' => 1], $update);
+    }
+
+    /**
+     * @dataProvider provideInvalidConstructorOptions
+     */
+    public function testConstructorOptionTypeChecks(array $options)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        new Update($this->getDatabaseName(), $this->getCollectionName(), ['x' => 1], ['y' => 1], $options);
+    }
+
+    public function provideInvalidConstructorOptions()
+    {
+        $options = [];
+
+        foreach ($this->getInvalidArrayValues() as $value) {
+            $options[][] = ['arrayFilters' => $value];
+        }
+
+        foreach ($this->getInvalidBooleanValues() as $value) {
+            $options[][] = ['bypassDocumentValidation' => $value];
+        }
+
+        foreach ($this->getInvalidDocumentValues() as $value) {
+            $options[][] = ['collation' => $value];
+        }
+
+        foreach ($this->getInvalidBooleanValues(true) as $value) {
+            $options[][] = ['multi' => $value];
+        }
+
+        foreach ($this->getInvalidSessionValues() as $value) {
+            $options[][] = ['session' => $value];
+        }
+
+        foreach ($this->getInvalidBooleanValues(true) as $value) {
+            $options[][] = ['upsert' => $value];
+        }
+
+        foreach ($this->getInvalidWriteConcernValues() as $value) {
+            $options[][] = ['writeConcern' => $value];
+        }
+
+        return $options;
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/WatchFunctionalTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/WatchFunctionalTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..01d2d57f7eb5d8c59d229ade248bc9f1f570806d
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/WatchFunctionalTest.php	
@@ -0,0 +1,1632 @@
+<?php
+
+namespace MongoDB\Tests\Operation;
+
+use Closure;
+use Iterator;
+use MongoDB\BSON\TimestampInterface;
+use MongoDB\ChangeStream;
+use MongoDB\Driver\Cursor;
+use MongoDB\Driver\Exception\CommandException;
+use MongoDB\Driver\Exception\ConnectionTimeoutException;
+use MongoDB\Driver\Exception\LogicException;
+use MongoDB\Driver\Exception\ServerException;
+use MongoDB\Driver\Manager;
+use MongoDB\Driver\Monitoring\CommandSucceededEvent;
+use MongoDB\Driver\ReadPreference;
+use MongoDB\Driver\WriteConcern;
+use MongoDB\Exception\ResumeTokenException;
+use MongoDB\Operation\InsertOne;
+use MongoDB\Operation\Watch;
+use MongoDB\Tests\CommandObserver;
+use PHPUnit\Framework\ExpectationFailedException;
+use ReflectionClass;
+use stdClass;
+use Symfony\Bridge\PhpUnit\SetUpTearDownTrait;
+use function array_diff_key;
+use function array_map;
+use function bin2hex;
+use function microtime;
+use function MongoDB\server_supports_feature;
+use function sprintf;
+use function version_compare;
+
+class WatchFunctionalTest extends FunctionalTestCase
+{
+    use SetUpTearDownTrait;
+
+    const INTERRUPTED = 11601;
+    const NOT_MASTER = 10107;
+
+    /** @var integer */
+    private static $wireVersionForStartAtOperationTime = 7;
+
+    /** @var array */
+    private $defaultOptions = ['maxAwaitTimeMS' => 500];
+
+    private function doSetUp()
+    {
+        parent::setUp();
+
+        $this->skipIfChangeStreamIsNotSupported();
+        $this->createCollection();
+    }
+
+    /**
+     * Prose test 1: "ChangeStream must continuously track the last seen
+     * resumeToken"
+     */
+    public function testGetResumeToken()
+    {
+        if ($this->isPostBatchResumeTokenSupported()) {
+            $this->markTestSkipped('postBatchResumeToken is supported');
+        }
+
+        $operation = new Watch($this->manager, $this->getDatabaseName(), $this->getCollectionName(), [], $this->defaultOptions);
+        $changeStream = $operation->execute($this->getPrimaryServer());
+
+        $changeStream->rewind();
+        $this->assertFalse($changeStream->valid());
+        $this->assertNull($changeStream->getResumeToken());
+
+        $this->insertDocument(['x' => 1]);
+        $this->insertDocument(['x' => 2]);
+
+        $this->advanceCursorUntilValid($changeStream);
+        $this->assertSameDocument($changeStream->current()->_id, $changeStream->getResumeToken());
+
+        $changeStream->next();
+        $this->assertTrue($changeStream->valid());
+        $this->assertSameDocument($changeStream->current()->_id, $changeStream->getResumeToken());
+
+        $this->insertDocument(['x' => 3]);
+
+        $this->advanceCursorUntilValid($changeStream);
+        $this->assertSameDocument($changeStream->current()->_id, $changeStream->getResumeToken());
+    }
+
+    /**
+     * Prose test 1: "ChangeStream must continuously track the last seen
+     * resumeToken"
+     *
+     * Prose test 11:
+     * For a ChangeStream under these conditions:
+     *  - Running against a server >=4.0.7.
+     *  - The batch is empty or has been iterated to the last document.
+     * Expected result: getResumeToken must return the postBatchResumeToken from
+     * the current command response.
+     *
+     * Prose test 13:
+     * For a ChangeStream under these conditions:
+     *  - The batch is not empty.
+     *  - The batch has been iterated up to but not including the last element.
+     * Expected result: getResumeToken must return the _id of the previous
+     * document returned.
+     */
+    public function testGetResumeTokenWithPostBatchResumeToken()
+    {
+        if (! $this->isPostBatchResumeTokenSupported()) {
+            $this->markTestSkipped('postBatchResumeToken is not supported');
+        }
+
+        $operation = new Watch($this->manager, $this->getDatabaseName(), $this->getCollectionName(), [], $this->defaultOptions);
+
+        $events = [];
+
+        (new CommandObserver())->observe(
+            function () use ($operation, &$changeStream) {
+                $changeStream = $operation->execute($this->getPrimaryServer());
+            },
+            function (array $event) use (&$events) {
+                $events[] = $event;
+            }
+        );
+
+        $this->assertCount(1, $events);
+        $this->assertSame('aggregate', $events[0]['started']->getCommandName());
+        $postBatchResumeToken = $this->getPostBatchResumeTokenFromReply($events[0]['succeeded']->getReply());
+
+        $changeStream->rewind();
+        $this->assertFalse($changeStream->valid());
+        $this->assertSameDocument($postBatchResumeToken, $changeStream->getResumeToken());
+
+        $this->insertDocument(['x' => 1]);
+        $this->insertDocument(['x' => 2]);
+
+        $lastEvent = null;
+
+        (new CommandObserver())->observe(
+            function () use ($changeStream) {
+                $this->advanceCursorUntilValid($changeStream);
+            },
+            function (array $event) use (&$lastEvent) {
+                $lastEvent = $event;
+            }
+        );
+
+        $this->assertNotNull($lastEvent);
+        $this->assertSame('getMore', $lastEvent['started']->getCommandName());
+        $postBatchResumeToken = $this->getPostBatchResumeTokenFromReply($lastEvent['succeeded']->getReply());
+
+        $this->assertSameDocument($changeStream->current()->_id, $changeStream->getResumeToken());
+
+        $changeStream->next();
+        $this->assertSameDocument($postBatchResumeToken, $changeStream->getResumeToken());
+    }
+
+    public function testNextResumesAfterConnectionException()
+    {
+        $this->skipIfIsShardedCluster('initial aggregate command times out due to socketTimeoutMS');
+
+        /* In order to trigger a dropped connection, we'll use a new client with
+         * a socket timeout that is less than the change stream's maxAwaitTimeMS
+         * option. */
+        $manager = new Manager(static::getUri(), ['socketTimeoutMS' => 50]);
+        $primaryServer = $manager->selectServer(new ReadPreference(ReadPreference::RP_PRIMARY));
+
+        $operation = new Watch($manager, $this->getDatabaseName(), $this->getCollectionName(), [], $this->defaultOptions);
+        $changeStream = $operation->execute($primaryServer);
+        $changeStream->rewind();
+
+        $commands = [];
+
+        (new CommandObserver())->observe(
+            function () use ($changeStream) {
+                $changeStream->next();
+            },
+            function (array $event) use (&$commands) {
+                $commands[] = $event['started']->getCommandName();
+            }
+        );
+
+        $expectedCommands = [
+            /* The initial aggregate command for change streams returns a cursor
+             * envelope with an empty initial batch, since there are no changes
+             * to report at the moment the change stream is created. Therefore,
+             * we expect a getMore to be issued when we first advance the change
+             * stream with next(). */
+            'getMore',
+            /* Since socketTimeoutMS is less than maxAwaitTimeMS, the previous
+             * getMore command encounters a client socket timeout and leaves the
+             * cursor open on the server. ChangeStream should catch this error
+             * and resume by issuing a new aggregate command. */
+            'aggregate',
+            /* When ChangeStream resumes, it overwrites its original cursor with
+             * the new cursor resulting from the last aggregate command. This
+             * removes the last reference to the old cursor, which causes the
+             * driver to kill it (via mongoc_cursor_destroy()). */
+            'killCursors',
+        ];
+
+        $this->assertSame($expectedCommands, $commands);
+    }
+
+    public function testResumeBeforeReceivingAnyResultsIncludesPostBatchResumeToken()
+    {
+        if (! $this->isPostBatchResumeTokenSupported()) {
+            $this->markTestSkipped('postBatchResumeToken is not supported');
+        }
+
+        $operation = new Watch($this->manager, $this->getDatabaseName(), $this->getCollectionName(), [], $this->defaultOptions);
+
+        $events = [];
+
+        (new CommandObserver())->observe(
+            function () use ($operation, &$changeStream) {
+                $changeStream = $operation->execute($this->getPrimaryServer());
+            },
+            function (array $event) use (&$events) {
+                $events[] = $event;
+            }
+        );
+
+        $this->assertCount(1, $events);
+        $this->assertSame('aggregate', $events[0]['started']->getCommandName());
+        $postBatchResumeToken = $this->getPostBatchResumeTokenFromReply($events[0]['succeeded']->getReply());
+
+        $this->assertFalse($changeStream->valid());
+        $this->forceChangeStreamResume();
+
+        $this->assertNoCommandExecuted(function () use ($changeStream) {
+            $changeStream->rewind();
+        });
+
+        $events = [];
+
+        (new CommandObserver())->observe(
+            function () use ($changeStream) {
+                $changeStream->next();
+            },
+            function (array $event) use (&$events) {
+                $events[] = $event;
+            }
+        );
+
+        $this->assertCount(3, $events);
+
+        $this->assertSame('getMore', $events[0]['started']->getCommandName());
+        $this->arrayHasKey('failed', $events[0]);
+
+        $this->assertSame('aggregate', $events[1]['started']->getCommandName());
+        $this->assertResumeAfter($postBatchResumeToken, $events[1]['started']->getCommand());
+        $this->arrayHasKey('succeeded', $events[1]);
+
+        // Original cursor is freed immediately after the change stream resumes
+        $this->assertSame('killCursors', $events[2]['started']->getCommandName());
+        $this->arrayHasKey('succeeded', $events[2]);
+
+        $this->assertFalse($changeStream->valid());
+    }
+
+    private function assertResumeAfter($expectedResumeToken, stdClass $command)
+    {
+        $this->assertObjectHasAttribute('pipeline', $command);
+        $this->assertIsArray($command->pipeline);
+        $this->assertArrayHasKey(0, $command->pipeline);
+        $this->assertObjectHasAttribute('$changeStream', $command->pipeline[0]);
+        $this->assertObjectHasAttribute('resumeAfter', $command->pipeline[0]->{'$changeStream'});
+        $this->assertEquals($expectedResumeToken, $command->pipeline[0]->{'$changeStream'}->resumeAfter);
+    }
+
+    /**
+     * Prose test 9: "$changeStream stage for ChangeStream against a server
+     * >=4.0 and <4.0.7 that has not received any results yet MUST include a
+     * startAtOperationTime option when resuming a changestream."
+     */
+    public function testResumeBeforeReceivingAnyResultsIncludesStartAtOperationTime()
+    {
+        if (! $this->isStartAtOperationTimeSupported()) {
+            $this->markTestSkipped('startAtOperationTime is not supported');
+        }
+
+        if ($this->isPostBatchResumeTokenSupported()) {
+            $this->markTestSkipped('postBatchResumeToken takes precedence over startAtOperationTime');
+        }
+
+        $operation = new Watch($this->manager, $this->getDatabaseName(), $this->getCollectionName(), [], $this->defaultOptions);
+
+        $events = [];
+
+        (new CommandObserver())->observe(
+            function () use ($operation, &$changeStream) {
+                $changeStream = $operation->execute($this->getPrimaryServer());
+            },
+            function (array $event) use (&$events) {
+                $events[] = $event;
+            }
+        );
+
+        $this->assertCount(1, $events);
+        $this->assertSame('aggregate', $events[0]['started']->getCommandName());
+        $reply = $events[0]['succeeded']->getReply();
+        $this->assertObjectHasAttribute('operationTime', $reply);
+        $operationTime = $reply->operationTime;
+        $this->assertInstanceOf(TimestampInterface::class, $operationTime);
+
+        $this->assertFalse($changeStream->valid());
+        $this->forceChangeStreamResume();
+
+        $this->assertNoCommandExecuted(function () use ($changeStream) {
+            $changeStream->rewind();
+        });
+
+        $events = [];
+
+        (new CommandObserver())->observe(
+            function () use ($changeStream) {
+                $changeStream->next();
+            },
+            function (array $event) use (&$events) {
+                $events[] = $event;
+            }
+        );
+
+        $this->assertCount(3, $events);
+
+        $this->assertSame('getMore', $events[0]['started']->getCommandName());
+        $this->arrayHasKey('failed', $events[0]);
+
+        $this->assertSame('aggregate', $events[1]['started']->getCommandName());
+        $this->assertStartAtOperationTime($operationTime, $events[1]['started']->getCommand());
+        $this->arrayHasKey('succeeded', $events[1]);
+
+        // Original cursor is freed immediately after the change stream resumes
+        $this->assertSame('killCursors', $events[2]['started']->getCommandName());
+        $this->arrayHasKey('succeeded', $events[2]);
+
+        $this->assertFalse($changeStream->valid());
+    }
+
+    private function assertStartAtOperationTime(TimestampInterface $expectedOperationTime, stdClass $command)
+    {
+        $this->assertObjectHasAttribute('pipeline', $command);
+        $this->assertIsArray($command->pipeline);
+        $this->assertArrayHasKey(0, $command->pipeline);
+        $this->assertObjectHasAttribute('$changeStream', $command->pipeline[0]);
+        $this->assertObjectHasAttribute('startAtOperationTime', $command->pipeline[0]->{'$changeStream'});
+        $this->assertEquals($expectedOperationTime, $command->pipeline[0]->{'$changeStream'}->startAtOperationTime);
+    }
+
+    public function testRewindMultipleTimesWithResults()
+    {
+        $this->skipIfIsShardedCluster('Cursor needs to be advanced multiple times and can\'t be rewound afterwards.');
+
+        $operation = new Watch($this->manager, $this->getDatabaseName(), $this->getCollectionName(), [], $this->defaultOptions);
+        $changeStream = $operation->execute($this->getPrimaryServer());
+
+        $this->insertDocument(['x' => 1]);
+        $this->insertDocument(['x' => 2]);
+
+        $this->assertNoCommandExecuted(function () use ($changeStream) {
+            $changeStream->rewind();
+        });
+        $this->assertFalse($changeStream->valid());
+        $this->assertNull($changeStream->key());
+        $this->assertNull($changeStream->current());
+
+        // Subsequent rewind does not change iterator state
+        $this->assertNoCommandExecuted(function () use ($changeStream) {
+            $changeStream->rewind();
+        });
+        $this->assertFalse($changeStream->valid());
+        $this->assertNull($changeStream->key());
+        $this->assertNull($changeStream->current());
+
+        $changeStream->next();
+        $this->assertTrue($changeStream->valid());
+        $this->assertSame(0, $changeStream->key());
+        $this->assertNotNull($changeStream->current());
+
+        /* Rewinding when the iterator is still at its first element is a NOP.
+         * Note: PHPLIB-448 may see rewind() throw after any call to next() */
+        $this->assertNoCommandExecuted(function () use ($changeStream) {
+            $changeStream->rewind();
+        });
+        $this->assertTrue($changeStream->valid());
+        $this->assertSame(0, $changeStream->key());
+        $this->assertNotNull($changeStream->current());
+
+        $changeStream->next();
+        $this->assertTrue($changeStream->valid());
+        $this->assertSame(1, $changeStream->key());
+        $this->assertNotNull($changeStream->current());
+
+        // Rewinding after advancing the iterator is an error
+        $this->expectException(LogicException::class);
+        $changeStream->rewind();
+    }
+
+    public function testRewindMultipleTimesWithNoResults()
+    {
+        $operation = new Watch($this->manager, $this->getDatabaseName(), $this->getCollectionName(), [], $this->defaultOptions);
+        $changeStream = $operation->execute($this->getPrimaryServer());
+
+        $this->assertNoCommandExecuted(function () use ($changeStream) {
+            $changeStream->rewind();
+        });
+        $this->assertFalse($changeStream->valid());
+        $this->assertNull($changeStream->key());
+        $this->assertNull($changeStream->current());
+
+        // Subsequent rewind does not change iterator state
+        $this->assertNoCommandExecuted(function () use ($changeStream) {
+            $changeStream->rewind();
+        });
+        $this->assertFalse($changeStream->valid());
+        $this->assertNull($changeStream->key());
+        $this->assertNull($changeStream->current());
+
+        $changeStream->next();
+        $this->assertFalse($changeStream->valid());
+        $this->assertNull($changeStream->key());
+        $this->assertNull($changeStream->current());
+
+        /* Rewinding when the iterator hasn't advanced to an element is a NOP.
+         * Note: PHPLIB-448 may see rewind() throw after any call to next() */
+        $this->assertNoCommandExecuted(function () use ($changeStream) {
+            $changeStream->rewind();
+        });
+        $this->assertFalse($changeStream->valid());
+        $this->assertNull($changeStream->key());
+        $this->assertNull($changeStream->current());
+    }
+
+    public function testNoChangeAfterResumeBeforeInsert()
+    {
+        $operation = new Watch($this->manager, $this->getDatabaseName(), $this->getCollectionName(), [], $this->defaultOptions);
+        $changeStream = $operation->execute($this->getPrimaryServer());
+
+        $this->assertNoCommandExecuted(function () use ($changeStream) {
+            $changeStream->rewind();
+        });
+        $this->assertFalse($changeStream->valid());
+
+        $this->insertDocument(['_id' => 1, 'x' => 'foo']);
+
+        $this->advanceCursorUntilValid($changeStream);
+
+        $expectedResult = [
+            '_id' => $changeStream->current()->_id,
+            'operationType' => 'insert',
+            'fullDocument' => ['_id' => 1, 'x' => 'foo'],
+            'ns' => ['db' => $this->getDatabaseName(), 'coll' => $this->getCollectionName()],
+            'documentKey' => ['_id' => 1],
+        ];
+
+        $this->assertMatchesDocument($expectedResult, $changeStream->current());
+
+        $this->forceChangeStreamResume();
+
+        $changeStream->next();
+        $this->assertFalse($changeStream->valid());
+
+        $this->insertDocument(['_id' => 2, 'x' => 'bar']);
+
+        $this->advanceCursorUntilValid($changeStream);
+
+        $expectedResult = [
+            '_id' => $changeStream->current()->_id,
+            'operationType' => 'insert',
+            'fullDocument' => ['_id' => 2, 'x' => 'bar'],
+            'ns' => ['db' => $this->getDatabaseName(), 'coll' => $this->getCollectionName()],
+            'documentKey' => ['_id' => 2],
+        ];
+
+        $this->assertMatchesDocument($expectedResult, $changeStream->current());
+    }
+
+    public function testResumeMultipleTimesInSuccession()
+    {
+        $this->skipIfIsShardedCluster('getMore may return empty response before periodicNoopIntervalSecs on sharded clusters.');
+
+        $operation = new Watch($this->manager, $this->getDatabaseName(), $this->getCollectionName(), [], $this->defaultOptions);
+        $changeStream = $operation->execute($this->getPrimaryServer());
+
+        /* Forcing a resume when there are no results will test that neither
+         * the initial rewind() nor a resume attempt via next() increment the
+         * key. */
+        $this->forceChangeStreamResume();
+
+        $this->assertNoCommandExecuted(function () use ($changeStream) {
+            $changeStream->rewind();
+        });
+        $this->assertFalse($changeStream->valid());
+        $this->assertNull($changeStream->key());
+        $this->assertNull($changeStream->current());
+
+        $changeStream->next();
+        $this->assertFalse($changeStream->valid());
+        $this->assertNull($changeStream->key());
+        $this->assertNull($changeStream->current());
+
+        // A consecutive resume attempt should still not increment the key
+        $this->forceChangeStreamResume();
+
+        $changeStream->next();
+        $this->assertFalse($changeStream->valid());
+        $this->assertNull($changeStream->key());
+        $this->assertNull($changeStream->current());
+
+        /* Insert a document and advance the change stream to ensure we capture
+         * a resume token. This is necessary when startAtOperationTime is not
+         * supported (i.e. 3.6 server version). */
+        $this->insertDocument(['_id' => 1]);
+
+        $changeStream->next();
+        $this->assertTrue($changeStream->valid());
+        $this->assertSame(0, $changeStream->key());
+
+        $expectedResult = [
+            '_id' => $changeStream->current()->_id,
+            'operationType' => 'insert',
+            'fullDocument' => ['_id' => 1],
+            'ns' => ['db' => $this->getDatabaseName(), 'coll' => $this->getCollectionName()],
+            'documentKey' => ['_id' => 1],
+        ];
+
+        $this->assertMatchesDocument($expectedResult, $changeStream->current());
+
+        /* Insert another document and force a resume. ChangeStream::next()
+         * should resume and pick up the last insert. */
+        $this->insertDocument(['_id' => 2]);
+        $this->forceChangeStreamResume();
+
+        $changeStream->next();
+        $this->assertTrue($changeStream->valid());
+        $this->assertSame(1, $changeStream->key());
+
+        $expectedResult = [
+            '_id' => $changeStream->current()->_id,
+            'operationType' => 'insert',
+            'fullDocument' => ['_id' => 2],
+            'ns' => ['db' => $this->getDatabaseName(), 'coll' => $this->getCollectionName()],
+            'documentKey' => ['_id' => 2],
+        ];
+
+        $this->assertMatchesDocument($expectedResult, $changeStream->current());
+
+        /* Insert another document and kill the cursor. It is technically
+         * permissable to call ChangeStream::rewind() since the previous call to
+         * next() will have left the cursor positioned at its first and only
+         * result. Assert that rewind() does not execute a getMore nor does it
+         * modify the iterator's state.
+         *
+         * Note: PHPLIB-448 may require rewind() to throw an exception here. */
+        $this->insertDocument(['_id' => 3]);
+        $this->forceChangeStreamResume();
+
+        $this->assertNoCommandExecuted(function () use ($changeStream) {
+            $changeStream->rewind();
+        });
+        $this->assertTrue($changeStream->valid());
+        $this->assertSame(1, $changeStream->key());
+        $this->assertMatchesDocument($expectedResult, $changeStream->current());
+
+        // ChangeStream::next() should resume and pick up the last insert
+        $changeStream->next();
+        $this->assertTrue($changeStream->valid());
+        $this->assertSame(2, $changeStream->key());
+
+        $expectedResult = [
+            '_id' => $changeStream->current()->_id,
+            'operationType' => 'insert',
+            'fullDocument' => ['_id' => 3],
+            'ns' => ['db' => $this->getDatabaseName(), 'coll' => $this->getCollectionName()],
+            'documentKey' => ['_id' => 3],
+        ];
+
+        $this->assertMatchesDocument($expectedResult, $changeStream->current());
+
+        // Test one final, consecutive resume via ChangeStream::next()
+        $this->insertDocument(['_id' => 4]);
+        $this->forceChangeStreamResume();
+
+        $changeStream->next();
+        $this->assertTrue($changeStream->valid());
+        $this->assertSame(3, $changeStream->key());
+
+        $expectedResult = [
+            '_id' => $changeStream->current()->_id,
+            'operationType' => 'insert',
+            'fullDocument' => ['_id' => 4],
+            'ns' => ['db' => $this->getDatabaseName(), 'coll' => $this->getCollectionName()],
+            'documentKey' => ['_id' => 4],
+        ];
+
+        $this->assertMatchesDocument($expectedResult, $changeStream->current());
+    }
+
+    public function testKey()
+    {
+        $operation = new Watch($this->manager, $this->getDatabaseName(), $this->getCollectionName(), [], $this->defaultOptions);
+        $changeStream = $operation->execute($this->getPrimaryServer());
+
+        $this->assertFalse($changeStream->valid());
+        $this->assertNull($changeStream->key());
+
+        $this->assertNoCommandExecuted(function () use ($changeStream) {
+            $changeStream->rewind();
+        });
+        $this->assertFalse($changeStream->valid());
+        $this->assertNull($changeStream->key());
+
+        $this->insertDocument(['_id' => 1, 'x' => 'foo']);
+
+        $this->advanceCursorUntilValid($changeStream);
+        $this->assertSame(0, $changeStream->key());
+
+        $changeStream->next();
+        $this->assertFalse($changeStream->valid());
+        $this->assertNull($changeStream->key());
+
+        $changeStream->next();
+        $this->assertFalse($changeStream->valid());
+        $this->assertNull($changeStream->key());
+
+        $this->forceChangeStreamResume();
+
+        $changeStream->next();
+        $this->assertFalse($changeStream->valid());
+        $this->assertNull($changeStream->key());
+
+        $this->insertDocument(['_id' => 2, 'x' => 'bar']);
+
+        $this->advanceCursorUntilValid($changeStream);
+        $this->assertSame(1, $changeStream->key());
+    }
+
+    public function testNonEmptyPipeline()
+    {
+        $pipeline = [['$project' => ['foo' => [0]]]];
+
+        $operation = new Watch($this->manager, $this->getDatabaseName(), $this->getCollectionName(), $pipeline, $this->defaultOptions);
+        $changeStream = $operation->execute($this->getPrimaryServer());
+
+        $this->insertDocument(['_id' => 1]);
+
+        $changeStream->rewind();
+        $this->assertFalse($changeStream->valid());
+
+        $this->advanceCursorUntilValid($changeStream);
+
+        $expectedResult = [
+            '_id' => $changeStream->current()->_id,
+            'foo' => [0],
+        ];
+
+        $this->assertSameDocument($expectedResult, $changeStream->current());
+    }
+
+    /**
+     * Prose test 7: "Ensure that a cursor returned from an aggregate command
+     * with a cursor id and an initial empty batch is not closed on the driver
+     * side."
+     */
+    public function testInitialCursorIsNotClosed()
+    {
+        $operation = new Watch($this->manager, $this->getDatabaseName(), $this->getCollectionName(), []);
+        $changeStream = $operation->execute($this->getPrimaryServer());
+
+        /* The spec requests that we assert that the cursor returned from the
+         * aggregate command is not closed on the driver side. We will verify
+         * this by checking that the cursor ID is non-zero and that libmongoc
+         * reports the cursor as alive. While the cursor ID is easily accessed
+         * through ChangeStream, we'll need to use reflection to access the
+         * internal Cursor and call isDead(). */
+        $this->assertNotEquals('0', (string) $changeStream->getCursorId());
+
+        $rc = new ReflectionClass(ChangeStream::class);
+        $rp = $rc->getProperty('iterator');
+        $rp->setAccessible(true);
+
+        $iterator = $rp->getValue($changeStream);
+
+        $this->assertInstanceOf('IteratorIterator', $iterator);
+
+        $cursor = $iterator->getInnerIterator();
+
+        $this->assertInstanceOf(Cursor::class, $cursor);
+        $this->assertFalse($cursor->isDead());
+    }
+
+    /**
+     * Prose test 2: "ChangeStream will throw an exception if the server
+     * response is missing the resume token (if wire version is < 8, this is a
+     * driver-side error; for 8+, this is a server-side error)"
+     */
+    public function testResumeTokenNotFoundClientSideError()
+    {
+        if (version_compare($this->getServerVersion(), '4.1.8', '>=')) {
+            $this->markTestSkipped('Server rejects change streams that modify resume token (SERVER-37786)');
+        }
+
+        $pipeline =  [['$project' => ['_id' => 0 ]]];
+
+        $operation = new Watch($this->manager, $this->getDatabaseName(), $this->getCollectionName(), $pipeline, $this->defaultOptions);
+        $changeStream = $operation->execute($this->getPrimaryServer());
+
+        $changeStream->rewind();
+
+        /* Insert two documents to ensure the client does not ignore the first
+         * document's resume token in favor of a postBatchResumeToken */
+        $this->insertDocument(['x' => 1]);
+        $this->insertDocument(['x' => 2]);
+
+        $this->expectException(ResumeTokenException::class);
+        $this->expectExceptionMessage('Resume token not found in change document');
+        $this->advanceCursorUntilValid($changeStream);
+    }
+
+    /**
+     * Prose test 2: "ChangeStream will throw an exception if the server
+     * response is missing the resume token (if wire version is < 8, this is a
+     * driver-side error; for 8+, this is a server-side error)"
+     */
+    public function testResumeTokenNotFoundServerSideError()
+    {
+        if (version_compare($this->getServerVersion(), '4.1.8', '<')) {
+            $this->markTestSkipped('Server does not reject change streams that modify resume token');
+        }
+
+        $pipeline =  [['$project' => ['_id' => 0 ]]];
+
+        $operation = new Watch($this->manager, $this->getDatabaseName(), $this->getCollectionName(), $pipeline, $this->defaultOptions);
+        $changeStream = $operation->execute($this->getPrimaryServer());
+
+        $changeStream->rewind();
+        $this->insertDocument(['x' => 1]);
+
+        $this->expectException(ServerException::class);
+        $this->advanceCursorUntilValid($changeStream);
+    }
+
+    /**
+     * Prose test 2: "ChangeStream will throw an exception if the server
+     * response is missing the resume token (if wire version is < 8, this is a
+     * driver-side error; for 8+, this is a server-side error)"
+     */
+    public function testResumeTokenInvalidTypeClientSideError()
+    {
+        if (version_compare($this->getServerVersion(), '4.1.8', '>=')) {
+            $this->markTestSkipped('Server rejects change streams that modify resume token (SERVER-37786)');
+        }
+
+        $pipeline =  [['$project' => ['_id' => ['$literal' => 'foo']]]];
+
+        $operation = new Watch($this->manager, $this->getDatabaseName(), $this->getCollectionName(), $pipeline, $this->defaultOptions);
+        $changeStream = $operation->execute($this->getPrimaryServer());
+
+        $changeStream->rewind();
+
+        /* Insert two documents to ensure the client does not ignore the first
+         * document's resume token in favor of a postBatchResumeToken */
+        $this->insertDocument(['x' => 1]);
+        $this->insertDocument(['x' => 2]);
+
+        $this->expectException(ResumeTokenException::class);
+        $this->expectExceptionMessage('Expected resume token to have type "array or object" but found "string"');
+        $this->advanceCursorUntilValid($changeStream);
+    }
+
+    /**
+     * Prose test 2: "ChangeStream will throw an exception if the server
+     * response is missing the resume token (if wire version is < 8, this is a
+     * driver-side error; for 8+, this is a server-side error)"
+     */
+    public function testResumeTokenInvalidTypeServerSideError()
+    {
+        if (version_compare($this->getServerVersion(), '4.1.8', '<')) {
+            $this->markTestSkipped('Server does not reject change streams that modify resume token');
+        }
+
+        $pipeline =  [['$project' => ['_id' => ['$literal' => 'foo']]]];
+
+        $operation = new Watch($this->manager, $this->getDatabaseName(), $this->getCollectionName(), $pipeline, $this->defaultOptions);
+        $changeStream = $operation->execute($this->getPrimaryServer());
+
+        $changeStream->rewind();
+        $this->insertDocument(['x' => 1]);
+
+        $this->expectException(ServerException::class);
+        $this->advanceCursorUntilValid($changeStream);
+    }
+
+    public function testMaxAwaitTimeMS()
+    {
+        /* On average, an acknowledged write takes about 20 ms to appear in a
+         * change stream on the server so we'll use a higher maxAwaitTimeMS to
+         * ensure we see the write. */
+        $maxAwaitTimeMS = 500;
+
+        /* Calculate an approximate pivot to use for time assertions. We will
+         * assert that the duration of blocking responses is greater than this
+         * value, and vice versa. */
+        $pivot = $maxAwaitTimeMS * 0.001 * 0.9;
+
+        /* Calculate an approximate upper bound to use for time assertions. We
+         * will assert that the duration of blocking responses is less than this
+         * value. */
+        $upperBound = $maxAwaitTimeMS * 0.001 * 1.5;
+
+        $operation = new Watch($this->manager, $this->getDatabaseName(), $this->getCollectionName(), [], ['maxAwaitTimeMS' => $maxAwaitTimeMS]);
+        $changeStream = $operation->execute($this->getPrimaryServer());
+
+        // Rewinding does not issue a getMore, so we should not expect a delay.
+        $startTime = microtime(true);
+        $changeStream->rewind();
+        $duration = microtime(true) - $startTime;
+        $this->assertLessThan($pivot, $duration);
+
+        $this->assertFalse($changeStream->valid());
+
+        /* Advancing again on a change stream will issue a getMore, so we should
+         * expect a delay. Expect to wait at least maxAwaitTimeMS, since no new
+         * documents will be inserted to wake up the server's query thread. Also
+         * ensure we don't wait too long (server default is one second). */
+        $startTime = microtime(true);
+        $changeStream->next();
+        $duration = microtime(true) - $startTime;
+        $this->assertGreaterThan($pivot, $duration);
+        $this->assertLessThan($upperBound, $duration);
+
+        $this->assertFalse($changeStream->valid());
+
+        $this->insertDocument(['_id' => 1]);
+
+        /* Advancing the change stream again will issue a getMore, but the
+         * server should not block since a document has been inserted.
+         * For sharded clusters, we have to repeat the getMore iteration until
+         * the cursor is valid since the first getMore commands after an insert
+         * may not return any data. Only the time of the last getMore command is
+         * taken. */
+        $attempts = $this->isShardedCluster() ? 5 : 1;
+        for ($i = 0; $i < $attempts; $i++) {
+            $startTime = microtime(true);
+            $changeStream->next();
+            $duration = microtime(true) - $startTime;
+
+            if ($changeStream->valid()) {
+                break;
+            }
+        }
+
+        $this->assertTrue($changeStream->valid());
+
+        if (! $this->isShardedCluster()) {
+            $this->assertLessThan($pivot, $duration);
+        }
+    }
+
+    public function testRewindExtractsResumeTokenAndNextResumes()
+    {
+        $operation = new Watch($this->manager, $this->getDatabaseName(), $this->getCollectionName(), [], $this->defaultOptions);
+        $changeStream = $operation->execute($this->getPrimaryServer());
+
+        $this->insertDocument(['_id' => 1, 'x' => 'foo']);
+        $this->insertDocument(['_id' => 2, 'x' => 'bar']);
+        $this->insertDocument(['_id' => 3, 'x' => 'baz']);
+
+        /* Obtain a resume token for the first insert. This will allow us to
+         * start a change stream from that point and ensure aggregate returns
+         * the second insert in its first batch, which in turn will serve as a
+         * resume token for rewind() to extract. */
+        $changeStream->rewind();
+        $this->assertFalse($changeStream->valid());
+
+        $this->advanceCursorUntilValid($changeStream);
+
+        $resumeToken = $changeStream->current()->_id;
+        $options = ['resumeAfter' => $resumeToken] + $this->defaultOptions;
+        $operation = new Watch($this->manager, $this->getDatabaseName(), $this->getCollectionName(), [], $options);
+        $changeStream = $operation->execute($this->getPrimaryServer());
+        $this->assertSameDocument($resumeToken, $changeStream->getResumeToken());
+
+        $changeStream->rewind();
+
+        if ($this->isShardedCluster()) {
+            /* aggregate on a sharded cluster may not return any data in the
+             * initial batch until periodicNoopIntervalSecs has passed. Thus,
+             * advance the change stream until we've received data. */
+            $this->advanceCursorUntilValid($changeStream);
+        } else {
+            $this->assertTrue($changeStream->valid());
+        }
+
+        $this->assertSame(0, $changeStream->key());
+        $expectedResult = [
+            '_id' => $changeStream->current()->_id,
+            'operationType' => 'insert',
+            'fullDocument' => ['_id' => 2, 'x' => 'bar'],
+            'ns' => ['db' => $this->getDatabaseName(), 'coll' => $this->getCollectionName()],
+            'documentKey' => ['_id' => 2],
+        ];
+        $this->assertMatchesDocument($expectedResult, $changeStream->current());
+
+        $this->forceChangeStreamResume();
+
+        $this->advanceCursorUntilValid($changeStream);
+        $this->assertSame(1, $changeStream->key());
+
+        $expectedResult = [
+            '_id' => $changeStream->current()->_id,
+            'operationType' => 'insert',
+            'fullDocument' => ['_id' => 3, 'x' => 'baz'],
+            'ns' => ['db' => $this->getDatabaseName(), 'coll' => $this->getCollectionName()],
+            'documentKey' => ['_id' => 3],
+        ];
+        $this->assertMatchesDocument($expectedResult, $changeStream->current());
+    }
+
+    public function testResumeAfterOption()
+    {
+        $operation = new Watch($this->manager, $this->getDatabaseName(), $this->getCollectionName(), [], $this->defaultOptions);
+        $changeStream = $operation->execute($this->getPrimaryServer());
+
+        $changeStream->rewind();
+        $this->assertFalse($changeStream->valid());
+
+        $this->insertDocument(['_id' => 1, 'x' => 'foo']);
+        $this->insertDocument(['_id' => 2, 'x' => 'bar']);
+
+        $this->advanceCursorUntilValid($changeStream);
+
+        $resumeToken = $changeStream->current()->_id;
+
+        $options = $this->defaultOptions + ['resumeAfter' => $resumeToken];
+        $operation = new Watch($this->manager, $this->getDatabaseName(), $this->getCollectionName(), [], $options);
+        $changeStream = $operation->execute($this->getPrimaryServer());
+        $this->assertSameDocument($resumeToken, $changeStream->getResumeToken());
+
+        $changeStream->rewind();
+
+        if ($this->isShardedCluster()) {
+            /* aggregate on a sharded cluster may not return any data in the
+             * initial batch until periodicNoopIntervalSecs has passed. Thus,
+             * advance the change stream until we've received data. */
+            $this->advanceCursorUntilValid($changeStream);
+        } else {
+            $this->assertTrue($changeStream->valid());
+        }
+
+        $expectedResult = [
+            '_id' => $changeStream->current()->_id,
+            'operationType' => 'insert',
+            'fullDocument' => ['_id' => 2, 'x' => 'bar'],
+            'ns' => ['db' => $this->getDatabaseName(), 'coll' => $this->getCollectionName()],
+            'documentKey' => ['_id' => 2],
+        ];
+
+        $this->assertMatchesDocument($expectedResult, $changeStream->current());
+    }
+
+    public function testStartAfterOption()
+    {
+        if (version_compare($this->getServerVersion(), '4.1.1', '<')) {
+            $this->markTestSkipped('startAfter is not supported');
+        }
+
+        $operation = new Watch($this->manager, $this->getDatabaseName(), $this->getCollectionName(), [], $this->defaultOptions);
+        $changeStream = $operation->execute($this->getPrimaryServer());
+
+        $changeStream->rewind();
+        $this->assertFalse($changeStream->valid());
+
+        $this->insertDocument(['_id' => 1, 'x' => 'foo']);
+        $this->insertDocument(['_id' => 2, 'x' => 'bar']);
+
+        $this->advanceCursorUntilValid($changeStream);
+
+        $resumeToken = $changeStream->current()->_id;
+
+        $options = $this->defaultOptions + ['startAfter' => $resumeToken];
+        $operation = new Watch($this->manager, $this->getDatabaseName(), $this->getCollectionName(), [], $options);
+        $changeStream = $operation->execute($this->getPrimaryServer());
+        $this->assertSameDocument($resumeToken, $changeStream->getResumeToken());
+
+        $changeStream->rewind();
+
+        if ($this->isShardedCluster()) {
+            /* aggregate on a sharded cluster may not return any data in the
+             * initial batch until periodicNoopIntervalSecs has passed. Thus,
+             * advance the change stream until we've received data. */
+            $this->advanceCursorUntilValid($changeStream);
+        } else {
+            $this->assertTrue($changeStream->valid());
+        }
+
+        $expectedResult = [
+            '_id' => $changeStream->current()->_id,
+            'operationType' => 'insert',
+            'fullDocument' => ['_id' => 2, 'x' => 'bar'],
+            'ns' => ['db' => $this->getDatabaseName(), 'coll' => $this->getCollectionName()],
+            'documentKey' => ['_id' => 2],
+        ];
+
+        $this->assertMatchesDocument($expectedResult, $changeStream->current());
+    }
+
+    /**
+     * @dataProvider provideTypeMapOptionsAndExpectedChangeDocument
+     */
+    public function testTypeMapOption(array $typeMap, $expectedChangeDocument)
+    {
+        $operation = new Watch($this->manager, $this->getDatabaseName(), $this->getCollectionName(), [], ['typeMap' => $typeMap] + $this->defaultOptions);
+        $changeStream = $operation->execute($this->getPrimaryServer());
+
+        $changeStream->rewind();
+        $this->assertFalse($changeStream->valid());
+
+        $this->insertDocument(['_id' => 1, 'x' => 'foo']);
+
+        $this->advanceCursorUntilValid($changeStream);
+
+        $this->assertMatchesDocument($expectedChangeDocument, $changeStream->current());
+    }
+
+    public function provideTypeMapOptionsAndExpectedChangeDocument()
+    {
+        /* Note: the "_id" and "ns" fields are purposefully omitted because the
+         * resume token's value cannot be anticipated and the collection name,
+         * which is generated from the test name, is not available in the data
+         * provider, respectively. */
+        return [
+            [
+                ['root' => 'array', 'document' => 'array'],
+                [
+                    'operationType' => 'insert',
+                    'fullDocument' => ['_id' => 1, 'x' => 'foo'],
+                    'documentKey' => ['_id' => 1],
+                ],
+            ],
+            [
+                ['root' => 'object', 'document' => 'array'],
+                (object) [
+                    'operationType' => 'insert',
+                    'fullDocument' => ['_id' => 1, 'x' => 'foo'],
+                    'documentKey' => ['_id' => 1],
+                ],
+            ],
+            [
+                ['root' => 'array', 'document' => 'stdClass'],
+                [
+                    'operationType' => 'insert',
+                    'fullDocument' => (object) ['_id' => 1, 'x' => 'foo'],
+                    'documentKey' => (object) ['_id' => 1],
+                ],
+            ],
+        ];
+    }
+
+    public function testNextAdvancesKey()
+    {
+        $operation = new Watch($this->manager, $this->getDatabaseName(), $this->getCollectionName(), [], $this->defaultOptions);
+        $changeStream = $operation->execute($this->getPrimaryServer());
+
+        $this->insertDocument(['x' => 1]);
+        $this->insertDocument(['x' => 2]);
+
+        /* Note: we intentionally do not start iteration with rewind() to ensure
+         * that next() behaves identically when called without rewind(). */
+        $this->advanceCursorUntilValid($changeStream);
+
+        $this->assertSame(0, $changeStream->key());
+
+        $changeStream->next();
+
+        $this->assertSame(1, $changeStream->key());
+    }
+
+    public function testResumeTokenNotFoundDoesNotAdvanceKey()
+    {
+        $pipeline =  [['$project' => ['_id' => 0 ]]];
+
+        $operation = new Watch($this->manager, $this->getDatabaseName(), $this->getCollectionName(), $pipeline, $this->defaultOptions);
+        $changeStream = $operation->execute($this->getPrimaryServer());
+
+        $this->insertDocument(['x' => 1]);
+        $this->insertDocument(['x' => 2]);
+        $this->insertDocument(['x' => 3]);
+
+        $changeStream->rewind();
+        $this->assertFalse($changeStream->valid());
+        $this->assertNull($changeStream->key());
+
+        try {
+            $this->advanceCursorUntilValid($changeStream);
+            $this->fail('Exception for missing resume token was not thrown');
+        } catch (ResumeTokenException $e) {
+            /* On server versions < 4.1.8, a client-side error is thrown. */
+        } catch (ServerException $e) {
+            /* On server versions >= 4.1.8, the error is thrown server-side. */
+        }
+
+        $this->assertFalse($changeStream->valid());
+        $this->assertNull($changeStream->key());
+
+        try {
+            $changeStream->next();
+            $this->fail('Exception for missing resume token was not thrown');
+        } catch (ResumeTokenException $e) {
+        } catch (ServerException $e) {
+        }
+
+        $this->assertFalse($changeStream->valid());
+        $this->assertNull($changeStream->key());
+    }
+
+    public function testSessionPersistsAfterResume()
+    {
+        $operation = new Watch($this->manager, $this->getDatabaseName(), $this->getCollectionName(), [], $this->defaultOptions);
+
+        $changeStream = null;
+        $originalSession = null;
+        $sessionAfterResume = [];
+        $commands = [];
+
+        /* We want to ensure that the lsid of the initial aggregate matches the
+         * lsid of any aggregates after the change stream resumes. After
+         * PHPC-1152 is complete, we will ensure that the lsid of the initial
+         * aggregate matches the lsid of any subsequent aggregates and getMores.
+         */
+        (new CommandObserver())->observe(
+            function () use ($operation, &$changeStream) {
+                $changeStream = $operation->execute($this->getPrimaryServer());
+            },
+            function (array $event) use (&$originalSession) {
+                $command = $event['started']->getCommand();
+                if (isset($command->aggregate)) {
+                    $originalSession = bin2hex((string) $command->lsid->id);
+                }
+            }
+        );
+
+        $changeStream->rewind();
+        $this->forceChangeStreamResume();
+
+        (new CommandObserver())->observe(
+            function () use (&$changeStream) {
+                $changeStream->next();
+            },
+            function (array $event) use (&$sessionAfterResume, &$commands) {
+                $commands[] = $event['started']->getCommandName();
+                $sessionAfterResume[] = bin2hex((string) $event['started']->getCommand()->lsid->id);
+            }
+        );
+
+        $expectedCommands = [
+            /* We expect a getMore to be issued because we are calling next(). */
+            'getMore',
+            /* Since we have killed the cursor, ChangeStream will resume by
+             * issuing a new aggregate commmand. */
+            'aggregate',
+            /* When ChangeStream resumes, it overwrites its original cursor with
+             * the new cursor resulting from the last aggregate command. This
+             * removes the last reference to the old cursor, which causes the
+             * driver to kill it (via mongoc_cursor_destroy()). */
+            'killCursors',
+        ];
+
+        $this->assertSame($expectedCommands, $commands);
+
+        foreach ($sessionAfterResume as $session) {
+            $this->assertEquals($session, $originalSession);
+        }
+    }
+
+    public function testSessionFreed()
+    {
+        $operation = new Watch($this->manager, $this->getDatabaseName(), $this->getCollectionName(), [], $this->defaultOptions);
+        $changeStream = $operation->execute($this->getPrimaryServer());
+
+        $rc = new ReflectionClass($changeStream);
+        $rp = $rc->getProperty('resumeCallable');
+        $rp->setAccessible(true);
+
+        $this->assertIsCallable($rp->getValue($changeStream));
+
+        // Invalidate the cursor to verify that resumeCallable is unset when the cursor is exhausted.
+        $this->dropCollection();
+
+        $this->advanceCursorUntilValid($changeStream);
+
+        $this->assertNull($rp->getValue($changeStream));
+    }
+
+    /**
+     * Prose test 3: "ChangeStream will automatically resume one time on a
+     * resumable error (including not master) with the initial pipeline and
+     * options, except for the addition/update of a resumeToken."
+     */
+    public function testResumeRepeatsOriginalPipelineAndOptions()
+    {
+        $operation = new Watch($this->manager, $this->getDatabaseName(), $this->getCollectionName(), [], $this->defaultOptions);
+
+        $aggregateCommands = [];
+
+        $this->configureFailPoint([
+            'configureFailPoint' => 'failCommand',
+            'mode' => ['times' => 1],
+            'data' => [
+                'failCommands' => ['getMore'],
+                'errorCode' => self::NOT_MASTER,
+                'errorLabels' => ['ResumableChangeStreamError'],
+            ],
+        ]);
+
+        (new CommandObserver())->observe(
+            function () use ($operation) {
+                $changeStream = $operation->execute($this->getPrimaryServer());
+
+                // The first next will hit the fail point, causing a resume
+                $changeStream->next();
+                $changeStream->next();
+            },
+            function (array $event) use (&$aggregateCommands) {
+                $command = $event['started']->getCommand();
+                if ($event['started']->getCommandName() !== 'aggregate') {
+                    return;
+                }
+
+                $aggregateCommands[] = (array) $command;
+            }
+        );
+
+        $this->assertCount(2, $aggregateCommands);
+
+        $this->assertThat(
+            $aggregateCommands[0]['pipeline'][0]->{'$changeStream'},
+            $this->logicalNot(
+                $this->logicalOr(
+                    $this->objectHasAttribute('resumeAfter'),
+                    $this->objectHasAttribute('startAfter'),
+                    $this->objectHasAttribute('startAtOperationTime')
+                )
+            )
+        );
+
+        $this->assertThat(
+            $aggregateCommands[1]['pipeline'][0]->{'$changeStream'},
+            $this->logicalOr(
+                $this->objectHasAttribute('resumeAfter'),
+                $this->objectHasAttribute('startAfter'),
+                $this->objectHasAttribute('startAtOperationTime')
+            )
+        );
+
+        $aggregateCommands = array_map(
+            function (array $aggregateCommand) {
+                // Remove resume options from the changestream document
+                if (isset($aggregateCommand['pipeline'][0]->{'$changeStream'})) {
+                    $aggregateCommand['pipeline'][0]->{'$changeStream'} = array_diff_key(
+                        (array) $aggregateCommand['pipeline'][0]->{'$changeStream'},
+                        ['resumeAfter' => false, 'startAfter' => false, 'startAtOperationTime' => false]
+                    );
+                }
+
+                // Remove options we don't want to compare between commands
+                return array_diff_key($aggregateCommand, ['lsid' => false, '$clusterTime' => false]);
+            },
+            $aggregateCommands
+        );
+
+        // Ensure options in original and resuming aggregate command match
+        $this->assertEquals($aggregateCommands[0], $aggregateCommands[1]);
+    }
+
+    /**
+     * Prose test 4: "ChangeStream will not attempt to resume on any error
+     * encountered while executing an aggregate command."
+     */
+    public function testErrorDuringAggregateCommandDoesNotCauseResume()
+    {
+        if (version_compare($this->getServerVersion(), '4.0.0', '<')) {
+            $this->markTestSkipped('failCommand is not supported');
+        }
+
+        $operation = new Watch($this->manager, $this->getDatabaseName(), $this->getCollectionName(), [], $this->defaultOptions);
+
+        $commandCount = 0;
+
+        $this->configureFailPoint([
+            'configureFailPoint' => 'failCommand',
+            'mode' => ['times' => 1],
+            'data' => ['failCommands' => ['aggregate'], 'errorCode' => self::INTERRUPTED],
+        ]);
+
+        $this->expectException(CommandException::class);
+
+        (new CommandObserver())->observe(
+            function () use ($operation) {
+                $operation->execute($this->getPrimaryServer());
+            },
+            function (array $event) use (&$commandCount) {
+                $commandCount++;
+            }
+        );
+
+        $this->assertSame(1, $commandCount);
+    }
+
+    /**
+     * Prose test 6: "ChangeStream will perform server selection before
+     * attempting to resume, using initial readPreference"
+     */
+    public function testOriginalReadPreferenceIsPreservedOnResume()
+    {
+        if ($this->isShardedCluster()) {
+            $this->markTestSkipped('Test does not apply to sharded clusters');
+        }
+
+        $readPreference = new ReadPreference('secondary');
+        $options = ['readPreference' => $readPreference] + $this->defaultOptions;
+        $operation = new Watch($this->manager, $this->getDatabaseName(), $this->getCollectionName(), [], $options);
+
+        try {
+            $secondary = $this->manager->selectServer($readPreference);
+        } catch (ConnectionTimeoutException $e) {
+            $this->markTestSkipped('Secondary is not available');
+        }
+
+        $changeStream = $operation->execute($secondary);
+        $previousCursorId = $changeStream->getCursorId();
+        $this->forceChangeStreamResume();
+
+        $changeStream->next();
+        $this->assertNotSame($previousCursorId, $changeStream->getCursorId());
+
+        $getCursor = Closure::bind(
+            function () {
+                return $this->iterator->getInnerIterator();
+            },
+            $changeStream,
+            ChangeStream::class
+        );
+        /** @var Cursor $cursor */
+        $cursor = $getCursor();
+        self::assertTrue($cursor->getServer()->isSecondary());
+    }
+
+    /**
+     * Prose test 12
+     * For a ChangeStream under these conditions:
+     * - Running against a server <4.0.7.
+     * - The batch is empty or has been iterated to the last document.
+     * Expected result:
+     * - getResumeToken must return the _id of the last document returned if one exists.
+     * - getResumeToken must return resumeAfter from the initial aggregate if the option was specified.
+     * - If resumeAfter was not specified, the getResumeToken result must be empty.
+     */
+    public function testGetResumeTokenReturnsOriginalResumeTokenOnEmptyBatch()
+    {
+        if ($this->isPostBatchResumeTokenSupported()) {
+            $this->markTestSkipped('postBatchResumeToken is supported');
+        }
+
+        $operation = new Watch($this->manager, $this->getDatabaseName(), $this->getCollectionName(), [], $this->defaultOptions);
+        $changeStream = $operation->execute($this->getPrimaryServer());
+
+        $this->assertNull($changeStream->getResumeToken());
+
+        $this->insertDocument(['x' => 1]);
+
+        $changeStream->next();
+        $this->assertTrue($changeStream->valid());
+        $resumeToken = $changeStream->getResumeToken();
+        $this->assertSame($resumeToken, $changeStream->current()->_id);
+
+        $options = ['resumeAfter' => $resumeToken] + $this->defaultOptions;
+        $operation = new Watch($this->manager, $this->getDatabaseName(), $this->getCollectionName(), [], $options);
+        $changeStream = $operation->execute($this->getPrimaryServer());
+
+        $this->assertSame($resumeToken, $changeStream->getResumeToken());
+    }
+
+    /**
+     * Prose test 14
+     * For a ChangeStream under these conditions:
+     *  - The batch is not empty.
+     *  - The batch hasn’t been iterated at all.
+     *  - Only the initial aggregate command has been executed.
+     * Expected result:
+     *  - getResumeToken must return startAfter from the initial aggregate if the option was specified.
+     *  - getResumeToken must return resumeAfter from the initial aggregate if the option was specified.
+     *  - If neither the startAfter nor resumeAfter options were specified, the getResumeToken result must be empty.
+     */
+    public function testResumeTokenBehaviour()
+    {
+        if (version_compare($this->getServerVersion(), '4.1.1', '<')) {
+            $this->markTestSkipped('Testing resumeAfter and startAfter can only be tested on servers >= 4.1.1');
+        }
+
+        $this->skipIfIsShardedCluster('Resume token behaviour can\'t be reliably tested on sharded clusters.');
+
+        $operation = new Watch($this->manager, $this->getDatabaseName(), $this->getCollectionName(), [], $this->defaultOptions);
+
+        $lastOpTime = null;
+
+        $changeStream = null;
+        (new CommandObserver())->observe(function () use ($operation, &$changeStream) {
+            $changeStream = $operation->execute($this->getPrimaryServer());
+        }, function ($event) use (&$lastOpTime) {
+            $this->assertInstanceOf(CommandSucceededEvent::class, $event['succeeded']);
+            $reply = $event['succeeded']->getReply();
+
+            $this->assertObjectHasAttribute('operationTime', $reply);
+            $lastOpTime = $reply->operationTime;
+        });
+
+        $this->insertDocument(['x' => 1]);
+
+        $this->advanceCursorUntilValid($changeStream);
+        $this->assertTrue($changeStream->valid());
+        $resumeToken = $changeStream->getResumeToken();
+
+        $this->insertDocument(['x' => 2]);
+
+        // Test startAfter option
+        $options = ['startAfter' => $resumeToken] + $this->defaultOptions;
+        $operation = new Watch($this->manager, $this->getDatabaseName(), $this->getCollectionName(), [], $options);
+        $changeStream = $operation->execute($this->getPrimaryServer());
+
+        $this->assertEquals($resumeToken, $changeStream->getResumeToken());
+
+        // Test resumeAfter option
+        $options = ['resumeAfter' => $resumeToken] + $this->defaultOptions;
+        $operation = new Watch($this->manager, $this->getDatabaseName(), $this->getCollectionName(), [], $options);
+        $changeStream = $operation->execute($this->getPrimaryServer());
+
+        $this->assertEquals($resumeToken, $changeStream->getResumeToken());
+
+        // Test without option
+        $options = ['startAtOperationTime' => $lastOpTime] + $this->defaultOptions;
+        $operation = new Watch($this->manager, $this->getDatabaseName(), $this->getCollectionName(), [], $options);
+        $changeStream = $operation->execute($this->getPrimaryServer());
+
+        $this->assertNull($changeStream->getResumeToken());
+    }
+
+    /**
+     * Prose test 17: "$changeStream stage for ChangeStream started with
+     * startAfter against a server >=4.1.1 that has not received any results yet
+     * MUST include a startAfter option and MUST NOT include a resumeAfter
+     * option when resuming a change stream."
+     */
+    public function testResumingChangeStreamWithoutPreviousResultsIncludesStartAfterOption()
+    {
+        if (version_compare($this->getServerVersion(), '4.1.1', '<')) {
+            $this->markTestSkipped('Testing resumeAfter and startAfter can only be tested on servers >= 4.1.1');
+        }
+
+        $operation = new Watch($this->manager, $this->getDatabaseName(), $this->getCollectionName(), [], $this->defaultOptions);
+        $changeStream = $operation->execute($this->getPrimaryServer());
+
+        $this->insertDocument(['x' => 1]);
+
+        $this->advanceCursorUntilValid($changeStream);
+        $this->assertTrue($changeStream->valid());
+        $resumeToken = $changeStream->getResumeToken();
+
+        $options = ['startAfter' => $resumeToken] + $this->defaultOptions;
+        $operation = new Watch($this->manager, $this->getDatabaseName(), $this->getCollectionName(), [], $options);
+        $changeStream = $operation->execute($this->getPrimaryServer());
+        $changeStream->rewind();
+        $this->forceChangeStreamResume();
+
+        $aggregateCommand = null;
+
+        (new CommandObserver())->observe(
+            function () use ($changeStream) {
+                $changeStream->next();
+            },
+            function (array $event) use (&$aggregateCommand) {
+                if ($event['started']->getCommandName() !== 'aggregate') {
+                    return;
+                }
+
+                $aggregateCommand = $event['started']->getCommand();
+            }
+        );
+
+        $this->assertNotNull($aggregateCommand);
+        $this->assertObjectNotHasAttribute('resumeAfter', $aggregateCommand->pipeline[0]->{'$changeStream'});
+        $this->assertObjectHasAttribute('startAfter', $aggregateCommand->pipeline[0]->{'$changeStream'});
+    }
+
+    /**
+     * Prose test 18: "$changeStream stage for ChangeStream started with
+     * startAfter against a server >=4.1.1 that has received at least one result
+     * MUST include a resumeAfter option and MUST NOT include a startAfter
+     * option when resuming a change stream."
+     */
+    public function testResumingChangeStreamWithPreviousResultsIncludesResumeAfterOption()
+    {
+        if (version_compare($this->getServerVersion(), '4.1.1', '<')) {
+            $this->markTestSkipped('Testing resumeAfter and startAfter can only be tested on servers >= 4.1.1');
+        }
+
+        $operation = new Watch($this->manager, $this->getDatabaseName(), $this->getCollectionName(), [], $this->defaultOptions);
+        $changeStream = $operation->execute($this->getPrimaryServer());
+
+        $this->insertDocument(['x' => 1]);
+
+        $this->advanceCursorUntilValid($changeStream);
+        $resumeToken = $changeStream->getResumeToken();
+
+        $options = ['startAfter' => $resumeToken] + $this->defaultOptions;
+        $operation = new Watch($this->manager, $this->getDatabaseName(), $this->getCollectionName(), [], $options);
+        $changeStream = $operation->execute($this->getPrimaryServer());
+        $changeStream->rewind();
+
+        $this->insertDocument(['x' => 2]);
+        $this->advanceCursorUntilValid($changeStream);
+        $this->assertTrue($changeStream->valid());
+
+        $this->forceChangeStreamResume();
+
+        $aggregateCommand = null;
+
+        (new CommandObserver())->observe(
+            function () use ($changeStream) {
+                $changeStream->next();
+            },
+            function (array $event) use (&$aggregateCommand) {
+                if ($event['started']->getCommandName() !== 'aggregate') {
+                    return;
+                }
+
+                $aggregateCommand = $event['started']->getCommand();
+            }
+        );
+
+        $this->assertNotNull($aggregateCommand);
+        $this->assertObjectNotHasAttribute('startAfter', $aggregateCommand->pipeline[0]->{'$changeStream'});
+        $this->assertObjectHasAttribute('resumeAfter', $aggregateCommand->pipeline[0]->{'$changeStream'});
+    }
+
+    private function assertNoCommandExecuted(callable $callable)
+    {
+        $commands = [];
+
+        (new CommandObserver())->observe(
+            $callable,
+            function (array $event) use (&$commands) {
+                $this->fail(sprintf('"%s" command was executed', $event['started']->getCommandName()));
+            }
+        );
+
+        $this->assertEmpty($commands);
+    }
+
+    private function forceChangeStreamResume()
+    {
+        $this->configureFailPoint([
+            'configureFailPoint' => 'failCommand',
+            'mode' => ['times' => 1],
+            'data' => [
+                'failCommands' => ['getMore'],
+                'errorCode' => self::NOT_MASTER,
+                'errorLabels' => ['ResumableChangeStreamError'],
+            ],
+        ]);
+    }
+
+    private function getPostBatchResumeTokenFromReply(stdClass $reply)
+    {
+        $this->assertObjectHasAttribute('cursor', $reply);
+        $this->assertIsObject($reply->cursor);
+        $this->assertObjectHasAttribute('postBatchResumeToken', $reply->cursor);
+        $this->assertIsObject($reply->cursor->postBatchResumeToken);
+
+        return $reply->cursor->postBatchResumeToken;
+    }
+
+    private function insertDocument($document)
+    {
+        $insertOne = new InsertOne(
+            $this->getDatabaseName(),
+            $this->getCollectionName(),
+            $document,
+            ['writeConcern' => new WriteConcern(WriteConcern::MAJORITY)]
+        );
+        $writeResult = $insertOne->execute($this->getPrimaryServer());
+        $this->assertEquals(1, $writeResult->getInsertedCount());
+    }
+
+    private function isPostBatchResumeTokenSupported()
+    {
+        return version_compare($this->getServerVersion(), '4.0.7', '>=');
+    }
+
+    private function isStartAtOperationTimeSupported()
+    {
+        return server_supports_feature($this->getPrimaryServer(), self::$wireVersionForStartAtOperationTime);
+    }
+
+    private function advanceCursorUntilValid(Iterator $iterator, $limitOnShardedClusters = 10)
+    {
+        if (! $this->isShardedCluster()) {
+            $iterator->next();
+            $this->assertTrue($iterator->valid());
+
+            return;
+        }
+
+        for ($i = 0; $i < $limitOnShardedClusters; $i++) {
+            $iterator->next();
+            if ($iterator->valid()) {
+                return;
+            }
+        }
+
+        throw new ExpectationFailedException(sprintf('Expected cursor to return an element but none was found after %d attempts.', $limitOnShardedClusters));
+    }
+
+    private function skipIfIsShardedCluster($message)
+    {
+        if (! $this->isShardedCluster()) {
+            return;
+        }
+
+        $this->markTestSkipped(sprintf('Test does not apply on sharded clusters: %s', $message));
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/WatchTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/WatchTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..8cf94254ac3c338185c5da8f8f25f1f5b529094e
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/Operation/WatchTest.php	
@@ -0,0 +1,94 @@
+<?php
+
+namespace MongoDB\Tests\Operation;
+
+use MongoDB\Exception\InvalidArgumentException;
+use MongoDB\Operation\Watch;
+use stdClass;
+
+/**
+ * Although these are unit tests, we extend FunctionalTestCase because Watch is
+ * constructed with a Manager instance.
+ */
+class WatchTest extends FunctionalTestCase
+{
+    public function testConstructorCollectionNameShouldBeNullIfDatabaseNameIsNull()
+    {
+        $this->expectException(InvalidArgumentException::class);
+        $this->expectExceptionMessage('$collectionName should also be null if $databaseName is null');
+
+        new Watch($this->manager, null, 'foo', []);
+    }
+
+    public function testConstructorPipelineArgumentMustBeAList()
+    {
+        $this->expectException(InvalidArgumentException::class);
+        $this->expectExceptionMessage('$pipeline is not a list (unexpected index: "foo")');
+
+        /* Note: Watch uses array_unshift() to prepend the $changeStream stage
+         * to the pipeline. Since array_unshift() reindexes numeric keys, we'll
+         * use a string key to test for this exception. */
+        new Watch($this->manager, $this->getDatabaseName(), $this->getCollectionName(), ['foo' => ['$match' => ['x' => 1]]]);
+    }
+
+    /**
+     * @dataProvider provideInvalidConstructorOptions
+     */
+    public function testConstructorOptionTypeChecks(array $options)
+    {
+        $this->expectException(InvalidArgumentException::class);
+        new Watch($this->manager, $this->getDatabaseName(), $this->getCollectionName(), [], $options);
+    }
+
+    public function provideInvalidConstructorOptions()
+    {
+        $options = [];
+
+        foreach ($this->getInvalidIntegerValues() as $value) {
+            $options[][] = ['batchSize' => $value];
+        }
+
+        foreach ($this->getInvalidDocumentValues() as $value) {
+            $options[][] = ['collation' => $value];
+        }
+
+        foreach ($this->getInvalidStringValues(true) as $value) {
+            $options[][] = ['fullDocument' => $value];
+        }
+
+        foreach ($this->getInvalidIntegerValues() as $value) {
+            $options[][] = ['maxAwaitTimeMS' => $value];
+        }
+
+        foreach ($this->getInvalidReadConcernValues() as $value) {
+            $options[][] = ['readConcern' => $value];
+        }
+
+        foreach ($this->getInvalidReadPreferenceValues(true) as $value) {
+            $options[][] = ['readPreference' => $value];
+        }
+
+        foreach ($this->getInvalidDocumentValues() as $value) {
+            $options[][] = ['resumeAfter' => $value];
+        }
+
+        foreach ($this->getInvalidSessionValues() as $value) {
+            $options[][] = ['session' => $value];
+        }
+
+        foreach ($this->getInvalidTimestampValues() as $value) {
+            $options[][] = ['startAtOperationTime' => $value];
+        }
+
+        foreach ($this->getInvalidArrayValues() as $value) {
+            $options[][] = ['typeMap' => $value];
+        }
+
+        return $options;
+    }
+
+    private function getInvalidTimestampValues()
+    {
+        return [123, 3.14, 'foo', true, [], new stdClass()];
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/PHPUnit/Functions.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/PHPUnit/Functions.php
new file mode 100644
index 0000000000000000000000000000000000000000..5d983e89398c131ae55761d231046faa0189d372
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/PHPUnit/Functions.php	
@@ -0,0 +1,2736 @@
+<?php declare(strict_types=1);
+/*
+ * This file is part of PHPUnit.
+ *
+ * (c) Sebastian Bergmann <sebastian@phpunit.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace PHPUnit\Framework;
+
+use ArrayAccess;
+use Countable;
+use DOMDocument;
+use DOMElement;
+use PHPUnit\Framework\Constraint\ArrayHasKey;
+use PHPUnit\Framework\Constraint\Callback;
+use PHPUnit\Framework\Constraint\ClassHasAttribute;
+use PHPUnit\Framework\Constraint\ClassHasStaticAttribute;
+use PHPUnit\Framework\Constraint\Constraint;
+use PHPUnit\Framework\Constraint\Count;
+use PHPUnit\Framework\Constraint\DirectoryExists;
+use PHPUnit\Framework\Constraint\FileExists;
+use PHPUnit\Framework\Constraint\GreaterThan;
+use PHPUnit\Framework\Constraint\IsAnything;
+use PHPUnit\Framework\Constraint\IsEmpty;
+use PHPUnit\Framework\Constraint\IsEqual;
+use PHPUnit\Framework\Constraint\IsEqualCanonicalizing;
+use PHPUnit\Framework\Constraint\IsEqualIgnoringCase;
+use PHPUnit\Framework\Constraint\IsEqualWithDelta;
+use PHPUnit\Framework\Constraint\IsFalse;
+use PHPUnit\Framework\Constraint\IsFinite;
+use PHPUnit\Framework\Constraint\IsIdentical;
+use PHPUnit\Framework\Constraint\IsInfinite;
+use PHPUnit\Framework\Constraint\IsInstanceOf;
+use PHPUnit\Framework\Constraint\IsJson;
+use PHPUnit\Framework\Constraint\IsNan;
+use PHPUnit\Framework\Constraint\IsNull;
+use PHPUnit\Framework\Constraint\IsReadable;
+use PHPUnit\Framework\Constraint\IsTrue;
+use PHPUnit\Framework\Constraint\IsType;
+use PHPUnit\Framework\Constraint\IsWritable;
+use PHPUnit\Framework\Constraint\LessThan;
+use PHPUnit\Framework\Constraint\LogicalAnd;
+use PHPUnit\Framework\Constraint\LogicalNot;
+use PHPUnit\Framework\Constraint\LogicalOr;
+use PHPUnit\Framework\Constraint\LogicalXor;
+use PHPUnit\Framework\Constraint\ObjectHasAttribute;
+use PHPUnit\Framework\Constraint\RegularExpression;
+use PHPUnit\Framework\Constraint\StringContains;
+use PHPUnit\Framework\Constraint\StringEndsWith;
+use PHPUnit\Framework\Constraint\StringMatchesFormatDescription;
+use PHPUnit\Framework\Constraint\StringStartsWith;
+use PHPUnit\Framework\Constraint\TraversableContainsEqual;
+use PHPUnit\Framework\Constraint\TraversableContainsIdentical;
+use PHPUnit\Framework\Constraint\TraversableContainsOnly;
+use PHPUnit\Framework\MockObject\Rule\AnyInvokedCount as AnyInvokedCountMatcher;
+use PHPUnit\Framework\MockObject\Rule\InvokedAtIndex as InvokedAtIndexMatcher;
+use PHPUnit\Framework\MockObject\Rule\InvokedAtLeastCount as InvokedAtLeastCountMatcher;
+use PHPUnit\Framework\MockObject\Rule\InvokedAtLeastOnce as InvokedAtLeastOnceMatcher;
+use PHPUnit\Framework\MockObject\Rule\InvokedAtMostCount as InvokedAtMostCountMatcher;
+use PHPUnit\Framework\MockObject\Rule\InvokedCount as InvokedCountMatcher;
+use PHPUnit\Framework\MockObject\Stub\ConsecutiveCalls as ConsecutiveCallsStub;
+use PHPUnit\Framework\MockObject\Stub\Exception as ExceptionStub;
+use PHPUnit\Framework\MockObject\Stub\ReturnArgument as ReturnArgumentStub;
+use PHPUnit\Framework\MockObject\Stub\ReturnCallback as ReturnCallbackStub;
+use PHPUnit\Framework\MockObject\Stub\ReturnSelf as ReturnSelfStub;
+use PHPUnit\Framework\MockObject\Stub\ReturnStub;
+use PHPUnit\Framework\MockObject\Stub\ReturnValueMap as ReturnValueMapStub;
+use PHPUnit\Util\Exception;
+use PHPUnit\Util\Xml\Exception as XmlException;
+use SebastianBergmann\RecursionContext\InvalidArgumentException;
+use Throwable;
+use function func_get_args;
+use function function_exists;
+
+if (! function_exists('PHPUnit\Framework\assertArrayHasKey')) {
+    /**
+     * Asserts that an array has a specified key.
+     *
+     * @see Assert::assertArrayHasKey
+     *
+     * @param int|string        $key
+     * @param array|ArrayAccess $array
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     * @throws Exception
+     */
+    function assertArrayHasKey($key, $array, string $message = '')
+    {
+        Assert::assertArrayHasKey(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertArrayNotHasKey')) {
+    /**
+     * Asserts that an array does not have a specified key.
+     *
+     * @see Assert::assertArrayNotHasKey
+     *
+     * @param int|string        $key
+     * @param array|ArrayAccess $array
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     * @throws Exception
+     */
+    function assertArrayNotHasKey($key, $array, string $message = '')
+    {
+        Assert::assertArrayNotHasKey(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertContains')) {
+    /**
+     * Asserts that a haystack contains a needle.
+     *
+     * @see Assert::assertContains
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     * @throws Exception
+     */
+    function assertContains($needle, $haystack, string $message = '')
+    {
+        Assert::assertContains(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertContainsEquals')) {
+    function assertContainsEquals($needle, $haystack, string $message = '')
+    {
+        Assert::assertContainsEquals(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertNotContains')) {
+    /**
+     * Asserts that a haystack does not contain a needle.
+     *
+     * @see Assert::assertNotContains
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     * @throws Exception
+     */
+    function assertNotContains($needle, $haystack, string $message = '')
+    {
+        Assert::assertNotContains(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertNotContainsEquals')) {
+    function assertNotContainsEquals($needle, $haystack, string $message = '')
+    {
+        Assert::assertNotContainsEquals(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertContainsOnly')) {
+    /**
+     * Asserts that a haystack contains only values of a given type.
+     *
+     * @see Assert::assertContainsOnly
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     */
+    function assertContainsOnly(string $type, $haystack, bool $isNativeType = null, string $message = '')
+    {
+        Assert::assertContainsOnly(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertContainsOnlyInstancesOf')) {
+    /**
+     * Asserts that a haystack contains only instances of a given class name.
+     *
+     * @see Assert::assertContainsOnlyInstancesOf
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     */
+    function assertContainsOnlyInstancesOf(string $className, $haystack, string $message = '')
+    {
+        Assert::assertContainsOnlyInstancesOf(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertNotContainsOnly')) {
+    /**
+     * Asserts that a haystack does not contain only values of a given type.
+     *
+     * @see Assert::assertNotContainsOnly
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     */
+    function assertNotContainsOnly(string $type, $haystack, bool $isNativeType = null, string $message = '')
+    {
+        Assert::assertNotContainsOnly(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertCount')) {
+    /**
+     * Asserts the number of elements of an array, Countable or Traversable.
+     *
+     * @see Assert::assertCount
+     *
+     * @param Countable|iterable $haystack
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     * @throws Exception
+     */
+    function assertCount(int $expectedCount, $haystack, string $message = '')
+    {
+        Assert::assertCount(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertNotCount')) {
+    /**
+     * Asserts the number of elements of an array, Countable or Traversable.
+     *
+     * @see Assert::assertNotCount
+     *
+     * @param Countable|iterable $haystack
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     * @throws Exception
+     */
+    function assertNotCount(int $expectedCount, $haystack, string $message = '')
+    {
+        Assert::assertNotCount(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertEquals')) {
+    /**
+     * Asserts that two variables are equal.
+     *
+     * @see Assert::assertEquals
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     */
+    function assertEquals($expected, $actual, string $message = '')
+    {
+        Assert::assertEquals(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertEqualsCanonicalizing')) {
+    /**
+     * Asserts that two variables are equal (canonicalizing).
+     *
+     * @see Assert::assertEqualsCanonicalizing
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     */
+    function assertEqualsCanonicalizing($expected, $actual, string $message = '')
+    {
+        Assert::assertEqualsCanonicalizing(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertEqualsIgnoringCase')) {
+    /**
+     * Asserts that two variables are equal (ignoring case).
+     *
+     * @see Assert::assertEqualsIgnoringCase
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     */
+    function assertEqualsIgnoringCase($expected, $actual, string $message = '')
+    {
+        Assert::assertEqualsIgnoringCase(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertEqualsWithDelta')) {
+    /**
+     * Asserts that two variables are equal (with delta).
+     *
+     * @see Assert::assertEqualsWithDelta
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     */
+    function assertEqualsWithDelta($expected, $actual, float $delta, string $message = '')
+    {
+        Assert::assertEqualsWithDelta(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertNotEquals')) {
+    /**
+     * Asserts that two variables are not equal.
+     *
+     * @see Assert::assertNotEquals
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     */
+    function assertNotEquals($expected, $actual, string $message = '')
+    {
+        Assert::assertNotEquals(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertNotEqualsCanonicalizing')) {
+    /**
+     * Asserts that two variables are not equal (canonicalizing).
+     *
+     * @see Assert::assertNotEqualsCanonicalizing
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     */
+    function assertNotEqualsCanonicalizing($expected, $actual, string $message = '')
+    {
+        Assert::assertNotEqualsCanonicalizing(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertNotEqualsIgnoringCase')) {
+    /**
+     * Asserts that two variables are not equal (ignoring case).
+     *
+     * @see Assert::assertNotEqualsIgnoringCase
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     */
+    function assertNotEqualsIgnoringCase($expected, $actual, string $message = '')
+    {
+        Assert::assertNotEqualsIgnoringCase(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertNotEqualsWithDelta')) {
+    /**
+     * Asserts that two variables are not equal (with delta).
+     *
+     * @see Assert::assertNotEqualsWithDelta
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     */
+    function assertNotEqualsWithDelta($expected, $actual, float $delta, string $message = '')
+    {
+        Assert::assertNotEqualsWithDelta(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertEmpty')) {
+    /**
+     * Asserts that a variable is empty.
+     *
+     * @see Assert::assertEmpty
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     *
+     * @psalm-assert empty $actual
+     */
+    function assertEmpty($actual, string $message = '')
+    {
+        Assert::assertEmpty(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertNotEmpty')) {
+    /**
+     * Asserts that a variable is not empty.
+     *
+     * @see Assert::assertNotEmpty
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     *
+     * @psalm-assert !empty $actual
+     */
+    function assertNotEmpty($actual, string $message = '')
+    {
+        Assert::assertNotEmpty(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertGreaterThan')) {
+    /**
+     * Asserts that a value is greater than another value.
+     *
+     * @see Assert::assertGreaterThan
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     */
+    function assertGreaterThan($expected, $actual, string $message = '')
+    {
+        Assert::assertGreaterThan(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertGreaterThanOrEqual')) {
+    /**
+     * Asserts that a value is greater than or equal to another value.
+     *
+     * @see Assert::assertGreaterThanOrEqual
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     */
+    function assertGreaterThanOrEqual($expected, $actual, string $message = '')
+    {
+        Assert::assertGreaterThanOrEqual(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertLessThan')) {
+    /**
+     * Asserts that a value is smaller than another value.
+     *
+     * @see Assert::assertLessThan
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     */
+    function assertLessThan($expected, $actual, string $message = '')
+    {
+        Assert::assertLessThan(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertLessThanOrEqual')) {
+    /**
+     * Asserts that a value is smaller than or equal to another value.
+     *
+     * @see Assert::assertLessThanOrEqual
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     */
+    function assertLessThanOrEqual($expected, $actual, string $message = '')
+    {
+        Assert::assertLessThanOrEqual(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertFileEquals')) {
+    /**
+     * Asserts that the contents of one file is equal to the contents of another
+     * file.
+     *
+     * @see Assert::assertFileEquals
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     */
+    function assertFileEquals(string $expected, string $actual, string $message = '')
+    {
+        Assert::assertFileEquals(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertFileEqualsCanonicalizing')) {
+    /**
+     * Asserts that the contents of one file is equal to the contents of another
+     * file (canonicalizing).
+     *
+     * @see Assert::assertFileEqualsCanonicalizing
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     */
+    function assertFileEqualsCanonicalizing(string $expected, string $actual, string $message = '')
+    {
+        Assert::assertFileEqualsCanonicalizing(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertFileEqualsIgnoringCase')) {
+    /**
+     * Asserts that the contents of one file is equal to the contents of another
+     * file (ignoring case).
+     *
+     * @see Assert::assertFileEqualsIgnoringCase
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     */
+    function assertFileEqualsIgnoringCase(string $expected, string $actual, string $message = '')
+    {
+        Assert::assertFileEqualsIgnoringCase(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertFileNotEquals')) {
+    /**
+     * Asserts that the contents of one file is not equal to the contents of
+     * another file.
+     *
+     * @see Assert::assertFileNotEquals
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     */
+    function assertFileNotEquals(string $expected, string $actual, string $message = '')
+    {
+        Assert::assertFileNotEquals(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertFileNotEqualsCanonicalizing')) {
+    /**
+     * Asserts that the contents of one file is not equal to the contents of another
+     * file (canonicalizing).
+     *
+     * @see Assert::assertFileNotEqualsCanonicalizing
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     */
+    function assertFileNotEqualsCanonicalizing(string $expected, string $actual, string $message = '')
+    {
+        Assert::assertFileNotEqualsCanonicalizing(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertFileNotEqualsIgnoringCase')) {
+    /**
+     * Asserts that the contents of one file is not equal to the contents of another
+     * file (ignoring case).
+     *
+     * @see Assert::assertFileNotEqualsIgnoringCase
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     */
+    function assertFileNotEqualsIgnoringCase(string $expected, string $actual, string $message = '')
+    {
+        Assert::assertFileNotEqualsIgnoringCase(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertStringEqualsFile')) {
+    /**
+     * Asserts that the contents of a string is equal
+     * to the contents of a file.
+     *
+     * @see Assert::assertStringEqualsFile
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     */
+    function assertStringEqualsFile(string $expectedFile, string $actualString, string $message = '')
+    {
+        Assert::assertStringEqualsFile(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertStringEqualsFileCanonicalizing')) {
+    /**
+     * Asserts that the contents of a string is equal
+     * to the contents of a file (canonicalizing).
+     *
+     * @see Assert::assertStringEqualsFileCanonicalizing
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     */
+    function assertStringEqualsFileCanonicalizing(string $expectedFile, string $actualString, string $message = '')
+    {
+        Assert::assertStringEqualsFileCanonicalizing(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertStringEqualsFileIgnoringCase')) {
+    /**
+     * Asserts that the contents of a string is equal
+     * to the contents of a file (ignoring case).
+     *
+     * @see Assert::assertStringEqualsFileIgnoringCase
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     */
+    function assertStringEqualsFileIgnoringCase(string $expectedFile, string $actualString, string $message = '')
+    {
+        Assert::assertStringEqualsFileIgnoringCase(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertStringNotEqualsFile')) {
+    /**
+     * Asserts that the contents of a string is not equal
+     * to the contents of a file.
+     *
+     * @see Assert::assertStringNotEqualsFile
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     */
+    function assertStringNotEqualsFile(string $expectedFile, string $actualString, string $message = '')
+    {
+        Assert::assertStringNotEqualsFile(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertStringNotEqualsFileCanonicalizing')) {
+    /**
+     * Asserts that the contents of a string is not equal
+     * to the contents of a file (canonicalizing).
+     *
+     * @see Assert::assertStringNotEqualsFileCanonicalizing
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     */
+    function assertStringNotEqualsFileCanonicalizing(string $expectedFile, string $actualString, string $message = '')
+    {
+        Assert::assertStringNotEqualsFileCanonicalizing(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertStringNotEqualsFileIgnoringCase')) {
+    /**
+     * Asserts that the contents of a string is not equal
+     * to the contents of a file (ignoring case).
+     *
+     * @see Assert::assertStringNotEqualsFileIgnoringCase
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     */
+    function assertStringNotEqualsFileIgnoringCase(string $expectedFile, string $actualString, string $message = '')
+    {
+        Assert::assertStringNotEqualsFileIgnoringCase(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertIsReadable')) {
+    /**
+     * Asserts that a file/dir is readable.
+     *
+     * @see Assert::assertIsReadable
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     */
+    function assertIsReadable(string $filename, string $message = '')
+    {
+        Assert::assertIsReadable(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertIsNotReadable')) {
+    /**
+     * Asserts that a file/dir exists and is not readable.
+     *
+     * @see Assert::assertIsNotReadable
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     */
+    function assertIsNotReadable(string $filename, string $message = '')
+    {
+        Assert::assertIsNotReadable(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertNotIsReadable')) {
+    /**
+     * Asserts that a file/dir exists and is not readable.
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     *
+     * @codeCoverageIgnore
+     *
+     * @deprecated https://github.com/sebastianbergmann/phpunit/issues/4062
+     * @see Assert::assertNotIsReadable
+     */
+    function assertNotIsReadable(string $filename, string $message = '')
+    {
+        Assert::assertNotIsReadable(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertIsWritable')) {
+    /**
+     * Asserts that a file/dir exists and is writable.
+     *
+     * @see Assert::assertIsWritable
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     */
+    function assertIsWritable(string $filename, string $message = '')
+    {
+        Assert::assertIsWritable(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertIsNotWritable')) {
+    /**
+     * Asserts that a file/dir exists and is not writable.
+     *
+     * @see Assert::assertIsNotWritable
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     */
+    function assertIsNotWritable(string $filename, string $message = '')
+    {
+        Assert::assertIsNotWritable(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertNotIsWritable')) {
+    /**
+     * Asserts that a file/dir exists and is not writable.
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     *
+     * @codeCoverageIgnore
+     *
+     * @deprecated https://github.com/sebastianbergmann/phpunit/issues/4065
+     * @see Assert::assertNotIsWritable
+     */
+    function assertNotIsWritable(string $filename, string $message = '')
+    {
+        Assert::assertNotIsWritable(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertDirectoryExists')) {
+    /**
+     * Asserts that a directory exists.
+     *
+     * @see Assert::assertDirectoryExists
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     */
+    function assertDirectoryExists(string $directory, string $message = '')
+    {
+        Assert::assertDirectoryExists(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertDirectoryDoesNotExist')) {
+    /**
+     * Asserts that a directory does not exist.
+     *
+     * @see Assert::assertDirectoryDoesNotExist
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     */
+    function assertDirectoryDoesNotExist(string $directory, string $message = '')
+    {
+        Assert::assertDirectoryDoesNotExist(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertDirectoryNotExists')) {
+    /**
+     * Asserts that a directory does not exist.
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     *
+     * @codeCoverageIgnore
+     *
+     * @deprecated https://github.com/sebastianbergmann/phpunit/issues/4068
+     * @see Assert::assertDirectoryNotExists
+     */
+    function assertDirectoryNotExists(string $directory, string $message = '')
+    {
+        Assert::assertDirectoryNotExists(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertDirectoryIsReadable')) {
+    /**
+     * Asserts that a directory exists and is readable.
+     *
+     * @see Assert::assertDirectoryIsReadable
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     */
+    function assertDirectoryIsReadable(string $directory, string $message = '')
+    {
+        Assert::assertDirectoryIsReadable(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertDirectoryIsNotReadable')) {
+    /**
+     * Asserts that a directory exists and is not readable.
+     *
+     * @see Assert::assertDirectoryIsNotReadable
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     */
+    function assertDirectoryIsNotReadable(string $directory, string $message = '')
+    {
+        Assert::assertDirectoryIsNotReadable(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertDirectoryNotIsReadable')) {
+    /**
+     * Asserts that a directory exists and is not readable.
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     *
+     * @codeCoverageIgnore
+     *
+     * @deprecated https://github.com/sebastianbergmann/phpunit/issues/4071
+     * @see Assert::assertDirectoryNotIsReadable
+     */
+    function assertDirectoryNotIsReadable(string $directory, string $message = '')
+    {
+        Assert::assertDirectoryNotIsReadable(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertDirectoryIsWritable')) {
+    /**
+     * Asserts that a directory exists and is writable.
+     *
+     * @see Assert::assertDirectoryIsWritable
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     */
+    function assertDirectoryIsWritable(string $directory, string $message = '')
+    {
+        Assert::assertDirectoryIsWritable(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertDirectoryIsNotWritable')) {
+    /**
+     * Asserts that a directory exists and is not writable.
+     *
+     * @see Assert::assertDirectoryIsNotWritable
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     */
+    function assertDirectoryIsNotWritable(string $directory, string $message = '')
+    {
+        Assert::assertDirectoryIsNotWritable(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertDirectoryNotIsWritable')) {
+    /**
+     * Asserts that a directory exists and is not writable.
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     *
+     * @codeCoverageIgnore
+     *
+     * @deprecated https://github.com/sebastianbergmann/phpunit/issues/4074
+     * @see Assert::assertDirectoryNotIsWritable
+     */
+    function assertDirectoryNotIsWritable(string $directory, string $message = '')
+    {
+        Assert::assertDirectoryNotIsWritable(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertFileExists')) {
+    /**
+     * Asserts that a file exists.
+     *
+     * @see Assert::assertFileExists
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     */
+    function assertFileExists(string $filename, string $message = '')
+    {
+        Assert::assertFileExists(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertFileDoesNotExist')) {
+    /**
+     * Asserts that a file does not exist.
+     *
+     * @see Assert::assertFileDoesNotExist
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     */
+    function assertFileDoesNotExist(string $filename, string $message = '')
+    {
+        Assert::assertFileDoesNotExist(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertFileNotExists')) {
+    /**
+     * Asserts that a file does not exist.
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     *
+     * @codeCoverageIgnore
+     *
+     * @deprecated https://github.com/sebastianbergmann/phpunit/issues/4077
+     * @see Assert::assertFileNotExists
+     */
+    function assertFileNotExists(string $filename, string $message = '')
+    {
+        Assert::assertFileNotExists(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertFileIsReadable')) {
+    /**
+     * Asserts that a file exists and is readable.
+     *
+     * @see Assert::assertFileIsReadable
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     */
+    function assertFileIsReadable(string $file, string $message = '')
+    {
+        Assert::assertFileIsReadable(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertFileIsNotReadable')) {
+    /**
+     * Asserts that a file exists and is not readable.
+     *
+     * @see Assert::assertFileIsNotReadable
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     */
+    function assertFileIsNotReadable(string $file, string $message = '')
+    {
+        Assert::assertFileIsNotReadable(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertFileNotIsReadable')) {
+    /**
+     * Asserts that a file exists and is not readable.
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     *
+     * @codeCoverageIgnore
+     *
+     * @deprecated https://github.com/sebastianbergmann/phpunit/issues/4080
+     * @see Assert::assertFileNotIsReadable
+     */
+    function assertFileNotIsReadable(string $file, string $message = '')
+    {
+        Assert::assertFileNotIsReadable(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertFileIsWritable')) {
+    /**
+     * Asserts that a file exists and is writable.
+     *
+     * @see Assert::assertFileIsWritable
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     */
+    function assertFileIsWritable(string $file, string $message = '')
+    {
+        Assert::assertFileIsWritable(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertFileIsNotWritable')) {
+    /**
+     * Asserts that a file exists and is not writable.
+     *
+     * @see Assert::assertFileIsNotWritable
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     */
+    function assertFileIsNotWritable(string $file, string $message = '')
+    {
+        Assert::assertFileIsNotWritable(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertFileNotIsWritable')) {
+    /**
+     * Asserts that a file exists and is not writable.
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     *
+     * @codeCoverageIgnore
+     *
+     * @deprecated https://github.com/sebastianbergmann/phpunit/issues/4083
+     * @see Assert::assertFileNotIsWritable
+     */
+    function assertFileNotIsWritable(string $file, string $message = '')
+    {
+        Assert::assertFileNotIsWritable(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertTrue')) {
+    /**
+     * Asserts that a condition is true.
+     *
+     * @see Assert::assertTrue
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     *
+     * @psalm-assert true $condition
+     */
+    function assertTrue($condition, string $message = '')
+    {
+        Assert::assertTrue(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertNotTrue')) {
+    /**
+     * Asserts that a condition is not true.
+     *
+     * @see Assert::assertNotTrue
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     *
+     * @psalm-assert !true $condition
+     */
+    function assertNotTrue($condition, string $message = '')
+    {
+        Assert::assertNotTrue(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertFalse')) {
+    /**
+     * Asserts that a condition is false.
+     *
+     * @see Assert::assertFalse
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     *
+     * @psalm-assert false $condition
+     */
+    function assertFalse($condition, string $message = '')
+    {
+        Assert::assertFalse(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertNotFalse')) {
+    /**
+     * Asserts that a condition is not false.
+     *
+     * @see Assert::assertNotFalse
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     *
+     * @psalm-assert !false $condition
+     */
+    function assertNotFalse($condition, string $message = '')
+    {
+        Assert::assertNotFalse(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertNull')) {
+    /**
+     * Asserts that a variable is null.
+     *
+     * @see Assert::assertNull
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     *
+     * @psalm-assert null $actual
+     */
+    function assertNull($actual, string $message = '')
+    {
+        Assert::assertNull(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertNotNull')) {
+    /**
+     * Asserts that a variable is not null.
+     *
+     * @see Assert::assertNotNull
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     *
+     * @psalm-assert !null $actual
+     */
+    function assertNotNull($actual, string $message = '')
+    {
+        Assert::assertNotNull(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertFinite')) {
+    /**
+     * Asserts that a variable is finite.
+     *
+     * @see Assert::assertFinite
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     */
+    function assertFinite($actual, string $message = '')
+    {
+        Assert::assertFinite(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertInfinite')) {
+    /**
+     * Asserts that a variable is infinite.
+     *
+     * @see Assert::assertInfinite
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     */
+    function assertInfinite($actual, string $message = '')
+    {
+        Assert::assertInfinite(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertNan')) {
+    /**
+     * Asserts that a variable is nan.
+     *
+     * @see Assert::assertNan
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     */
+    function assertNan($actual, string $message = '')
+    {
+        Assert::assertNan(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertClassHasAttribute')) {
+    /**
+     * Asserts that a class has a specified attribute.
+     *
+     * @see Assert::assertClassHasAttribute
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     * @throws Exception
+     */
+    function assertClassHasAttribute(string $attributeName, string $className, string $message = '')
+    {
+        Assert::assertClassHasAttribute(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertClassNotHasAttribute')) {
+    /**
+     * Asserts that a class does not have a specified attribute.
+     *
+     * @see Assert::assertClassNotHasAttribute
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     * @throws Exception
+     */
+    function assertClassNotHasAttribute(string $attributeName, string $className, string $message = '')
+    {
+        Assert::assertClassNotHasAttribute(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertClassHasStaticAttribute')) {
+    /**
+     * Asserts that a class has a specified static attribute.
+     *
+     * @see Assert::assertClassHasStaticAttribute
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     * @throws Exception
+     */
+    function assertClassHasStaticAttribute(string $attributeName, string $className, string $message = '')
+    {
+        Assert::assertClassHasStaticAttribute(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertClassNotHasStaticAttribute')) {
+    /**
+     * Asserts that a class does not have a specified static attribute.
+     *
+     * @see Assert::assertClassNotHasStaticAttribute
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     * @throws Exception
+     */
+    function assertClassNotHasStaticAttribute(string $attributeName, string $className, string $message = '')
+    {
+        Assert::assertClassNotHasStaticAttribute(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertObjectHasAttribute')) {
+    /**
+     * Asserts that an object has a specified attribute.
+     *
+     * @see Assert::assertObjectHasAttribute
+     *
+     * @param object $object
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     * @throws Exception
+     */
+    function assertObjectHasAttribute(string $attributeName, $object, string $message = '')
+    {
+        Assert::assertObjectHasAttribute(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertObjectNotHasAttribute')) {
+    /**
+     * Asserts that an object does not have a specified attribute.
+     *
+     * @see Assert::assertObjectNotHasAttribute
+     *
+     * @param object $object
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     * @throws Exception
+     */
+    function assertObjectNotHasAttribute(string $attributeName, $object, string $message = '')
+    {
+        Assert::assertObjectNotHasAttribute(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertSame')) {
+    /**
+     * Asserts that two variables have the same type and value.
+     * Used on objects, it asserts that two variables reference
+     * the same object.
+     *
+     * @see Assert::assertSame
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     *
+     * @psalm-template ExpectedType
+     * @psalm-param ExpectedType $expected
+     * @psalm-assert =ExpectedType $actual
+     */
+    function assertSame($expected, $actual, string $message = '')
+    {
+        Assert::assertSame(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertNotSame')) {
+    /**
+     * Asserts that two variables do not have the same type and value.
+     * Used on objects, it asserts that two variables do not reference
+     * the same object.
+     *
+     * @see Assert::assertNotSame
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     */
+    function assertNotSame($expected, $actual, string $message = '')
+    {
+        Assert::assertNotSame(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertInstanceOf')) {
+    /**
+     * Asserts that a variable is of a given type.
+     *
+     * @see Assert::assertInstanceOf
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     * @throws Exception
+     *
+     * @psalm-template ExpectedType of object
+     * @psalm-param class-string<ExpectedType> $expected
+     * @psalm-assert ExpectedType $actual
+     */
+    function assertInstanceOf(string $expected, $actual, string $message = '')
+    {
+        Assert::assertInstanceOf(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertNotInstanceOf')) {
+    /**
+     * Asserts that a variable is not of a given type.
+     *
+     * @see Assert::assertNotInstanceOf
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     * @throws Exception
+     *
+     * @psalm-template ExpectedType of object
+     * @psalm-param class-string<ExpectedType> $expected
+     * @psalm-assert !ExpectedType $actual
+     */
+    function assertNotInstanceOf(string $expected, $actual, string $message = '')
+    {
+        Assert::assertNotInstanceOf(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertIsArray')) {
+    /**
+     * Asserts that a variable is of type array.
+     *
+     * @see Assert::assertIsArray
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     *
+     * @psalm-assert array $actual
+     */
+    function assertIsArray($actual, string $message = '')
+    {
+        Assert::assertIsArray(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertIsBool')) {
+    /**
+     * Asserts that a variable is of type bool.
+     *
+     * @see Assert::assertIsBool
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     *
+     * @psalm-assert bool $actual
+     */
+    function assertIsBool($actual, string $message = '')
+    {
+        Assert::assertIsBool(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertIsFloat')) {
+    /**
+     * Asserts that a variable is of type float.
+     *
+     * @see Assert::assertIsFloat
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     *
+     * @psalm-assert float $actual
+     */
+    function assertIsFloat($actual, string $message = '')
+    {
+        Assert::assertIsFloat(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertIsInt')) {
+    /**
+     * Asserts that a variable is of type int.
+     *
+     * @see Assert::assertIsInt
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     *
+     * @psalm-assert int $actual
+     */
+    function assertIsInt($actual, string $message = '')
+    {
+        Assert::assertIsInt(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertIsNumeric')) {
+    /**
+     * Asserts that a variable is of type numeric.
+     *
+     * @see Assert::assertIsNumeric
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     *
+     * @psalm-assert numeric $actual
+     */
+    function assertIsNumeric($actual, string $message = '')
+    {
+        Assert::assertIsNumeric(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertIsObject')) {
+    /**
+     * Asserts that a variable is of type object.
+     *
+     * @see Assert::assertIsObject
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     *
+     * @psalm-assert object $actual
+     */
+    function assertIsObject($actual, string $message = '')
+    {
+        Assert::assertIsObject(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertIsResource')) {
+    /**
+     * Asserts that a variable is of type resource.
+     *
+     * @see Assert::assertIsResource
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     *
+     * @psalm-assert resource $actual
+     */
+    function assertIsResource($actual, string $message = '')
+    {
+        Assert::assertIsResource(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertIsClosedResource')) {
+    /**
+     * Asserts that a variable is of type resource and is closed.
+     *
+     * @see Assert::assertIsClosedResource
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     *
+     * @psalm-assert resource $actual
+     */
+    function assertIsClosedResource($actual, string $message = '')
+    {
+        Assert::assertIsClosedResource(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertIsString')) {
+    /**
+     * Asserts that a variable is of type string.
+     *
+     * @see Assert::assertIsString
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     *
+     * @psalm-assert string $actual
+     */
+    function assertIsString($actual, string $message = '')
+    {
+        Assert::assertIsString(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertIsScalar')) {
+    /**
+     * Asserts that a variable is of type scalar.
+     *
+     * @see Assert::assertIsScalar
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     *
+     * @psalm-assert scalar $actual
+     */
+    function assertIsScalar($actual, string $message = '')
+    {
+        Assert::assertIsScalar(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertIsCallable')) {
+    /**
+     * Asserts that a variable is of type callable.
+     *
+     * @see Assert::assertIsCallable
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     *
+     * @psalm-assert callable $actual
+     */
+    function assertIsCallable($actual, string $message = '')
+    {
+        Assert::assertIsCallable(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertIsIterable')) {
+    /**
+     * Asserts that a variable is of type iterable.
+     *
+     * @see Assert::assertIsIterable
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     *
+     * @psalm-assert iterable $actual
+     */
+    function assertIsIterable($actual, string $message = '')
+    {
+        Assert::assertIsIterable(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertIsNotArray')) {
+    /**
+     * Asserts that a variable is not of type array.
+     *
+     * @see Assert::assertIsNotArray
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     *
+     * @psalm-assert !array $actual
+     */
+    function assertIsNotArray($actual, string $message = '')
+    {
+        Assert::assertIsNotArray(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertIsNotBool')) {
+    /**
+     * Asserts that a variable is not of type bool.
+     *
+     * @see Assert::assertIsNotBool
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     *
+     * @psalm-assert !bool $actual
+     */
+    function assertIsNotBool($actual, string $message = '')
+    {
+        Assert::assertIsNotBool(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertIsNotFloat')) {
+    /**
+     * Asserts that a variable is not of type float.
+     *
+     * @see Assert::assertIsNotFloat
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     *
+     * @psalm-assert !float $actual
+     */
+    function assertIsNotFloat($actual, string $message = '')
+    {
+        Assert::assertIsNotFloat(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertIsNotInt')) {
+    /**
+     * Asserts that a variable is not of type int.
+     *
+     * @see Assert::assertIsNotInt
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     *
+     * @psalm-assert !int $actual
+     */
+    function assertIsNotInt($actual, string $message = '')
+    {
+        Assert::assertIsNotInt(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertIsNotNumeric')) {
+    /**
+     * Asserts that a variable is not of type numeric.
+     *
+     * @see Assert::assertIsNotNumeric
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     *
+     * @psalm-assert !numeric $actual
+     */
+    function assertIsNotNumeric($actual, string $message = '')
+    {
+        Assert::assertIsNotNumeric(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertIsNotObject')) {
+    /**
+     * Asserts that a variable is not of type object.
+     *
+     * @see Assert::assertIsNotObject
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     *
+     * @psalm-assert !object $actual
+     */
+    function assertIsNotObject($actual, string $message = '')
+    {
+        Assert::assertIsNotObject(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertIsNotResource')) {
+    /**
+     * Asserts that a variable is not of type resource.
+     *
+     * @see Assert::assertIsNotResource
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     *
+     * @psalm-assert !resource $actual
+     */
+    function assertIsNotResource($actual, string $message = '')
+    {
+        Assert::assertIsNotResource(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertIsNotClosedResource')) {
+    /**
+     * Asserts that a variable is not of type resource.
+     *
+     * @see Assert::assertIsNotClosedResource
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     *
+     * @psalm-assert !resource $actual
+     */
+    function assertIsNotClosedResource($actual, string $message = '')
+    {
+        Assert::assertIsNotClosedResource(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertIsNotString')) {
+    /**
+     * Asserts that a variable is not of type string.
+     *
+     * @see Assert::assertIsNotString
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     *
+     * @psalm-assert !string $actual
+     */
+    function assertIsNotString($actual, string $message = '')
+    {
+        Assert::assertIsNotString(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertIsNotScalar')) {
+    /**
+     * Asserts that a variable is not of type scalar.
+     *
+     * @see Assert::assertIsNotScalar
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     *
+     * @psalm-assert !scalar $actual
+     */
+    function assertIsNotScalar($actual, string $message = '')
+    {
+        Assert::assertIsNotScalar(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertIsNotCallable')) {
+    /**
+     * Asserts that a variable is not of type callable.
+     *
+     * @see Assert::assertIsNotCallable
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     *
+     * @psalm-assert !callable $actual
+     */
+    function assertIsNotCallable($actual, string $message = '')
+    {
+        Assert::assertIsNotCallable(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertIsNotIterable')) {
+    /**
+     * Asserts that a variable is not of type iterable.
+     *
+     * @see Assert::assertIsNotIterable
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     *
+     * @psalm-assert !iterable $actual
+     */
+    function assertIsNotIterable($actual, string $message = '')
+    {
+        Assert::assertIsNotIterable(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertMatchesRegularExpression')) {
+    /**
+     * Asserts that a string matches a given regular expression.
+     *
+     * @see Assert::assertMatchesRegularExpression
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     */
+    function assertMatchesRegularExpression(string $pattern, string $string, string $message = '')
+    {
+        Assert::assertMatchesRegularExpression(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertRegExp')) {
+    /**
+     * Asserts that a string matches a given regular expression.
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     *
+     * @codeCoverageIgnore
+     *
+     * @deprecated https://github.com/sebastianbergmann/phpunit/issues/4086
+     * @see Assert::assertRegExp
+     */
+    function assertRegExp(string $pattern, string $string, string $message = '')
+    {
+        Assert::assertRegExp(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertDoesNotMatchRegularExpression')) {
+    /**
+     * Asserts that a string does not match a given regular expression.
+     *
+     * @see Assert::assertDoesNotMatchRegularExpression
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     */
+    function assertDoesNotMatchRegularExpression(string $pattern, string $string, string $message = '')
+    {
+        Assert::assertDoesNotMatchRegularExpression(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertNotRegExp')) {
+    /**
+     * Asserts that a string does not match a given regular expression.
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     *
+     * @codeCoverageIgnore
+     *
+     * @deprecated https://github.com/sebastianbergmann/phpunit/issues/4089
+     * @see Assert::assertNotRegExp
+     */
+    function assertNotRegExp(string $pattern, string $string, string $message = '')
+    {
+        Assert::assertNotRegExp(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertSameSize')) {
+    /**
+     * Assert that the size of two arrays (or `Countable` or `Traversable` objects)
+     * is the same.
+     *
+     * @see Assert::assertSameSize
+     *
+     * @param Countable|iterable $expected
+     * @param Countable|iterable $actual
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     * @throws Exception
+     */
+    function assertSameSize($expected, $actual, string $message = '')
+    {
+        Assert::assertSameSize(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertNotSameSize')) {
+    /**
+     * Assert that the size of two arrays (or `Countable` or `Traversable` objects)
+     * is not the same.
+     *
+     * @see Assert::assertNotSameSize
+     *
+     * @param Countable|iterable $expected
+     * @param Countable|iterable $actual
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     * @throws Exception
+     */
+    function assertNotSameSize($expected, $actual, string $message = '')
+    {
+        Assert::assertNotSameSize(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertStringMatchesFormat')) {
+    /**
+     * Asserts that a string matches a given format string.
+     *
+     * @see Assert::assertStringMatchesFormat
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     */
+    function assertStringMatchesFormat(string $format, string $string, string $message = '')
+    {
+        Assert::assertStringMatchesFormat(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertStringNotMatchesFormat')) {
+    /**
+     * Asserts that a string does not match a given format string.
+     *
+     * @see Assert::assertStringNotMatchesFormat
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     */
+    function assertStringNotMatchesFormat(string $format, string $string, string $message = '')
+    {
+        Assert::assertStringNotMatchesFormat(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertStringMatchesFormatFile')) {
+    /**
+     * Asserts that a string matches a given format file.
+     *
+     * @see Assert::assertStringMatchesFormatFile
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     */
+    function assertStringMatchesFormatFile(string $formatFile, string $string, string $message = '')
+    {
+        Assert::assertStringMatchesFormatFile(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertStringNotMatchesFormatFile')) {
+    /**
+     * Asserts that a string does not match a given format string.
+     *
+     * @see Assert::assertStringNotMatchesFormatFile
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     */
+    function assertStringNotMatchesFormatFile(string $formatFile, string $string, string $message = '')
+    {
+        Assert::assertStringNotMatchesFormatFile(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertStringStartsWith')) {
+    /**
+     * Asserts that a string starts with a given prefix.
+     *
+     * @see Assert::assertStringStartsWith
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     */
+    function assertStringStartsWith(string $prefix, string $string, string $message = '')
+    {
+        Assert::assertStringStartsWith(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertStringStartsNotWith')) {
+    /**
+     * Asserts that a string starts not with a given prefix.
+     *
+     * @see Assert::assertStringStartsNotWith
+     *
+     * @param string $prefix
+     * @param string $string
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     */
+    function assertStringStartsNotWith($prefix, $string, string $message = '')
+    {
+        Assert::assertStringStartsNotWith(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertStringContainsString')) {
+    /**
+     * @see Assert::assertStringContainsString
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     */
+    function assertStringContainsString(string $needle, string $haystack, string $message = '')
+    {
+        Assert::assertStringContainsString(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertStringContainsStringIgnoringCase')) {
+    /**
+     * @see Assert::assertStringContainsStringIgnoringCase
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     */
+    function assertStringContainsStringIgnoringCase(string $needle, string $haystack, string $message = '')
+    {
+        Assert::assertStringContainsStringIgnoringCase(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertStringNotContainsString')) {
+    /**
+     * @see Assert::assertStringNotContainsString
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     */
+    function assertStringNotContainsString(string $needle, string $haystack, string $message = '')
+    {
+        Assert::assertStringNotContainsString(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertStringNotContainsStringIgnoringCase')) {
+    /**
+     * @see Assert::assertStringNotContainsStringIgnoringCase
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     */
+    function assertStringNotContainsStringIgnoringCase(string $needle, string $haystack, string $message = '')
+    {
+        Assert::assertStringNotContainsStringIgnoringCase(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertStringEndsWith')) {
+    /**
+     * Asserts that a string ends with a given suffix.
+     *
+     * @see Assert::assertStringEndsWith
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     */
+    function assertStringEndsWith(string $suffix, string $string, string $message = '')
+    {
+        Assert::assertStringEndsWith(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertStringEndsNotWith')) {
+    /**
+     * Asserts that a string ends not with a given suffix.
+     *
+     * @see Assert::assertStringEndsNotWith
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     */
+    function assertStringEndsNotWith(string $suffix, string $string, string $message = '')
+    {
+        Assert::assertStringEndsNotWith(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertXmlFileEqualsXmlFile')) {
+    /**
+     * Asserts that two XML files are equal.
+     *
+     * @see Assert::assertXmlFileEqualsXmlFile
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     * @throws Exception
+     */
+    function assertXmlFileEqualsXmlFile(string $expectedFile, string $actualFile, string $message = '')
+    {
+        Assert::assertXmlFileEqualsXmlFile(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertXmlFileNotEqualsXmlFile')) {
+    /**
+     * Asserts that two XML files are not equal.
+     *
+     * @see Assert::assertXmlFileNotEqualsXmlFile
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     * @throws Exception
+     */
+    function assertXmlFileNotEqualsXmlFile(string $expectedFile, string $actualFile, string $message = '')
+    {
+        Assert::assertXmlFileNotEqualsXmlFile(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertXmlStringEqualsXmlFile')) {
+    /**
+     * Asserts that two XML documents are equal.
+     *
+     * @see Assert::assertXmlStringEqualsXmlFile
+     *
+     * @param DOMDocument|string $actualXml
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     * @throws XmlException
+     */
+    function assertXmlStringEqualsXmlFile(string $expectedFile, $actualXml, string $message = '')
+    {
+        Assert::assertXmlStringEqualsXmlFile(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertXmlStringNotEqualsXmlFile')) {
+    /**
+     * Asserts that two XML documents are not equal.
+     *
+     * @see Assert::assertXmlStringNotEqualsXmlFile
+     *
+     * @param DOMDocument|string $actualXml
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     * @throws XmlException
+     */
+    function assertXmlStringNotEqualsXmlFile(string $expectedFile, $actualXml, string $message = '')
+    {
+        Assert::assertXmlStringNotEqualsXmlFile(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertXmlStringEqualsXmlString')) {
+    /**
+     * Asserts that two XML documents are equal.
+     *
+     * @see Assert::assertXmlStringEqualsXmlString
+     *
+     * @param DOMDocument|string $expectedXml
+     * @param DOMDocument|string $actualXml
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     * @throws XmlException
+     */
+    function assertXmlStringEqualsXmlString($expectedXml, $actualXml, string $message = '')
+    {
+        Assert::assertXmlStringEqualsXmlString(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertXmlStringNotEqualsXmlString')) {
+    /**
+     * Asserts that two XML documents are not equal.
+     *
+     * @see Assert::assertXmlStringNotEqualsXmlString
+     *
+     * @param DOMDocument|string $expectedXml
+     * @param DOMDocument|string $actualXml
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     * @throws XmlException
+     */
+    function assertXmlStringNotEqualsXmlString($expectedXml, $actualXml, string $message = '')
+    {
+        Assert::assertXmlStringNotEqualsXmlString(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertEqualXMLStructure')) {
+    /**
+     * Asserts that a hierarchy of DOMElements matches.
+     *
+     * @throws AssertionFailedError
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     *
+     * @codeCoverageIgnore
+     *
+     * @deprecated https://github.com/sebastianbergmann/phpunit/issues/4091
+     * @see Assert::assertEqualXMLStructure
+     */
+    function assertEqualXMLStructure(DOMElement $expectedElement, DOMElement $actualElement, bool $checkAttributes = false, string $message = '')
+    {
+        Assert::assertEqualXMLStructure(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertThat')) {
+    /**
+     * Evaluates a PHPUnit\Framework\Constraint matcher object.
+     *
+     * @see Assert::assertThat
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     */
+    function assertThat($value, Constraint $constraint, string $message = '')
+    {
+        Assert::assertThat(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertJson')) {
+    /**
+     * Asserts that a string is a valid JSON string.
+     *
+     * @see Assert::assertJson
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     */
+    function assertJson(string $actualJson, string $message = '')
+    {
+        Assert::assertJson(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertJsonStringEqualsJsonString')) {
+    /**
+     * Asserts that two given JSON encoded objects or arrays are equal.
+     *
+     * @see Assert::assertJsonStringEqualsJsonString
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     */
+    function assertJsonStringEqualsJsonString(string $expectedJson, string $actualJson, string $message = '')
+    {
+        Assert::assertJsonStringEqualsJsonString(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertJsonStringNotEqualsJsonString')) {
+    /**
+     * Asserts that two given JSON encoded objects or arrays are not equal.
+     *
+     * @see Assert::assertJsonStringNotEqualsJsonString
+     *
+     * @param string $expectedJson
+     * @param string $actualJson
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     */
+    function assertJsonStringNotEqualsJsonString($expectedJson, $actualJson, string $message = '')
+    {
+        Assert::assertJsonStringNotEqualsJsonString(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertJsonStringEqualsJsonFile')) {
+    /**
+     * Asserts that the generated JSON encoded object and the content of the given file are equal.
+     *
+     * @see Assert::assertJsonStringEqualsJsonFile
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     */
+    function assertJsonStringEqualsJsonFile(string $expectedFile, string $actualJson, string $message = '')
+    {
+        Assert::assertJsonStringEqualsJsonFile(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertJsonStringNotEqualsJsonFile')) {
+    /**
+     * Asserts that the generated JSON encoded object and the content of the given file are not equal.
+     *
+     * @see Assert::assertJsonStringNotEqualsJsonFile
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     */
+    function assertJsonStringNotEqualsJsonFile(string $expectedFile, string $actualJson, string $message = '')
+    {
+        Assert::assertJsonStringNotEqualsJsonFile(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertJsonFileEqualsJsonFile')) {
+    /**
+     * Asserts that two JSON files are equal.
+     *
+     * @see Assert::assertJsonFileEqualsJsonFile
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     */
+    function assertJsonFileEqualsJsonFile(string $expectedFile, string $actualFile, string $message = '')
+    {
+        Assert::assertJsonFileEqualsJsonFile(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\assertJsonFileNotEqualsJsonFile')) {
+    /**
+     * Asserts that two JSON files are not equal.
+     *
+     * @see Assert::assertJsonFileNotEqualsJsonFile
+     *
+     * @throws ExpectationFailedException
+     * @throws InvalidArgumentException
+     */
+    function assertJsonFileNotEqualsJsonFile(string $expectedFile, string $actualFile, string $message = '')
+    {
+        Assert::assertJsonFileNotEqualsJsonFile(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\logicalAnd')) {
+    function logicalAnd() : LogicalAnd
+    {
+        return Assert::logicalAnd(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\logicalOr')) {
+    function logicalOr() : LogicalOr
+    {
+        return Assert::logicalOr(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\logicalNot')) {
+    function logicalNot(Constraint $constraint) : LogicalNot
+    {
+        return Assert::logicalNot(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\logicalXor')) {
+    function logicalXor() : LogicalXor
+    {
+        return Assert::logicalXor(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\anything')) {
+    function anything() : IsAnything
+    {
+        return Assert::anything(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\isTrue')) {
+    function isTrue() : IsTrue
+    {
+        return Assert::isTrue(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\callback')) {
+    function callback(callable $callback) : Callback
+    {
+        return Assert::callback(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\isFalse')) {
+    function isFalse() : IsFalse
+    {
+        return Assert::isFalse(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\isJson')) {
+    function isJson() : IsJson
+    {
+        return Assert::isJson(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\isNull')) {
+    function isNull() : IsNull
+    {
+        return Assert::isNull(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\isFinite')) {
+    function isFinite() : IsFinite
+    {
+        return Assert::isFinite(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\isInfinite')) {
+    function isInfinite() : IsInfinite
+    {
+        return Assert::isInfinite(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\isNan')) {
+    function isNan() : IsNan
+    {
+        return Assert::isNan(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\containsEqual')) {
+    function containsEqual($value) : TraversableContainsEqual
+    {
+        return Assert::containsEqual(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\containsIdentical')) {
+    function containsIdentical($value) : TraversableContainsIdentical
+    {
+        return Assert::containsIdentical(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\containsOnly')) {
+    function containsOnly(string $type) : TraversableContainsOnly
+    {
+        return Assert::containsOnly(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\containsOnlyInstancesOf')) {
+    function containsOnlyInstancesOf(string $className) : TraversableContainsOnly
+    {
+        return Assert::containsOnlyInstancesOf(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\arrayHasKey')) {
+    function arrayHasKey($key) : ArrayHasKey
+    {
+        return Assert::arrayHasKey(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\equalTo')) {
+    function equalTo($value) : IsEqual
+    {
+        return Assert::equalTo(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\equalToCanonicalizing')) {
+    function equalToCanonicalizing($value) : IsEqualCanonicalizing
+    {
+        return Assert::equalToCanonicalizing(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\equalToIgnoringCase')) {
+    function equalToIgnoringCase($value) : IsEqualIgnoringCase
+    {
+        return Assert::equalToIgnoringCase(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\equalToWithDelta')) {
+    function equalToWithDelta($value, float $delta) : IsEqualWithDelta
+    {
+        return Assert::equalToWithDelta(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\isEmpty')) {
+    function isEmpty() : IsEmpty
+    {
+        return Assert::isEmpty(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\isWritable')) {
+    function isWritable() : IsWritable
+    {
+        return Assert::isWritable(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\isReadable')) {
+    function isReadable() : IsReadable
+    {
+        return Assert::isReadable(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\directoryExists')) {
+    function directoryExists() : DirectoryExists
+    {
+        return Assert::directoryExists(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\fileExists')) {
+    function fileExists() : FileExists
+    {
+        return Assert::fileExists(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\greaterThan')) {
+    function greaterThan($value) : GreaterThan
+    {
+        return Assert::greaterThan(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\greaterThanOrEqual')) {
+    function greaterThanOrEqual($value) : LogicalOr
+    {
+        return Assert::greaterThanOrEqual(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\classHasAttribute')) {
+    function classHasAttribute(string $attributeName) : ClassHasAttribute
+    {
+        return Assert::classHasAttribute(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\classHasStaticAttribute')) {
+    function classHasStaticAttribute(string $attributeName) : ClassHasStaticAttribute
+    {
+        return Assert::classHasStaticAttribute(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\objectHasAttribute')) {
+    function objectHasAttribute($attributeName) : ObjectHasAttribute
+    {
+        return Assert::objectHasAttribute(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\identicalTo')) {
+    function identicalTo($value) : IsIdentical
+    {
+        return Assert::identicalTo(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\isInstanceOf')) {
+    function isInstanceOf(string $className) : IsInstanceOf
+    {
+        return Assert::isInstanceOf(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\isType')) {
+    function isType(string $type) : IsType
+    {
+        return Assert::isType(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\lessThan')) {
+    function lessThan($value) : LessThan
+    {
+        return Assert::lessThan(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\lessThanOrEqual')) {
+    function lessThanOrEqual($value) : LogicalOr
+    {
+        return Assert::lessThanOrEqual(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\matchesRegularExpression')) {
+    function matchesRegularExpression(string $pattern) : RegularExpression
+    {
+        return Assert::matchesRegularExpression(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\matches')) {
+    function matches(string $string) : StringMatchesFormatDescription
+    {
+        return Assert::matches(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\stringStartsWith')) {
+    function stringStartsWith($prefix) : StringStartsWith
+    {
+        return Assert::stringStartsWith(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\stringContains')) {
+    function stringContains(string $string, bool $case = true) : StringContains
+    {
+        return Assert::stringContains(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\stringEndsWith')) {
+    function stringEndsWith(string $suffix) : StringEndsWith
+    {
+        return Assert::stringEndsWith(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\countOf')) {
+    function countOf(int $count) : Count
+    {
+        return Assert::countOf(...func_get_args());
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\any')) {
+    /**
+     * Returns a matcher that matches when the method is executed
+     * zero or more times.
+     */
+    function any() : AnyInvokedCountMatcher
+    {
+        return new AnyInvokedCountMatcher();
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\never')) {
+    /**
+     * Returns a matcher that matches when the method is never executed.
+     */
+    function never() : InvokedCountMatcher
+    {
+        return new InvokedCountMatcher(0);
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\atLeast')) {
+    /**
+     * Returns a matcher that matches when the method is executed
+     * at least N times.
+     */
+    function atLeast(int $requiredInvocations) : InvokedAtLeastCountMatcher
+    {
+        return new InvokedAtLeastCountMatcher(
+            $requiredInvocations
+        );
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\atLeastOnce')) {
+    /**
+     * Returns a matcher that matches when the method is executed at least once.
+     */
+    function atLeastOnce() : InvokedAtLeastOnceMatcher
+    {
+        return new InvokedAtLeastOnceMatcher();
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\once')) {
+    /**
+     * Returns a matcher that matches when the method is executed exactly once.
+     */
+    function once() : InvokedCountMatcher
+    {
+        return new InvokedCountMatcher(1);
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\exactly')) {
+    /**
+     * Returns a matcher that matches when the method is executed
+     * exactly $count times.
+     */
+    function exactly(int $count) : InvokedCountMatcher
+    {
+        return new InvokedCountMatcher($count);
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\atMost')) {
+    /**
+     * Returns a matcher that matches when the method is executed
+     * at most N times.
+     */
+    function atMost(int $allowedInvocations) : InvokedAtMostCountMatcher
+    {
+        return new InvokedAtMostCountMatcher($allowedInvocations);
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\at')) {
+    /**
+     * Returns a matcher that matches when the method is executed
+     * at the given index.
+     */
+    function at(int $index) : InvokedAtIndexMatcher
+    {
+        return new InvokedAtIndexMatcher($index);
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\returnValue')) {
+    function returnValue($value) : ReturnStub
+    {
+        return new ReturnStub($value);
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\returnValueMap')) {
+    function returnValueMap(array $valueMap) : ReturnValueMapStub
+    {
+        return new ReturnValueMapStub($valueMap);
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\returnArgument')) {
+    function returnArgument(int $argumentIndex) : ReturnArgumentStub
+    {
+        return new ReturnArgumentStub($argumentIndex);
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\returnCallback')) {
+    function returnCallback($callback) : ReturnCallbackStub
+    {
+        return new ReturnCallbackStub($callback);
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\returnSelf')) {
+    /**
+     * Returns the current object.
+     *
+     * This method is useful when mocking a fluent interface.
+     */
+    function returnSelf() : ReturnSelfStub
+    {
+        return new ReturnSelfStub();
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\throwException')) {
+    function throwException(Throwable $exception) : ExceptionStub
+    {
+        return new ExceptionStub($exception);
+    }
+}
+
+if (! function_exists('PHPUnit\Framework\onConsecutiveCalls')) {
+    function onConsecutiveCalls() : ConsecutiveCallsStub
+    {
+        $args = func_get_args();
+
+        return new ConsecutiveCallsStub($args);
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/PedantryTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/PedantryTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..e9b3f3feda2847730be27fd41f73b771a9ccab1e
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/PedantryTest.php	
@@ -0,0 +1,92 @@
+<?php
+
+namespace MongoDB\Tests;
+
+use RecursiveDirectoryIterator;
+use RecursiveIteratorIterator;
+use ReflectionClass;
+use ReflectionMethod;
+use RegexIterator;
+use function array_filter;
+use function array_map;
+use function realpath;
+use function str_replace;
+use function strcasecmp;
+use function strlen;
+use function substr;
+use function usort;
+use const DIRECTORY_SEPARATOR;
+
+/**
+ * Pedantic tests that have nothing to do with functional correctness.
+ */
+class PedantryTest extends TestCase
+{
+    /**
+     * @dataProvider provideProjectClassNames
+     */
+    public function testMethodsAreOrderedAlphabeticallyByVisibility($className)
+    {
+        $class = new ReflectionClass($className);
+        $methods = $class->getMethods();
+
+        $methods = array_filter(
+            $methods,
+            function (ReflectionMethod $method) use ($class) {
+                return $method->getDeclaringClass() == $class;
+            }
+        );
+
+        $getSortValue = function (ReflectionMethod $method) {
+            if ($method->getModifiers() & ReflectionMethod::IS_PRIVATE) {
+                return '2' . $method->getName();
+            }
+            if ($method->getModifiers() & ReflectionMethod::IS_PROTECTED) {
+                return '1' . $method->getName();
+            }
+            if ($method->getModifiers() & ReflectionMethod::IS_PUBLIC) {
+                return '0' . $method->getName();
+            }
+        };
+
+        $sortedMethods = $methods;
+        usort(
+            $sortedMethods,
+            function (ReflectionMethod $a, ReflectionMethod $b) use ($getSortValue) {
+                return strcasecmp($getSortValue($a), $getSortValue($b));
+            }
+        );
+
+        $methods = array_map(function (ReflectionMethod $method) {
+            return $method->getName();
+        }, $methods);
+        $sortedMethods = array_map(function (ReflectionMethod $method) {
+            return $method->getName();
+        }, $sortedMethods);
+
+        $this->assertEquals($sortedMethods, $methods);
+    }
+
+    public function provideProjectClassNames()
+    {
+        $classNames = [];
+        $srcDir = realpath(__DIR__ . '/../src/');
+
+        $files = new RegexIterator(new RecursiveIteratorIterator(new RecursiveDirectoryIterator($srcDir)), '/\.php$/i');
+
+        foreach ($files as $file) {
+            if ($file->getFilename() === 'functions.php') {
+                continue;
+            }
+
+            /* autoload.php added downstream (e.g. Fedora) */
+            if ($file->getFilename() === 'autoload.php') {
+                continue;
+            }
+
+            $classNames[][] = 'MongoDB\\' . str_replace(DIRECTORY_SEPARATOR, '\\', substr($file->getRealPath(), strlen($srcDir) + 1, -4));
+        }
+
+        return $classNames;
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/AtlasDataLakeSpecTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/AtlasDataLakeSpecTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..1e4fda722160cb27350cc9ae312f58e1a086747b
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/AtlasDataLakeSpecTest.php	
@@ -0,0 +1,250 @@
+<?php
+
+namespace MongoDB\Tests\SpecTests;
+
+use MongoDB\Client;
+use MongoDB\Driver\Command;
+use MongoDB\Driver\Cursor;
+use MongoDB\Tests\CommandObserver;
+use stdClass;
+use Symfony\Bridge\PhpUnit\SetUpTearDownTrait;
+use function basename;
+use function current;
+use function explode;
+use function file_get_contents;
+use function glob;
+use function parse_url;
+
+/**
+ * Atlas Data Lake spec tests.
+ *
+ * @see https://github.com/mongodb/specifications/tree/master/source/atlas-data-lake-testing/tests
+ */
+class AtlasDataLakeSpecTest extends FunctionalTestCase
+{
+    use SetUpTearDownTrait;
+
+    private function doSetUp()
+    {
+        parent::setUp();
+
+        if (! $this->isAtlasDataLake()) {
+            $this->markTestSkipped('Server is not Atlas Data Lake');
+        }
+    }
+
+    /**
+     * Assert that the expected and actual command documents match.
+     *
+     * @param stdClass $expected Expected command document
+     * @param stdClass $actual   Actual command document
+     */
+    public static function assertCommandMatches(stdClass $expected, stdClass $actual)
+    {
+        foreach ($expected as $key => $value) {
+            if ($value === null) {
+                static::assertObjectNotHasAttribute($key, $actual);
+                unset($expected->{$key});
+            }
+        }
+
+        static::assertDocumentsMatch($expected, $actual);
+    }
+
+    /**
+     * Execute an individual test case from the specification.
+     *
+     * @dataProvider provideTests
+     * @param stdClass $test           Individual "tests[]" document
+     * @param array    $runOn          Top-level "runOn" array with server requirements
+     * @param array    $data           Top-level "data" array to initialize collection
+     * @param string   $databaseName   Name of database under test
+     * @param string   $collectionName Name of collection under test
+     */
+    public function testAtlasDataLake(stdClass $test, array $runOn = null, array $data, $databaseName = null, $collectionName = null)
+    {
+        if (isset($runOn)) {
+            $this->checkServerRequirements($runOn);
+        }
+
+        if (isset($test->skipReason)) {
+            $this->markTestSkipped($test->skipReason);
+        }
+
+        $databaseName = $databaseName ?? $this->getDatabaseName();
+        $collectionName = $collectionName ?? $this->getCollectionName();
+
+        $context = Context::fromCrud($test, $databaseName, $collectionName);
+        $this->setContext($context);
+
+        /* Note: Atlas Data Lake is read-only, so do not attempt to drop the
+         * collection under test or insert data fixtures. Necesarry data
+         * fixtures are already specified in the mongohoused configuration. */
+
+        if (isset($test->failPoint)) {
+            throw new LogicException('ADL tests are not expected to configure fail points');
+        }
+
+        if (isset($test->expectations)) {
+            $commandExpectations = CommandExpectations::fromCrud((array) $test->expectations);
+            $commandExpectations->startMonitoring();
+        }
+
+        foreach ($test->operations as $operation) {
+            Operation::fromCrud($operation)->assert($this, $context);
+        }
+
+        if (isset($commandExpectations)) {
+            $commandExpectations->stopMonitoring();
+            $commandExpectations->assert($this, $context);
+        }
+
+        if (isset($test->outcome->collection->data)) {
+            throw new LogicException('ADL tests are not expected to assert collection data');
+        }
+    }
+
+    public function provideTests()
+    {
+        $testArgs = [];
+
+        foreach (glob(__DIR__ . '/atlas_data_lake/*.json') as $filename) {
+            $json = $this->decodeJson(file_get_contents($filename));
+            $group = basename($filename, '.json');
+            $runOn = $json->runOn ?? null;
+            $data = $json->data ?? [];
+            $databaseName = $json->database_name ?? null;
+            $collectionName = $json->collection_name ?? null;
+
+            foreach ($json->tests as $test) {
+                $name = $group . ': ' . $test->description;
+                $testArgs[$name] = [$test, $runOn, $data, $databaseName, $collectionName];
+            }
+        }
+
+        return $testArgs;
+    }
+
+    /**
+     * Prose test 1: Connect without authentication
+     */
+    public function testKillCursors()
+    {
+        $cursorId = null;
+        $cursorNamespace = null;
+
+        (new CommandObserver())->observe(
+            function () {
+                $client = new Client(static::getUri());
+                $client->test->driverdata->find([], ['batchSize' => 2, 'limit' => 3]);
+            },
+            function (array $event) use (&$cursorId, &$cursorNamespace) {
+                if ($event['started']->getCommandName() === 'find') {
+                    $this->assertArrayHasKey('succeeded', $event);
+
+                    $reply = $event['succeeded']->getReply();
+                    $this->assertObjectHasAttribute('cursor', $reply);
+                    $this->assertIsObject($reply->cursor);
+                    $this->assertObjectHasAttribute('id', $reply->cursor);
+                    $this->assertIsInt($reply->cursor->id);
+                    $this->assertObjectHasAttribute('ns', $reply->cursor);
+                    $this->assertIsString($reply->cursor->ns);
+
+                    /* Note: MongoDB\Driver\CursorId is not used here; however,
+                     * we shouldn't have to worry about encoutnering a 64-bit
+                     * cursor IDs on a 32-bit platform mongohoused allocates IDs
+                     * sequentially (starting from 1). */
+                    $cursorId = $reply->cursor->id;
+                    $cursorNamespace = $reply->cursor->ns;
+
+                    return;
+                }
+
+                /* After the initial find command, expect that killCursors is
+                 * next and that a cursor ID and namespace were collected. */
+                $this->assertSame('killCursors', $event['started']->getCommandName());
+                $this->assertIsInt($cursorId);
+                $this->assertIsString($cursorNamespace);
+
+                list($databaseName, $collectionName) = explode('.', $cursorNamespace, 2);
+                $command = $event['started']->getCommand();
+
+                /* Assert that the killCursors command uses the namespace and
+                 * cursor ID from the find command reply. */
+                $this->assertSame($databaseName, $event['started']->getDatabaseName());
+                $this->assertSame($databaseName, $command->{'$db'});
+                $this->assertObjectHasAttribute('killCursors', $command);
+                $this->assertSame($collectionName, $command->killCursors);
+                $this->assertObjectHasAttribute('cursors', $command);
+                $this->assertIsArray($command->cursors);
+                $this->assertArrayHasKey(0, $command->cursors);
+                $this->assertSame($cursorId, $command->cursors[0]);
+
+                /* Assert that the killCursors command reply indicates that the
+                 * expected cursor ID was killed. */
+                $reply = $event['succeeded']->getReply();
+                $this->assertObjectHasAttribute('cursorsKilled', $reply);
+                $this->assertIsArray($reply->cursorsKilled);
+                $this->assertArrayHasKey(0, $reply->cursorsKilled);
+                $this->assertSame($cursorId, $reply->cursorsKilled[0]);
+            }
+        );
+    }
+
+    /**
+     * Prose test 2: Connect without authentication
+     */
+    public function testConnectWithoutAuth()
+    {
+        /* Parse URI to remove userinfo component. The query string is left
+         * as-is and must not include authMechanism or credentials. */
+        $parts = parse_url(static::getUri());
+        $port = isset($parts['port']) ? ':' . $parts['port'] : '';
+        $path = $parts['path'] ?? '/';
+        $query = isset($parts['query']) ? '?' . $parts['query'] : '';
+
+        $uri = $parts['scheme'] . '://' . $parts['host'] . $port . $path . $query;
+
+        $client = new Client($uri);
+        $cursor = $client->selectDatabase($this->getDatabaseName())->command(['ping' => 1]);
+
+        $this->assertInstanceOf(Cursor::class, $cursor);
+        $this->assertCommandSucceeded(current($cursor->toArray()));
+    }
+
+    /**
+     * Prose test 3: Connect with SCRAM-SHA-1 authentication
+     */
+    public function testConnectwithSCRAMSHA1()
+    {
+        $client = new Client(static::getUri(), ['authMechanism' => 'SCRAM-SHA-1']);
+        $cursor = $client->selectDatabase($this->getDatabaseName())->command(['ping' => 1]);
+
+        $this->assertInstanceOf(Cursor::class, $cursor);
+        $this->assertCommandSucceeded(current($cursor->toArray()));
+    }
+
+    /**
+     * Prose test 4: Connect with SCRAM-SHA-256 authentication
+     */
+    public function testConnectwithSCRAMSHA256()
+    {
+        $client = new Client(static::getUri(), ['authMechanism' => 'SCRAM-SHA-256']);
+        $cursor = $client->selectDatabase($this->getDatabaseName())->command(['ping' => 1]);
+
+        $this->assertInstanceOf(Cursor::class, $cursor);
+        $this->assertCommandSucceeded(current($cursor->toArray()));
+    }
+
+    private function isAtlasDataLake() : bool
+    {
+        $cursor = $this->manager->executeCommand(
+            $this->getDatabaseName(),
+            new Command(['buildInfo' => 1])
+        );
+
+        $document = current($cursor->toArray());
+
+        return ! empty($document->dataLake);
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/ChangeStreamsSpecTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/ChangeStreamsSpecTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..5dcb391327efb66da392234e3167b35611ae11b1
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/ChangeStreamsSpecTest.php	
@@ -0,0 +1,295 @@
+<?php
+
+namespace MongoDB\Tests\SpecTests;
+
+use ArrayIterator;
+use LogicException;
+use MongoDB\BSON\Int64;
+use MongoDB\ChangeStream;
+use MongoDB\Driver\Exception\Exception;
+use MongoDB\Model\BSONDocument;
+use MultipleIterator;
+use stdClass;
+use function basename;
+use function count;
+use function file_get_contents;
+use function glob;
+
+/**
+ * Change Streams spec tests.
+ *
+ * @see https://github.com/mongodb/specifications/tree/master/source/change-streams
+ */
+class ChangeStreamsSpecTest extends FunctionalTestCase
+{
+    /** @var array */
+    private static $incompleteTests = [];
+
+    /**
+     * Assert that the expected and actual command documents match.
+     *
+     * Note: this method may modify the $expected object.
+     *
+     * @param stdClass $expected Expected command document
+     * @param stdClass $actual   Actual command document
+     */
+    public static function assertCommandMatches(stdClass $expected, stdClass $actual)
+    {
+        if (isset($expected->getMore) && $expected->getMore === 42) {
+            static::assertObjectHasAttribute('getMore', $actual);
+            static::assertThat($actual->getMore, static::logicalOr(
+                static::isInstanceOf(Int64::class),
+                static::isType('integer')
+            ));
+            unset($expected->getMore);
+        }
+
+        static::assertDocumentsMatch($expected, $actual);
+    }
+
+    /**
+     * Assert that the expected and actual documents match.
+     *
+     * @param array $expectedDocuments Expected documents
+     * @param array $actualDocuments   Actual documents
+     */
+    public static function assertResult(array $expectedDocuments, array $actualDocuments)
+    {
+        static::assertCount(count($expectedDocuments), $actualDocuments);
+
+        $mi = new MultipleIterator(MultipleIterator::MIT_NEED_ANY);
+        $mi->attachIterator(new ArrayIterator($expectedDocuments));
+        $mi->attachIterator(new ArrayIterator($actualDocuments));
+
+        foreach ($mi as $documents) {
+            list($expectedDocument, $actualDocument) = $documents;
+
+            $constraint = new DocumentsMatchConstraint($expectedDocument, true, true, ['42']);
+
+            static::assertThat($actualDocument, $constraint);
+        }
+    }
+
+    /**
+     * Execute an individual test case from the specification.
+     *
+     * @dataProvider provideTests
+     * @param stdClass $test            Individual "tests[]" document
+     * @param string   $databaseName    Name of database under test
+     * @param string   $collectionName  Name of collection under test
+     * @param string   $database2Name   Name of alternate database under test
+     * @param string   $collection2Name Name of alternate collection under test
+     */
+    public function testChangeStreams(stdClass $test, $databaseName = null, $collectionName = null, $database2Name = null, $collection2Name = null)
+    {
+        if (isset(self::$incompleteTests[$this->dataDescription()])) {
+            $this->markTestIncomplete(self::$incompleteTests[$this->dataDescription()]);
+        }
+
+        if ($this->isShardedCluster() && ! $this->isShardedClusterUsingReplicasets()) {
+            $this->markTestSkipped('$changeStream is only supported with replicasets');
+        }
+
+        $this->checkServerRequirements($this->createRunOn($test));
+
+        if (! isset($databaseName, $collectionName)) {
+            $this->fail('Required database and collection names are unset');
+        }
+
+        $context = Context::fromChangeStreams($test, $databaseName, $collectionName);
+        $this->setContext($context);
+
+        $this->dropDatabasesAndCreateCollection($databaseName, $collectionName);
+
+        if (isset($database2Name, $collection2Name)) {
+            $this->dropDatabasesAndCreateCollection($database2Name, $collection2Name);
+        }
+
+        if (isset($test->failPoint)) {
+            $this->configureFailPoint($test->failPoint);
+        }
+
+        if (isset($test->expectations)) {
+            $commandExpectations = CommandExpectations::fromChangeStreams($test->expectations);
+            $commandExpectations->startMonitoring();
+        }
+
+        $errorExpectation = ErrorExpectation::fromChangeStreams($test->result);
+        $resultExpectation = ResultExpectation::fromChangeStreams($test->result, [$this, 'assertResult']);
+
+        $result = null;
+        $exception = null;
+
+        try {
+            $changeStream = $this->createChangeStream($test);
+        } catch (Exception $e) {
+            $exception = $e;
+        }
+
+        if (isset($commandExpectations)) {
+            $commandExpectations->stopMonitoring();
+        }
+
+        foreach ($test->operations as $operation) {
+            Operation::fromChangeStreams($operation)->assert($this, $context);
+        }
+
+        if (isset($commandExpectations)) {
+            $commandExpectations->startMonitoring();
+        }
+
+        /* If the change stream was successfully created (i.e. $exception is
+         * null), attempt to iterate up to the expected number of results. It's
+         * possible that some errors (e.g. projecting out _id) will only be
+         * thrown during iteration, so we must also try/catch here. */
+        try {
+            if (isset($changeStream)) {
+                $limit = isset($test->result->success) ? count($test->result->success) : 0;
+                $result = $this->iterateChangeStream($changeStream, $limit);
+            }
+        } catch (Exception $e) {
+            $this->assertNull($exception);
+            $exception = $e;
+        }
+
+        $errorExpectation->assert($this, $exception);
+        $resultExpectation->assert($this, $result);
+
+        if (isset($commandExpectations)) {
+            $commandExpectations->stopMonitoring();
+            $commandExpectations->assert($this, $context);
+        }
+    }
+
+    public function provideTests()
+    {
+        $testArgs = [];
+
+        foreach (glob(__DIR__ . '/change-streams/*.json') as $filename) {
+            $json = $this->decodeJson(file_get_contents($filename));
+            $group = basename($filename, '.json');
+            $databaseName = $json->database_name ?? null;
+            $database2Name = $json->database2_name ?? null;
+            $collectionName = $json->collection_name ?? null;
+            $collection2Name = $json->collection2_name ?? null;
+
+            foreach ($json->tests as $test) {
+                $name = $group . ': ' . $test->description;
+                $testArgs[$name] = [$test, $databaseName, $collectionName, $database2Name, $collection2Name];
+            }
+        }
+
+        return $testArgs;
+    }
+
+    /**
+     * Create a change stream.
+     *
+     * @param stdClass $test
+     * @return ChangeStream
+     * @throws LogicException if the target is unsupported
+     */
+    private function createChangeStream(stdClass $test)
+    {
+        $context = $this->getContext();
+        $pipeline = $test->changeStreamPipeline ?? [];
+        $options = isset($test->changeStreamOptions) ? (array) $test->changeStreamOptions : [];
+
+        switch ($test->target) {
+            case 'client':
+                return $context->getClient()->watch($pipeline, $options);
+            case 'database':
+                return $context->getDatabase()->watch($pipeline, $options);
+            case 'collection':
+                return $context->getCollection()->watch($pipeline, $options);
+            default:
+                throw new LogicException('Unsupported target: ' . $test->target);
+        }
+    }
+
+    /**
+     * Convert the server requirements to a standard "runOn" array used by other
+     * specifications.
+     *
+     * @param stdClass $test
+     * @return array
+     */
+    private function createRunOn(stdClass $test)
+    {
+        $req = new stdClass();
+
+        /* Append ".99" as patch version, since command monitoring tests expect
+         * the minor version to be an inclusive upper bound. */
+        if (isset($test->maxServerVersion)) {
+            $req->maxServerVersion = $test->maxServerVersion;
+        }
+
+        if (isset($test->minServerVersion)) {
+            $req->minServerVersion = $test->minServerVersion;
+        }
+
+        if (isset($test->topology)) {
+            $req->topology = $test->topology;
+        }
+
+        return [$req];
+    }
+
+    /**
+     * Drop the database and create the collection.
+     *
+     * @param string $databaseName
+     * @param string $collectionName
+     */
+    private function dropDatabasesAndCreateCollection($databaseName, $collectionName)
+    {
+        $context = $this->getContext();
+
+        $database = $context->getClient()->selectDatabase($databaseName);
+        $database->drop($context->defaultWriteOptions);
+        $database->createCollection($collectionName, $context->defaultWriteOptions);
+    }
+
+    /**
+     * Iterate a change stream.
+     *
+     * @param ChangeStream $changeStream
+     * @param integer      $limit
+     * @return BSONDocument[]
+     */
+    private function iterateChangeStream(ChangeStream $changeStream, $limit = 0)
+    {
+        if ($limit < 0) {
+            throw new LogicException('$limit is negative');
+        }
+
+        /* Limit iterations to guard against an infinite loop should a test fail
+         * to return as many results as are expected. Require at least one
+         * iteration to allow next() a chance to throw for error tests. */
+        $maxIterations = $limit + 1;
+
+        /* On sharded clusters, allow for empty getMore calls due to sharding
+         * architecture */
+        if ($this->isShardedCluster()) {
+            $maxIterations *= 5;
+        }
+
+        $events = [];
+
+        for ($i = 0, $changeStream->rewind(); $i < $maxIterations; $i++, $changeStream->next()) {
+            if (! $changeStream->valid()) {
+                continue;
+            }
+
+            $event = $changeStream->current();
+            $this->assertInstanceOf(BSONDocument::class, $event);
+            $events[] = $event;
+
+            if (count($events) >= $limit) {
+                break;
+            }
+        }
+
+        return $events;
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/ClientSideEncryptionSpecTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/ClientSideEncryptionSpecTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..f2edd7f6b16ea689440efca5102b5346f95a99da
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/ClientSideEncryptionSpecTest.php	
@@ -0,0 +1,798 @@
+<?php
+
+namespace MongoDB\Tests\SpecTests;
+
+use Closure;
+use MongoDB\BSON\Binary;
+use MongoDB\BSON\Int64;
+use MongoDB\Client;
+use MongoDB\Collection;
+use MongoDB\Driver\ClientEncryption;
+use MongoDB\Driver\Exception\AuthenticationException;
+use MongoDB\Driver\Exception\BulkWriteException;
+use MongoDB\Driver\Exception\ConnectionException;
+use MongoDB\Driver\Exception\ConnectionTimeoutException;
+use MongoDB\Driver\Exception\EncryptionException;
+use MongoDB\Driver\Exception\RuntimeException;
+use MongoDB\Driver\WriteConcern;
+use MongoDB\Operation\CreateCollection;
+use MongoDB\Tests\CommandObserver;
+use PHPUnit\Framework\SkippedTestError;
+use stdClass;
+use Symfony\Bridge\PhpUnit\SetUpTearDownTrait;
+use Throwable;
+use UnexpectedValueException;
+use function base64_decode;
+use function basename;
+use function file_get_contents;
+use function glob;
+use function iterator_to_array;
+use function json_decode;
+use function sprintf;
+use function str_repeat;
+use function strlen;
+use function unserialize;
+
+/**
+ * Client-side encryption spec tests.
+ *
+ * @see https://github.com/mongodb/specifications/tree/master/source/client-side-encryption
+ */
+class ClientSideEncryptionSpecTest extends FunctionalTestCase
+{
+    use SetUpTearDownTrait;
+
+    const LOCAL_MASTERKEY = 'Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk';
+
+    private function doSetUp()
+    {
+        parent::setUp();
+
+        $this->skipIfClientSideEncryptionIsNotSupported();
+    }
+
+    /**
+     * Assert that the expected and actual command documents match.
+     *
+     * @param stdClass $expected Expected command document
+     * @param stdClass $actual   Actual command document
+     */
+    public static function assertCommandMatches(stdClass $expected, stdClass $actual)
+    {
+        static::assertDocumentsMatch($expected, $actual);
+    }
+
+    /**
+     * Execute an individual test case from the specification.
+     *
+     * @dataProvider provideTests
+     * @param stdClass    $test           Individual "tests[]" document
+     * @param array       $runOn          Top-level "runOn" array with server requirements
+     * @param array       $data           Top-level "data" array to initialize collection
+     * @param array|null  $keyVaultData   Top-level "key_vault_data" array to initialize keyvault.datakeys collection
+     * @param object|null $jsonSchema     Top-level "json_schema" array to initialize collection
+     * @param string      $databaseName   Name of database under test
+     * @param string      $collectionName Name of collection under test
+     */
+    public function testClientSideEncryption(stdClass $test, array $runOn = null, array $data, array $keyVaultData = null, $jsonSchema = null, $databaseName = null, $collectionName = null)
+    {
+        if (isset($runOn)) {
+            $this->checkServerRequirements($runOn);
+        }
+
+        if (isset($test->skipReason)) {
+            $this->markTestSkipped($test->skipReason);
+        }
+
+        $databaseName = $databaseName ?? $this->getDatabaseName();
+        $collectionName = $collectionName ?? $this->getCollectionName();
+
+        try {
+            $context = Context::fromClientSideEncryption($test, $databaseName, $collectionName);
+        } catch (SkippedTestError $e) {
+            $this->markTestSkipped($e->getMessage());
+        }
+
+        $this->setContext($context);
+
+        $this->insertKeyVaultData($keyVaultData);
+        $this->dropTestAndOutcomeCollections();
+        $this->createTestCollection($jsonSchema);
+        $this->insertDataFixtures($data);
+
+        if (isset($test->failPoint)) {
+            $this->configureFailPoint($test->failPoint);
+        }
+
+        $context->enableEncryption();
+
+        if (isset($test->expectations)) {
+            $commandExpectations = CommandExpectations::fromClientSideEncryption($test->expectations);
+            $commandExpectations->startMonitoring();
+        }
+
+        foreach ($test->operations as $operation) {
+            Operation::fromClientSideEncryption($operation)->assert($this, $context);
+        }
+
+        if (isset($commandExpectations)) {
+            $commandExpectations->stopMonitoring();
+            $commandExpectations->assert($this, $context);
+        }
+
+        $context->disableEncryption();
+
+        if (isset($test->outcome->collection->data)) {
+            $this->assertOutcomeCollectionData($test->outcome->collection->data, ResultExpectation::ASSERT_DOCUMENTS_MATCH);
+        }
+    }
+
+    public function provideTests()
+    {
+        $testArgs = [];
+
+        foreach (glob(__DIR__ . '/client-side-encryption/tests/*.json') as $filename) {
+            $group = basename($filename, '.json');
+
+            try {
+                $json = $this->decodeJson(file_get_contents($filename));
+            } catch (Throwable $e) {
+                $testArgs[$group] = [
+                    (object) ['skipReason' => sprintf('Exception loading file "%s": %s', $filename, $e->getMessage())],
+                    null,
+                    [],
+                ];
+
+                continue;
+            }
+
+            $runOn = $json->runOn ?? null;
+            $data = $json->data ?? [];
+            $keyVaultData = $json->key_vault_data ?? null;
+            $jsonSchema = $json->json_schema ?? null;
+            $databaseName = $json->database_name ?? null;
+            $collectionName = $json->collection_name ?? null;
+
+            foreach ($json->tests as $test) {
+                $name = $group . ': ' . $test->description;
+                $testArgs[$name] = [$test, $runOn, $data, $keyVaultData, $jsonSchema, $databaseName, $collectionName];
+            }
+        }
+
+        return $testArgs;
+    }
+
+    /**
+     * Prose test: Data key and double encryption
+     *
+     * @dataProvider dataKeyProvider
+     */
+    public function testDataKeyAndDoubleEncryption(Closure $test)
+    {
+        $client = new Client(static::getUri());
+
+        $client->selectCollection('keyvault', 'datakeys')->drop();
+        $client->selectCollection('db', 'coll')->drop();
+
+        $encryptionOpts = [
+            'keyVaultNamespace' => 'keyvault.datakeys',
+            'kmsProviders' => [
+                'aws' => Context::getAWSCredentials(),
+                'local' => ['key' => new Binary(base64_decode(self::LOCAL_MASTERKEY), 0)],
+            ],
+        ];
+
+        $autoEncryptionOpts = $encryptionOpts + [
+            'schemaMap' => [
+                'db.coll' => [
+                    'bsonType' => 'object',
+                    'properties' => [
+                        'encrypted_placeholder' => [
+                            'encrypt' => [
+                                'keyId' => '/placeholder',
+                                'bsonType' => 'string',
+                                'algorithm' => ClientEncryption::AEAD_AES_256_CBC_HMAC_SHA_512_RANDOM,
+                            ],
+                        ],
+                    ],
+                ],
+            ],
+            'keyVaultClient' => $client,
+        ];
+
+        $clientEncrypted = new Client(static::getUri(), [], ['autoEncryption' => $autoEncryptionOpts]);
+        $clientEncryption = $clientEncrypted->createClientEncryption($encryptionOpts);
+
+        $test($clientEncryption, $client, $clientEncrypted, $this);
+    }
+
+    public static function dataKeyProvider()
+    {
+        return [
+            'local' => [
+                static function (ClientEncryption $clientEncryption, Client $client, Client $clientEncrypted, self $test) {
+                    $commands = [];
+
+                    $localDatakeyId = null;
+
+                    (new CommandObserver())->observe(
+                        function () use ($clientEncryption, &$localDatakeyId) {
+                            $localDatakeyId = $clientEncryption->createDataKey('local', ['keyAltNames' => ['local_altname']]);
+                        },
+                        function ($command) use (&$commands) {
+                            $commands[] = $command;
+                        }
+                    );
+
+                    $test->assertInstanceOf(Binary::class, $localDatakeyId);
+                    $test->assertSame(Binary::TYPE_UUID, $localDatakeyId->getType());
+
+                    $test->assertCount(2, $commands);
+                    $insert = $commands[1]['started'];
+                    $test->assertSame('insert', $insert->getCommandName());
+                    $test->assertSame(WriteConcern::MAJORITY, $insert->getCommand()->writeConcern->w);
+
+                    $keys = $client->selectCollection('keyvault', 'datakeys')->find(['_id' => $localDatakeyId]);
+                    $keys = iterator_to_array($keys);
+                    $test->assertCount(1, $keys);
+
+                    $key = $keys[0];
+                    $test->assertNotNull($key);
+                    $test->assertSame('local', $key['masterKey']['provider']);
+
+                    $localEncrypted = $clientEncryption->encrypt('hello local', ['algorithm' => ClientEncryption::AEAD_AES_256_CBC_HMAC_SHA_512_DETERMINISTIC, 'keyId' => $localDatakeyId]);
+                    $test->assertInstanceOf(Binary::class, $localEncrypted);
+                    $test->assertSame(Binary::TYPE_ENCRYPTED, $localEncrypted->getType());
+
+                    $clientEncrypted->selectCollection('db', 'coll')->insertOne(['_id' => 'local', 'value' => $localEncrypted]);
+                    $helloLocal = $clientEncrypted->selectCollection('db', 'coll')->findOne(['_id' => 'local']);
+                    $test->assertNotNull($helloLocal);
+                    $test->assertSame('hello local', $helloLocal['value']);
+
+                    $localEncryptedAltName = $clientEncryption->encrypt('hello local', ['algorithm' => ClientEncryption::AEAD_AES_256_CBC_HMAC_SHA_512_DETERMINISTIC, 'keyAltName' => 'local_altname']);
+                    $test->assertEquals($localEncrypted, $localEncryptedAltName);
+
+                    $test->expectException(BulkWriteException::class);
+                    $clientEncrypted->selectCollection('db', 'coll')->insertOne(['encrypted_placeholder' => $localEncrypted]);
+                },
+            ],
+            'aws' => [
+                static function (ClientEncryption $clientEncryption, Client $client, Client $clientEncrypted, self $test) {
+                    $commands = [];
+                    $awsDatakeyId = null;
+
+                    (new CommandObserver())->observe(
+                        function () use ($clientEncryption, &$awsDatakeyId) {
+                            $awsDatakeyId = $clientEncryption->createDataKey('aws', ['keyAltNames' => ['aws_altname'], 'masterKey' => ['region' => 'us-east-1', 'key' => 'arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0']]);
+                        },
+                        function ($command) use (&$commands) {
+                            $commands[] = $command;
+                        }
+                    );
+
+                    $test->assertInstanceOf(Binary::class, $awsDatakeyId);
+                    $test->assertSame(Binary::TYPE_UUID, $awsDatakeyId->getType());
+
+                    $test->assertCount(2, $commands);
+                    $insert = $commands[1]['started'];
+                    $test->assertSame('insert', $insert->getCommandName());
+                    $test->assertSame(WriteConcern::MAJORITY, $insert->getCommand()->writeConcern->w);
+
+                    $keys = $client->selectCollection('keyvault', 'datakeys')->find(['_id' => $awsDatakeyId]);
+                    $keys = iterator_to_array($keys);
+                    $test->assertCount(1, $keys);
+
+                    $key = $keys[0];
+                    $test->assertNotNull($key);
+                    $test->assertSame('aws', $key['masterKey']['provider']);
+
+                    $awsEncrypted = $clientEncryption->encrypt('hello aws', ['algorithm' => ClientEncryption::AEAD_AES_256_CBC_HMAC_SHA_512_DETERMINISTIC, 'keyId' => $awsDatakeyId]);
+                    $test->assertInstanceOf(Binary::class, $awsEncrypted);
+                    $test->assertSame(Binary::TYPE_ENCRYPTED, $awsEncrypted->getType());
+
+                    $clientEncrypted->selectCollection('db', 'coll')->insertOne(['_id' => 'aws', 'value' => $awsEncrypted]);
+                    $helloAws = $clientEncrypted->selectCollection('db', 'coll')->findOne(['_id' => 'aws']);
+                    $test->assertNotNull($helloAws);
+                    $test->assertSame('hello aws', $helloAws['value']);
+
+                    $awsEncryptedAltName = $clientEncryption->encrypt('hello aws', ['algorithm' => ClientEncryption::AEAD_AES_256_CBC_HMAC_SHA_512_DETERMINISTIC, 'keyAltName' => 'aws_altname']);
+                    $test->assertEquals($awsEncrypted, $awsEncryptedAltName);
+
+                    $test->expectException(BulkWriteException::class);
+                    $clientEncrypted->selectCollection('db', 'coll')->insertOne(['encrypted_placeholder' => $awsEncrypted]);
+                },
+            ],
+        ];
+    }
+
+    /**
+     * Prose test: External Key Vault
+     *
+     * @testWith [false]
+     *           [true]
+     */
+    public function testExternalKeyVault($withExternalKeyVault)
+    {
+        $client = new Client(static::getUri());
+
+        $client->selectCollection('keyvault', 'datakeys')->drop();
+        $client->selectCollection('db', 'coll')->drop();
+
+        $keyId = $client
+            ->selectCollection('keyvault', 'datakeys')
+            ->insertOne(
+                $this->decodeJson(file_get_contents(__DIR__ . '/client-side-encryption/external/external-key.json')),
+                ['writeConcern' => new WriteConcern(WriteConcern::MAJORITY)]
+            )
+            ->getInsertedId();
+
+        $encryptionOpts = [
+            'keyVaultNamespace' => 'keyvault.datakeys',
+            'kmsProviders' => [
+                'local' => ['key' => new Binary(base64_decode(self::LOCAL_MASTERKEY), 0)],
+            ],
+        ];
+
+        if ($withExternalKeyVault) {
+            $encryptionOpts['keyVaultClient'] = new Client(static::getUri(), ['username' => 'fake-user', 'password' => 'fake-pwd']);
+        }
+
+        $autoEncryptionOpts = $encryptionOpts + [
+            'schemaMap' => [
+                'db.coll' => $this->decodeJson(file_get_contents(__DIR__ . '/client-side-encryption/external/external-schema.json')),
+            ],
+        ];
+
+        $clientEncrypted = new Client(static::getUri(), [], ['autoEncryption' => $autoEncryptionOpts]);
+        $clientEncryption = $clientEncrypted->createClientEncryption($encryptionOpts);
+
+        try {
+            $result = $clientEncrypted->selectCollection('db', 'coll')->insertOne(['encrypted' => 'test']);
+
+            if ($withExternalKeyVault) {
+                $this->fail('Expected exception to be thrown');
+            } else {
+                $this->assertSame(1, $result->getInsertedCount());
+            }
+        } catch (BulkWriteException $e) {
+            if (! $withExternalKeyVault) {
+                throw $e;
+            }
+
+            $this->assertInstanceOf(AuthenticationException::class, $e->getPrevious());
+        }
+
+        if ($withExternalKeyVault) {
+            $this->expectException(AuthenticationException::class);
+        }
+
+        $clientEncryption->encrypt('test', ['algorithm' => ClientEncryption::AEAD_AES_256_CBC_HMAC_SHA_512_DETERMINISTIC, 'keyId' => $keyId]);
+    }
+
+    public static function provideBSONSizeLimitsAndBatchSplittingTests()
+    {
+        yield [static function (self $test, Collection $collection) {
+            // Test 1
+            $collection->insertOne(['_id' => 'over_2mib_under_16mib', 'unencrypted' => str_repeat('a', 2097152)]);
+            $test->assertCollectionCount($collection->getNamespace(), 1);
+        },
+        ];
+
+        yield [static function (self $test, Collection $collection, array $document) {
+            // Test 2
+            $collection->insertOne(
+                ['_id' => 'encryption_exceeds_2mib', 'unencrypted' => str_repeat('a', 2097152 - 2000)] + $document
+            );
+            $test->assertCollectionCount($collection->getNamespace(), 1);
+        },
+        ];
+
+        yield [static function (self $test, Collection $collection) {
+            // Test 3
+            $commands = [];
+            (new CommandObserver())->observe(
+                function () use ($collection) {
+                    $collection->insertMany([
+                        ['_id' => 'over_2mib_1', 'unencrypted' => str_repeat('a', 2097152)],
+                        ['_id' => 'over_2mib_2', 'unencrypted' => str_repeat('a', 2097152)],
+                    ]);
+                },
+                function ($command) use (&$commands) {
+                    $commands[] = $command;
+                }
+            );
+
+            $test->assertCount(2, $commands);
+            foreach ($commands as $command) {
+                $test->assertSame('insert', $command['started']->getCommandName());
+            }
+        },
+        ];
+
+        yield [static function (self $test, Collection $collection, array $document) {
+            // Test 4
+            $commands = [];
+            (new CommandObserver())->observe(
+                function () use ($collection, $document) {
+                    $collection->insertMany([
+                        [
+                            '_id' => 'encryption_exceeds_2mib_1',
+                            'unencrypted' => str_repeat('a', 2097152 - 2000),
+                        ] + $document,
+                        [
+                            '_id' => 'encryption_exceeds_2mib_2',
+                            'unencrypted' => str_repeat('a', 2097152 - 2000),
+                        ] + $document,
+                    ]);
+                },
+                function ($command) use (&$commands) {
+                    $commands[] = $command;
+                }
+            );
+
+            $test->assertCount(2, $commands);
+            foreach ($commands as $command) {
+                $test->assertSame('insert', $command['started']->getCommandName());
+            }
+        },
+        ];
+
+        yield [static function (self $test, Collection $collection) {
+            // Test 5
+            $collection->insertOne(['_id' => 'under_16mib', 'unencrypted' => str_repeat('a', 16777216 - 2000)]);
+            $test->assertCollectionCount($collection->getNamespace(), 1);
+        },
+        ];
+
+        yield [static function (self $test, Collection $collection, array $document) {
+            // Test 6
+            $test->expectException(BulkWriteException::class);
+            $test->expectExceptionMessageMatches('#object to insert too large#');
+            $collection->insertOne(['_id' => 'encryption_exceeds_16mib', 'unencrypted' => str_repeat('a', 16777216 - 2000)] + $document);
+        },
+        ];
+    }
+
+    /**
+     * Prose test: BSON size limits and batch splitting
+     *
+     * @dataProvider provideBSONSizeLimitsAndBatchSplittingTests
+     */
+    public function testBSONSizeLimitsAndBatchSplitting(Closure $test)
+    {
+        $client = new Client(static::getUri());
+
+        $client->selectCollection('keyvault', 'datakeys')->drop();
+        $client->selectCollection('db', 'coll')->drop();
+
+        $client->selectDatabase('db')->createCollection('coll', ['validator' => ['$jsonSchema' => $this->decodeJson(file_get_contents(__DIR__ . '/client-side-encryption/limits/limits-schema.json'))]]);
+        $client->selectCollection('keyvault', 'datakeys')->insertOne($this->decodeJson(file_get_contents(__DIR__ . '/client-side-encryption/limits/limits-key.json')));
+
+        $autoEncryptionOpts = [
+            'keyVaultNamespace' => 'keyvault.datakeys',
+            'kmsProviders' => [
+                'local' => ['key' => new Binary(base64_decode(self::LOCAL_MASTERKEY), 0)],
+            ],
+            'keyVaultClient' => $client,
+        ];
+
+        $clientEncrypted = new Client(static::getUri(), [], ['autoEncryption' => $autoEncryptionOpts]);
+
+        $collection = $clientEncrypted->selectCollection('db', 'coll');
+
+        $document = json_decode(file_get_contents(__DIR__ . '/client-side-encryption/limits/limits-doc.json'), true);
+
+        $test($this, $collection, $document);
+    }
+
+    /**
+     * Prose test: Views are prohibited
+     */
+    public function testViewsAreProhibited()
+    {
+        $client = new Client(static::getUri());
+
+        $client->selectCollection('db', 'view')->drop();
+        $client->selectDatabase('db')->command(['create' => 'view', 'viewOn' => 'coll']);
+
+        $autoEncryptionOpts = [
+            'keyVaultNamespace' => 'keyvault.datakeys',
+            'kmsProviders' => [
+                'local' => ['key' => new Binary(base64_decode(self::LOCAL_MASTERKEY), 0)],
+            ],
+        ];
+
+        $clientEncrypted = new Client(static::getUri(), [], ['autoEncryption' => $autoEncryptionOpts]);
+
+        try {
+            $clientEncrypted->selectCollection('db', 'view')->insertOne(['foo' => 'bar']);
+            $this->fail('Expected exception to be thrown');
+        } catch (BulkWriteException $e) {
+            $previous = $e->getPrevious();
+
+            $this->assertInstanceOf(EncryptionException::class, $previous);
+            $this->assertSame('cannot auto encrypt a view', $previous->getMessage());
+        }
+    }
+
+    /**
+     * Prose test: BSON Corpus
+     *
+     * @testWith [true]
+     *           [false]
+     */
+    public function testCorpus($schemaMap = true)
+    {
+        $client = new Client(static::getUri());
+
+        $client->selectDatabase('db')->dropCollection('coll');
+
+        $schema = $this->decodeJson(file_get_contents(__DIR__ . '/client-side-encryption/corpus/corpus-schema.json'));
+
+        if (! $schemaMap) {
+            $client
+                ->selectDatabase('db')
+                ->createCollection('coll', ['validator' => ['$jsonSchema' => $schema]]);
+        }
+
+        $client->selectDatabase('keyvault')->dropCollection('datakeys');
+        $client->selectCollection('keyvault', 'datakeys')->insertMany([
+            $this->decodeJson(file_get_contents(__DIR__ . '/client-side-encryption/corpus/corpus-key-local.json')),
+            $this->decodeJson(file_get_contents(__DIR__ . '/client-side-encryption/corpus/corpus-key-aws.json')),
+        ]);
+
+        $encryptionOpts = [
+            'keyVaultNamespace' => 'keyvault.datakeys',
+            'kmsProviders' => [
+                'aws' => Context::getAWSCredentials(),
+                'local' => ['key' => new Binary(base64_decode(self::LOCAL_MASTERKEY), 0)],
+            ],
+        ];
+
+        $autoEncryptionOpts = $encryptionOpts;
+
+        if ($schemaMap) {
+            $autoEncryptionOpts += [
+                'schemaMap' => ['db.coll' => $schema],
+            ];
+        }
+
+        $corpus = (array) $this->decodeJson(file_get_contents(__DIR__ . '/client-side-encryption/corpus/corpus.json'));
+        $corpusCopied = [];
+
+        $clientEncrypted = new Client(static::getUri(), [], ['autoEncryption' => $autoEncryptionOpts]);
+        $clientEncryption = $clientEncrypted->createClientEncryption($encryptionOpts);
+
+        $collection = $clientEncrypted->selectCollection('db', 'coll');
+
+        foreach ($corpus as $fieldName => $data) {
+            switch ($fieldName) {
+                case '_id':
+                case 'altname_aws':
+                case 'altname_local':
+                    $corpusCopied[$fieldName] = $data;
+                    break;
+
+                default:
+                    $corpusCopied[$fieldName] = $this->prepareCorpusData($data, $clientEncryption);
+            }
+        }
+
+        $collection->insertOne($corpusCopied);
+        $corpusDecrypted = $collection->findOne(['_id' => 'client_side_encryption_corpus']);
+
+        $this->assertDocumentsMatch($corpus, $corpusDecrypted);
+    }
+
+    /**
+     * Prose test: Custom Endpoint
+     */
+    public function testCustomEndpoint()
+    {
+        // Test 1
+        $client = new Client(static::getUri());
+
+        $encryptionOpts = [
+            'keyVaultNamespace' => 'keyvault.datakeys',
+            'kmsProviders' => [
+                'aws' => Context::getAWSCredentials(),
+            ],
+        ];
+
+        $clientEncryption = $client->createClientEncryption($encryptionOpts);
+
+        // Test 2
+        $masterKeyConfig = ['region' => 'us-east-1', 'key' => 'arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0'];
+        $keyId = $clientEncryption->createDataKey('aws', ['masterKey' => $masterKeyConfig]);
+        $encrypted = $clientEncryption->encrypt('test', ['algorithm' => ClientEncryption::AEAD_AES_256_CBC_HMAC_SHA_512_DETERMINISTIC, 'keyId' => $keyId]);
+        $this->assertSame('test', $clientEncryption->decrypt($encrypted));
+
+        // Test 3
+        $keyId = $clientEncryption->createDataKey('aws', ['masterKey' => $masterKeyConfig + ['endpoint' => 'kms.us-east-1.amazonaws.com']]);
+        $encrypted = $clientEncryption->encrypt('test', ['algorithm' => ClientEncryption::AEAD_AES_256_CBC_HMAC_SHA_512_DETERMINISTIC, 'keyId' => $keyId]);
+        $this->assertSame('test', $clientEncryption->decrypt($encrypted));
+
+        // Test 4
+        $keyId = $clientEncryption->createDataKey('aws', ['masterKey' => $masterKeyConfig + [ 'endpoint' => 'kms.us-east-1.amazonaws.com:443']]);
+        $encrypted = $clientEncryption->encrypt('test', ['algorithm' => ClientEncryption::AEAD_AES_256_CBC_HMAC_SHA_512_DETERMINISTIC, 'keyId' => $keyId]);
+        $this->assertSame('test', $clientEncryption->decrypt($encrypted));
+
+        // Test 5
+        try {
+            $clientEncryption->createDataKey('aws', ['masterKey' => $masterKeyConfig + [ 'endpoint' => 'kms.us-east-1.amazonaws.com:12345']]);
+            $this->fail('Expected exception to be thrown');
+        } catch (ConnectionException $e) {
+        }
+
+        // Test 6
+        try {
+            $clientEncryption->createDataKey('aws', ['masterKey' => $masterKeyConfig + [ 'endpoint' => 'kms.us-east-2.amazonaws.com']]);
+            $this->fail('Expected exception to be thrown');
+        } catch (RuntimeException $e) {
+            $this->assertStringContainsString('us-east-1', $e->getMessage());
+        }
+
+        // Test 7
+        try {
+            $clientEncryption->createDataKey('aws', ['masterKey' => $masterKeyConfig + [ 'endpoint' => 'example.com']]);
+            $this->fail('Expected exception to be thrown');
+        } catch (RuntimeException $e) {
+            $this->assertStringContainsString('parse error', $e->getMessage());
+        }
+    }
+
+    /**
+     * Prose test: Bypass spawning mongocryptd (via mongocryptdBypassSpawn)
+     */
+    public function testBypassSpawningMongocryptdViaBypassSpawn()
+    {
+        $autoEncryptionOpts = [
+            'keyVaultNamespace' => 'keyvault.datakeys',
+            'kmsProviders' => [
+                'local' => ['key' => new Binary(base64_decode(self::LOCAL_MASTERKEY), 0)],
+            ],
+            'schemaMap' => [
+                'db.coll' => $this->decodeJson(file_get_contents(__DIR__ . '/client-side-encryption/external/external-schema.json')),
+            ],
+            'extraOptions' => [
+                'mongocryptdBypassSpawn' => true,
+                'mongocryptdURI' => 'mongodb://localhost:27021/db?serverSelectionTimeoutMS=1000',
+                'mongocryptdSpawnArgs' => ['--pidfilepath=bypass-spawning-mongocryptd.pid', '--port=27021'],
+            ],
+        ];
+
+        $clientEncrypted = new Client(static::getUri(), [], ['autoEncryption' => $autoEncryptionOpts]);
+
+        try {
+            $clientEncrypted->selectCollection('db', 'coll')->insertOne(['encrypted' => 'test']);
+            $this->fail('Expected exception to be thrown');
+        } catch (BulkWriteException $e) {
+            $previous = $e->getPrevious();
+            $this->assertInstanceOf(ConnectionTimeoutException::class, $previous);
+
+            $this->assertStringContainsString('mongocryptd error: No suitable servers found', $previous->getMessage());
+        }
+    }
+
+    /**
+     * Bypass spawning mongocryptd (via bypassAutoEncryption)
+     */
+    public function testBypassSpawningMongocryptdViaBypassAutoEncryption()
+    {
+        $autoEncryptionOpts = [
+            'keyVaultNamespace' => 'keyvault.datakeys',
+            'kmsProviders' => [
+                'local' => ['key' => new Binary(base64_decode(self::LOCAL_MASTERKEY), 0)],
+            ],
+            'bypassAutoEncryption' => true,
+            'extraOptions' => [
+                'mongocryptdSpawnArgs' => ['--pidfilepath=bypass-spawning-mongocryptd.pid', '--port=27021'],
+            ],
+        ];
+
+        $clientEncrypted = new Client(static::getUri(), [], ['autoEncryption' => $autoEncryptionOpts]);
+
+        $clientEncrypted->selectCollection('db', 'coll')->insertOne(['encrypted' => 'test']);
+
+        $clientMongocryptd = new Client('mongodb://localhost:27021');
+
+        $this->expectException(ConnectionTimeoutException::class);
+        $clientMongocryptd->selectDatabase('db')->command(['isMaster' => true]);
+    }
+
+    /**
+     * Casts the value for a BSON corpus structure to int64 if necessary.
+     *
+     * This is a workaround for an issue in mongocryptd which refuses to encrypt
+     * int32 values if the schemaMap defines a "long" bsonType for an object.
+     *
+     * @param object $data
+     *
+     * @return Int64|mixed
+     */
+    private function craftInt64($data)
+    {
+        if ($data->type !== 'long' || $data->value instanceof Int64) {
+            return $data->value;
+        }
+
+        $class = Int64::class;
+
+        $intAsString = sprintf((string) $data->value);
+        $array = sprintf('a:1:{s:7:"integer";s:%d:"%s";}', strlen($intAsString), $intAsString);
+        $int64 = sprintf('C:%d:"%s":%d:{%s}', strlen($class), $class, strlen($array), $array);
+
+        return unserialize($int64);
+    }
+
+    private function createTestCollection($jsonSchema)
+    {
+        $options = empty($jsonSchema) ? [] : ['validator' => ['$jsonSchema' => $jsonSchema]];
+        $operation = new CreateCollection($this->getContext()->databaseName, $this->getContext()->collectionName, $options);
+        $operation->execute($this->getPrimaryServer());
+    }
+
+    private function encryptCorpusValue(stdClass $data, ClientEncryption $clientEncryption)
+    {
+        $encryptionOptions = [
+            'algorithm' => $data->algo === 'rand' ? ClientEncryption::AEAD_AES_256_CBC_HMAC_SHA_512_RANDOM : ClientEncryption::AEAD_AES_256_CBC_HMAC_SHA_512_DETERMINISTIC,
+        ];
+
+        switch ($data->identifier) {
+            case 'id':
+                $keyId = $data->kms === 'local' ? 'LOCALAAAAAAAAAAAAAAAAA==' : 'AWSAAAAAAAAAAAAAAAAAAA==';
+                $encryptionOptions['keyId'] = new Binary(base64_decode($keyId), 4);
+                break;
+
+            case 'altname':
+                $encryptionOptions['keyAltName'] = $data->kms === 'local' ? 'local' : 'aws';
+                break;
+
+            default:
+                throw new UnexpectedValueException('Unexpected value "%s" for identifier', $data->identifier);
+        }
+
+        if ($data->allowed) {
+            $encrypted = $clientEncryption->encrypt($this->craftInt64($data), $encryptionOptions);
+            $this->assertEquals($data->value, $clientEncryption->decrypt($encrypted));
+
+            return $encrypted;
+        }
+
+        try {
+            $clientEncryption->encrypt($data->value, $encryptionOptions);
+            $this->fail('Expected exception to be thrown');
+        } catch (RuntimeException $e) {
+        }
+
+        return $data->value;
+    }
+
+    private function insertKeyVaultData(array $keyVaultData = null)
+    {
+        if (empty($keyVaultData)) {
+            return;
+        }
+
+        $context = $this->getContext();
+        $collection = $context->selectCollection('keyvault', 'datakeys', ['writeConcern' => new WriteConcern(WriteConcern::MAJORITY)] + $context->defaultWriteOptions);
+        $collection->drop();
+        $collection->insertMany($keyVaultData);
+
+        return;
+    }
+
+    private function prepareCorpusData(stdClass $data, ClientEncryption $clientEncryption)
+    {
+        if ($data->method === 'auto') {
+            $data->value = $this->craftInt64($data);
+
+            return $data;
+        }
+
+        $returnData = clone $data;
+        $returnData->value = $this->encryptCorpusValue($data, $clientEncryption);
+
+        return $data->allowed ? $returnData : $data;
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/CommandExpectations.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/CommandExpectations.php
new file mode 100644
index 0000000000000000000000000000000000000000..6e203f9316804876e14616d42983763386008b9a
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/CommandExpectations.php	
@@ -0,0 +1,253 @@
+<?php
+
+namespace MongoDB\Tests\SpecTests;
+
+use ArrayIterator;
+use LogicException;
+use MongoDB\Driver\Monitoring\CommandFailedEvent;
+use MongoDB\Driver\Monitoring\CommandStartedEvent;
+use MongoDB\Driver\Monitoring\CommandSubscriber;
+use MongoDB\Driver\Monitoring\CommandSucceededEvent;
+use MultipleIterator;
+use function count;
+use function in_array;
+use function key;
+use function MongoDB\Driver\Monitoring\addSubscriber;
+use function MongoDB\Driver\Monitoring\removeSubscriber;
+
+/**
+ * Spec test CommandStartedEvent expectations.
+ */
+class CommandExpectations implements CommandSubscriber
+{
+    /** @var array */
+    private $actualEvents = [];
+
+    /** @var array */
+    private $expectedEvents = [];
+
+    /** @var boolean */
+    private $ignoreCommandFailed = false;
+
+    /** @var boolean */
+    private $ignoreCommandStarted = false;
+
+    /** @var boolean */
+    private $ignoreCommandSucceeded = false;
+
+    /** @var boolean */
+    private $ignoreExtraEvents = false;
+
+    /** @var string[] */
+    private $ignoredCommandNames = [];
+
+    private function __construct(array $events)
+    {
+        foreach ($events as $event) {
+            switch (key($event)) {
+                case 'command_failed_event':
+                    $this->expectedEvents[] = [$event->command_failed_event, CommandFailedEvent::class];
+                    break;
+
+                case 'command_started_event':
+                    $this->expectedEvents[] = [$event->command_started_event, CommandStartedEvent::class];
+                    break;
+
+                case 'command_succeeded_event':
+                    $this->expectedEvents[] = [$event->command_succeeded_event, CommandSucceededEvent::class];
+                    break;
+
+                default:
+                    throw new LogicException('Unsupported event type: ' . key($event));
+            }
+        }
+    }
+
+    public static function fromChangeStreams(array $expectedEvents)
+    {
+        $o = new self($expectedEvents);
+
+        $o->ignoreCommandFailed = true;
+        $o->ignoreCommandSucceeded = true;
+        /* Change Streams spec tests do not include getMore commands in the
+         * list of expected events, so ignore any observed events beyond the
+         * number that are expected. */
+        $o->ignoreExtraEvents = true;
+
+        return $o;
+    }
+
+    public static function fromClientSideEncryption(array $expectedEvents)
+    {
+        $o = new self($expectedEvents);
+
+        $o->ignoreCommandFailed = true;
+        $o->ignoreCommandSucceeded = true;
+
+        return $o;
+    }
+
+    public static function fromCommandMonitoring(array $expectedEvents)
+    {
+        return new self($expectedEvents);
+    }
+
+    public static function fromCrud(array $expectedEvents)
+    {
+        $o = new self($expectedEvents);
+
+        $o->ignoreCommandFailed = true;
+        $o->ignoreCommandSucceeded = true;
+
+        return $o;
+    }
+
+    public static function fromReadWriteConcern(array $expectedEvents)
+    {
+        $o = new self($expectedEvents);
+
+        $o->ignoreCommandFailed = true;
+        $o->ignoreCommandSucceeded = true;
+
+        return $o;
+    }
+
+    public static function fromRetryableReads(array $expectedEvents)
+    {
+        $o = new self($expectedEvents);
+
+        $o->ignoreCommandFailed = true;
+        $o->ignoreCommandSucceeded = true;
+
+        /* Retryable read spec tests don't include extra commands, e.g. the
+         * killCursors command issued when a change stream is garbage collected.
+         * We ignore any extra events for that reason. \*/
+        $o->ignoreExtraEvents = true;
+
+        return $o;
+    }
+
+    public static function fromTransactions(array $expectedEvents)
+    {
+        $o = new self($expectedEvents);
+
+        $o->ignoreCommandFailed = true;
+        $o->ignoreCommandSucceeded = true;
+
+        /* Ignore the buildInfo and getParameter commands as they are used to
+         * check for the availability of configureFailPoint and are not expected
+         * to be called by any spec tests.
+         * configureFailPoint needs to be ignored as the targetedFailPoint
+         * operation will be caught by command monitoring and is also not
+         * present in the expected commands in spec tests. */
+        $o->ignoredCommandNames = ['buildInfo', 'getParameter', 'configureFailPoint', 'listCollections', 'listIndexes'];
+
+        return $o;
+    }
+
+    /**
+     * Not used.
+     *
+     * @see https://www.php.net/manual/en/mongodb-driver-monitoring-commandsubscriber.commandfailed.php
+     */
+    public function commandFailed(CommandFailedEvent $event)
+    {
+        if ($this->ignoreCommandFailed || $this->isEventIgnored($event)) {
+            return;
+        }
+
+        $this->actualEvents[] = $event;
+    }
+
+    /**
+     * Tracks outgoing commands for spec test APM assertions.
+     *
+     * @see https://www.php.net/manual/en/mongodb-driver-monitoring-commandsubscriber.commandstarted.php
+     */
+    public function commandStarted(CommandStartedEvent $event)
+    {
+        if ($this->ignoreCommandStarted || $this->isEventIgnored($event)) {
+            return;
+        }
+
+        $this->actualEvents[] = $event;
+    }
+
+    /**
+     * Not used.
+     *
+     * @see https://www.php.net/manual/en/mongodb-driver-monitoring-commandsubscriber.commandsucceeded.php
+     */
+    public function commandSucceeded(CommandSucceededEvent $event)
+    {
+        if ($this->ignoreCommandSucceeded || $this->isEventIgnored($event)) {
+            return;
+        }
+
+        $this->actualEvents[] = $event;
+    }
+
+    /**
+     * Start command monitoring.
+     */
+    public function startMonitoring()
+    {
+        addSubscriber($this);
+    }
+
+    /**
+     * Stop command monitoring.
+     */
+    public function stopMonitoring()
+    {
+        removeSubscriber($this);
+    }
+
+    /**
+     * Assert that the command expectations match the monitored events.
+     *
+     * @param FunctionalTestCase $test    Test instance
+     * @param Context            $context Execution context
+     */
+    public function assert(FunctionalTestCase $test, Context $context)
+    {
+        $test->assertCount(count($this->expectedEvents), $this->actualEvents);
+
+        $mi = new MultipleIterator(MultipleIterator::MIT_NEED_ANY);
+        $mi->attachIterator(new ArrayIterator($this->expectedEvents));
+        $mi->attachIterator(new ArrayIterator($this->actualEvents));
+
+        foreach ($mi as $events) {
+            list($expectedEventAndClass, $actualEvent) = $events;
+            list($expectedEvent, $expectedClass) = $expectedEventAndClass;
+
+            $test->assertInstanceOf($expectedClass, $actualEvent);
+
+            if (isset($expectedEvent->command_name)) {
+                $test->assertSame($expectedEvent->command_name, $actualEvent->getCommandName());
+            }
+
+            if (isset($expectedEvent->database_name)) {
+                $test->assertSame($expectedEvent->database_name, $actualEvent->getDatabaseName());
+            }
+
+            if (isset($expectedEvent->command)) {
+                $test->assertInstanceOf(CommandStartedEvent::class, $actualEvent);
+                $expectedCommand = $expectedEvent->command;
+                $context->replaceCommandSessionPlaceholder($expectedCommand);
+                $test->assertCommandMatches($expectedCommand, $actualEvent->getCommand());
+            }
+
+            if (isset($expectedEvent->reply)) {
+                $test->assertInstanceOf(CommandSucceededEvent::class, $actualEvent);
+                $test->assertCommandReplyMatches($expectedEvent->reply, $actualEvent->getReply());
+            }
+        }
+    }
+
+    private function isEventIgnored($event)
+    {
+        return ($this->ignoreExtraEvents && count($this->actualEvents) === count($this->expectedEvents))
+            || in_array($event->getCommandName(), $this->ignoredCommandNames);
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/CommandMonitoringSpecTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/CommandMonitoringSpecTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..0f9bf907566e1cf68e9fe1bf8829994974245b3f
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/CommandMonitoringSpecTest.php	
@@ -0,0 +1,223 @@
+<?php
+
+namespace MongoDB\Tests\SpecTests;
+
+use stdClass;
+use function array_diff;
+use function basename;
+use function file_get_contents;
+use function glob;
+use function is_array;
+use function is_numeric;
+
+/**
+ * Command monitoring spec tests.
+ *
+ * @see https://github.com/mongodb/specifications/tree/master/source/command-monitoring
+ */
+class CommandMonitoringSpecTest extends FunctionalTestCase
+{
+    /**
+     * Assert that the expected and actual command documents match.
+     *
+     * Note: this method may modify the $expected object.
+     *
+     * @param stdClass $expected Expected command document
+     * @param stdClass $actual   Actual command document
+     */
+    public static function assertCommandMatches(stdClass $expected, stdClass $actual)
+    {
+        if (isset($expected->getMore) && $expected->getMore === 42) {
+            static::assertObjectHasAttribute('getMore', $actual);
+            static::assertThat($actual->getMore, static::logicalOr(
+                static::isInstanceOf(Int64::class),
+                static::isType('integer')
+            ));
+            unset($expected->getMore);
+        }
+
+        if (isset($expected->killCursors) && isset($expected->cursors) && is_array($expected->cursors)) {
+            static::assertObjectHasAttribute('cursors', $actual);
+            static::assertIsArray($actual->cursors);
+
+            foreach ($expected->cursors as $i => $cursorId) {
+                static::assertArrayHasKey($i, $actual->cursors);
+
+                if ($cursorId === 42) {
+                    static::assertThat($actual->cursors[$i], static::logicalOr(
+                        static::isInstanceOf(Int64::class),
+                        static::isType('integer')
+                    ));
+                }
+            }
+
+            unset($expected->cursors);
+        }
+
+        static::assertDocumentsMatch($expected, $actual);
+    }
+
+    /**
+     * Assert that the expected and actual command reply documents match.
+     *
+     * Note: this method may modify the $expectedReply object.
+     *
+     * @param stdClass $expected Expected command reply document
+     * @param stdClass $actual   Actual command reply document
+     */
+    public static function assertCommandReplyMatches(stdClass $expected, stdClass $actual)
+    {
+        if (isset($expected->cursor->id) && $expected->cursor->id === 42) {
+            static::assertObjectHasAttribute('cursor', $actual);
+            static::assertIsObject($actual->cursor);
+            static::assertObjectHasAttribute('id', $actual->cursor);
+            static::assertThat($actual->cursor->id, static::logicalOr(
+                static::isInstanceOf(Int64::class),
+                static::isType('integer')
+            ));
+            unset($expected->cursor->id);
+        }
+
+        if (isset($expected->cursorsUnknown) && is_array($expected->cursorsUnknown)) {
+            static::assertObjectHasAttribute('cursorsUnknown', $actual);
+            static::assertIsArray($actual->cursorsUnknown);
+
+            foreach ($expected->cursorsUnknown as $i => $cursorId) {
+                static::assertArrayHasKey($i, $actual->cursorsUnknown);
+
+                if ($cursorId === 42) {
+                    static::assertThat($actual->cursorsUnknown[$i], static::logicalOr(
+                        static::isInstanceOf(Int64::class),
+                        static::isType('integer')
+                    ));
+                }
+            }
+
+            unset($expected->cursorsUnknown);
+        }
+
+        if (isset($expected->ok) && is_numeric($expected->ok)) {
+            static::assertObjectHasAttribute('ok', $actual);
+            static::assertIsNumeric($actual->ok);
+            static::assertEquals($expected->ok, $actual->ok);
+            unset($expected->ok);
+        }
+
+        if (isset($expected->writeErrors) && is_array($expected->writeErrors)) {
+            static::assertObjectHasAttribute('writeErrors', $actual);
+            static::assertIsArray($actual->writeErrors);
+
+            foreach ($expected->writeErrors as $i => $expectedWriteError) {
+                static::assertArrayHasKey($i, $actual->writeErrors);
+                $actualWriteError = $actual->writeErrors[$i];
+
+                if (isset($expectedWriteError->code) && $expectedWriteError->code === 42) {
+                    static::assertObjectHasAttribute('code', $actualWriteError);
+                    static::assertThat($actualWriteError->code, static::logicalOr(
+                        static::isInstanceOf(Int64::class),
+                        static::isType('integer')
+                    ));
+                    unset($expected->writeErrors[$i]->code);
+                }
+
+                if (isset($expectedWriteError->errmsg) && $expectedWriteError->errmsg === '') {
+                    static::assertObjectHasAttribute('errmsg', $actualWriteError);
+                    static::assertIsString($actualWriteError->errmsg);
+                    static::assertNotEmpty($actualWriteError->errmsg);
+                    unset($expected->writeErrors[$i]->errmsg);
+                }
+            }
+        }
+
+        static::assertDocumentsMatch($expected, $actual);
+    }
+
+    /**
+     * Execute an individual test case from the specification.
+     *
+     * @dataProvider provideTests
+     * @param stdClass $test           Individual "tests[]" document
+     * @param array    $data           Top-level "data" array to initialize collection
+     * @param string   $databaseName   Name of database under test
+     * @param string   $collectionName Name of collection under test
+     */
+    public function testCommandMonitoring(stdClass $test, array $data, $databaseName = null, $collectionName = null)
+    {
+        $this->checkServerRequirements($this->createRunOn($test));
+
+        $databaseName = $databaseName ?? $this->getDatabaseName();
+        $collectionName = $collectionName ?? $this->getCollectionName();
+
+        $context = Context::fromCommandMonitoring($test, $databaseName, $collectionName);
+        $this->setContext($context);
+
+        $this->dropTestAndOutcomeCollections();
+        $this->insertDataFixtures($data);
+
+        if (isset($test->expectations)) {
+            $commandExpectations = CommandExpectations::fromCommandMonitoring($test->expectations);
+            $commandExpectations->startMonitoring();
+        }
+
+        Operation::fromCommandMonitoring($test->operation)->assert($this, $context);
+
+        if (isset($commandExpectations)) {
+            $commandExpectations->stopMonitoring();
+            $commandExpectations->assert($this, $context);
+        }
+    }
+
+    public function provideTests()
+    {
+        $testArgs = [];
+
+        foreach (glob(__DIR__ . '/command-monitoring/*.json') as $filename) {
+            $json = $this->decodeJson(file_get_contents($filename));
+            $group = basename($filename, '.json');
+            $data = $json->data ?? [];
+            $databaseName = $json->database_name ?? null;
+            $collectionName = $json->collection_name ?? null;
+
+            foreach ($json->tests as $test) {
+                $name = $group . ': ' . $test->description;
+                $testArgs[$name] = [$test, $data, $databaseName, $collectionName];
+            }
+        }
+
+        return $testArgs;
+    }
+
+    /**
+     * Convert the server and topology requirements to a standard "runOn" array
+     * used by other specifications.
+     *
+     * @param stdClass $test
+     * @return array
+     */
+    private function createRunOn(stdClass $test)
+    {
+        $req = new stdClass();
+
+        $topologies = [
+            self::TOPOLOGY_SINGLE,
+            self::TOPOLOGY_REPLICASET,
+            self::TOPOLOGY_SHARDED,
+        ];
+
+        /* Append ".99" as patch version, since command monitoring tests expect
+         * the minor version to be an inclusive upper bound. */
+        if (isset($test->ignore_if_server_version_greater_than)) {
+            $req->maxServerVersion = $test->ignore_if_server_version_greater_than . '.99';
+        }
+
+        if (isset($test->ignore_if_server_version_less_than)) {
+            $req->minServerVersion = $test->ignore_if_server_version_less_than;
+        }
+
+        if (isset($test->ignore_if_topology_type)) {
+            $req->topology = array_diff($topologies, $test->ignore_if_topology_type);
+        }
+
+        return [$req];
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/Context.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/Context.php
new file mode 100644
index 0000000000000000000000000000000000000000..dde7304d7da9c44d0434b5119073500c5cf7f038
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/Context.php	
@@ -0,0 +1,440 @@
+<?php
+
+namespace MongoDB\Tests\SpecTests;
+
+use LogicException;
+use MongoDB\Client;
+use MongoDB\Driver\ReadConcern;
+use MongoDB\Driver\ReadPreference;
+use MongoDB\Driver\Session;
+use MongoDB\Driver\WriteConcern;
+use PHPUnit\Framework\SkippedTestError;
+use stdClass;
+use function array_diff_key;
+use function array_keys;
+use function getenv;
+use function implode;
+use function mt_rand;
+use function uniqid;
+
+/**
+ * Execution context for spec tests.
+ *
+ * This object tracks state that would be difficult to store on the test itself
+ * due to the design of PHPUnit's data providers and setUp/tearDown methods.
+ */
+final class Context
+{
+    /** @var string|null */
+    public $bucketName;
+
+    /** @var Client|null */
+    private $client;
+
+    /** @var string */
+    public $collectionName;
+
+    /** @var string */
+    public $databaseName;
+
+    /** @var array */
+    public $defaultWriteOptions = [];
+
+    /** @var array */
+    public $outcomeReadOptions = [];
+
+    /** @var string */
+    public $outcomeCollectionName;
+
+    /** @var Session|null */
+    public $session0;
+
+    /** @var object */
+    public $session0Lsid;
+
+    /** @var Session|null */
+    public $session1;
+
+    /** @var object */
+    public $session1Lsid;
+
+    /** @var Client|null */
+    private $encryptedClient;
+
+    /** @var bool */
+    private $useEncryptedClient = false;
+
+    /**
+     * @param string $databaseName
+     * @param string $collectionName
+     */
+    private function __construct($databaseName, $collectionName)
+    {
+        $this->databaseName = $databaseName;
+        $this->collectionName = $collectionName;
+        $this->outcomeCollectionName = $collectionName;
+    }
+
+    public function disableEncryption()
+    {
+        $this->useEncryptedClient = false;
+    }
+
+    public function enableEncryption()
+    {
+        if (! $this->encryptedClient instanceof Client) {
+            throw new LogicException('Cannot enable encryption without autoEncryption options');
+        }
+
+        $this->useEncryptedClient = true;
+    }
+
+    public static function fromChangeStreams(stdClass $test, $databaseName, $collectionName)
+    {
+        $o = new self($databaseName, $collectionName);
+
+        $o->client = new Client(FunctionalTestCase::getUri());
+
+        return $o;
+    }
+
+    public static function fromClientSideEncryption(stdClass $test, $databaseName, $collectionName)
+    {
+        $o = new self($databaseName, $collectionName);
+
+        $clientOptions = isset($test->clientOptions) ? (array) $test->clientOptions : [];
+
+        /* mongocryptd caches collection information, which causes test failures
+         * if we reuse the client. Thus, we add a random value to ensure we're
+         * creating a new client for each test. */
+        $driverOptions = ['random' => uniqid()];
+
+        $autoEncryptionOptions = [];
+
+        if (isset($clientOptions['autoEncryptOpts'])) {
+            $autoEncryptionOptions = (array) $clientOptions['autoEncryptOpts'] + ['keyVaultNamespace' => 'keyvault.datakeys'];
+            unset($clientOptions['autoEncryptOpts']);
+
+            if (isset($autoEncryptionOptions['kmsProviders']->aws)) {
+                $autoEncryptionOptions['kmsProviders']->aws = self::getAWSCredentials();
+            }
+        }
+
+        if (isset($test->outcome->collection->name)) {
+            $o->outcomeCollectionName = $test->outcome->collection->name;
+        }
+
+        $o->client = new Client(FunctionalTestCase::getUri(), $clientOptions, $driverOptions);
+
+        if ($autoEncryptionOptions !== []) {
+            $o->encryptedClient = new Client(FunctionalTestCase::getUri(), $clientOptions, $driverOptions + ['autoEncryption' => $autoEncryptionOptions]);
+        }
+
+        return $o;
+    }
+
+    public static function fromCommandMonitoring(stdClass $test, $databaseName, $collectionName)
+    {
+        $o = new self($databaseName, $collectionName);
+
+        $o->client = new Client(FunctionalTestCase::getUri());
+
+        return $o;
+    }
+
+    public static function fromCrud(stdClass $test, $databaseName, $collectionName)
+    {
+        $o = new self($databaseName, $collectionName);
+
+        $clientOptions = isset($test->clientOptions) ? (array) $test->clientOptions : [];
+
+        if (isset($test->outcome->collection->name)) {
+            $o->outcomeCollectionName = $test->outcome->collection->name;
+        }
+
+        $o->defaultWriteOptions = [
+            'writeConcern' => new WriteConcern(WriteConcern::MAJORITY),
+        ];
+
+        $o->outcomeReadOptions = [
+            'readConcern' => new ReadConcern('local'),
+            'readPreference' => new ReadPreference('primary'),
+        ];
+
+        $o->client = new Client(FunctionalTestCase::getUri(), $clientOptions);
+
+        return $o;
+    }
+
+    public static function fromReadWriteConcern(stdClass $test, $databaseName, $collectionName)
+    {
+        $o = new self($databaseName, $collectionName);
+
+        if (isset($test->outcome->collection->name)) {
+            $o->outcomeCollectionName = $test->outcome->collection->name;
+        }
+
+        $clientOptions = isset($test->clientOptions) ? (array) $test->clientOptions : [];
+
+        $o->client = new Client(FunctionalTestCase::getUri(), $clientOptions);
+
+        return $o;
+    }
+
+    public static function fromRetryableReads(stdClass $test, $databaseName, $collectionName, $bucketName)
+    {
+        $o = new self($databaseName, $collectionName);
+
+        $o->bucketName = $bucketName;
+
+        $clientOptions = isset($test->clientOptions) ? (array) $test->clientOptions : [];
+
+        $o->client = new Client(FunctionalTestCase::getUri(), $clientOptions);
+
+        return $o;
+    }
+
+    public static function fromRetryableWrites(stdClass $test, $databaseName, $collectionName, $useMultipleMongoses)
+    {
+        $o = new self($databaseName, $collectionName);
+
+        $clientOptions = isset($test->clientOptions) ? (array) $test->clientOptions : [];
+
+        if (isset($test->outcome->collection->name)) {
+            $o->outcomeCollectionName = $test->outcome->collection->name;
+        }
+
+        $o->client = new Client(FunctionalTestCase::getUri($useMultipleMongoses), $clientOptions);
+
+        return $o;
+    }
+
+    public static function fromTransactions(stdClass $test, $databaseName, $collectionName, $useMultipleMongoses)
+    {
+        $o = new self($databaseName, $collectionName);
+
+        $o->defaultWriteOptions = [
+            'writeConcern' => new WriteConcern(WriteConcern::MAJORITY),
+        ];
+
+        $o->outcomeReadOptions = [
+            'readConcern' => new ReadConcern('local'),
+            'readPreference' => new ReadPreference('primary'),
+        ];
+
+        $clientOptions = isset($test->clientOptions) ? (array) $test->clientOptions : [];
+
+        /* Transaction spec tests expect a new client for each test so that
+         * txnNumber values are deterministic. Append a random option to avoid
+         * re-using a previously persisted libmongoc client object. */
+        $clientOptions += ['p' => mt_rand()];
+
+        $o->client = new Client(FunctionalTestCase::getUri($useMultipleMongoses), $clientOptions);
+
+        $session0Options = isset($test->sessionOptions->session0) ? (array) $test->sessionOptions->session0 : [];
+        $session1Options = isset($test->sessionOptions->session1) ? (array) $test->sessionOptions->session1 : [];
+
+        $o->session0 = $o->client->startSession($o->prepareSessionOptions($session0Options));
+        $o->session1 = $o->client->startSession($o->prepareSessionOptions($session1Options));
+
+        $o->session0Lsid = $o->session0->getLogicalSessionId();
+        $o->session1Lsid = $o->session1->getLogicalSessionId();
+
+        return $o;
+    }
+
+    /**
+     * @return array
+     *
+     * @throws SkippedTestError
+     */
+    public static function getAWSCredentials()
+    {
+        if (! getenv('AWS_ACCESS_KEY_ID') || ! getenv('AWS_SECRET_ACCESS_KEY')) {
+            throw new SkippedTestError('Please configure AWS credentials to use AWS KMS provider.');
+        }
+
+        return [
+            'accessKeyId' => getenv('AWS_ACCESS_KEY_ID'),
+            'secretAccessKey' => getenv('AWS_SECRET_ACCESS_KEY'),
+        ];
+    }
+
+    /**
+     * @return Client
+     */
+    public function getClient()
+    {
+        return $this->useEncryptedClient && $this->encryptedClient ? $this->encryptedClient : $this->client;
+    }
+
+    public function getCollection(array $collectionOptions = [], array $databaseOptions = [])
+    {
+        return $this->selectCollection(
+            $this->databaseName,
+            $this->collectionName,
+            $collectionOptions,
+            $databaseOptions
+        );
+    }
+
+    public function getDatabase(array $databaseOptions = [])
+    {
+        return $this->selectDatabase($this->databaseName, $databaseOptions);
+    }
+
+    public function getGridFSBucket(array $bucketOptions = [])
+    {
+        return $this->selectGridFSBucket($this->databaseName, $this->bucketName, $bucketOptions);
+    }
+
+    /**
+     * Prepare options readConcern, readPreference, and writeConcern options by
+     * creating value objects.
+     *
+     * @param array $options
+     * @return array
+     * @throws LogicException if any option keys are unsupported
+     */
+    public function prepareOptions(array $options)
+    {
+        if (isset($options['readConcern']) && ! ($options['readConcern'] instanceof ReadConcern)) {
+            $readConcern = (array) $options['readConcern'];
+            $diff = array_diff_key($readConcern, ['level' => 1]);
+
+            if (! empty($diff)) {
+                throw new LogicException('Unsupported readConcern args: ' . implode(',', array_keys($diff)));
+            }
+
+            $options['readConcern'] = new ReadConcern($readConcern['level']);
+        }
+
+        if (isset($options['readPreference']) && ! ($options['readPreference'] instanceof ReadPreference)) {
+            $readPreference = (array) $options['readPreference'];
+            $diff = array_diff_key($readPreference, ['mode' => 1]);
+
+            if (! empty($diff)) {
+                throw new LogicException('Unsupported readPreference args: ' . implode(',', array_keys($diff)));
+            }
+
+            $options['readPreference'] = new ReadPreference($readPreference['mode']);
+        }
+
+        if (isset($options['writeConcern']) && ! ($options['writeConcern'] instanceof WriteConcern)) {
+            $writeConcern = (array) $options['writeConcern'];
+            $diff = array_diff_key($writeConcern, ['w' => 1, 'wtimeout' => 1, 'j' => 1]);
+
+            if (! empty($diff)) {
+                throw new LogicException('Unsupported writeConcern args: ' . implode(',', array_keys($diff)));
+            }
+
+            if (! empty($writeConcern)) {
+                $w = $writeConcern['w'];
+                $wtimeout = $writeConcern['wtimeout'] ?? 0;
+                $j = $writeConcern['j'] ?? null;
+
+                $options['writeConcern'] = isset($j)
+                    ? new WriteConcern($w, $wtimeout, $j)
+                    : new WriteConcern($w, $wtimeout);
+            } else {
+                unset($options['writeConcern']);
+            }
+        }
+
+        return $options;
+    }
+
+    /**
+     * Replace a session placeholder in an operation arguments array.
+     *
+     * Note: this method will modify the $args parameter.
+     *
+     * @param array $args Operation arguments
+     * @throws LogicException if the session placeholder is unsupported
+     */
+    public function replaceArgumentSessionPlaceholder(array &$args)
+    {
+        if (! isset($args['session'])) {
+            return;
+        }
+
+        switch ($args['session']) {
+            case 'session0':
+                $args['session'] = $this->session0;
+                break;
+
+            case 'session1':
+                $args['session'] = $this->session1;
+                break;
+
+            default:
+                throw new LogicException('Unsupported session placeholder: ' . $args['session']);
+        }
+    }
+
+    /**
+     * Replace a logical session ID placeholder in a command document.
+     *
+     * Note: this method will modify the $command parameter.
+     *
+     * @param stdClass $command Command document
+     * @throws LogicException if the session placeholder is unsupported
+     */
+    public function replaceCommandSessionPlaceholder(stdClass $command)
+    {
+        if (! isset($command->lsid)) {
+            return;
+        }
+
+        switch ($command->lsid) {
+            case 'session0':
+                $command->lsid = $this->session0Lsid;
+                break;
+
+            case 'session1':
+                $command->lsid = $this->session1Lsid;
+                break;
+
+            default:
+                throw new LogicException('Unsupported session placeholder: ' . $command->lsid);
+        }
+    }
+
+    public function selectCollection($databaseName, $collectionName, array $collectionOptions = [], array $databaseOptions = [])
+    {
+        return $this
+            ->selectDatabase($databaseName, $databaseOptions)
+            ->selectCollection($collectionName, $this->prepareOptions($collectionOptions));
+    }
+
+    public function selectDatabase($databaseName, array $databaseOptions = [])
+    {
+        return $this->getClient()->selectDatabase(
+            $databaseName,
+            $this->prepareOptions($databaseOptions)
+        );
+    }
+
+    public function selectGridFSBucket($databaseName, $bucketName, array $bucketOptions = [])
+    {
+        return $this->selectDatabase($databaseName)->selectGridFSBucket($this->prepareGridFSBucketOptions($bucketOptions, $bucketName));
+    }
+
+    private function prepareGridFSBucketOptions(array $options, $bucketPrefix)
+    {
+        if ($bucketPrefix !== null) {
+            $options['bucketPrefix'] = $bucketPrefix;
+        }
+
+        return $options;
+    }
+
+    private function prepareSessionOptions(array $options)
+    {
+        if (isset($options['defaultTransactionOptions'])) {
+            $options['defaultTransactionOptions'] = $this->prepareOptions((array) $options['defaultTransactionOptions']);
+        }
+
+        return $options;
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/CrudSpecTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/CrudSpecTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..8835b92e69942f3572d41df508e3a5636495683a
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/CrudSpecTest.php	
@@ -0,0 +1,156 @@
+<?php
+
+namespace MongoDB\Tests\SpecTests;
+
+use MongoDB\Client;
+use MongoDB\Driver\Exception\BulkWriteException;
+use stdClass;
+use function basename;
+use function file_get_contents;
+use function glob;
+
+/**
+ * Crud spec tests.
+ *
+ * @see https://github.com/mongodb/specifications/tree/master/source/crud
+ */
+class CrudSpecTest extends FunctionalTestCase
+{
+    /** @var array */
+    private static $incompleteTests = [];
+
+    /**
+     * Assert that the expected and actual command documents match.
+     *
+     * @param stdClass $expected Expected command document
+     * @param stdClass $actual   Actual command document
+     */
+    public static function assertCommandMatches(stdClass $expected, stdClass $actual)
+    {
+        foreach ($expected as $key => $value) {
+            if ($value === null) {
+                static::assertObjectNotHasAttribute($key, $actual);
+                unset($expected->{$key});
+            }
+        }
+
+        static::assertDocumentsMatch($expected, $actual);
+    }
+
+    /**
+     * Execute an individual test case from the specification.
+     *
+     * @dataProvider provideTests
+     * @param stdClass $test           Individual "tests[]" document
+     * @param array    $runOn          Top-level "runOn" array with server requirements
+     * @param array    $data           Top-level "data" array to initialize collection
+     * @param string   $databaseName   Name of database under test
+     * @param string   $collectionName Name of collection under test
+     */
+    public function testCrud(stdClass $test, array $runOn = null, array $data, $databaseName = null, $collectionName = null)
+    {
+        if (isset(self::$incompleteTests[$this->dataDescription()])) {
+            $this->markTestIncomplete(self::$incompleteTests[$this->dataDescription()]);
+        }
+
+        if (isset($runOn)) {
+            $this->checkServerRequirements($runOn);
+        }
+
+        if (isset($test->skipReason)) {
+            $this->markTestSkipped($test->skipReason);
+        }
+
+        $databaseName = $databaseName ?? $this->getDatabaseName();
+        $collectionName = $collectionName ?? $this->getCollectionName();
+
+        $context = Context::fromCrud($test, $databaseName, $collectionName);
+        $this->setContext($context);
+
+        $this->dropTestAndOutcomeCollections();
+        $this->insertDataFixtures($data);
+
+        if (isset($test->failPoint)) {
+            $this->configureFailPoint($test->failPoint);
+        }
+
+        if (isset($test->expectations)) {
+            $commandExpectations = CommandExpectations::fromCrud((array) $test->expectations);
+            $commandExpectations->startMonitoring();
+        }
+
+        foreach ($test->operations as $operation) {
+            Operation::fromCrud($operation)->assert($this, $context);
+        }
+
+        if (isset($commandExpectations)) {
+            $commandExpectations->stopMonitoring();
+            $commandExpectations->assert($this, $context);
+        }
+
+        if (isset($test->outcome->collection->data)) {
+            $this->assertOutcomeCollectionData($test->outcome->collection->data);
+        }
+    }
+
+    public function provideTests()
+    {
+        $testArgs = [];
+
+        foreach (glob(__DIR__ . '/crud/*.json') as $filename) {
+            $json = $this->decodeJson(file_get_contents($filename));
+            $group = basename($filename, '.json');
+            $runOn = $json->runOn ?? null;
+            $data = $json->data ?? [];
+            $databaseName = $json->database_name ?? null;
+            $collectionName = $json->collection_name ?? null;
+
+            foreach ($json->tests as $test) {
+                $name = $group . ': ' . $test->description;
+                $testArgs[$name] = [$test, $runOn, $data, $databaseName, $collectionName];
+            }
+        }
+
+        return $testArgs;
+    }
+
+    /**
+     * Prose test 1: "errInfo" is propagated
+     */
+    public function testErrInfoIsPropagated()
+    {
+        $runOn = [(object) ['minServerVersion' => '4.0.0']];
+        $this->checkServerRequirements($runOn);
+
+        $errInfo = (object) [
+            'writeConcern' => (object) [
+                'w' => 2,
+                'wtimeout' => 0,
+                'provenance' => 'clientSupplied',
+            ],
+        ];
+
+        $this->configureFailPoint([
+            'configureFailPoint' => 'failCommand',
+            'mode' => ['times' => 1],
+            'data' => [
+                'failCommands' => ['insert'],
+                'writeConcernError' => [
+                    'code' => 100,
+                    'codeName' => 'UnsatisfiableWriteConcern',
+                    'errmsg' => 'Not enough data-bearing nodes',
+                    'errInfo' => $errInfo,
+                ],
+            ],
+        ]);
+
+        $client = new Client(static::getUri());
+
+        try {
+            $client->selectCollection($this->getDatabaseName(), $this->getCollectionName())->insertOne(['fail' => 1]);
+            $this->fail('Expected insert command to fail');
+        } catch (BulkWriteException $e) {
+            self::assertEquals($errInfo, $e->getWriteResult()->getWriteConcernError()->getInfo());
+        }
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/DocumentsMatchConstraint.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/DocumentsMatchConstraint.php
new file mode 100644
index 0000000000000000000000000000000000000000..cfce06d89f7153560d38dfdfbc28aa105c5cdb88
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/DocumentsMatchConstraint.php	
@@ -0,0 +1,458 @@
+<?php
+
+namespace MongoDB\Tests\SpecTests;
+
+use ArrayObject;
+use InvalidArgumentException;
+use MongoDB\BSON\BinaryInterface;
+use MongoDB\BSON\DBPointer;
+use MongoDB\BSON\Decimal128;
+use MongoDB\BSON\Int64;
+use MongoDB\BSON\Javascript;
+use MongoDB\BSON\MaxKey;
+use MongoDB\BSON\MinKey;
+use MongoDB\BSON\ObjectId;
+use MongoDB\BSON\Regex;
+use MongoDB\BSON\Symbol;
+use MongoDB\BSON\Timestamp;
+use MongoDB\BSON\Undefined;
+use MongoDB\BSON\UTCDateTime;
+use MongoDB\Model\BSONArray;
+use MongoDB\Model\BSONDocument;
+use PHPUnit\Framework\Constraint\Constraint;
+use PHPUnit\Framework\Constraint\IsInstanceOf;
+use PHPUnit\Framework\Constraint\IsNull;
+use PHPUnit\Framework\Constraint\IsType;
+use PHPUnit\Framework\Constraint\LogicalAnd;
+use PHPUnit\Framework\Constraint\LogicalNot;
+use PHPUnit\Framework\Constraint\LogicalOr;
+use RuntimeException;
+use SebastianBergmann\Comparator\ComparisonFailure;
+use SebastianBergmann\Comparator\Factory;
+use stdClass;
+use Symfony\Bridge\PhpUnit\ConstraintTrait;
+use function array_values;
+use function get_class;
+use function get_debug_type;
+use function in_array;
+use function is_array;
+use function is_object;
+use function is_scalar;
+use function method_exists;
+use function sprintf;
+use const PHP_INT_SIZE;
+
+/**
+ * Constraint that checks if one document matches another.
+ *
+ * The expected value is passed in the constructor.
+ */
+class DocumentsMatchConstraint extends Constraint
+{
+    use ConstraintTrait;
+
+    /** @var boolean */
+    private $ignoreExtraKeysInRoot = false;
+
+    /** @var boolean */
+    private $ignoreExtraKeysInEmbedded = false;
+
+    /** @var array */
+    private $placeholders = [];
+
+    /**
+     * TODO: This is not currently used, but was preserved from the design of
+     * TestCase::assertMatchesDocument(), which would sort keys and then compare
+     * documents as JSON strings. If the TODO item in matches() is implemented
+     * to make document comparisons more efficient, we may consider supporting
+     * this option.
+     *
+     * @var boolean
+     */
+    private $sortKeys = false;
+
+    /** @var BSONArray|BSONDocument */
+    private $value;
+
+    /** @var ComparisonFailure|null */
+    private $lastFailure;
+
+    /** @var Factory */
+    private $comparatorFactory;
+
+    /**
+     * Creates a new constraint.
+     *
+     * @param array|object $value
+     * @param boolean      $ignoreExtraKeysInRoot     If true, ignore extra keys within the root document
+     * @param boolean      $ignoreExtraKeysInEmbedded If true, ignore extra keys within embedded documents
+     * @param array        $placeholders              Placeholders for any value
+     */
+    public function __construct($value, $ignoreExtraKeysInRoot = false, $ignoreExtraKeysInEmbedded = false, array $placeholders = [])
+    {
+        $this->value = $this->prepareBSON($value, true, $this->sortKeys);
+        $this->ignoreExtraKeysInRoot = $ignoreExtraKeysInRoot;
+        $this->ignoreExtraKeysInEmbedded = $ignoreExtraKeysInEmbedded;
+        $this->placeholders = $placeholders;
+        $this->comparatorFactory = Factory::getInstance();
+    }
+
+    private function doEvaluate($other, $description = '', $returnResult = false)
+    {
+        /* TODO: If ignoreExtraKeys and sortKeys are both false, then we may be
+         * able to skip preparation, convert both documents to extended JSON,
+         * and compare strings.
+         *
+         * If ignoreExtraKeys is false and sortKeys is true, we still be able to
+         * compare JSON strings but will still require preparation to sort keys
+         * in all documents and sub-documents. */
+        $other = $this->prepareBSON($other, true, $this->sortKeys);
+
+        $success = false;
+        $this->lastFailure = null;
+
+        try {
+            $this->assertEquals($this->value, $other, $this->ignoreExtraKeysInRoot);
+            $success = true;
+        } catch (RuntimeException $e) {
+            $this->lastFailure = new ComparisonFailure(
+                $this->value,
+                $other,
+                $this->exporter()->export($this->value),
+                $this->exporter()->export($other),
+                false,
+                $e->getMessage()
+            );
+        }
+
+        if ($returnResult) {
+            return $success;
+        }
+
+        if (! $success) {
+            $this->fail($other, $description, $this->lastFailure);
+        }
+    }
+
+    /**
+     * @param string $expectedType
+     * @param mixed  $actualValue
+     */
+    private function assertBSONType($expectedType, $actualValue)
+    {
+        switch ($expectedType) {
+            case 'double':
+                (new IsType('float'))->evaluate($actualValue);
+
+                return;
+            case 'string':
+                (new IsType('string'))->evaluate($actualValue);
+
+                return;
+            case 'object':
+                $constraints = [
+                    new IsType('object'),
+                    new LogicalNot(new IsInstanceOf(BSONArray::class)),
+                ];
+
+                // LogicalAnd::fromConstraints was introduced in PHPUnit 6.5.0.
+                // This check can be removed when the PHPUnit dependency is bumped to that version
+                if (method_exists(LogicalAnd::class, 'fromConstraints')) {
+                    $constraint = LogicalAnd::fromConstraints(...$constraints);
+                } else {
+                    $constraint = new LogicalAnd();
+                    $constraint->setConstraints($constraints);
+                }
+
+                $constraint->evaluate($actualValue);
+
+                return;
+            case 'array':
+                $constraints = [
+                    new IsType('array'),
+                    new IsInstanceOf(BSONArray::class),
+                ];
+
+                // LogicalOr::fromConstraints was introduced in PHPUnit 6.5.0.
+                // This check can be removed when the PHPUnit dependency is bumped to that version
+                if (method_exists(LogicalOr::class, 'fromConstraints')) {
+                    $constraint = LogicalOr::fromConstraints(...$constraints);
+                } else {
+                    $constraint = new LogicalOr();
+                    $constraint->setConstraints($constraints);
+                }
+
+                $constraint->evaluate($actualValue);
+
+                return;
+            case 'binData':
+                (new IsInstanceOf(BinaryInterface::class))->evaluate($actualValue);
+
+                return;
+            case 'undefined':
+                (new IsInstanceOf(Undefined::class))->evaluate($actualValue);
+
+                return;
+            case 'objectId':
+                (new IsInstanceOf(ObjectId::class))->evaluate($actualValue);
+
+                return;
+            case 'boolean':
+                (new IsType('bool'))->evaluate($actualValue);
+
+                return;
+            case 'date':
+                (new IsInstanceOf(UTCDateTime::class))->evaluate($actualValue);
+
+                return;
+            case 'null':
+                (new IsNull())->evaluate($actualValue);
+
+                return;
+            case 'regex':
+                (new IsInstanceOf(Regex::class))->evaluate($actualValue);
+
+                return;
+            case 'dbPointer':
+                (new IsInstanceOf(DBPointer::class))->evaluate($actualValue);
+
+                return;
+            case 'javascript':
+                (new IsInstanceOf(Javascript::class))->evaluate($actualValue);
+
+                return;
+            case 'symbol':
+                (new IsInstanceOf(Symbol::class))->evaluate($actualValue);
+
+                return;
+            case 'int':
+                (new IsType('int'))->evaluate($actualValue);
+
+                return;
+            case 'timestamp':
+                (new IsInstanceOf(Timestamp::class))->evaluate($actualValue);
+
+                return;
+            case 'long':
+                if (PHP_INT_SIZE == 4) {
+                    (new IsInstanceOf(Int64::class))->evaluate($actualValue);
+                } else {
+                    (new IsType('int'))->evaluate($actualValue);
+                }
+
+                return;
+            case 'decimal':
+                (new IsInstanceOf(Decimal128::class))->evaluate($actualValue);
+
+                return;
+            case 'minKey':
+                (new IsInstanceOf(MinKey::class))->evaluate($actualValue);
+
+                return;
+            case 'maxKey':
+                (new IsInstanceOf(MaxKey::class))->evaluate($actualValue);
+
+                return;
+        }
+    }
+
+    /**
+     * Compares two documents recursively.
+     *
+     * @param ArrayObject $expected
+     * @param ArrayObject $actual
+     * @param boolean     $ignoreExtraKeys
+     * @param string      $keyPrefix
+     * @throws RuntimeException if the documents do not match
+     */
+    private function assertEquals(ArrayObject $expected, ArrayObject $actual, $ignoreExtraKeys, $keyPrefix = '')
+    {
+        if (get_class($expected) !== get_class($actual)) {
+            throw new RuntimeException(sprintf(
+                '%s is not instance of expected class "%s"',
+                $this->exporter()->shortenedExport($actual),
+                get_class($expected)
+            ));
+        }
+
+        foreach ($expected as $key => $expectedValue) {
+            $actualHasKey = $actual->offsetExists($key);
+
+            if (! $actualHasKey) {
+                throw new RuntimeException(sprintf('$actual is missing key: "%s"', $keyPrefix . $key));
+            }
+
+            if (in_array($expectedValue, $this->placeholders, true)) {
+                continue;
+            }
+
+            $actualValue = $actual[$key];
+
+            if ($expectedValue instanceof BSONDocument && isset($expectedValue['$$type'])) {
+                $this->assertBSONType($expectedValue['$$type'], $actualValue);
+                continue;
+            }
+
+            if (($expectedValue instanceof BSONArray && $actualValue instanceof BSONArray) ||
+                ($expectedValue instanceof BSONDocument && $actualValue instanceof BSONDocument)) {
+                $this->assertEquals($expectedValue, $actualValue, $this->ignoreExtraKeysInEmbedded, $keyPrefix . $key . '.');
+                continue;
+            }
+
+            if (is_scalar($expectedValue) && is_scalar($actualValue)) {
+                if ($expectedValue !== $actualValue) {
+                    throw new ComparisonFailure(
+                        $expectedValue,
+                        $actualValue,
+                        '',
+                        '',
+                        false,
+                        sprintf('Field path "%s": %s', $keyPrefix . $key, 'Failed asserting that two values are equal.')
+                    );
+                }
+
+                continue;
+            }
+
+            $expectedType = get_debug_type($expectedValue);
+            $actualType = get_debug_type($actualValue);
+
+            // Workaround for ObjectComparator printing the whole actual object
+            if ($expectedType !== $actualType) {
+                throw new ComparisonFailure(
+                    $expectedValue,
+                    $actualValue,
+                    '',
+                    '',
+                    false,
+                    sprintf(
+                        'Field path "%s": %s is not instance of expected type "%s".',
+                        $keyPrefix . $key,
+                        $this->exporter()->shortenedExport($actualValue),
+                        $expectedType
+                    )
+                );
+            }
+
+            try {
+                $this->comparatorFactory->getComparatorFor($expectedValue, $actualValue)->assertEquals($expectedValue, $actualValue);
+            } catch (ComparisonFailure $failure) {
+                throw new ComparisonFailure(
+                    $expectedValue,
+                    $actualValue,
+                    '',
+                    '',
+                    false,
+                    sprintf('Field path "%s": %s', $keyPrefix . $key, $failure->getMessage())
+                );
+            }
+        }
+
+        if ($ignoreExtraKeys) {
+            return;
+        }
+
+        foreach ($actual as $key => $value) {
+            if (! $expected->offsetExists($key)) {
+                throw new RuntimeException(sprintf('$actual has extra key: "%s"', $keyPrefix . $key));
+            }
+        }
+    }
+
+    private function doAdditionalFailureDescription($other)
+    {
+        if ($this->lastFailure === null) {
+            return '';
+        }
+
+        return $this->lastFailure->getMessage();
+    }
+
+    private function doFailureDescription($other)
+    {
+        return 'two BSON objects are equal';
+    }
+
+    private function doMatches($other)
+    {
+        /* TODO: If ignoreExtraKeys and sortKeys are both false, then we may be
+         * able to skip preparation, convert both documents to extended JSON,
+         * and compare strings.
+         *
+         * If ignoreExtraKeys is false and sortKeys is true, we still be able to
+         * compare JSON strings but will still require preparation to sort keys
+         * in all documents and sub-documents. */
+        $other = $this->prepareBSON($other, true, $this->sortKeys);
+
+        try {
+            $this->assertEquals($this->value, $other, $this->ignoreExtraKeysInRoot);
+        } catch (RuntimeException $e) {
+            return false;
+        }
+
+        return true;
+    }
+
+    private function doToString()
+    {
+        return 'matches ' . $this->exporter()->export($this->value);
+    }
+
+    /**
+     * Prepare a BSON document or array for comparison.
+     *
+     * The argument will be converted to a BSONArray or BSONDocument based on
+     * its type and keys. Keys within documents will optionally be sorted. Each
+     * value within the array or document will then be prepared recursively.
+     *
+     * @param array|object $bson
+     * @param boolean      $isRoot   If true, ensure an array value is converted to a document
+     * @param boolean      $sortKeys
+     * @return BSONDocument|BSONArray
+     * @throws InvalidArgumentException if $bson is not an array or object
+     */
+    private function prepareBSON($bson, $isRoot, $sortKeys = false)
+    {
+        if (! is_array($bson) && ! is_object($bson)) {
+            throw new InvalidArgumentException('$bson is not an array or object');
+        }
+
+        if ($isRoot && is_array($bson)) {
+            $bson = (object) $bson;
+        }
+
+        if ($bson instanceof BSONArray || (is_array($bson) && $bson === array_values($bson))) {
+            if (! $bson instanceof BSONArray) {
+                $bson = new BSONArray($bson);
+            }
+        } else {
+            if (! $bson instanceof BSONDocument) {
+                $bson = new BSONDocument((array) $bson);
+            }
+
+            if ($sortKeys) {
+                $bson->ksort();
+            }
+        }
+
+        foreach ($bson as $key => $value) {
+            if ($value instanceof BSONArray || (is_array($value) && $value === array_values($value))) {
+                $bson[$key] = $this->prepareBSON($value, false, $sortKeys);
+                continue;
+            }
+
+            if ($value instanceof BSONDocument || $value instanceof stdClass || is_array($value)) {
+                $bson[$key] = $this->prepareBSON($value, false, $sortKeys);
+                continue;
+            }
+
+            /* Convert Int64 objects to integers on 64-bit platforms for
+             * compatibility reasons. */
+            if ($value instanceof Int64 && PHP_INT_SIZE != 4) {
+                $bson[$key] = (int) ((string) $value);
+            }
+        }
+
+        return $bson;
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/DocumentsMatchConstraintTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/DocumentsMatchConstraintTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..1d4abddfe58df8cac918151f23a0949076bcfb41
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/DocumentsMatchConstraintTest.php	
@@ -0,0 +1,168 @@
+<?php
+
+namespace MongoDB\Tests\SpecTests;
+
+use MongoDB\BSON\Binary;
+use MongoDB\BSON\Decimal128;
+use MongoDB\BSON\Javascript;
+use MongoDB\BSON\MaxKey;
+use MongoDB\BSON\MinKey;
+use MongoDB\BSON\ObjectId;
+use MongoDB\BSON\Regex;
+use MongoDB\BSON\Timestamp;
+use MongoDB\BSON\UTCDateTime;
+use MongoDB\Model\BSONArray;
+use MongoDB\Model\BSONDocument;
+use MongoDB\Tests\TestCase;
+use PHPUnit\Framework\ExpectationFailedException;
+use function MongoDB\BSON\fromJSON;
+use function MongoDB\BSON\toPHP;
+use function unserialize;
+use const PHP_INT_SIZE;
+
+class DocumentsMatchConstraintTest extends TestCase
+{
+    public function testIgnoreExtraKeysInRoot()
+    {
+        $c = new DocumentsMatchConstraint(['x' => 1, 'y' => ['a' => 1, 'b' => 2]], true, false);
+
+        $this->assertResult(false, $c, ['x' => 1, 'y' => 2], 'Incorrect value');
+        $this->assertResult(true, $c, ['x' => 1, 'y' => ['a' => 1, 'b' => 2]], 'Exact match');
+        $this->assertResult(true, $c, ['x' => 1, 'y' => ['a' => 1, 'b' => 2], 'z' => 3], 'Extra keys in root are permitted');
+        $this->assertResult(false, $c, ['x' => 1, 'y' => ['a' => 1, 'b' => 2, 'c' => 3]], 'Extra keys in embedded are not permitted');
+        $this->assertResult(true, $c, ['y' => ['b' => 2, 'a' => 1], 'x' => 1], 'Root and embedded key order is not significant');
+
+        // Arrays are always interpreted as root documents
+        $c = new DocumentsMatchConstraint([1, ['a' => 1]], true, false);
+
+        $this->assertResult(false, $c, [1, 2], 'Incorrect value');
+        $this->assertResult(true, $c, [1, ['a' => 1]], 'Exact match');
+        $this->assertResult(true, $c, [1, ['a' => 1], 3], 'Extra keys in root are permitted');
+        $this->assertResult(false, $c, [1, ['a' => 1, 'b' => 2]], 'Extra keys in embedded are not permitted');
+    }
+
+    public function testIgnoreExtraKeysInEmbedded()
+    {
+        $c = new DocumentsMatchConstraint(['x' => 1, 'y' => ['a' => 1, 'b' => 2]], false, true);
+
+        $this->assertResult(false, $c, ['x' => 1, 'y' => 2], 'Incorrect value');
+        $this->assertResult(false, $c, ['x' => 1, 'y' => ['a' => 1, 'b' => 3]], 'Incorrect value');
+        $this->assertResult(true, $c, ['x' => 1, 'y' => ['a' => 1, 'b' => 2]], 'Exact match');
+        $this->assertResult(false, $c, ['x' => 1, 'y' => ['a' => 1, 'b' => 2], 'z' => 3], 'Extra keys in root are not permitted');
+        $this->assertResult(true, $c, ['x' => 1, 'y' => ['a' => 1, 'b' => 2, 'c' => 3]], 'Extra keys in embedded are permitted');
+        $this->assertResult(true, $c, ['y' => ['b' => 2, 'a' => 1], 'x' => 1], 'Root and embedded Key order is not significant');
+
+        // Arrays are always interpreted as root documents
+        $c = new DocumentsMatchConstraint([1, ['a' => 1]], false, true);
+
+        $this->assertResult(false, $c, [1, 2], 'Incorrect value');
+        $this->assertResult(true, $c, [1, ['a' => 1]], 'Exact match');
+        $this->assertResult(false, $c, [1, ['a' => 1], 3], 'Extra keys in root are not permitted');
+        $this->assertResult(true, $c, [1, ['a' => 1, 'b' => 2]], 'Extra keys in embedded are permitted');
+        $this->assertResult(false, $c, [1, ['a' => 2]], 'Keys must have the correct value');
+    }
+
+    public function testPlaceholders()
+    {
+        $c = new DocumentsMatchConstraint(['x' => '42', 'y' => 42, 'z' => ['a' => 24]], false, false, [24, 42]);
+
+        $this->assertResult(true, $c, ['x' => '42', 'y' => 'foo', 'z' => ['a' => 1]], 'Placeholders accept any value');
+        $this->assertResult(false, $c, ['x' => 42, 'y' => 'foo', 'z' => ['a' => 1]], 'Placeholder type must match');
+        $this->assertResult(true, $c, ['x' => '42', 'y' => 42, 'z' => ['a' => 24]], 'Exact match');
+    }
+
+    /**
+     * @dataProvider provideBSONTypes
+     */
+    public function testBSONTypeAssertions($type, $value)
+    {
+        $constraint = new DocumentsMatchConstraint(['x' => ['$$type' => $type]]);
+
+        $this->assertResult(true, $constraint, ['x' => $value], 'Type matches');
+    }
+
+    public function provideBSONTypes()
+    {
+        $undefined = toPHP(fromJSON('{ "undefined": {"$undefined": true} }'));
+        $symbol = toPHP(fromJSON('{ "symbol": {"$symbol": "test"} }'));
+        $dbPointer = toPHP(fromJSON('{ "dbPointer": {"$dbPointer": {"$ref": "phongo.test", "$id" : { "$oid" : "5a2e78accd485d55b405ac12" }  }} }'));
+
+        return [
+            'double' => ['double', 1.4],
+            'string' => ['string', 'foo'],
+            'object' => ['object', new BSONDocument()],
+            'array' => ['array', ['foo']],
+            'binData' => ['binData', new Binary('', 0)],
+            'undefined' => ['undefined', $undefined->undefined],
+            'objectId' => ['objectId', new ObjectId()],
+            'boolean' => ['boolean', true],
+            'date' => ['date', new UTCDateTime()],
+            'null' => ['null', null],
+            'regex' => ['regex', new Regex('.*')],
+            'dbPointer' => ['dbPointer', $dbPointer->dbPointer],
+            'javascript' => ['javascript', new Javascript('foo = 1;')],
+            'symbol' => ['symbol', $symbol->symbol],
+            'int' => ['int', 1],
+            'timestamp' => ['timestamp', new Timestamp(0, 0)],
+            'long' => ['long', PHP_INT_SIZE == 4 ? unserialize('C:18:"MongoDB\BSON\Int64":38:{a:1:{s:7:"integer";s:10:"4294967296";}}') : 4294967296],
+            'decimal' => ['decimal', new Decimal128('18446744073709551616')],
+            'minKey' => ['minKey', new MinKey()],
+            'maxKey' => ['maxKey', new MaxKey()],
+        ];
+    }
+
+    /**
+     * @dataProvider errorMessageProvider
+     */
+    public function testErrorMessages($expectedMessagePart, DocumentsMatchConstraint $constraint, $actualValue)
+    {
+        try {
+            $constraint->evaluate($actualValue);
+            $this->fail('Expected a comparison failure');
+        } catch (ExpectationFailedException $failure) {
+            $this->assertStringContainsString('Failed asserting that two BSON objects are equal.', $failure->getMessage());
+            $this->assertStringContainsString($expectedMessagePart, $failure->getMessage());
+        }
+    }
+
+    public function errorMessageProvider()
+    {
+        return [
+            'Root type mismatch' => [
+                'MongoDB\Model\BSONArray Object (...) is not instance of expected class "MongoDB\Model\BSONDocument"',
+                new DocumentsMatchConstraint(['foo' => 'bar']),
+                new BSONArray(['foo' => 'bar']),
+            ],
+            'Missing key' => [
+                '$actual is missing key: "foo.bar"',
+                new DocumentsMatchConstraint(['foo' => ['bar' => 'baz']]),
+                ['foo' => ['foo' => 'bar']],
+            ],
+            'Extra key' => [
+                '$actual has extra key: "foo.foo"',
+                new DocumentsMatchConstraint(['foo' => ['bar' => 'baz']]),
+                ['foo' => ['foo' => 'bar', 'bar' => 'baz']],
+            ],
+            'Scalar value not equal' => [
+                'Field path "foo": Failed asserting that two values are equal.',
+                new DocumentsMatchConstraint(['foo' => 'bar']),
+                ['foo' => 'baz'],
+            ],
+            'Scalar type mismatch' => [
+                'Field path "foo": Failed asserting that two values are equal.',
+                new DocumentsMatchConstraint(['foo' => 42]),
+                ['foo' => '42'],
+            ],
+            'Type mismatch' => [
+                'Field path "foo": MongoDB\Model\BSONDocument Object (...) is not instance of expected type "MongoDB\Model\BSONArray".',
+                new DocumentsMatchConstraint(['foo' => ['bar']]),
+                ['foo' => (object) ['bar']],
+            ],
+        ];
+    }
+
+    private function assertResult($expectedResult, DocumentsMatchConstraint $constraint, $value, $message)
+    {
+        $this->assertSame($expectedResult, $constraint->evaluate($value, '', true), $message);
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/ErrorExpectation.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/ErrorExpectation.php
new file mode 100644
index 0000000000000000000000000000000000000000..6e0c03806a170d8bbc05906ae0b3f8e669f3b9ef
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/ErrorExpectation.php	
@@ -0,0 +1,284 @@
+<?php
+
+namespace MongoDB\Tests\SpecTests;
+
+use Exception;
+use MongoDB\Driver\Exception\BulkWriteException;
+use MongoDB\Driver\Exception\CommandException;
+use MongoDB\Driver\Exception\ExecutionTimeoutException;
+use MongoDB\Driver\Exception\RuntimeException;
+use MongoDB\Exception\InvalidArgumentException;
+use MongoDB\Tests\TestCase;
+use stdClass;
+use Throwable;
+use function get_class;
+use function is_array;
+use function is_string;
+use function sprintf;
+
+/**
+ * Spec test operation error expectation.
+ */
+final class ErrorExpectation
+{
+    /**
+     * @see https://github.com/mongodb/mongo/blob/master/src/mongo/base/error_codes.err
+     *
+     * @var array
+     */
+    private static $codeNameMap = [
+        'Interrupted' => 11601,
+        'MaxTimeMSExpired' => 50,
+        'NoSuchTransaction' => 251,
+        'OperationNotSupportedInTransaction' => 263,
+        'WriteConflict' => 112,
+    ];
+
+    /** @var integer */
+    private $code;
+
+    /** @var string */
+    private $codeName;
+
+    /** @var boolean */
+    private $isExpected = false;
+
+    /** @var string[] */
+    private $excludedLabels = [];
+
+    /** @var string[] */
+    private $includedLabels = [];
+
+    /** @var string */
+    private $messageContains;
+
+    private function __construct()
+    {
+    }
+
+    public static function fromChangeStreams(stdClass $result)
+    {
+        $o = new self();
+
+        if (isset($result->error->code)) {
+            $o->code = $result->error->code;
+            $o->isExpected = true;
+        }
+
+        if (isset($result->error->errorLabels)) {
+            if (! self::isArrayOfStrings($result->error->errorLabels)) {
+                throw InvalidArgumentException::invalidType('errorLabels', $result->error->errorLabels, 'string[]');
+            }
+            $o->includedLabels = $result->error->errorLabels;
+            $o->isExpected = true;
+        }
+
+        return $o;
+    }
+
+    public static function fromClientSideEncryption(stdClass $operation)
+    {
+        return self::fromGenericOperation($operation);
+    }
+
+    public static function fromCrud(stdClass $result)
+    {
+        $o = new self();
+
+        if (isset($result->error)) {
+            $o->isExpected = $result->error;
+        }
+
+        return $o;
+    }
+
+    public static function fromReadWriteConcern(stdClass $operation)
+    {
+        return self::fromGenericOperation($operation);
+    }
+
+    public static function fromRetryableReads(stdClass $operation)
+    {
+        $o = new self();
+
+        if (isset($operation->error)) {
+            $o->isExpected = $operation->error;
+        }
+
+        return $o;
+    }
+
+    public static function fromRetryableWrites(stdClass $outcome)
+    {
+        $o = new self();
+
+        if (isset($outcome->error)) {
+            $o->isExpected = $outcome->error;
+        }
+
+        /* outcome.result will only contain error label assertions if an error
+         * is expected (i.e. outcome.error is true). */
+        if ($o->isExpected && isset($outcome->result->errorLabelsContain)) {
+            if (! self::isArrayOfStrings($outcome->result->errorLabelsContain)) {
+                throw InvalidArgumentException::invalidType('errorLabelsContain', $outcome->result->errorLabelsContain, 'string[]');
+            }
+            $o->includedLabels = $outcome->result->errorLabelsContain;
+        }
+
+        if ($o->isExpected && isset($outcome->result->errorLabelsOmit)) {
+            if (! self::isArrayOfStrings($outcome->result->errorLabelsOmit)) {
+                throw InvalidArgumentException::invalidType('errorLabelsOmit', $outcome->result->errorLabelsOmit, 'string[]');
+            }
+            $o->excludedLabels = $outcome->result->errorLabelsOmit;
+        }
+
+        return $o;
+    }
+
+    /**
+     * @throws InvalidArgumentException
+     */
+    public static function fromTransactions(stdClass $operation)
+    {
+        return self::fromGenericOperation($operation);
+    }
+
+    public static function noError()
+    {
+        return new self();
+    }
+
+    /**
+     * Assert that the error expectation matches the actual outcome.
+     *
+     * @param TestCase       $test   Test instance for performing assertions
+     * @param Exception|null $actual Exception (if any) from the actual outcome
+     */
+    public function assert(TestCase $test, Throwable $actual = null)
+    {
+        if (! $this->isExpected) {
+            if ($actual !== null) {
+                $test->fail(sprintf("Operation threw unexpected %s: %s\n%s", get_class($actual), $actual->getMessage(), $actual->getTraceAsString()));
+            }
+
+            return;
+        }
+
+        $test->assertNotNull($actual);
+
+        if (isset($this->messageContains) && $this->messageContains !== '') {
+            $test->assertStringContainsStringIgnoringCase($this->messageContains, $actual->getMessage());
+        }
+
+        if (isset($this->codeName)) {
+            $this->assertCodeName($test, $actual);
+        }
+
+        if (! empty($this->excludedLabels) || ! empty($this->includedLabels)) {
+            $test->assertInstanceOf(RuntimeException::class, $actual);
+
+            foreach ($this->excludedLabels as $label) {
+                $test->assertFalse($actual->hasErrorLabel($label), 'Exception should not have error label: ' . $label);
+            }
+
+            foreach ($this->includedLabels as $label) {
+                $test->assertTrue($actual->hasErrorLabel($label), 'Exception should have error label: ' . $label);
+            }
+        }
+    }
+
+    public function isExpected()
+    {
+        return $this->isExpected;
+    }
+
+    /**
+     * Assert that the error code name expectation matches the actual outcome.
+     *
+     * @param TestCase       $test   Test instance for performing assertions
+     * @param Exception|null $actual Exception (if any) from the actual outcome
+     */
+    private function assertCodeName(TestCase $test, Throwable $actual = null)
+    {
+        /* BulkWriteException does not expose codeName for server errors. Work
+         * around this be comparing the error code against a map.
+         *
+         * TODO: Remove this once PHPC-1386 is resolved. */
+        if ($actual instanceof BulkWriteException || $actual instanceof ExecutionTimeoutException) {
+            $test->assertArrayHasKey($this->codeName, self::$codeNameMap);
+            $test->assertSame(self::$codeNameMap[$this->codeName], $actual->getCode());
+
+            return;
+        }
+
+        $test->assertInstanceOf(CommandException::class, $actual);
+        $result = $actual->getResultDocument();
+
+        if (isset($result->writeConcernError)) {
+            $test->assertObjectHasAttribute('codeName', $result->writeConcernError);
+            $test->assertSame($this->codeName, $result->writeConcernError->codeName);
+
+            return;
+        }
+
+        $test->assertObjectHasAttribute('codeName', $result);
+        $test->assertSame($this->codeName, $result->codeName);
+    }
+
+    /**
+     * @throws InvalidArgumentException
+     */
+    private static function fromGenericOperation(stdClass $operation)
+    {
+        $o = new self();
+
+        if (isset($operation->error)) {
+            $o->isExpected = $operation->error;
+        }
+
+        $result = $operation->result ?? null;
+
+        if (isset($result->errorContains)) {
+            $o->messageContains = $result->errorContains;
+            $o->isExpected = true;
+        }
+
+        if (isset($result->errorCodeName)) {
+            $o->codeName = $result->errorCodeName;
+            $o->isExpected = true;
+        }
+
+        if (isset($result->errorLabelsContain)) {
+            if (! self::isArrayOfStrings($result->errorLabelsContain)) {
+                throw InvalidArgumentException::invalidType('errorLabelsContain', $result->errorLabelsContain, 'string[]');
+            }
+            $o->includedLabels = $result->errorLabelsContain;
+            $o->isExpected = true;
+        }
+
+        if (isset($result->errorLabelsOmit)) {
+            if (! self::isArrayOfStrings($result->errorLabelsOmit)) {
+                throw InvalidArgumentException::invalidType('errorLabelsOmit', $result->errorLabelsOmit, 'string[]');
+            }
+            $o->excludedLabels = $result->errorLabelsOmit;
+            $o->isExpected = true;
+        }
+
+        return $o;
+    }
+
+    private static function isArrayOfStrings($array)
+    {
+        if (! is_array($array)) {
+            return false;
+        }
+
+        foreach ($array as $string) {
+            if (! is_string($string)) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/FunctionalTestCase.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/FunctionalTestCase.php
new file mode 100644
index 0000000000000000000000000000000000000000..1c0a76803ec4be0b8de23d4408e344e8a5979f6f
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/FunctionalTestCase.php	
@@ -0,0 +1,305 @@
+<?php
+
+namespace MongoDB\Tests\SpecTests;
+
+use ArrayIterator;
+use IteratorIterator;
+use LogicException;
+use MongoDB\Collection;
+use MongoDB\Driver\Server;
+use MongoDB\Tests\FunctionalTestCase as BaseFunctionalTestCase;
+use MultipleIterator;
+use PHPUnit\Framework\SkippedTest;
+use stdClass;
+use Symfony\Bridge\PhpUnit\SetUpTearDownTrait;
+use UnexpectedValueException;
+use function in_array;
+use function json_encode;
+use function MongoDB\BSON\fromJSON;
+use function MongoDB\BSON\toPHP;
+use function sprintf;
+use function version_compare;
+
+/**
+ * Base class for spec test runners.
+ *
+ * @see https://github.com/mongodb/specifications
+ */
+class FunctionalTestCase extends BaseFunctionalTestCase
+{
+    use SetUpTearDownTrait;
+
+    const TOPOLOGY_SINGLE = 'single';
+    const TOPOLOGY_REPLICASET = 'replicaset';
+    const TOPOLOGY_SHARDED = 'sharded';
+
+    /** @var Context|null */
+    private $context;
+
+    private function doSetUp()
+    {
+        parent::setUp();
+
+        $this->context = null;
+    }
+
+    private function doTearDown()
+    {
+        $this->context = null;
+
+        parent::tearDown();
+    }
+
+    /**
+     * Assert that the expected and actual command documents match.
+     *
+     * Note: Spec tests that do not assert command started events may throw an
+     * exception in lieu of implementing this method.
+     *
+     * @param stdClass $expectedCommand Expected command document
+     * @param stdClass $actualCommand   Actual command document
+     */
+    public static function assertCommandMatches(stdClass $expected, stdClass $actual)
+    {
+        throw new LogicException(sprintf('%s does not assert CommandStartedEvents', static::class));
+    }
+
+    /**
+     * Assert that the expected and actual command reply documents match.
+     *
+     * Note: Spec tests that do not assert command started events may throw an
+     * exception in lieu of implementing this method.
+     *
+     * @param stdClass $expected Expected command reply document
+     * @param stdClass $actual   Actual command reply document
+     */
+    public static function assertCommandReplyMatches(stdClass $expected, stdClass $actual)
+    {
+        throw new LogicException(sprintf('%s does not assert CommandSucceededEvents', static::class));
+    }
+
+    /**
+     * Asserts that two given documents match.
+     *
+     * Extra keys in the actual value's document(s) will be ignored.
+     *
+     * @param array|object $expectedDocument
+     * @param array|object $actualDocument
+     * @param string       $message
+     */
+    protected static function assertDocumentsMatch($expectedDocument, $actualDocument, $message = '')
+    {
+        $constraint = new DocumentsMatchConstraint($expectedDocument, true, true);
+
+        static::assertThat($actualDocument, $constraint, $message);
+    }
+
+    /**
+     * Assert data within the outcome collection.
+     *
+     * @param array $expectedDocuments
+     * @param int   $resultExpectation
+     */
+    protected function assertOutcomeCollectionData(array $expectedDocuments, $resultExpectation = ResultExpectation::ASSERT_SAME_DOCUMENT)
+    {
+        $outcomeCollection = $this->getOutcomeCollection($this->getContext()->outcomeReadOptions);
+
+        $mi = new MultipleIterator(MultipleIterator::MIT_NEED_ANY);
+        $mi->attachIterator(new ArrayIterator($expectedDocuments));
+        $mi->attachIterator(new IteratorIterator($outcomeCollection->find([], ['sort' => ['_id' => 1]])));
+
+        foreach ($mi as $documents) {
+            list($expectedDocument, $actualDocument) = $documents;
+            $this->assertNotNull($expectedDocument);
+            $this->assertNotNull($actualDocument);
+
+            switch ($resultExpectation) {
+                case ResultExpectation::ASSERT_SAME_DOCUMENT:
+                    $this->assertSameDocument($expectedDocument, $actualDocument);
+                    break;
+
+                case ResultExpectation::ASSERT_DOCUMENTS_MATCH:
+                    $this->assertDocumentsMatch($expectedDocument, $actualDocument);
+                    break;
+
+                default:
+                    $this->fail(sprintf('Invalid result expectation "%d" for %s', $resultExpectation, __METHOD__));
+            }
+        }
+    }
+
+    /**
+     * Checks server version and topology requirements.
+     *
+     * @param array $runOn
+     * @throws SkippedTest if the server requirements are not met
+     */
+    protected function checkServerRequirements(array $runOn)
+    {
+        foreach ($runOn as $req) {
+            $minServerVersion = $req->minServerVersion ?? null;
+            $maxServerVersion = $req->maxServerVersion ?? null;
+            $topologies = $req->topology ?? null;
+
+            if ($this->isServerRequirementSatisifed($minServerVersion, $maxServerVersion, $topologies)) {
+                return;
+            }
+        }
+
+        $serverVersion = $this->getServerVersion();
+        $topology = $this->getTopology();
+
+        $this->markTestSkipped(sprintf('Server version "%s" and topology "%s" do not meet test requirements: %s', $serverVersion, $topology, json_encode($runOn)));
+    }
+
+    /**
+     * Decode a JSON spec test.
+     *
+     * This decodes the file through the driver's extended JSON parser to ensure
+     * proper handling of special types.
+     *
+     * @param string $json
+     * @return array
+     */
+    protected function decodeJson($json)
+    {
+        return toPHP(fromJSON($json));
+    }
+
+    /**
+     * Return the test context.
+     *
+     * @return Context
+     * @throws LogicException if the context has not been set
+     */
+    protected function getContext()
+    {
+        if (! $this->context instanceof Context) {
+            throw new LogicException('Context has not been set');
+        }
+
+        return $this->context;
+    }
+
+    /**
+     * Set the test context.
+     *
+     * @param Context $context
+     */
+    protected function setContext(Context $context)
+    {
+        $this->context = $context;
+    }
+
+    /**
+     * Drop the test and outcome collections by dropping them.
+     */
+    protected function dropTestAndOutcomeCollections()
+    {
+        $context = $this->getContext();
+
+        if ($context->databaseName === 'admin') {
+            return;
+        }
+
+        if ($context->bucketName !== null) {
+            $bucket = $context->getGridFSBucket($context->defaultWriteOptions);
+            $bucket->drop();
+        }
+
+        $collection = null;
+        if ($context->collectionName !== null) {
+            $collection = $context->getCollection($context->defaultWriteOptions);
+            $collection->drop();
+        }
+
+        if ($context->outcomeCollectionName !== null) {
+            $outcomeCollection = $this->getOutcomeCollection($context->defaultWriteOptions);
+
+            // Avoid redundant drop if the test and outcome collections are the same
+            if ($collection === null || $outcomeCollection->getNamespace() !== $collection->getNamespace()) {
+                $outcomeCollection->drop();
+            }
+        }
+    }
+
+    /**
+     * Insert data fixtures into the test collection.
+     *
+     * @param array       $documents
+     * @param string|null $collectionName
+     */
+    protected function insertDataFixtures(array $documents, $collectionName = null)
+    {
+        if (empty($documents)) {
+            return;
+        }
+
+        $context = $this->getContext();
+        $collection = $collectionName ? $context->selectCollection($context->databaseName, $collectionName) : $context->getCollection();
+
+        $collection->insertMany($documents, $context->defaultWriteOptions);
+
+        return;
+    }
+
+    private function getOutcomeCollection(array $collectionOptions = [])
+    {
+        $context = $this->getContext();
+
+        // Outcome collection need not use the client under test
+        return new Collection($this->manager, $context->databaseName, $context->outcomeCollectionName, $collectionOptions);
+    }
+
+    /**
+     * Return the corresponding topology constants for the current topology.
+     *
+     * @return string
+     * @throws UnexpectedValueException if topology is neither single nor RS nor sharded
+     */
+    private function getTopology()
+    {
+        $topologyTypeMap = [
+            Server::TYPE_STANDALONE => self::TOPOLOGY_SINGLE,
+            Server::TYPE_RS_PRIMARY => self::TOPOLOGY_REPLICASET,
+            Server::TYPE_MONGOS => self::TOPOLOGY_SHARDED,
+        ];
+
+        $primaryType = $this->getPrimaryServer()->getType();
+
+        if (isset($topologyTypeMap[$primaryType])) {
+            return $topologyTypeMap[$primaryType];
+        }
+
+        throw new UnexpectedValueException('Toplogy is neither single nor RS nor sharded');
+    }
+
+    /**
+     * Checks if server version and topology requirements are satifised.
+     *
+     * @param string|null $minServerVersion
+     * @param string|null $maxServerVersion
+     * @param array|null  $topologies
+     * @return boolean
+     */
+    private function isServerRequirementSatisifed($minServerVersion, $maxServerVersion, array $topologies = null)
+    {
+        $serverVersion = $this->getServerVersion();
+
+        if (isset($minServerVersion) && version_compare($serverVersion, $minServerVersion, '<')) {
+            return false;
+        }
+
+        if (isset($maxServerVersion) && version_compare($serverVersion, $maxServerVersion, '>')) {
+            return false;
+        }
+
+        $topology = $this->getTopology();
+
+        if (isset($topologies) && ! in_array($topology, $topologies)) {
+            return false;
+        }
+
+        return true;
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/Operation.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/Operation.php
new file mode 100644
index 0000000000000000000000000000000000000000..bd34e735fe68f730d622089901063c0cc91e5769
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/Operation.php	
@@ -0,0 +1,854 @@
+<?php
+
+namespace MongoDB\Tests\SpecTests;
+
+use LogicException;
+use MongoDB\Client;
+use MongoDB\Collection;
+use MongoDB\Database;
+use MongoDB\Driver\Cursor;
+use MongoDB\Driver\Exception\BulkWriteException;
+use MongoDB\Driver\Exception\Exception;
+use MongoDB\Driver\Server;
+use MongoDB\Driver\Session;
+use MongoDB\Driver\WriteConcern;
+use MongoDB\GridFS\Bucket;
+use MongoDB\Model\IndexInfo;
+use MongoDB\Operation\FindOneAndReplace;
+use MongoDB\Operation\FindOneAndUpdate;
+use stdClass;
+use function array_diff_key;
+use function array_map;
+use function fclose;
+use function fopen;
+use function iterator_to_array;
+use function MongoDB\is_last_pipeline_operator_write;
+use function MongoDB\with_transaction;
+use function stream_get_contents;
+use function strtolower;
+
+/**
+ * Spec test operation.
+ */
+final class Operation
+{
+    const OBJECT_CLIENT = 'client';
+    const OBJECT_COLLECTION = 'collection';
+    const OBJECT_DATABASE = 'database';
+    const OBJECT_GRIDFS_BUCKET = 'gridfsbucket';
+    const OBJECT_SELECT_COLLECTION = 'selectCollection';
+    const OBJECT_SELECT_DATABASE = 'selectDatabase';
+    const OBJECT_SESSION0 = 'session0';
+    const OBJECT_SESSION1 = 'session1';
+    const OBJECT_TEST_RUNNER = 'testRunner';
+
+    /** @var ErrorExpectation|null */
+    public $errorExpectation;
+
+    /** @var ResultExpectation|null */
+    public $resultExpectation;
+
+    /** @var array */
+    private $arguments = [];
+
+    /** @var string|null */
+    private $collectionName;
+
+    /** @var array */
+    private $collectionOptions = [];
+
+    /** @var string|null */
+    private $databaseName;
+
+    /** @var array */
+    private $databaseOptions = [];
+
+    /** @var string */
+    private $name;
+
+    /** @var string */
+    private $object = self::OBJECT_COLLECTION;
+
+    private function __construct(stdClass $operation)
+    {
+        $this->name = $operation->name;
+
+        if (isset($operation->arguments)) {
+            $this->arguments = (array) $operation->arguments;
+        }
+
+        if (isset($operation->object)) {
+            $this->object = $operation->object;
+        }
+    }
+
+    public static function fromChangeStreams(stdClass $operation)
+    {
+        $o = new self($operation);
+
+        /* Note: change streams only return majority-committed writes, so ensure
+         * each operation applies that write concern. This will avoid spurious
+         * test failures. */
+        $writeConcern = new WriteConcern(WriteConcern::MAJORITY);
+
+        // Expect all operations to succeed
+        $o->errorExpectation = ErrorExpectation::noError();
+
+        /* The Change Streams spec tests include a unique "rename" operation,
+         * which we should convert to a renameCollection command to be run
+         * against the admin database. */
+        if ($operation->name === 'rename') {
+            $o->object = self::OBJECT_SELECT_DATABASE;
+            $o->databaseName = 'admin';
+            $o->name = 'runCommand';
+            $o->arguments = [
+                'command' => [
+                    'renameCollection' => $operation->database . '.' . $operation->collection,
+                    'to' => $operation->database . '.' . $operation->arguments->to,
+                // Note: Database::command() does not inherit WC, so be explicit
+                    'writeConcern' => $writeConcern,
+                ],
+            ];
+
+            return $o;
+        }
+
+        $o->databaseName = $operation->database;
+        $o->collectionName = $operation->collection;
+        $o->collectionOptions = ['writeConcern' => $writeConcern];
+        $o->object = self::OBJECT_SELECT_COLLECTION;
+
+        return $o;
+    }
+
+    public static function fromClientSideEncryption(stdClass $operation)
+    {
+        $o = new self($operation);
+
+        $o->errorExpectation = ErrorExpectation::fromClientSideEncryption($operation);
+        $o->resultExpectation = ResultExpectation::fromClientSideEncryption($operation, $o->getResultAssertionType());
+
+        if (isset($operation->collectionOptions)) {
+            $o->collectionOptions = (array) $operation->collectionOptions;
+        }
+
+        return $o;
+    }
+
+    public static function fromCommandMonitoring(stdClass $operation)
+    {
+        $o = new self($operation);
+
+        if (isset($operation->collectionOptions)) {
+            $o->collectionOptions = (array) $operation->collectionOptions;
+        }
+
+        /* We purposefully avoid setting a default error expectation, because
+         * some tests may trigger a write or command error. */
+
+        return $o;
+    }
+
+    /**
+     * This method is exclusively used to prepare nested operations for the
+     * withTransaction session operation
+     *
+     * @return Operation
+     */
+    private static function fromConvenientTransactions(stdClass $operation)
+    {
+        $o = new self($operation);
+
+        if (isset($operation->error)) {
+            $o->errorExpectation = ErrorExpectation::fromTransactions($operation);
+        }
+
+        $o->resultExpectation = ResultExpectation::fromTransactions($operation, $o->getResultAssertionType());
+
+        if (isset($operation->collectionOptions)) {
+            $o->collectionOptions = (array) $operation->collectionOptions;
+        }
+
+        return $o;
+    }
+
+    public static function fromCrud(stdClass $operation)
+    {
+        $o = new self($operation);
+
+        $o->errorExpectation = ErrorExpectation::fromCrud($operation);
+        $o->resultExpectation = ResultExpectation::fromCrud($operation, $o->getResultAssertionType());
+
+        if (isset($operation->collectionOptions)) {
+            $o->collectionOptions = (array) $operation->collectionOptions;
+        }
+
+        return $o;
+    }
+
+    public static function fromReadWriteConcern(stdClass $operation)
+    {
+        $o = new self($operation);
+
+        $o->errorExpectation = ErrorExpectation::fromReadWriteConcern($operation);
+        $o->resultExpectation = ResultExpectation::fromReadWriteConcern($operation, $o->getResultAssertionType());
+
+        if (isset($operation->databaseOptions)) {
+            $o->databaseOptions = (array) $operation->databaseOptions;
+        }
+
+        if (isset($operation->collectionOptions)) {
+            $o->collectionOptions = (array) $operation->collectionOptions;
+        }
+
+        return $o;
+    }
+
+    public static function fromRetryableReads(stdClass $operation)
+    {
+        $o = new self($operation);
+
+        $o->errorExpectation = ErrorExpectation::fromRetryableReads($operation);
+        $o->resultExpectation = ResultExpectation::fromRetryableReads($operation, $o->getResultAssertionType());
+
+        return $o;
+    }
+
+    public static function fromRetryableWrites(stdClass $operation, stdClass $outcome)
+    {
+        $o = new self($operation);
+
+        $o->errorExpectation = ErrorExpectation::fromRetryableWrites($outcome);
+        $o->resultExpectation = ResultExpectation::fromRetryableWrites($outcome, $o->getResultAssertionType());
+
+        return $o;
+    }
+
+    public static function fromTransactions(stdClass $operation)
+    {
+        $o = new self($operation);
+
+        $o->errorExpectation = ErrorExpectation::fromTransactions($operation);
+        $o->resultExpectation = ResultExpectation::fromTransactions($operation, $o->getResultAssertionType());
+
+        if (isset($operation->collectionOptions)) {
+            $o->collectionOptions = (array) $operation->collectionOptions;
+        }
+
+        return $o;
+    }
+
+    /**
+     * Execute the operation and assert its outcome.
+     *
+     * @param FunctionalTestCase $test             Test instance
+     * @param Context            $context          Execution context
+     * @param bool               $bubbleExceptions If true, any exception that was caught is rethrown
+     */
+    public function assert(FunctionalTestCase $test, Context $context, $bubbleExceptions = false)
+    {
+        $result = null;
+        $exception = null;
+
+        try {
+            $result = $this->execute($test, $context);
+
+            /* Eagerly iterate the results of a cursor. This both allows an
+             * exception to be thrown sooner and ensures that any expected
+             * getMore command(s) can be observed even if a ResultExpectation
+             * is not used (e.g. Command Monitoring spec). */
+            if ($result instanceof Cursor) {
+                $result = $result->toArray();
+            }
+        } catch (Exception $e) {
+            $exception = $e;
+        }
+
+        // Extract incomplete result for failed bulkWrite and insertMany operations
+        if ($exception instanceof BulkWriteException) {
+            $result = $exception->getWriteResult();
+        }
+
+        if (isset($this->errorExpectation)) {
+            $this->errorExpectation->assert($test, $exception);
+        }
+
+        if (isset($this->resultExpectation)) {
+            $this->resultExpectation->assert($test, $result);
+        }
+
+        if ($exception && $bubbleExceptions) {
+            throw $exception;
+        }
+    }
+
+    /**
+     * Executes the operation with a given context.
+     *
+     * @param Context $context Execution context
+     * @return mixed
+     * @throws LogicException if the operation is unsupported
+     */
+    private function execute(FunctionalTestCase $test, Context $context)
+    {
+        switch ($this->object) {
+            case self::OBJECT_CLIENT:
+                $client = $context->getClient();
+
+                return $this->executeForClient($client, $context);
+            case self::OBJECT_COLLECTION:
+                $collection = $context->getCollection($this->collectionOptions, $this->databaseOptions);
+
+                return $this->executeForCollection($collection, $context);
+            case self::OBJECT_DATABASE:
+                $database = $context->getDatabase();
+
+                return $this->executeForDatabase($database, $context);
+            case self::OBJECT_GRIDFS_BUCKET:
+                $bucket = $context->getGridFSBucket();
+
+                return $this->executeForGridFSBucket($bucket, $context);
+            case self::OBJECT_SELECT_COLLECTION:
+                $collection = $context->selectCollection($this->databaseName, $this->collectionName, $this->collectionOptions, $this->databaseOptions);
+
+                return $this->executeForCollection($collection, $context);
+            case self::OBJECT_SELECT_DATABASE:
+                $database = $context->selectDatabase($this->databaseName);
+
+                return $this->executeForDatabase($database, $context);
+            case self::OBJECT_SESSION0:
+                return $this->executeForSession($context->session0, $test, $context);
+            case self::OBJECT_SESSION1:
+                return $this->executeForSession($context->session1, $test, $context);
+            case self::OBJECT_TEST_RUNNER:
+                return $this->executeForTestRunner($test, $context);
+            default:
+                throw new LogicException('Unsupported object: ' . $this->object);
+        }
+    }
+
+    /**
+     * Executes the client operation and return its result.
+     *
+     * @param Client  $client
+     * @param Context $context Execution context
+     * @return mixed
+     * @throws LogicException if the collection operation is unsupported
+     */
+    private function executeForClient(Client $client, Context $context)
+    {
+        $args = $context->prepareOptions($this->arguments);
+        $context->replaceArgumentSessionPlaceholder($args);
+
+        switch ($this->name) {
+            case 'listDatabaseNames':
+                return iterator_to_array($client->listDatabaseNames($args));
+            case 'listDatabases':
+                return $client->listDatabases($args);
+            case 'watch':
+                return $client->watch(
+                    $args['pipeline'] ?? [],
+                    array_diff_key($args, ['pipeline' => 1])
+                );
+            default:
+                throw new LogicException('Unsupported client operation: ' . $this->name);
+        }
+    }
+
+    /**
+     * Executes the collection operation and return its result.
+     *
+     * @param Collection $collection
+     * @param Context    $context    Execution context
+     * @return mixed
+     * @throws LogicException if the collection operation is unsupported
+     */
+    private function executeForCollection(Collection $collection, Context $context)
+    {
+        $args = $context->prepareOptions($this->arguments);
+        $context->replaceArgumentSessionPlaceholder($args);
+
+        switch ($this->name) {
+            case 'aggregate':
+                return $collection->aggregate(
+                    $args['pipeline'],
+                    array_diff_key($args, ['pipeline' => 1])
+                );
+            case 'bulkWrite':
+                // Merge nested and top-level options (see: SPEC-1158)
+                $options = isset($args['options']) ? (array) $args['options'] : [];
+                $options += array_diff_key($args, ['requests' => 1]);
+
+                return $collection->bulkWrite(
+                    // TODO: Check if self can be used with a private static function
+                    array_map([$this, 'prepareBulkWriteRequest'], $args['requests']),
+                    $options
+                );
+            case 'createIndex':
+                return $collection->createIndex(
+                    $args['keys'],
+                    array_diff_key($args, ['keys' => 1])
+                );
+            case 'dropIndex':
+                return $collection->dropIndex(
+                    $args['name'],
+                    array_diff_key($args, ['name' => 1])
+                );
+            case 'count':
+            case 'countDocuments':
+            case 'find':
+                return $collection->{$this->name}(
+                    $args['filter'] ?? [],
+                    array_diff_key($args, ['filter' => 1])
+                );
+            case 'estimatedDocumentCount':
+                return $collection->estimatedDocumentCount($args);
+            case 'deleteMany':
+            case 'deleteOne':
+            case 'findOneAndDelete':
+                return $collection->{$this->name}(
+                    $args['filter'],
+                    array_diff_key($args, ['filter' => 1])
+                );
+            case 'distinct':
+                return $collection->distinct(
+                    $args['fieldName'],
+                    $args['filter'] ?? [],
+                    array_diff_key($args, ['fieldName' => 1, 'filter' => 1])
+                );
+            case 'drop':
+                return $collection->drop($args);
+            case 'findOne':
+                return $collection->findOne($args['filter'], array_diff_key($args, ['filter' => 1]));
+            case 'findOneAndReplace':
+                if (isset($args['returnDocument'])) {
+                    $args['returnDocument'] = 'after' === strtolower($args['returnDocument'])
+                        ? FindOneAndReplace::RETURN_DOCUMENT_AFTER
+                        : FindOneAndReplace::RETURN_DOCUMENT_BEFORE;
+                }
+                // Fall through
+
+            case 'replaceOne':
+                return $collection->{$this->name}(
+                    $args['filter'],
+                    $args['replacement'],
+                    array_diff_key($args, ['filter' => 1, 'replacement' => 1])
+                );
+            case 'findOneAndUpdate':
+                if (isset($args['returnDocument'])) {
+                    $args['returnDocument'] = 'after' === strtolower($args['returnDocument'])
+                        ? FindOneAndUpdate::RETURN_DOCUMENT_AFTER
+                        : FindOneAndUpdate::RETURN_DOCUMENT_BEFORE;
+                }
+                // Fall through
+
+            case 'updateMany':
+            case 'updateOne':
+                return $collection->{$this->name}(
+                    $args['filter'],
+                    $args['update'],
+                    array_diff_key($args, ['filter' => 1, 'update' => 1])
+                );
+            case 'insertMany':
+                // Merge nested and top-level options (see: SPEC-1158)
+                $options = isset($args['options']) ? (array) $args['options'] : [];
+                $options += array_diff_key($args, ['documents' => 1]);
+
+                return $collection->insertMany(
+                    $args['documents'],
+                    $options
+                );
+            case 'insertOne':
+                return $collection->insertOne(
+                    $args['document'],
+                    array_diff_key($args, ['document' => 1])
+                );
+            case 'listIndexes':
+                return $collection->listIndexes($args);
+            case 'mapReduce':
+                return $collection->mapReduce(
+                    $args['map'],
+                    $args['reduce'],
+                    $args['out'],
+                    array_diff_key($args, ['map' => 1, 'reduce' => 1, 'out' => 1])
+                );
+            case 'watch':
+                return $collection->watch(
+                    $args['pipeline'] ?? [],
+                    array_diff_key($args, ['pipeline' => 1])
+                );
+            default:
+                throw new LogicException('Unsupported collection operation: ' . $this->name);
+        }
+    }
+
+    /**
+     * Executes the database operation and return its result.
+     *
+     * @param Database $database
+     * @param Context  $context  Execution context
+     * @return mixed
+     * @throws LogicException if the database operation is unsupported
+     */
+    private function executeForDatabase(Database $database, Context $context)
+    {
+        $args = $context->prepareOptions($this->arguments);
+        $context->replaceArgumentSessionPlaceholder($args);
+
+        switch ($this->name) {
+            case 'aggregate':
+                return $database->aggregate(
+                    $args['pipeline'],
+                    array_diff_key($args, ['pipeline' => 1])
+                );
+            case 'createCollection':
+                return $database->createCollection(
+                    $args['collection'],
+                    array_diff_key($args, ['collection' => 1])
+                );
+            case 'dropCollection':
+                return $database->dropCollection(
+                    $args['collection'],
+                    array_diff_key($args, ['collection' => 1])
+                );
+            case 'listCollectionNames':
+                return iterator_to_array($database->listCollectionNames($args));
+            case 'listCollections':
+                return $database->listCollections($args);
+            case 'runCommand':
+                return $database->command(
+                    $args['command'],
+                    array_diff_key($args, ['command' => 1])
+                )->toArray()[0];
+            case 'watch':
+                return $database->watch(
+                    $args['pipeline'] ?? [],
+                    array_diff_key($args, ['pipeline' => 1])
+                );
+            default:
+                throw new LogicException('Unsupported database operation: ' . $this->name);
+        }
+    }
+
+    /**
+     * Executes the GridFS bucket operation and return its result.
+     *
+     * @param Bucket  $bucket
+     * @param Context $context Execution context
+     * @return mixed
+     * @throws LogicException if the database operation is unsupported
+     */
+    private function executeForGridFSBucket(Bucket $bucket, Context $context)
+    {
+        $args = $context->prepareOptions($this->arguments);
+        $context->replaceArgumentSessionPlaceholder($args);
+
+        switch ($this->name) {
+            case 'download':
+                $stream = fopen('php://memory', 'w+');
+                try {
+                    $bucket->downloadToStream($args['id'], $stream);
+
+                    return stream_get_contents($stream);
+                } finally {
+                    fclose($stream);
+                }
+                break;
+
+            case 'download_by_name':
+                $stream = fopen('php://memory', 'w+');
+                try {
+                    $bucket->downloadToStreamByName($args['filename'], $stream, array_diff_key($args, ['filename' => 1]));
+
+                    return stream_get_contents($stream);
+                } finally {
+                    fclose($stream);
+                }
+                break;
+
+            default:
+                throw new LogicException('Unsupported GridFS bucket operation: ' . $this->name);
+        }
+    }
+
+    /**
+     * Executes the session operation and return its result.
+     *
+     * @param Session            $session
+     * @param FunctionalTestCase $test
+     * @param Context            $context Execution context
+     * @return mixed
+     * @throws LogicException if the session operation is unsupported
+     */
+    private function executeForSession(Session $session, FunctionalTestCase $test, Context $context)
+    {
+        switch ($this->name) {
+            case 'abortTransaction':
+                return $session->abortTransaction();
+            case 'commitTransaction':
+                return $session->commitTransaction();
+            case 'startTransaction':
+                $options = isset($this->arguments['options']) ? (array) $this->arguments['options'] : [];
+
+                return $session->startTransaction($context->prepareOptions($options));
+            case 'withTransaction':
+                /** @var self[] $callbackOperations */
+                $callbackOperations = array_map(function ($operation) {
+                    return self::fromConvenientTransactions($operation);
+                }, $this->arguments['callback']->operations);
+
+                $callback = function () use ($callbackOperations, $test, $context) {
+                    foreach ($callbackOperations as $operation) {
+                        $operation->assert($test, $context, true);
+                    }
+                };
+
+                $options = isset($this->arguments['options']) ? (array) $this->arguments['options'] : [];
+
+                return with_transaction($session, $callback, $context->prepareOptions($options));
+            default:
+                throw new LogicException('Unsupported session operation: ' . $this->name);
+        }
+    }
+
+    private function executeForTestRunner(FunctionalTestCase $test, Context $context)
+    {
+        $args = $context->prepareOptions($this->arguments);
+        $context->replaceArgumentSessionPlaceholder($args);
+
+        switch ($this->name) {
+            case 'assertCollectionExists':
+                $databaseName = $args['database'];
+                $collectionName = $args['collection'];
+
+                $test->assertContains($collectionName, $context->selectDatabase($databaseName)->listCollectionNames());
+
+                return null;
+            case 'assertCollectionNotExists':
+                $databaseName = $args['database'];
+                $collectionName = $args['collection'];
+
+                $test->assertNotContains($collectionName, $context->selectDatabase($databaseName)->listCollectionNames());
+
+                return null;
+            case 'assertIndexExists':
+                $databaseName = $args['database'];
+                $collectionName = $args['collection'];
+                $indexName = $args['index'];
+
+                $test->assertContains($indexName, $this->getIndexNames($context, $databaseName, $collectionName));
+
+                return null;
+            case 'assertIndexNotExists':
+                $databaseName = $args['database'];
+                $collectionName = $args['collection'];
+                $indexName = $args['index'];
+
+                $test->assertNotContains($indexName, $this->getIndexNames($context, $databaseName, $collectionName));
+
+                return null;
+            case 'assertSessionPinned':
+                $test->assertInstanceOf(Session::class, $args['session']);
+                $test->assertInstanceOf(Server::class, $args['session']->getServer());
+
+                return null;
+            case 'assertSessionTransactionState':
+                $test->assertInstanceOf(Session::class, $args['session']);
+                $test->assertSame($this->arguments['state'], $args['session']->getTransactionState());
+
+                return null;
+            case 'assertSessionUnpinned':
+                $test->assertInstanceOf(Session::class, $args['session']);
+                $test->assertNull($args['session']->getServer());
+
+                return null;
+            case 'targetedFailPoint':
+                $test->assertInstanceOf(Session::class, $args['session']);
+                $test->configureFailPoint($this->arguments['failPoint'], $args['session']->getServer());
+
+                return null;
+            default:
+                throw new LogicException('Unsupported test runner operation: ' . $this->name);
+        }
+    }
+
+    /**
+     * @param string $databaseName
+     * @param string $collectionName
+     *
+     * @return array
+     */
+    private function getIndexNames(Context $context, $databaseName, $collectionName)
+    {
+        return array_map(
+            function (IndexInfo $indexInfo) {
+                return $indexInfo->getName();
+            },
+            iterator_to_array($context->selectCollection($databaseName, $collectionName)->listIndexes())
+        );
+    }
+
+    /**
+     * @throws LogicException if the operation object is unsupported
+     */
+    private function getResultAssertionType()
+    {
+        switch ($this->object) {
+            case self::OBJECT_CLIENT:
+                return $this->getResultAssertionTypeForClient();
+            case self::OBJECT_COLLECTION:
+                return $this->getResultAssertionTypeForCollection();
+            case self::OBJECT_DATABASE:
+                return $this->getResultAssertionTypeForDatabase();
+            case self::OBJECT_GRIDFS_BUCKET:
+                return ResultExpectation::ASSERT_SAME;
+            case self::OBJECT_SESSION0:
+            case self::OBJECT_SESSION1:
+            case self::OBJECT_TEST_RUNNER:
+                return ResultExpectation::ASSERT_NOTHING;
+            default:
+                throw new LogicException('Unsupported object: ' . $this->object);
+        }
+    }
+
+    /**
+     * @throws LogicException if the collection operation is unsupported
+     */
+    private function getResultAssertionTypeForClient()
+    {
+        switch ($this->name) {
+            case 'listDatabaseNames':
+                return ResultExpectation::ASSERT_SAME;
+            case 'listDatabases':
+                return ResultExpectation::ASSERT_SAME_DOCUMENTS;
+            case 'watch':
+                return ResultExpectation::ASSERT_SAME_DOCUMENTS;
+            default:
+                throw new LogicException('Unsupported client operation: ' . $this->name);
+        }
+    }
+
+    /**
+     * @throws LogicException if the collection operation is unsupported
+     */
+    private function getResultAssertionTypeForCollection()
+    {
+        switch ($this->name) {
+            case 'aggregate':
+                /* Returning a cursor for the $out collection is optional per
+                 * the CRUD specification and is not implemented in the library
+                 * since we have no concept of lazy cursors. Rely on examining
+                 * the output collection rather than the operation result. */
+                if (is_last_pipeline_operator_write($this->arguments['pipeline'])) {
+                    return ResultExpectation::ASSERT_NOTHING;
+                }
+
+                return ResultExpectation::ASSERT_SAME_DOCUMENTS;
+            case 'bulkWrite':
+                return ResultExpectation::ASSERT_BULKWRITE;
+            case 'count':
+            case 'countDocuments':
+                return ResultExpectation::ASSERT_SAME;
+            case 'createIndex':
+            case 'dropIndex':
+                return ResultExpectation::ASSERT_MATCHES_DOCUMENT;
+            case 'distinct':
+            case 'estimatedDocumentCount':
+                return ResultExpectation::ASSERT_SAME;
+            case 'deleteMany':
+            case 'deleteOne':
+                return ResultExpectation::ASSERT_DELETE;
+            case 'drop':
+                return ResultExpectation::ASSERT_NOTHING;
+            case 'findOne':
+            case 'findOneAndDelete':
+            case 'findOneAndReplace':
+            case 'findOneAndUpdate':
+                return ResultExpectation::ASSERT_SAME_DOCUMENT;
+            case 'find':
+                return ResultExpectation::ASSERT_SAME_DOCUMENTS;
+            case 'insertMany':
+                return ResultExpectation::ASSERT_INSERTMANY;
+            case 'insertOne':
+                return ResultExpectation::ASSERT_INSERTONE;
+            case 'listIndexes':
+                return ResultExpectation::ASSERT_SAME_DOCUMENTS;
+            case 'mapReduce':
+                return ResultExpectation::ASSERT_SAME_DOCUMENTS;
+            case 'replaceOne':
+            case 'updateMany':
+            case 'updateOne':
+                return ResultExpectation::ASSERT_UPDATE;
+            case 'watch':
+                return ResultExpectation::ASSERT_SAME_DOCUMENTS;
+            default:
+                throw new LogicException('Unsupported collection operation: ' . $this->name);
+        }
+    }
+
+    /**
+     * @throws LogicException if the database operation is unsupported
+     */
+    private function getResultAssertionTypeForDatabase()
+    {
+        switch ($this->name) {
+            case 'aggregate':
+            case 'listCollections':
+                return ResultExpectation::ASSERT_SAME_DOCUMENTS;
+            case 'listCollectionNames':
+                return ResultExpectation::ASSERT_SAME;
+            case 'createCollection':
+            case 'dropCollection':
+            case 'runCommand':
+                return ResultExpectation::ASSERT_MATCHES_DOCUMENT;
+            case 'watch':
+                return ResultExpectation::ASSERT_SAME_DOCUMENTS;
+            default:
+                throw new LogicException('Unsupported database operation: ' . $this->name);
+        }
+    }
+
+    /**
+     * Prepares a request element for a bulkWrite operation.
+     *
+     * @param stdClass $request
+     * @return array
+     * @throws LogicException if the bulk write request is unsupported
+     */
+    private function prepareBulkWriteRequest(stdClass $request)
+    {
+        $args = (array) $request->arguments;
+
+        switch ($request->name) {
+            case 'deleteMany':
+            case 'deleteOne':
+                return [
+                    $request->name => [
+                        $args['filter'],
+                        array_diff_key($args, ['filter' => 1]),
+                    ],
+                ];
+            case 'insertOne':
+                return [ 'insertOne' => [ $args['document'] ]];
+            case 'replaceOne':
+                return [
+                    'replaceOne' => [
+                        $args['filter'],
+                        $args['replacement'],
+                        array_diff_key($args, ['filter' => 1, 'replacement' => 1]),
+                    ],
+                ];
+            case 'updateMany':
+            case 'updateOne':
+                return [
+                    $request->name => [
+                        $args['filter'],
+                        $args['update'],
+                        array_diff_key($args, ['filter' => 1, 'update' => 1]),
+                    ],
+                ];
+            default:
+                throw new LogicException('Unsupported bulk write request: ' . $request->name);
+        }
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/PrimaryStepDownSpecTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/PrimaryStepDownSpecTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..986c1a47734070be67b8db629a12a4032e9c2831
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/PrimaryStepDownSpecTest.php	
@@ -0,0 +1,309 @@
+<?php
+
+namespace MongoDB\Tests\SpecTests;
+
+use IteratorIterator;
+use MongoDB\Client;
+use MongoDB\Collection;
+use MongoDB\Driver\Command;
+use MongoDB\Driver\Exception\BulkWriteException;
+use MongoDB\Driver\Exception\Exception as DriverException;
+use MongoDB\Driver\ReadPreference;
+use MongoDB\Driver\Server;
+use MongoDB\Driver\WriteConcern;
+use MongoDB\Operation\BulkWrite;
+use MongoDB\Tests\CommandObserver;
+use Symfony\Bridge\PhpUnit\SetUpTearDownTrait;
+use UnexpectedValueException;
+use function current;
+use function sprintf;
+
+/**
+ * @see https://github.com/mongodb/specifications/tree/master/source/connections-survive-step-down/tests
+ */
+class PrimaryStepDownSpecTest extends FunctionalTestCase
+{
+    use SetUpTearDownTrait;
+
+    const INTERRUPTED_AT_SHUTDOWN = 11600;
+    const NOT_MASTER = 10107;
+    const SHUTDOWN_IN_PROGRESS = 91;
+
+    /** @var Client */
+    private $client;
+
+    /** @var Collection */
+    private $collection;
+
+    private function doSetUp()
+    {
+        parent::setUp();
+
+        $this->client = new Client(static::getUri(), ['retryWrites' => false, 'heartbeatFrequencyMS' => 500, 'serverSelectionTimeoutMS' => 20000, 'serverSelectionTryOnce' => false]);
+
+        $this->dropAndRecreateCollection();
+        $this->collection = $this->client->selectCollection($this->getDatabaseName(), $this->getCollectionName());
+    }
+
+    /**
+     * @see https://github.com/mongodb/specifications/tree/master/source/connections-survive-step-down/tests#id10
+     */
+    public function testNotMasterKeepsConnectionPool()
+    {
+        $runOn = [(object) ['minServerVersion' => '4.1.11', 'topology' => [self::TOPOLOGY_REPLICASET]]];
+        $this->checkServerRequirements($runOn);
+
+        // Set a fail point
+        $this->configureFailPoint([
+            'configureFailPoint' => 'failCommand',
+            'mode' => ['times' => 1],
+            'data' => [
+                'failCommands' => ['insert'],
+                'errorCode' => self::NOT_MASTER,
+            ],
+        ]);
+
+        $totalConnectionsCreated = $this->getTotalConnectionsCreated();
+
+        // Execute an insert into the test collection of a {test: 1} document.
+        try {
+            $this->insertDocuments(1);
+        } catch (BulkWriteException $e) {
+            // Verify that the insert failed with an operation failure with 10107 code.
+            $this->assertSame(self::NOT_MASTER, $e->getCode());
+        }
+
+        // Execute an insert into the test collection of a {test: 1} document and verify that it succeeds.
+        $result = $this->insertDocuments(1);
+        $this->assertSame(1, $result->getInsertedCount());
+
+        // Verify that the connection pool has not been cleared
+        $this->assertSame($totalConnectionsCreated, $this->getTotalConnectionsCreated());
+    }
+
+    /**
+     * @see https://github.com/mongodb/specifications/tree/master/source/connections-survive-step-down/tests#id11
+     */
+    public function testNotMasterResetConnectionPool()
+    {
+        $runOn = [(object) ['minServerVersion' => '4.0.0', 'maxServerVersion' => '4.0.999', 'topology' => [self::TOPOLOGY_REPLICASET]]];
+        $this->checkServerRequirements($runOn);
+
+        // Set a fail point
+        $this->configureFailPoint([
+            'configureFailPoint' => 'failCommand',
+            'mode' => ['times' => 1],
+            'data' => [
+                'failCommands' => ['insert'],
+                'errorCode' => self::NOT_MASTER,
+            ],
+        ]);
+
+        $totalConnectionsCreated = $this->getTotalConnectionsCreated();
+
+        // Execute an insert into the test collection of a {test: 1} document.
+        try {
+            $this->insertDocuments(1);
+        } catch (BulkWriteException $e) {
+            // Verify that the insert failed with an operation failure with 10107 code.
+            $this->assertSame(self::NOT_MASTER, $e->getCode());
+        }
+
+        // Verify that the connection pool has been cleared
+        $this->assertSame($totalConnectionsCreated + 1, $this->getTotalConnectionsCreated());
+
+        // Execute an insert into the test collection of a {test: 1} document and verify that it succeeds.
+        $result = $this->insertDocuments(1);
+        $this->assertSame(1, $result->getInsertedCount());
+    }
+
+    /**
+     * @see https://github.com/mongodb/specifications/tree/master/source/connections-survive-step-down/tests#id12
+     */
+    public function testShutdownResetConnectionPool()
+    {
+        $runOn = [(object) ['minServerVersion' => '4.0.0']];
+        $this->checkServerRequirements($runOn);
+
+        // Set a fail point
+        $this->configureFailPoint([
+            'configureFailPoint' => 'failCommand',
+            'mode' => ['times' => 1],
+            'data' => [
+                'failCommands' => ['insert'],
+                'errorCode' => self::SHUTDOWN_IN_PROGRESS,
+            ],
+        ]);
+
+        $totalConnectionsCreated = $this->getTotalConnectionsCreated();
+
+        // Execute an insert into the test collection of a {test: 1} document.
+        try {
+            $this->insertDocuments(1);
+        } catch (BulkWriteException $e) {
+            // Verify that the insert failed with an operation failure with 91 code.
+            $this->assertSame(self::SHUTDOWN_IN_PROGRESS, $e->getCode());
+        }
+
+        // Verify that the connection pool has been cleared
+        $this->assertSame($totalConnectionsCreated + 1, $this->getTotalConnectionsCreated());
+
+        // Execute an insert into the test collection of a {test: 1} document and verify that it succeeds.
+        $result = $this->insertDocuments(1);
+        $this->assertSame(1, $result->getInsertedCount());
+    }
+
+    /**
+     * @see https://github.com/mongodb/specifications/tree/master/source/connections-survive-step-down/tests#id13
+     */
+    public function testInterruptedAtShutdownResetConnectionPool()
+    {
+        $runOn = [(object) ['minServerVersion' => '4.0.0']];
+        $this->checkServerRequirements($runOn);
+
+        // Set a fail point
+        $this->configureFailPoint([
+            'configureFailPoint' => 'failCommand',
+            'mode' => ['times' => 1],
+            'data' => [
+                'failCommands' => ['insert'],
+                'errorCode' => self::INTERRUPTED_AT_SHUTDOWN,
+            ],
+        ]);
+
+        $totalConnectionsCreated = $this->getTotalConnectionsCreated();
+
+        // Execute an insert into the test collection of a {test: 1} document.
+        try {
+            $this->insertDocuments(1);
+        } catch (BulkWriteException $e) {
+            // Verify that the insert failed with an operation failure with 11600 code.
+            $this->assertSame(self::INTERRUPTED_AT_SHUTDOWN, $e->getCode());
+        }
+
+        // Verify that the connection pool has been cleared
+        $this->assertSame($totalConnectionsCreated + 1, $this->getTotalConnectionsCreated());
+
+        // Execute an insert into the test collection of a {test: 1} document and verify that it succeeds.
+        $result = $this->insertDocuments(1);
+        $this->assertSame(1, $result->getInsertedCount());
+    }
+
+    /**
+     * @see https://github.com/mongodb/specifications/tree/master/source/connections-survive-step-down/tests#id9
+     */
+    public function testGetMoreIteration()
+    {
+        $this->markTestSkipped('Test causes subsequent failures in other tests (see PHPLIB-471)');
+
+        $runOn = [(object) ['minServerVersion' => '4.1.11', 'topology' => [self::TOPOLOGY_REPLICASET]]];
+        $this->checkServerRequirements($runOn);
+
+        // Insert 5 documents into a collection with a majority write concern.
+        $this->insertDocuments(5);
+
+        // Start a find operation on the collection with a batch size of 2, and retrieve the first batch of results.
+        $cursor = $this->collection->find([], ['batchSize' => 2]);
+
+        $iterator = new IteratorIterator($cursor);
+        $iterator->rewind();
+        $this->assertTrue($iterator->valid());
+
+        $iterator->next();
+        $this->assertTrue($iterator->valid());
+
+        $totalConnectionsCreated = $this->getTotalConnectionsCreated();
+
+        // Send a {replSetStepDown: 5, force: true} command to the current primary and verify that the command succeeded
+        $primary = $this->client->getManager()->selectServer(new ReadPreference(ReadPreference::RP_PRIMARY));
+
+        $success = false;
+        $attempts = 0;
+        do {
+            try {
+                $attempts++;
+                $primary->executeCommand('admin', new Command(['replSetStepDown' => 5, 'force' => true]));
+                $success = true;
+            } catch (DriverException $e) {
+                if ($attempts == 10) {
+                    $this->fail(sprintf('Could not successfully execute replSetStepDown within %d attempts', $attempts));
+                }
+            }
+        } while (! $success);
+
+        // Retrieve the next batch of results from the cursor obtained in the find operation, and verify that this operation succeeded.
+        $events = [];
+        $observer = new CommandObserver();
+        $observer->observe(
+            function () use ($iterator) {
+                $iterator->next();
+            },
+            function ($event) use (&$events) {
+                $events[] = $event;
+            }
+        );
+        $this->assertTrue($iterator->valid());
+        $this->assertCount(1, $events);
+        $this->assertSame('getMore', $events[0]['started']->getCommandName());
+
+        // Verify that no new connections have been created
+        $this->assertSame($totalConnectionsCreated, $this->getTotalConnectionsCreated($cursor->getServer()));
+
+        // Wait to allow primary election to complete and prevent subsequent test failures
+        $this->waitForMasterReelection();
+    }
+
+    private function insertDocuments($count)
+    {
+        $operations = [];
+
+        for ($i = 1; $i <= $count; $i++) {
+            $operations[] = [
+                BulkWrite::INSERT_ONE => [['test' => $i]],
+            ];
+        }
+
+        return $this->collection->bulkWrite($operations, ['writeConcern' => new WriteConcern('majority')]);
+    }
+
+    private function dropAndRecreateCollection()
+    {
+        $this->client->selectCollection($this->getDatabaseName(), $this->getCollectionName())->drop();
+        $this->client->selectDatabase($this->getDatabaseName())->command(['create' => $this->getCollectionName()]);
+    }
+
+    private function getTotalConnectionsCreated(Server $server = null)
+    {
+        $server = $server ?: $this->client->getManager()->selectServer(new ReadPreference('primary'));
+
+        $cursor = $server->executeCommand(
+            $this->getDatabaseName(),
+            new Command(['serverStatus' => 1]),
+            new ReadPreference(ReadPreference::RP_PRIMARY)
+        );
+
+        $cursor->setTypeMap(['root' => 'array', 'document' => 'array']);
+        $document = current($cursor->toArray());
+
+        if (isset($document['connections'], $document['connections']['totalCreated'])) {
+            return (int) $document['connections']['totalCreated'];
+        }
+
+        throw new UnexpectedValueException('Could not determine number of total connections');
+    }
+
+    private function waitForMasterReelection()
+    {
+        try {
+            $this->insertDocuments(1);
+
+            return;
+        } catch (DriverException $e) {
+            $this->client->getManager()->selectServer(new ReadPreference('primary'));
+
+            return;
+        }
+
+        $this->fail('Expected primary to be re-elected within 20 seconds.');
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/ReadWriteConcernSpecTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/ReadWriteConcernSpecTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..12f4f624f3b29937445ca249db5130c951fe048a
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/ReadWriteConcernSpecTest.php	
@@ -0,0 +1,113 @@
+<?php
+
+namespace MongoDB\Tests\SpecTests;
+
+use stdClass;
+use function basename;
+use function dirname;
+use function file_get_contents;
+use function glob;
+
+/**
+ * @see https://github.com/mongodb/specifications/tree/master/source/read-write-concern
+ */
+class ReadWriteConcernSpecTest extends FunctionalTestCase
+{
+    /** @var array */
+    private static $incompleteTests = [];
+
+    /**
+     * Assert that the expected and actual command documents match.
+     *
+     * @param stdClass $expected Expected command document
+     * @param stdClass $actual   Actual command document
+     */
+    public static function assertCommandMatches(stdClass $expected, stdClass $actual)
+    {
+        foreach ($expected as $key => $value) {
+            if ($value === null) {
+                static::assertObjectNotHasAttribute($key, $actual);
+                unset($expected->{$key});
+            }
+        }
+
+        static::assertDocumentsMatch($expected, $actual);
+    }
+
+    /**
+     * Execute an individual test case from the specification.
+     *
+     * @dataProvider provideTests
+     * @param stdClass $test           Individual "tests[]" document
+     * @param array    $runOn          Top-level "runOn" array with server requirements
+     * @param array    $data           Top-level "data" array to initialize collection
+     * @param string   $databaseName   Name of database under test
+     * @param string   $collectionName Name of collection under test
+     */
+    public function testReadWriteConcern(stdClass $test, array $runOn = null, array $data, $databaseName = null, $collectionName = null)
+    {
+        if (isset(self::$incompleteTests[$this->dataDescription()])) {
+            $this->markTestIncomplete(self::$incompleteTests[$this->dataDescription()]);
+        }
+
+        if (isset($runOn)) {
+            $this->checkServerRequirements($runOn);
+        }
+
+        if (isset($test->skipReason)) {
+            $this->markTestSkipped($test->skipReason);
+        }
+
+        $databaseName = $databaseName ?? $this->getDatabaseName();
+        $collectionName = $collectionName ?? $this->getCollectionName();
+
+        $context = Context::fromReadWriteConcern($test, $databaseName, $collectionName);
+        $this->setContext($context);
+
+        $this->dropTestAndOutcomeCollections();
+        $this->insertDataFixtures($data);
+
+        if (isset($test->failPoint)) {
+            $this->configureFailPoint($test->failPoint);
+        }
+
+        if (isset($test->expectations)) {
+            $commandExpectations = CommandExpectations::fromReadWriteConcern($test->expectations);
+            $commandExpectations->startMonitoring();
+        }
+
+        foreach ($test->operations as $operation) {
+            Operation::fromReadWriteConcern($operation)->assert($this, $context);
+        }
+
+        if (isset($commandExpectations)) {
+            $commandExpectations->stopMonitoring();
+            $commandExpectations->assert($this, $context);
+        }
+
+        if (isset($test->outcome->collection->data)) {
+            $this->assertOutcomeCollectionData($test->outcome->collection->data);
+        }
+    }
+
+    public function provideTests()
+    {
+        $testArgs = [];
+
+        foreach (glob(__DIR__ . '/read-write-concern/operation/*.json') as $filename) {
+            $json = $this->decodeJson(file_get_contents($filename));
+            $group = basename(dirname($filename)) . '/' . basename($filename, '.json');
+            $runOn = $json->runOn ?? null;
+            $data = $json->data ?? [];
+            $databaseName = $json->database_name ?? null;
+            $collectionName = $json->collection_name ?? null;
+
+            foreach ($json->tests as $test) {
+                $name = $group . ': ' . $test->description;
+                $testArgs[$name] = [$test, $runOn, $data, $databaseName, $collectionName];
+            }
+        }
+
+        return $testArgs;
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/ResultExpectation.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/ResultExpectation.php
new file mode 100644
index 0000000000000000000000000000000000000000..199fc003559588a11178e65e52826bdfc82e5fcf
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/ResultExpectation.php	
@@ -0,0 +1,378 @@
+<?php
+
+namespace MongoDB\Tests\SpecTests;
+
+use LogicException;
+use MongoDB\BulkWriteResult;
+use MongoDB\DeleteResult;
+use MongoDB\Driver\WriteResult;
+use MongoDB\Exception\InvalidArgumentException;
+use MongoDB\InsertManyResult;
+use MongoDB\InsertOneResult;
+use MongoDB\UpdateResult;
+use stdClass;
+use function call_user_func;
+use function is_array;
+use function is_object;
+use function property_exists;
+
+/**
+ * Spec test operation result expectation.
+ */
+final class ResultExpectation
+{
+    const ASSERT_NOTHING = 0;
+    const ASSERT_BULKWRITE = 1;
+    const ASSERT_DELETE = 2;
+    const ASSERT_INSERTMANY = 3;
+    const ASSERT_INSERTONE = 4;
+    const ASSERT_UPDATE = 5;
+    const ASSERT_SAME = 6;
+    const ASSERT_SAME_DOCUMENT = 7;
+    const ASSERT_SAME_DOCUMENTS = 8;
+    const ASSERT_MATCHES_DOCUMENT = 9;
+    const ASSERT_NULL = 10;
+    const ASSERT_CALLABLE = 11;
+    const ASSERT_DOCUMENTS_MATCH = 12;
+
+    /** @var integer */
+    private $assertionType = self::ASSERT_NOTHING;
+
+    /** @var mixed */
+    private $expectedValue;
+
+    /** @var callable */
+    private $assertionCallable;
+
+    /**
+     * @param integer $assertionType
+     * @param mixed   $expectedValue
+     */
+    private function __construct($assertionType, $expectedValue)
+    {
+        switch ($assertionType) {
+            case self::ASSERT_BULKWRITE:
+            case self::ASSERT_DELETE:
+            case self::ASSERT_INSERTMANY:
+            case self::ASSERT_INSERTONE:
+            case self::ASSERT_UPDATE:
+                if (! is_object($expectedValue)) {
+                    throw InvalidArgumentException::invalidType('$expectedValue', $expectedValue, 'object');
+                }
+                break;
+
+            case self::ASSERT_SAME_DOCUMENTS:
+                if (! self::isArrayOfObjects($expectedValue)) {
+                    throw InvalidArgumentException::invalidType('$expectedValue', $expectedValue, 'object[]');
+                }
+                break;
+        }
+
+        $this->assertionType = $assertionType;
+        $this->expectedValue = $expectedValue;
+    }
+
+    public static function fromChangeStreams(stdClass $result, callable $assertionCallable)
+    {
+        if (! property_exists($result, 'success')) {
+            return new self(self::ASSERT_NOTHING, null);
+        }
+
+        $o = new self(self::ASSERT_CALLABLE, $result->success);
+
+        $o->assertionCallable = $assertionCallable;
+
+        return $o;
+    }
+
+    public static function fromClientSideEncryption(stdClass $operation, $defaultAssertionType)
+    {
+        if (property_exists($operation, 'result') && ! self::isErrorResult($operation->result)) {
+            $assertionType = $operation->result === null ? self::ASSERT_NULL : $defaultAssertionType;
+            $expectedValue = $operation->result;
+        } else {
+            $assertionType = self::ASSERT_NOTHING;
+            $expectedValue = null;
+        }
+
+        return new self($assertionType, $expectedValue);
+    }
+
+    public static function fromCrud(stdClass $operation, $defaultAssertionType)
+    {
+        if (property_exists($operation, 'result') && ! self::isErrorResult($operation->result)) {
+            $assertionType = $operation->result === null ? self::ASSERT_NULL : $defaultAssertionType;
+            $expectedValue = $operation->result;
+        } else {
+            $assertionType = self::ASSERT_NOTHING;
+            $expectedValue = null;
+        }
+
+        return new self($assertionType, $expectedValue);
+    }
+
+    public static function fromReadWriteConcern(stdClass $operation, $defaultAssertionType)
+    {
+        if (property_exists($operation, 'result') && ! self::isErrorResult($operation->result)) {
+            $assertionType = $operation->result === null ? self::ASSERT_NULL : $defaultAssertionType;
+            $expectedValue = $operation->result;
+        } else {
+            $assertionType = self::ASSERT_NOTHING;
+            $expectedValue = null;
+        }
+
+        return new self($assertionType, $expectedValue);
+    }
+
+    public static function fromRetryableReads(stdClass $operation, $defaultAssertionType)
+    {
+        if (property_exists($operation, 'result') && ! self::isErrorResult($operation->result)) {
+            $assertionType = $operation->result === null ? self::ASSERT_NULL : $defaultAssertionType;
+            $expectedValue = $operation->result;
+        } else {
+            $assertionType = self::ASSERT_NOTHING;
+            $expectedValue = null;
+        }
+
+        return new self($assertionType, $expectedValue);
+    }
+
+    public static function fromRetryableWrites(stdClass $outcome, $defaultAssertionType)
+    {
+        if (property_exists($outcome, 'result') && ! self::isErrorResult($outcome->result)) {
+            $assertionType = $outcome->result === null ? self::ASSERT_NULL : $defaultAssertionType;
+            $expectedValue = $outcome->result;
+        } else {
+            $assertionType = self::ASSERT_NOTHING;
+            $expectedValue = null;
+        }
+
+        return new self($assertionType, $expectedValue);
+    }
+
+    public static function fromTransactions(stdClass $operation, $defaultAssertionType)
+    {
+        if (property_exists($operation, 'result') && ! self::isErrorResult($operation->result)) {
+            $assertionType = $operation->result === null ? self::ASSERT_NULL : $defaultAssertionType;
+            $expectedValue = $operation->result;
+        } else {
+            $assertionType = self::ASSERT_NOTHING;
+            $expectedValue = null;
+        }
+
+        return new self($assertionType, $expectedValue);
+    }
+
+    /**
+     * Assert that the result expectation matches the actual outcome.
+     *
+     * @param FunctionalTestCase $test   Test instance for performing assertions
+     * @param mixed              $result Result (if any) from the actual outcome
+     * @throws LogicException if the assertion type is unsupported
+     */
+    public function assert(FunctionalTestCase $test, $actual)
+    {
+        $expected = $this->expectedValue;
+
+        switch ($this->assertionType) {
+            case self::ASSERT_BULKWRITE:
+                /* If the bulk write was successful, the actual value should be
+                 * a BulkWriteResult; otherwise, expect a WriteResult extracted
+                 * from the BulkWriteException. */
+                $test->assertThat($actual, $test->logicalOr(
+                    $test->isInstanceOf(BulkWriteResult::class),
+                    $test->isInstanceOf(WriteResult::class)
+                ));
+
+                if (! $actual->isAcknowledged()) {
+                    break;
+                }
+
+                if (isset($expected->deletedCount)) {
+                    $test->assertSame($expected->deletedCount, $actual->getDeletedCount());
+                }
+
+                if (isset($expected->insertedCount)) {
+                    $test->assertSame($expected->insertedCount, $actual->getInsertedCount());
+                }
+
+                // insertedIds are not available after BulkWriteException (see: PHPLIB-428)
+                if (isset($expected->insertedIds) && $actual instanceof BulkWriteResult) {
+                    $test->assertSameDocument($expected->insertedIds, $actual->getInsertedIds());
+                }
+
+                if (isset($expected->matchedCount)) {
+                    $test->assertSame($expected->matchedCount, $actual->getMatchedCount());
+                }
+
+                if (isset($expected->modifiedCount)) {
+                    $test->assertSame($expected->modifiedCount, $actual->getModifiedCount());
+                }
+
+                if (isset($expected->upsertedCount)) {
+                    $test->assertSame($expected->upsertedCount, $actual->getUpsertedCount());
+                }
+
+                if (isset($expected->upsertedIds)) {
+                    $test->assertSameDocument($expected->upsertedIds, $actual->getUpsertedIds());
+                }
+                break;
+
+            case self::ASSERT_CALLABLE:
+                call_user_func($this->assertionCallable, $expected, $actual);
+                break;
+
+            case self::ASSERT_DELETE:
+                $test->assertInstanceOf(DeleteResult::class, $actual);
+
+                if (isset($expected->deletedCount)) {
+                    $test->assertSame($expected->deletedCount, $actual->getDeletedCount());
+                }
+                break;
+
+            case self::ASSERT_INSERTMANY:
+                /* If the bulk insert was successful, the actual value should be
+                 * a InsertManyResult; otherwise, expect a WriteResult extracted
+                 * from the BulkWriteException. */
+                $test->assertThat($actual, $test->logicalOr(
+                    $test->isInstanceOf(InsertManyResult::class),
+                    $test->isInstanceOf(WriteResult::class)
+                ));
+
+                if (isset($expected->insertedCount)) {
+                    $test->assertSame($expected->insertedCount, $actual->getInsertedCount());
+                }
+
+                // insertedIds are not available after BulkWriteException (see: PHPLIB-428)
+                if (isset($expected->insertedIds) && $actual instanceof BulkWriteResult) {
+                    $test->assertSameDocument($expected->insertedIds, $actual->getInsertedIds());
+                }
+                break;
+
+            case self::ASSERT_INSERTONE:
+                $test->assertThat($actual, $test->logicalOr(
+                    $test->isInstanceOf(InsertOneResult::class),
+                    $test->isInstanceOf(WriteResult::class)
+                ));
+
+                if (isset($expected->insertedCount)) {
+                    $test->assertSame($expected->insertedCount, $actual->getInsertedCount());
+                }
+
+                if (property_exists($expected, 'insertedId')) {
+                    $test->assertSameDocument(
+                        ['insertedId' => $expected->insertedId],
+                        ['insertedId' => $actual->getInsertedId()]
+                    );
+                }
+                break;
+
+            case self::ASSERT_MATCHES_DOCUMENT:
+                $test->assertIsObject($expected);
+                $test->assertThat($actual, $test->logicalOr(
+                    $test->isType('array'),
+                    $test->isType('object')
+                ));
+                $test->assertMatchesDocument($expected, $actual);
+                break;
+
+            case self::ASSERT_NOTHING:
+                break;
+
+            case self::ASSERT_NULL:
+                $test->assertNull($actual);
+                break;
+
+            case self::ASSERT_SAME:
+                $test->assertSame($expected, $actual);
+                break;
+
+            case self::ASSERT_SAME_DOCUMENT:
+                $test->assertIsObject($expected);
+                $test->assertThat($actual, $test->logicalOr(
+                    $test->isType('array'),
+                    $test->isType('object')
+                ));
+                $test->assertSameDocument($expected, $actual);
+                break;
+
+            case self::ASSERT_SAME_DOCUMENTS:
+                $test->assertSameDocuments($expected, $actual);
+                break;
+
+            case self::ASSERT_DOCUMENTS_MATCH:
+                $test->assertDocumentsMatch($expected, $actual);
+                break;
+
+            case self::ASSERT_UPDATE:
+                $test->assertInstanceOf(UpdateResult::class, $actual);
+
+                if (isset($expected->matchedCount)) {
+                    $test->assertSame($expected->matchedCount, $actual->getMatchedCount());
+                }
+
+                if (isset($expected->modifiedCount)) {
+                    $test->assertSame($expected->modifiedCount, $actual->getModifiedCount());
+                }
+
+                if (isset($expected->upsertedCount)) {
+                    $test->assertSame($expected->upsertedCount, $actual->getUpsertedCount());
+                }
+
+                if (property_exists($expected, 'upsertedId')) {
+                    $test->assertSameDocument(
+                        ['upsertedId' => $expected->upsertedId],
+                        ['upsertedId' => $actual->getUpsertedId()]
+                    );
+                }
+                break;
+
+            default:
+                throw new LogicException('Unsupported assertion type: ' . $this->assertionType);
+        }
+    }
+
+    public function isExpected()
+    {
+        return $this->assertionType !== self::ASSERT_NOTHING;
+    }
+
+    private static function isArrayOfObjects($array)
+    {
+        if (! is_array($array)) {
+            return false;
+        }
+
+        foreach ($array as $object) {
+            if (! is_object($object)) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * Determines whether the result is actually an error expectation.
+     *
+     * @see https://github.com/mongodb/specifications/blob/master/source/transactions/tests/README.rst#test-format
+     * @param mixed $result
+     * @return boolean
+     */
+    private static function isErrorResult($result)
+    {
+        if (! is_object($result)) {
+            return false;
+        }
+
+        $keys = ['errorContains', 'errorCodeName', 'errorLabelsContain', 'errorLabelsOmit'];
+
+        foreach ($keys as $key) {
+            if (isset($result->{$key})) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/RetryableReadsSpecTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/RetryableReadsSpecTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..befe361bce439cfa57710584a97c03da2f246e30
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/RetryableReadsSpecTest.php	
@@ -0,0 +1,122 @@
+<?php
+
+namespace MongoDB\Tests\SpecTests;
+
+use stdClass;
+use function basename;
+use function file_get_contents;
+use function glob;
+use function is_object;
+use function strpos;
+
+/**
+ * Retryable reads spec tests.
+ *
+ * @see https://github.com/mongodb/specifications/tree/master/source/retryable-reads
+ */
+class RetryableReadsSpecTest extends FunctionalTestCase
+{
+    /** @var array */
+    private static $skippedOperations = [
+        'listCollectionObjects' => 'Not implemented',
+        'listDatabaseObjects' => 'Not implemented',
+        'listIndexNames' => 'Not implemented',
+    ];
+
+    /**
+     * Assert that the expected and actual command documents match.
+     *
+     * @param stdClass $expected Expected command document
+     * @param stdClass $actual   Actual command document
+     */
+    public static function assertCommandMatches(stdClass $expected, stdClass $actual)
+    {
+        static::assertDocumentsMatch($expected, $actual);
+    }
+
+    /**
+     * Execute an individual test case from the specification.
+     *
+     * @dataProvider provideTests
+     * @param stdClass     $test           Individual "tests[]" document
+     * @param array        $runOn          Top-level "runOn" array with server requirements
+     * @param array|object $data           Top-level "data" array to initialize collection
+     * @param string       $databaseName   Name of database under test
+     * @param string|null  $collectionName Name of collection under test
+     * @param string|null  $bucketName     Name of GridFS bucket under test
+     */
+    public function testRetryableReads(stdClass $test, array $runOn = null, $data, $databaseName, $collectionName, $bucketName)
+    {
+        if (isset($runOn)) {
+            $this->checkServerRequirements($runOn);
+        }
+
+        foreach (self::$skippedOperations as $operation => $skipReason) {
+            if (strpos($this->dataDescription(), $operation) === 0) {
+                $this->markTestSkipped($skipReason);
+            }
+        }
+
+        if (strpos($this->dataDescription(), 'changeStreams-') === 0) {
+            $this->skipIfChangeStreamIsNotSupported();
+        }
+
+        $context = Context::fromRetryableReads($test, $databaseName, $collectionName, $bucketName);
+        $this->setContext($context);
+
+        $this->dropTestAndOutcomeCollections();
+
+        if (is_object($data)) {
+            foreach ($data as $collectionName => $documents) {
+                $this->assertIsArray($documents);
+                $this->insertDataFixtures($documents, $collectionName);
+            }
+        } else {
+            $this->insertDataFixtures($data);
+        }
+
+        if (isset($test->failPoint)) {
+            $this->configureFailPoint($test->failPoint);
+        }
+
+        if (isset($test->expectations)) {
+            $commandExpectations = CommandExpectations::fromRetryableReads($test->expectations);
+            $commandExpectations->startMonitoring();
+        }
+
+        foreach ($test->operations as $operation) {
+            Operation::fromRetryableReads($operation)->assert($this, $context);
+        }
+
+        if (isset($commandExpectations)) {
+            $commandExpectations->stopMonitoring();
+            $commandExpectations->assert($this, $context);
+        }
+
+        if (isset($test->outcome->collection->data)) {
+            $this->assertOutcomeCollectionData($test->outcome->collection->data);
+        }
+    }
+
+    public function provideTests()
+    {
+        $testArgs = [];
+
+        foreach (glob(__DIR__ . '/retryable-reads/*.json') as $filename) {
+            $json = $this->decodeJson(file_get_contents($filename));
+            $group = basename($filename, '.json');
+            $runOn = $json->runOn ?? null;
+            $data = $json->data ?? [];
+            $databaseName = $json->database_name ?? null;
+            $collectionName = $json->collection_name ?? null;
+            $bucketName = $json->bucket_name ?? null;
+
+            foreach ($json->tests as $test) {
+                $name = $group . ': ' . $test->description;
+                $testArgs[$name] = [$test, $runOn, $data, $databaseName, $collectionName, $bucketName];
+            }
+        }
+
+        return $testArgs;
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/RetryableWritesSpecTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/RetryableWritesSpecTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..5d41a752f717f2066f6f27b06539c07f3343ff2c
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/RetryableWritesSpecTest.php	
@@ -0,0 +1,72 @@
+<?php
+
+namespace MongoDB\Tests\SpecTests;
+
+use stdClass;
+use function basename;
+use function file_get_contents;
+use function glob;
+
+/**
+ * Retryable writes spec tests.
+ *
+ * @see https://github.com/mongodb/specifications/tree/master/source/retryable-writes
+ */
+class RetryableWritesSpecTest extends FunctionalTestCase
+{
+    /**
+     * Execute an individual test case from the specification.
+     *
+     * @dataProvider provideTests
+     * @param stdClass $test  Individual "tests[]" document
+     * @param array    $runOn Top-level "runOn" array with server requirements
+     * @param array    $data  Top-level "data" array to initialize collection
+     */
+    public function testRetryableWrites(stdClass $test, array $runOn = null, array $data)
+    {
+        if ($this->isShardedCluster() && ! $this->isShardedClusterUsingReplicasets()) {
+            $this->markTestSkipped('Transaction numbers are only allowed on a replica set member or mongos (PHPC-1415)');
+        }
+
+        $useMultipleMongoses = isset($test->useMultipleMongoses) && $test->useMultipleMongoses && $this->isShardedCluster();
+
+        if (isset($runOn)) {
+            $this->checkServerRequirements($runOn);
+        }
+
+        $context = Context::fromRetryableWrites($test, $this->getDatabaseName(), $this->getCollectionName(), $useMultipleMongoses);
+        $this->setContext($context);
+
+        $this->dropTestAndOutcomeCollections();
+        $this->insertDataFixtures($data);
+
+        if (isset($test->failPoint)) {
+            $this->configureFailPoint($test->failPoint);
+        }
+
+        Operation::fromRetryableWrites($test->operation, $test->outcome)->assert($this, $context);
+
+        if (isset($test->outcome->collection->data)) {
+            $this->assertOutcomeCollectionData($test->outcome->collection->data);
+        }
+    }
+
+    public function provideTests()
+    {
+        $testArgs = [];
+
+        foreach (glob(__DIR__ . '/retryable-writes/*.json') as $filename) {
+            $json = $this->decodeJson(file_get_contents($filename));
+            $group = basename($filename, '.json');
+            $runOn = $json->runOn ?? null;
+            $data = $json->data ?? [];
+
+            foreach ($json->tests as $test) {
+                $name = $group . ': ' . $test->description;
+                $testArgs[$name] = [$test, $runOn, $data];
+            }
+        }
+
+        return $testArgs;
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/TransactionsSpecTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/TransactionsSpecTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..2bec5ab4192aed189fd5d3c4e8fe1f5474aabeb5
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/TransactionsSpecTest.php	
@@ -0,0 +1,338 @@
+<?php
+
+namespace MongoDB\Tests\SpecTests;
+
+use MongoDB\BSON\Int64;
+use MongoDB\BSON\Timestamp;
+use MongoDB\Client;
+use MongoDB\Driver\Command;
+use MongoDB\Driver\Exception\ServerException;
+use MongoDB\Driver\Manager;
+use MongoDB\Driver\ReadPreference;
+use MongoDB\Driver\Server;
+use stdClass;
+use Symfony\Bridge\PhpUnit\SetUpTearDownTrait;
+use function array_unique;
+use function basename;
+use function count;
+use function dirname;
+use function file_get_contents;
+use function get_object_vars;
+use function glob;
+
+/**
+ * Transactions spec tests.
+ *
+ * @see https://github.com/mongodb/specifications/tree/master/source/transactions
+ */
+class TransactionsSpecTest extends FunctionalTestCase
+{
+    use SetUpTearDownTrait;
+
+    const INTERRUPTED = 11601;
+
+    /**
+     * In addition to the useMultipleMongoses tests, these should all pass
+     * before the driver can be considered compatible with MongoDB 4.2.
+     *
+     * @var array
+     */
+    private static $incompleteTests = [
+        'transactions/mongos-recovery-token: commitTransaction retry fails on new mongos' => 'isMaster failpoints cannot be disabled',
+        'transactions/pin-mongos: remain pinned after non-transient error on commit' => 'Blocked on SPEC-1320',
+        'transactions/pin-mongos: unpin after transient error within a transaction and commit' => 'isMaster failpoints cannot be disabled',
+    ];
+
+    private function doSetUp()
+    {
+        parent::setUp();
+
+        static::killAllSessions();
+
+        $this->skipIfTransactionsAreNotSupported();
+    }
+
+    private function doTearDown()
+    {
+        if ($this->hasFailed()) {
+            static::killAllSessions();
+        }
+
+        parent::tearDown();
+    }
+
+    /**
+     * Assert that the expected and actual command documents match.
+     *
+     * Note: this method may modify the $expected object.
+     *
+     * @param stdClass $expected Expected command document
+     * @param stdClass $actual   Actual command document
+     */
+    public static function assertCommandMatches(stdClass $expected, stdClass $actual)
+    {
+        if (isset($expected->getMore) && $expected->getMore === 42) {
+            static::assertObjectHasAttribute('getMore', $actual);
+            static::assertThat($actual->getMore, static::logicalOr(
+                static::isInstanceOf(Int64::class),
+                static::isType('integer')
+            ));
+            unset($expected->getMore);
+        }
+
+        if (isset($expected->recoveryToken) && $expected->recoveryToken === 42) {
+            static::assertObjectHasAttribute('recoveryToken', $actual);
+            static::assertIsObject($actual->recoveryToken);
+            unset($expected->recoveryToken);
+        }
+
+        if (isset($expected->readConcern->afterClusterTime) && $expected->readConcern->afterClusterTime === 42) {
+            static::assertObjectHasAttribute('readConcern', $actual);
+            static::assertIsObject($actual->readConcern);
+            static::assertObjectHasAttribute('afterClusterTime', $actual->readConcern);
+            static::assertInstanceOf(Timestamp::class, $actual->readConcern->afterClusterTime);
+            unset($expected->readConcern->afterClusterTime);
+
+            /* If "afterClusterTime" was the only assertion for "readConcern",
+             * unset the field to avoid expecting an empty document later. */
+            if (get_object_vars($expected->readConcern) === []) {
+                unset($expected->readConcern);
+            }
+        }
+
+        /* TODO: Determine if forcing a new libmongoc client in Context is
+         * preferable to skipping the txnNumber assertion. */
+        //unset($expected['txnNumber']);
+
+        foreach ($expected as $key => $value) {
+            if ($value === null) {
+                static::assertObjectNotHasAttribute($key, $actual);
+                unset($expected->{$key});
+            }
+        }
+
+        static::assertDocumentsMatch($expected, $actual);
+    }
+
+    /**
+     * Execute an individual test case from the specification.
+     *
+     * @dataProvider provideTests
+     * @param stdClass $test           Individual "tests[]" document
+     * @param array    $runOn          Top-level "runOn" array with server requirements
+     * @param array    $data           Top-level "data" array to initialize collection
+     * @param string   $databaseName   Name of database under test
+     * @param string   $collectionName Name of collection under test
+     */
+    public function testTransactions(stdClass $test, array $runOn = null, array $data, $databaseName = null, $collectionName = null)
+    {
+        if (isset(self::$incompleteTests[$this->dataDescription()])) {
+            $this->markTestIncomplete(self::$incompleteTests[$this->dataDescription()]);
+        }
+
+        $useMultipleMongoses = isset($test->useMultipleMongoses) && $test->useMultipleMongoses && $this->isShardedCluster();
+
+        if (isset($runOn)) {
+            $this->checkServerRequirements($runOn);
+        }
+
+        if (isset($test->skipReason)) {
+            $this->markTestSkipped($test->skipReason);
+        }
+
+        $databaseName = $databaseName ?? $this->getDatabaseName();
+        $collectionName = $collectionName ?? $this->getCollectionName();
+
+        $context = Context::fromTransactions($test, $databaseName, $collectionName, $useMultipleMongoses);
+        $this->setContext($context);
+
+        $this->dropTestAndOutcomeCollections();
+        $this->createTestCollection();
+        $this->insertDataFixtures($data);
+        $this->preventStaleDbVersionError($test->operations);
+
+        if (isset($test->failPoint)) {
+            $this->configureFailPoint($test->failPoint);
+        }
+
+        if (isset($test->expectations)) {
+            $commandExpectations = CommandExpectations::fromTransactions($test->expectations);
+            $commandExpectations->startMonitoring();
+        }
+
+        foreach ($test->operations as $operation) {
+            Operation::fromTransactions($operation)->assert($this, $context);
+        }
+
+        $context->session0->endSession();
+        $context->session1->endSession();
+
+        if (isset($commandExpectations)) {
+            $commandExpectations->stopMonitoring();
+            $commandExpectations->assert($this, $context);
+        }
+
+        if (isset($test->outcome->collection->data)) {
+            $this->assertOutcomeCollectionData($test->outcome->collection->data);
+        }
+    }
+
+    public function provideTests()
+    {
+        $testArgs = [];
+
+        foreach (glob(__DIR__ . '/transactions*/*.json') as $filename) {
+            $json = $this->decodeJson(file_get_contents($filename));
+            $group = basename(dirname($filename)) . '/' . basename($filename, '.json');
+            $runOn = $json->runOn ?? null;
+            $data = $json->data ?? [];
+            $databaseName = $json->database_name ?? null;
+            $collectionName = $json->collection_name ?? null;
+
+            foreach ($json->tests as $test) {
+                $name = $group . ': ' . $test->description;
+                $testArgs[$name] = [$test, $runOn, $data, $databaseName, $collectionName];
+            }
+        }
+
+        return $testArgs;
+    }
+
+    /**
+     * Prose test 1: Test that starting a new transaction on a pinned
+     * ClientSession unpins the session and normal server selection is performed
+     * for the next operation.
+     */
+    public function testStartingNewTransactionOnPinnedSessionUnpinsSession()
+    {
+        if (! $this->isShardedClusterUsingReplicasets()) {
+            $this->markTestSkipped('Mongos pinning tests can only run on sharded clusters using replica sets');
+        }
+
+        $client = new Client($this->getUri(true));
+
+        $session = $client->startSession();
+        $collection = $client->selectCollection($this->getDatabaseName(), $this->getCollectionName());
+
+        // Create collection before transaction
+        $collection->insertOne([]);
+
+        $session->startTransaction([]);
+        $collection->insertOne([], ['session' => $session]);
+        $session->commitTransaction();
+
+        $servers = [];
+        for ($i = 0; $i < 50; $i++) {
+            $session->startTransaction([]);
+            $cursor = $collection->find([], ['session' => $session]);
+            $servers[] = $cursor->getServer()->getHost() . ':' . $cursor->getServer()->getPort();
+            $this->assertInstanceOf(Server::class, $session->getServer());
+            $session->commitTransaction();
+        }
+
+        $servers = array_unique($servers);
+        $this->assertGreaterThan(1, count($servers));
+
+        $session->endSession();
+    }
+
+    /**
+     * Prose test 2: Test non-transaction operations using a pinned
+     * ClientSession unpins the session and normal server selection is
+     * performed.
+     */
+    public function testRunningNonTransactionOperationOnPinnedSessionUnpinsSession()
+    {
+        if (! $this->isShardedClusterUsingReplicasets()) {
+            $this->markTestSkipped('Mongos pinning tests can only run on sharded clusters using replica sets');
+        }
+
+        $client = new Client($this->getUri(true));
+
+        $session = $client->startSession();
+        $collection = $client->selectCollection($this->getDatabaseName(), $this->getCollectionName());
+
+        // Create collection before transaction
+        $collection->insertOne([]);
+
+        $session->startTransaction([]);
+        $collection->insertOne([], ['session' => $session]);
+        $session->commitTransaction();
+
+        $servers = [];
+        for ($i = 0; $i < 50; $i++) {
+            $cursor = $collection->find([], ['session' => $session]);
+            $servers[] = $cursor->getServer()->getHost() . ':' . $cursor->getServer()->getPort();
+            $this->assertNull($session->getServer());
+        }
+
+        $servers = array_unique($servers);
+        $this->assertGreaterThan(1, count($servers));
+
+        $session->endSession();
+    }
+
+    /**
+     * Create the collection, since it cannot be created within a transaction.
+     */
+    protected function createTestCollection()
+    {
+        $context = $this->getContext();
+
+        $database = $context->getDatabase();
+        $database->createCollection($context->collectionName, $context->defaultWriteOptions);
+    }
+
+    /**
+     * Kill all sessions on the cluster.
+     *
+     * This will clean up any open transactions that may remain from a
+     * previously failed test. For sharded clusters, this command will be run
+     * on all mongos nodes.
+     */
+    private static function killAllSessions()
+    {
+        $manager = new Manager(static::getUri());
+        $primary = $manager->selectServer(new ReadPreference('primary'));
+
+        $servers = $primary->getType() === Server::TYPE_MONGOS
+            ? $manager->getServers()
+            : [$primary];
+
+        foreach ($servers as $server) {
+            try {
+                // Skip servers that do not support sessions
+                if (! isset($server->getInfo()['logicalSessionTimeoutMinutes'])) {
+                    continue;
+                }
+                $server->executeCommand('admin', new Command(['killAllSessions' => []]));
+            } catch (ServerException $e) {
+                // Interrupted error is safe to ignore (see: SERVER-38335)
+                if ($e->getCode() != self::INTERRUPTED) {
+                    throw $e;
+                }
+            }
+        }
+    }
+
+    /**
+     * Work around potential error executing distinct on sharded clusters.
+     *
+     * @param array $operations
+     * @see https://github.com/mongodb/specifications/tree/master/source/transactions/tests#why-do-tests-that-run-distinct-sometimes-fail-with-staledbversionts.
+     */
+    private function preventStaleDbVersionError(array $operations)
+    {
+        if (! $this->isShardedCluster()) {
+            return;
+        }
+
+        foreach ($operations as $operation) {
+            if ($operation->name === 'distinct') {
+                $this->getContext()->getCollection()->distinct('foo');
+
+                return;
+            }
+        }
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/atlas_data_lake/aggregate.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/atlas_data_lake/aggregate.json
new file mode 100644
index 0000000000000000000000000000000000000000..99995bca415a5a3858ec580c73938273091c33bf
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/atlas_data_lake/aggregate.json	
@@ -0,0 +1,53 @@
+{
+  "collection_name": "driverdata",
+  "database_name": "test",
+  "tests": [
+    {
+      "description": "Aggregate with pipeline (project, sort, limit)",
+      "operations": [
+        {
+          "object": "collection",
+          "name": "aggregate",
+          "arguments": {
+            "pipeline": [
+              {
+                "$project": {
+                  "_id": 0
+                }
+              },
+              {
+                "$sort": {
+                  "a": 1
+                }
+              },
+              {
+                "$limit": 2
+              }
+            ]
+          },
+          "result": [
+            {
+              "a": 1,
+              "b": 2,
+              "c": 3
+            },
+            {
+              "a": 2,
+              "b": 3,
+              "c": 4
+            }
+          ]
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "driverdata"
+            }
+          }
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/atlas_data_lake/estimatedDocumentCount.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/atlas_data_lake/estimatedDocumentCount.json
new file mode 100644
index 0000000000000000000000000000000000000000..d039a51f06202545bb1cdf7232cd6eed0d66bb93
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/atlas_data_lake/estimatedDocumentCount.json	
@@ -0,0 +1,25 @@
+{
+  "collection_name": "driverdata",
+  "database_name": "test",
+  "tests": [
+    {
+      "description": "estimatedDocumentCount succeeds",
+      "operations": [
+        {
+          "object": "collection",
+          "name": "estimatedDocumentCount",
+          "result": 15
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "count": "driverdata"
+            }
+          }
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/atlas_data_lake/find.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/atlas_data_lake/find.json
new file mode 100644
index 0000000000000000000000000000000000000000..8a3468a135efa6dc09bfb5b7d257570e2d6d7db2
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/atlas_data_lake/find.json	
@@ -0,0 +1,65 @@
+{
+  "collection_name": "driverdata",
+  "database_name": "test",
+  "tests": [
+    {
+      "description": "Find with projection and sort",
+      "operations": [
+        {
+          "object": "collection",
+          "name": "find",
+          "arguments": {
+            "filter": {
+              "b": {
+                "$gt": 5
+              }
+            },
+            "projection": {
+              "_id": 0
+            },
+            "sort": {
+              "a": 1
+            },
+            "limit": 5
+          },
+          "result": [
+            {
+              "a": 5,
+              "b": 6,
+              "c": 7
+            },
+            {
+              "a": 6,
+              "b": 7,
+              "c": 8
+            },
+            {
+              "a": 7,
+              "b": 8,
+              "c": 9
+            },
+            {
+              "a": 8,
+              "b": 9,
+              "c": 10
+            },
+            {
+              "a": 9,
+              "b": 10,
+              "c": 11
+            }
+          ]
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "find": "driverdata"
+            }
+          }
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/atlas_data_lake/getMore.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/atlas_data_lake/getMore.json
new file mode 100644
index 0000000000000000000000000000000000000000..fa1deab4f395eed579b487964239672ac3bb2871
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/atlas_data_lake/getMore.json	
@@ -0,0 +1,57 @@
+{
+  "collection_name": "driverdata",
+  "database_name": "test",
+  "tests": [
+    {
+      "description": "A successful find event with getMore",
+      "operations": [
+        {
+          "object": "collection",
+          "name": "find",
+          "arguments": {
+            "filter": {
+              "a": {
+                "$gte": 2
+              }
+            },
+            "sort": {
+              "a": 1
+            },
+            "batchSize": 3,
+            "limit": 4
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "find": "driverdata",
+              "filter": {
+                "a": {
+                  "$gte": 2
+                }
+              },
+              "sort": {
+                "a": 1
+              },
+              "batchSize": 3,
+              "limit": 4
+            },
+            "command_name": "find",
+            "database_name": "test"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "batchSize": 1
+            },
+            "command_name": "getMore",
+            "database_name": "cursors"
+          }
+        }
+      ]
+    }
+  ]
+}
\ No newline at end of file
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/atlas_data_lake/listCollections.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/atlas_data_lake/listCollections.json
new file mode 100644
index 0000000000000000000000000000000000000000..8d8a8f6c1b6f417873ab206a94aad133d71e58f1
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/atlas_data_lake/listCollections.json	
@@ -0,0 +1,25 @@
+{
+  "database_name": "test",
+  "tests": [
+    {
+      "description": "ListCollections succeeds",
+      "operations": [
+        {
+          "name": "listCollections",
+          "object": "database"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command_name": "listCollections",
+            "database_name": "test",
+            "command": {
+              "listCollections": 1
+            }
+          }
+        }
+      ]
+    }
+  ]
+}
\ No newline at end of file
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/atlas_data_lake/listDatabases.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/atlas_data_lake/listDatabases.json
new file mode 100644
index 0000000000000000000000000000000000000000..f8ec9a0bf41b2f105657dc99468c3f4c394bd172
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/atlas_data_lake/listDatabases.json	
@@ -0,0 +1,24 @@
+{
+  "tests": [
+    {
+      "description": "ListDatabases succeeds",
+      "operations": [
+        {
+          "name": "listDatabases",
+          "object": "client"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command_name": "listDatabases",
+            "database_name": "admin",
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        }
+      ]
+    }
+  ]
+}
\ No newline at end of file
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/atlas_data_lake/runCommand.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/atlas_data_lake/runCommand.json
new file mode 100644
index 0000000000000000000000000000000000000000..f72e863ba5dd6459bf7b422ca4cfd9ada44f090b
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/atlas_data_lake/runCommand.json	
@@ -0,0 +1,31 @@
+{
+  "database_name": "test",
+  "tests": [
+    {
+      "description": "ping succeeds using runCommand",
+      "operations": [
+        {
+          "name": "runCommand",
+          "object": "database",
+          "command_name": "ping",
+          "arguments": {
+            "command": {
+              "ping": 1
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command_name": "ping",
+            "database_name": "test",
+            "command": {
+              "ping": 1
+            }
+          }
+        }
+      ]
+    }
+  ]
+}
\ No newline at end of file
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/change-streams/README.rst b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/change-streams/README.rst
new file mode 100644
index 0000000000000000000000000000000000000000..8472d1f6ce4c4f8fa581af1333bdaa88b4ab66ee
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/change-streams/README.rst	
@@ -0,0 +1,203 @@
+.. role:: javascript(code)
+  :language: javascript
+
+==============
+Change Streams
+==============
+
+.. contents::
+
+--------
+
+Introduction
+============
+
+The YAML and JSON files in this directory are platform-independent tests that
+drivers can use to prove their conformance to the Change Streams Spec.
+
+Several prose tests, which are not easily expressed in YAML, are also presented
+in this file. Those tests will need to be manually implemented by each driver.
+
+Spec Test Format
+================
+
+Each YAML file has the following keys:
+
+- ``database_name``: The default database
+- ``collection_name``: The default collection
+- ``database2_name``: Another database
+- ``collection2_name``: Another collection
+- ``tests``: An array of tests that are to be run independently of each other.
+  Each test will have some of the following fields:
+
+  - ``description``: The name of the test.
+  - ``minServerVersion``: The minimum server version to run this test against. If not present, assume there is no minimum server version.
+  - ``maxServerVersion``: Reserved for later use
+  - ``failPoint``(optional): The configureFailPoint command document to run to configure a fail point on the primary server.
+  - ``target``: The entity on which to run the change stream. Valid values are:
+  
+    - ``collection``: Watch changes on collection ``database_name.collection_name``
+    - ``database``: Watch changes on database ``database_name``
+    - ``client``: Watch changes on entire clusters
+  - ``topology``: An array of server topologies against which to run the test.
+    Valid topologies are ``single``, ``replicaset``, and ``sharded``.
+  - ``changeStreamPipeline``: An array of additional aggregation pipeline stages to add to the change stream
+  - ``changeStreamOptions``: Additional options to add to the changeStream
+  - ``operations``: Array of documents, each describing an operation. Each document has the following fields:
+
+    - ``database``: Database against which to run the operation
+    - ``collection``: Collection against which to run the operation
+    - ``name``: Name of the command to run
+    - ``arguments`` (optional): Object of arguments for the command (ex: document to insert)
+
+  - ``expectations``: Optional list of command-started events in Extended JSON format
+  - ``result``: Document with ONE of the following fields:
+
+    - ``error``: Describes an error received during the test
+    - ``success``: An Extended JSON array of documents expected to be received from the changeStream
+
+Spec Test Match Function
+========================
+
+The definition of MATCH or MATCHES in the Spec Test Runner is as follows:
+
+- MATCH takes two values, ``expected`` and ``actual``
+- Notation is "Assert [actual] MATCHES [expected]
+- Assertion passes if ``expected`` is a subset of ``actual``, with the values ``42`` and ``"42"`` acting as placeholders for "any value"
+
+Pseudocode implementation of ``actual`` MATCHES ``expected``:
+
+::
+  
+  If expected is "42" or 42:
+    Assert that actual exists (is not null or undefined)
+  Else:
+    Assert that actual is of the same JSON type as expected
+    If expected is a JSON array:
+      For every idx/value in expected:
+        Assert that actual[idx] MATCHES value
+    Else if expected is a JSON object:
+      For every key/value in expected
+        Assert that actual[key] MATCHES value
+    Else:
+      Assert that expected equals actual
+
+The expected values for ``result.success`` and ``expectations`` are written in Extended JSON. Drivers may adopt any of the following approaches to comparisons, as long as they are consistent:
+
+- Convert ``actual`` to Extended JSON and compare to ``expected``
+- Convert ``expected`` and ``actual`` to BSON, and compare them
+- Convert ``expected`` and ``actual`` to native equivalents of JSON, and compare them
+
+Spec Test Runner
+================
+
+Before running the tests
+
+- Create a MongoClient ``globalClient``, and connect to the server
+
+For each YAML file, for each element in ``tests``:
+
+- If ``topology`` does not include the topology of the server instance(s), skip this test.
+- Use ``globalClient`` to
+
+  - Drop the database ``database_name``
+  - Drop the database ``database2_name``
+  - Create the database ``database_name`` and the collection ``database_name.collection_name``
+  - Create the database ``database2_name`` and the collection ``database2_name.collection2_name``
+  - If the the ``failPoint`` field is present, configure the fail point on the primary server. See
+    `Server Fail Point <../../transactions/tests#server-fail-point>`_ in the
+    Transactions spec test documentation for more information.
+
+- Create a new MongoClient ``client``
+- Begin monitoring all APM events for ``client``. (If the driver uses global listeners, filter out all events that do not originate with ``client``). Filter out any "internal" commands (e.g. ``isMaster``)
+- Using ``client``, create a changeStream ``changeStream`` against the specified ``target``. Use ``changeStreamPipeline`` and ``changeStreamOptions`` if they are non-empty
+- Using ``globalClient``, run every operation in ``operations`` in serial against the server
+- Wait until either:
+
+  - An error occurs
+  - All operations have been successful AND the changeStream has received as many changes as there are in ``result.success``
+
+- Close ``changeStream``
+- If there was an error:
+
+  - Assert that an error was expected for the test.
+  - Assert that the error MATCHES ``result.error``
+
+- Else:
+
+  - Assert that no error was expected for the test
+  - Assert that the changes received from ``changeStream`` MATCH the results in ``result.success``
+
+- If there are any ``expectations``
+
+  - For each (``expected``, ``idx``) in ``expectations``
+
+    - Assert that ``actual[idx]`` MATCHES ``expected``
+
+- Close the MongoClient ``client``
+
+After running all tests
+
+- Close the MongoClient ``globalClient``
+- Drop database ``database_name``
+- Drop database ``database2_name``
+
+
+Prose Tests
+===========
+
+The following tests have not yet been automated, but MUST still be tested
+
+#. ``ChangeStream`` must continuously track the last seen ``resumeToken``
+#. ``ChangeStream`` will throw an exception if the server response is missing the resume token (if wire version is < 8, this is a driver-side error; for 8+, this is a server-side error)
+#. ``ChangeStream`` will automatically resume one time on a resumable error (including `not master`) with the initial pipeline and options, except for the addition/update of a ``resumeToken``.
+#. ``ChangeStream`` will not attempt to resume on any error encountered while executing an ``aggregate`` command.
+#. ``ChangeStream`` will not attempt to resume after encountering error code 11601 (Interrupted), 136 (CappedPositionLost), or 237 (CursorKilled) while executing a ``getMore`` command.
+#. ``ChangeStream`` will perform server selection before attempting to resume, using initial ``readPreference``
+#. Ensure that a cursor returned from an aggregate command with a cursor id and an initial empty batch is not closed on the driver side.
+#. The ``killCursors`` command sent during the "Resume Process" must not be allowed to throw an exception.
+#. ``$changeStream`` stage for ``ChangeStream`` against a server ``>=4.0`` and ``<4.0.7`` that has not received any results yet MUST include a ``startAtOperationTime`` option when resuming a changestream.
+#. ``ChangeStream`` will resume after a ``killCursors`` command is issued for its child cursor.
+#. - For a ``ChangeStream`` under these conditions:
+      - Running against a server ``>=4.0.7``.
+      - The batch is empty or has been iterated to the last document.
+   - Expected result: 
+       - ``getResumeToken`` must return the ``postBatchResumeToken`` from the current command response.
+#. - For a ``ChangeStream`` under these conditions:
+      - Running against a server ``<4.0.7``.
+      - The batch is empty or has been iterated to the last document.
+   - Expected result: 
+      - ``getResumeToken`` must return the ``_id`` of the last document returned if one exists.
+      - ``getResumeToken`` must return ``startAfter`` from the initial aggregate if the option was specified.
+      - ``getResumeToken`` must return ``resumeAfter`` from the initial aggregate if the option was specified.
+      - If neither the ``startAfter`` nor ``resumeAfter`` options were specified, the ``getResumeToken`` result must be empty.
+#. - For a ``ChangeStream`` under these conditions:
+      - The batch is not empty.
+      - The batch has been iterated up to but not including the last element.
+   - Expected result:
+      - ``getResumeToken`` must return the ``_id`` of the previous document returned.
+#. - For a ``ChangeStream`` under these conditions:
+      - The batch is not empty.
+      - The batch hasn’t been iterated at all.
+      - Only the initial ``aggregate`` command has been executed.
+   - Expected result:
+      - ``getResumeToken`` must return ``startAfter`` from the initial aggregate if the option was specified.
+      - ``getResumeToken`` must return ``resumeAfter`` from the initial aggregate if the option was specified.
+      - If neither the ``startAfter`` nor ``resumeAfter`` options were specified, the ``getResumeToken`` result must be empty.
+#. - For a ``ChangeStream`` under these conditions:
+      - Running against a server ``>=4.0.7``.
+      - The batch is not empty.
+      - The batch hasn’t been iterated at all.
+      - The stream has iterated beyond a previous batch and a ``getMore`` command has just been executed.
+   - Expected result:
+      - ``getResumeToken`` must return the ``postBatchResumeToken`` from the previous command response.
+#. - For a ``ChangeStream`` under these conditions:
+      - Running against a server ``<4.0.7``.
+      - The batch is not empty.
+      - The batch hasn’t been iterated at all.
+      - The stream has iterated beyond a previous batch and a ``getMore`` command has just been executed.
+   - Expected result:
+      - ``getResumeToken`` must return the ``_id`` of the previous document returned if one exists.
+      - ``getResumeToken`` must return ``startAfter`` from the initial aggregate if the option was specified.
+      - ``getResumeToken`` must return ``resumeAfter`` from the initial aggregate if the option was specified.
+      - If neither the ``startAfter`` nor ``resumeAfter`` options were specified, the ``getResumeToken`` result must be empty.
\ No newline at end of file
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/change-streams/change-streams-errors.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/change-streams/change-streams-errors.json
new file mode 100644
index 0000000000000000000000000000000000000000..f0ae14ebc60e7528b6380dc6a44b36f936425d8a
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/change-streams/change-streams-errors.json	
@@ -0,0 +1,151 @@
+{
+  "collection_name": "test",
+  "database_name": "change-stream-tests",
+  "collection2_name": "test2",
+  "database2_name": "change-stream-tests-2",
+  "tests": [
+    {
+      "description": "The watch helper must not throw a custom exception when executed against a single server topology, but instead depend on a server error",
+      "minServerVersion": "3.6.0",
+      "target": "collection",
+      "topology": [
+        "single"
+      ],
+      "changeStreamPipeline": [],
+      "changeStreamOptions": {},
+      "operations": [],
+      "expectations": null,
+      "result": {
+        "error": {
+          "code": 40573
+        }
+      }
+    },
+    {
+      "description": "Change Stream should error when an invalid aggregation stage is passed in",
+      "minServerVersion": "3.6.0",
+      "target": "collection",
+      "topology": [
+        "replicaset"
+      ],
+      "changeStreamPipeline": [
+        {
+          "$unsupported": "foo"
+        }
+      ],
+      "changeStreamOptions": {},
+      "operations": [
+        {
+          "database": "change-stream-tests",
+          "collection": "test",
+          "name": "insertOne",
+          "arguments": {
+            "document": {
+              "z": 3
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                },
+                {
+                  "$unsupported": "foo"
+                }
+              ]
+            },
+            "command_name": "aggregate",
+            "database_name": "change-stream-tests"
+          }
+        }
+      ],
+      "result": {
+        "error": {
+          "code": 40324
+        }
+      }
+    },
+    {
+      "description": "Change Stream should error when _id is projected out",
+      "minServerVersion": "4.1.11",
+      "target": "collection",
+      "topology": [
+        "replicaset",
+        "sharded"
+      ],
+      "changeStreamPipeline": [
+        {
+          "$project": {
+            "_id": 0
+          }
+        }
+      ],
+      "changeStreamOptions": {},
+      "operations": [
+        {
+          "database": "change-stream-tests",
+          "collection": "test",
+          "name": "insertOne",
+          "arguments": {
+            "document": {
+              "z": 3
+            }
+          }
+        }
+      ],
+      "result": {
+        "error": {
+          "code": 280
+        }
+      }
+    },
+    {
+      "description": "change stream errors on ElectionInProgress",
+      "minServerVersion": "4.2",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "getMore"
+          ],
+          "errorCode": 216,
+          "closeConnection": false
+        }
+      },
+      "target": "collection",
+      "topology": [
+        "replicaset",
+        "sharded"
+      ],
+      "changeStreamPipeline": [],
+      "changeStreamOptions": {},
+      "operations": [
+        {
+          "database": "change-stream-tests",
+          "collection": "test",
+          "name": "insertOne",
+          "arguments": {
+            "document": {
+              "z": 3
+            }
+          }
+        }
+      ],
+      "result": {
+        "error": {
+          "code": 216
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/change-streams/change-streams-resume-errorLabels.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/change-streams/change-streams-resume-errorLabels.json
new file mode 100644
index 0000000000000000000000000000000000000000..cf8957b21f2ffb70c687d8c53e5c027d961236e8
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/change-streams/change-streams-resume-errorLabels.json	
@@ -0,0 +1,1634 @@
+{
+  "collection_name": "test",
+  "database_name": "change-stream-tests",
+  "tests": [
+    {
+      "description": "change stream resumes after HostUnreachable",
+      "minServerVersion": "4.3.1",
+      "failPoint": {
+        "configureFailPoint": "failGetMoreAfterCursorCheckout",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "errorCode": 6,
+          "closeConnection": false
+        }
+      },
+      "target": "collection",
+      "topology": [
+        "replicaset",
+        "sharded"
+      ],
+      "changeStreamPipeline": [],
+      "changeStreamOptions": {},
+      "operations": [
+        {
+          "database": "change-stream-tests",
+          "collection": "test",
+          "name": "insertOne",
+          "arguments": {
+            "document": {
+              "x": 1
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "command_name": "aggregate",
+            "database_name": "change-stream-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "getMore": 42,
+              "collection": "test"
+            },
+            "command_name": "getMore",
+            "database_name": "change-stream-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "command_name": "aggregate",
+            "database_name": "change-stream-tests"
+          }
+        }
+      ],
+      "result": {
+        "success": [
+          {
+            "_id": "42",
+            "documentKey": "42",
+            "operationType": "insert",
+            "ns": {
+              "db": "change-stream-tests",
+              "coll": "test"
+            },
+            "fullDocument": {
+              "x": {
+                "$numberInt": "1"
+              }
+            }
+          }
+        ]
+      }
+    },
+    {
+      "description": "change stream resumes after HostNotFound",
+      "minServerVersion": "4.3.1",
+      "failPoint": {
+        "configureFailPoint": "failGetMoreAfterCursorCheckout",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "errorCode": 7,
+          "closeConnection": false
+        }
+      },
+      "target": "collection",
+      "topology": [
+        "replicaset",
+        "sharded"
+      ],
+      "changeStreamPipeline": [],
+      "changeStreamOptions": {},
+      "operations": [
+        {
+          "database": "change-stream-tests",
+          "collection": "test",
+          "name": "insertOne",
+          "arguments": {
+            "document": {
+              "x": 1
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "command_name": "aggregate",
+            "database_name": "change-stream-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "getMore": 42,
+              "collection": "test"
+            },
+            "command_name": "getMore",
+            "database_name": "change-stream-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "command_name": "aggregate",
+            "database_name": "change-stream-tests"
+          }
+        }
+      ],
+      "result": {
+        "success": [
+          {
+            "_id": "42",
+            "documentKey": "42",
+            "operationType": "insert",
+            "ns": {
+              "db": "change-stream-tests",
+              "coll": "test"
+            },
+            "fullDocument": {
+              "x": {
+                "$numberInt": "1"
+              }
+            }
+          }
+        ]
+      }
+    },
+    {
+      "description": "change stream resumes after NetworkTimeout",
+      "minServerVersion": "4.3.1",
+      "failPoint": {
+        "configureFailPoint": "failGetMoreAfterCursorCheckout",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "errorCode": 89,
+          "closeConnection": false
+        }
+      },
+      "target": "collection",
+      "topology": [
+        "replicaset",
+        "sharded"
+      ],
+      "changeStreamPipeline": [],
+      "changeStreamOptions": {},
+      "operations": [
+        {
+          "database": "change-stream-tests",
+          "collection": "test",
+          "name": "insertOne",
+          "arguments": {
+            "document": {
+              "x": 1
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "command_name": "aggregate",
+            "database_name": "change-stream-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "getMore": 42,
+              "collection": "test"
+            },
+            "command_name": "getMore",
+            "database_name": "change-stream-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "command_name": "aggregate",
+            "database_name": "change-stream-tests"
+          }
+        }
+      ],
+      "result": {
+        "success": [
+          {
+            "_id": "42",
+            "documentKey": "42",
+            "operationType": "insert",
+            "ns": {
+              "db": "change-stream-tests",
+              "coll": "test"
+            },
+            "fullDocument": {
+              "x": {
+                "$numberInt": "1"
+              }
+            }
+          }
+        ]
+      }
+    },
+    {
+      "description": "change stream resumes after ShutdownInProgress",
+      "minServerVersion": "4.3.1",
+      "failPoint": {
+        "configureFailPoint": "failGetMoreAfterCursorCheckout",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "errorCode": 91,
+          "closeConnection": false
+        }
+      },
+      "target": "collection",
+      "topology": [
+        "replicaset",
+        "sharded"
+      ],
+      "changeStreamPipeline": [],
+      "changeStreamOptions": {},
+      "operations": [
+        {
+          "database": "change-stream-tests",
+          "collection": "test",
+          "name": "insertOne",
+          "arguments": {
+            "document": {
+              "x": 1
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "command_name": "aggregate",
+            "database_name": "change-stream-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "getMore": 42,
+              "collection": "test"
+            },
+            "command_name": "getMore",
+            "database_name": "change-stream-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "command_name": "aggregate",
+            "database_name": "change-stream-tests"
+          }
+        }
+      ],
+      "result": {
+        "success": [
+          {
+            "_id": "42",
+            "documentKey": "42",
+            "operationType": "insert",
+            "ns": {
+              "db": "change-stream-tests",
+              "coll": "test"
+            },
+            "fullDocument": {
+              "x": {
+                "$numberInt": "1"
+              }
+            }
+          }
+        ]
+      }
+    },
+    {
+      "description": "change stream resumes after PrimarySteppedDown",
+      "minServerVersion": "4.3.1",
+      "failPoint": {
+        "configureFailPoint": "failGetMoreAfterCursorCheckout",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "errorCode": 189,
+          "closeConnection": false
+        }
+      },
+      "target": "collection",
+      "topology": [
+        "replicaset",
+        "sharded"
+      ],
+      "changeStreamPipeline": [],
+      "changeStreamOptions": {},
+      "operations": [
+        {
+          "database": "change-stream-tests",
+          "collection": "test",
+          "name": "insertOne",
+          "arguments": {
+            "document": {
+              "x": 1
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "command_name": "aggregate",
+            "database_name": "change-stream-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "getMore": 42,
+              "collection": "test"
+            },
+            "command_name": "getMore",
+            "database_name": "change-stream-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "command_name": "aggregate",
+            "database_name": "change-stream-tests"
+          }
+        }
+      ],
+      "result": {
+        "success": [
+          {
+            "_id": "42",
+            "documentKey": "42",
+            "operationType": "insert",
+            "ns": {
+              "db": "change-stream-tests",
+              "coll": "test"
+            },
+            "fullDocument": {
+              "x": {
+                "$numberInt": "1"
+              }
+            }
+          }
+        ]
+      }
+    },
+    {
+      "description": "change stream resumes after ExceededTimeLimit",
+      "minServerVersion": "4.3.1",
+      "failPoint": {
+        "configureFailPoint": "failGetMoreAfterCursorCheckout",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "errorCode": 262,
+          "closeConnection": false
+        }
+      },
+      "target": "collection",
+      "topology": [
+        "replicaset",
+        "sharded"
+      ],
+      "changeStreamPipeline": [],
+      "changeStreamOptions": {},
+      "operations": [
+        {
+          "database": "change-stream-tests",
+          "collection": "test",
+          "name": "insertOne",
+          "arguments": {
+            "document": {
+              "x": 1
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "command_name": "aggregate",
+            "database_name": "change-stream-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "getMore": 42,
+              "collection": "test"
+            },
+            "command_name": "getMore",
+            "database_name": "change-stream-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "command_name": "aggregate",
+            "database_name": "change-stream-tests"
+          }
+        }
+      ],
+      "result": {
+        "success": [
+          {
+            "_id": "42",
+            "documentKey": "42",
+            "operationType": "insert",
+            "ns": {
+              "db": "change-stream-tests",
+              "coll": "test"
+            },
+            "fullDocument": {
+              "x": {
+                "$numberInt": "1"
+              }
+            }
+          }
+        ]
+      }
+    },
+    {
+      "description": "change stream resumes after SocketException",
+      "minServerVersion": "4.3.1",
+      "failPoint": {
+        "configureFailPoint": "failGetMoreAfterCursorCheckout",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "errorCode": 9001,
+          "closeConnection": false
+        }
+      },
+      "target": "collection",
+      "topology": [
+        "replicaset",
+        "sharded"
+      ],
+      "changeStreamPipeline": [],
+      "changeStreamOptions": {},
+      "operations": [
+        {
+          "database": "change-stream-tests",
+          "collection": "test",
+          "name": "insertOne",
+          "arguments": {
+            "document": {
+              "x": 1
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "command_name": "aggregate",
+            "database_name": "change-stream-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "getMore": 42,
+              "collection": "test"
+            },
+            "command_name": "getMore",
+            "database_name": "change-stream-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "command_name": "aggregate",
+            "database_name": "change-stream-tests"
+          }
+        }
+      ],
+      "result": {
+        "success": [
+          {
+            "_id": "42",
+            "documentKey": "42",
+            "operationType": "insert",
+            "ns": {
+              "db": "change-stream-tests",
+              "coll": "test"
+            },
+            "fullDocument": {
+              "x": {
+                "$numberInt": "1"
+              }
+            }
+          }
+        ]
+      }
+    },
+    {
+      "description": "change stream resumes after NotMaster",
+      "minServerVersion": "4.3.1",
+      "failPoint": {
+        "configureFailPoint": "failGetMoreAfterCursorCheckout",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "errorCode": 10107,
+          "closeConnection": false
+        }
+      },
+      "target": "collection",
+      "topology": [
+        "replicaset",
+        "sharded"
+      ],
+      "changeStreamPipeline": [],
+      "changeStreamOptions": {},
+      "operations": [
+        {
+          "database": "change-stream-tests",
+          "collection": "test",
+          "name": "insertOne",
+          "arguments": {
+            "document": {
+              "x": 1
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "command_name": "aggregate",
+            "database_name": "change-stream-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "getMore": 42,
+              "collection": "test"
+            },
+            "command_name": "getMore",
+            "database_name": "change-stream-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "command_name": "aggregate",
+            "database_name": "change-stream-tests"
+          }
+        }
+      ],
+      "result": {
+        "success": [
+          {
+            "_id": "42",
+            "documentKey": "42",
+            "operationType": "insert",
+            "ns": {
+              "db": "change-stream-tests",
+              "coll": "test"
+            },
+            "fullDocument": {
+              "x": {
+                "$numberInt": "1"
+              }
+            }
+          }
+        ]
+      }
+    },
+    {
+      "description": "change stream resumes after InterruptedAtShutdown",
+      "minServerVersion": "4.3.1",
+      "failPoint": {
+        "configureFailPoint": "failGetMoreAfterCursorCheckout",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "errorCode": 11600,
+          "closeConnection": false
+        }
+      },
+      "target": "collection",
+      "topology": [
+        "replicaset",
+        "sharded"
+      ],
+      "changeStreamPipeline": [],
+      "changeStreamOptions": {},
+      "operations": [
+        {
+          "database": "change-stream-tests",
+          "collection": "test",
+          "name": "insertOne",
+          "arguments": {
+            "document": {
+              "x": 1
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "command_name": "aggregate",
+            "database_name": "change-stream-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "getMore": 42,
+              "collection": "test"
+            },
+            "command_name": "getMore",
+            "database_name": "change-stream-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "command_name": "aggregate",
+            "database_name": "change-stream-tests"
+          }
+        }
+      ],
+      "result": {
+        "success": [
+          {
+            "_id": "42",
+            "documentKey": "42",
+            "operationType": "insert",
+            "ns": {
+              "db": "change-stream-tests",
+              "coll": "test"
+            },
+            "fullDocument": {
+              "x": {
+                "$numberInt": "1"
+              }
+            }
+          }
+        ]
+      }
+    },
+    {
+      "description": "change stream resumes after InterruptedDueToReplStateChange",
+      "minServerVersion": "4.3.1",
+      "failPoint": {
+        "configureFailPoint": "failGetMoreAfterCursorCheckout",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "errorCode": 11602,
+          "closeConnection": false
+        }
+      },
+      "target": "collection",
+      "topology": [
+        "replicaset",
+        "sharded"
+      ],
+      "changeStreamPipeline": [],
+      "changeStreamOptions": {},
+      "operations": [
+        {
+          "database": "change-stream-tests",
+          "collection": "test",
+          "name": "insertOne",
+          "arguments": {
+            "document": {
+              "x": 1
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "command_name": "aggregate",
+            "database_name": "change-stream-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "getMore": 42,
+              "collection": "test"
+            },
+            "command_name": "getMore",
+            "database_name": "change-stream-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "command_name": "aggregate",
+            "database_name": "change-stream-tests"
+          }
+        }
+      ],
+      "result": {
+        "success": [
+          {
+            "_id": "42",
+            "documentKey": "42",
+            "operationType": "insert",
+            "ns": {
+              "db": "change-stream-tests",
+              "coll": "test"
+            },
+            "fullDocument": {
+              "x": {
+                "$numberInt": "1"
+              }
+            }
+          }
+        ]
+      }
+    },
+    {
+      "description": "change stream resumes after NotMasterNoSlaveOk",
+      "minServerVersion": "4.3.1",
+      "failPoint": {
+        "configureFailPoint": "failGetMoreAfterCursorCheckout",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "errorCode": 13435,
+          "closeConnection": false
+        }
+      },
+      "target": "collection",
+      "topology": [
+        "replicaset",
+        "sharded"
+      ],
+      "changeStreamPipeline": [],
+      "changeStreamOptions": {},
+      "operations": [
+        {
+          "database": "change-stream-tests",
+          "collection": "test",
+          "name": "insertOne",
+          "arguments": {
+            "document": {
+              "x": 1
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "command_name": "aggregate",
+            "database_name": "change-stream-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "getMore": 42,
+              "collection": "test"
+            },
+            "command_name": "getMore",
+            "database_name": "change-stream-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "command_name": "aggregate",
+            "database_name": "change-stream-tests"
+          }
+        }
+      ],
+      "result": {
+        "success": [
+          {
+            "_id": "42",
+            "documentKey": "42",
+            "operationType": "insert",
+            "ns": {
+              "db": "change-stream-tests",
+              "coll": "test"
+            },
+            "fullDocument": {
+              "x": {
+                "$numberInt": "1"
+              }
+            }
+          }
+        ]
+      }
+    },
+    {
+      "description": "change stream resumes after NotMasterOrSecondary",
+      "minServerVersion": "4.3.1",
+      "failPoint": {
+        "configureFailPoint": "failGetMoreAfterCursorCheckout",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "errorCode": 13436,
+          "closeConnection": false
+        }
+      },
+      "target": "collection",
+      "topology": [
+        "replicaset",
+        "sharded"
+      ],
+      "changeStreamPipeline": [],
+      "changeStreamOptions": {},
+      "operations": [
+        {
+          "database": "change-stream-tests",
+          "collection": "test",
+          "name": "insertOne",
+          "arguments": {
+            "document": {
+              "x": 1
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "command_name": "aggregate",
+            "database_name": "change-stream-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "getMore": 42,
+              "collection": "test"
+            },
+            "command_name": "getMore",
+            "database_name": "change-stream-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "command_name": "aggregate",
+            "database_name": "change-stream-tests"
+          }
+        }
+      ],
+      "result": {
+        "success": [
+          {
+            "_id": "42",
+            "documentKey": "42",
+            "operationType": "insert",
+            "ns": {
+              "db": "change-stream-tests",
+              "coll": "test"
+            },
+            "fullDocument": {
+              "x": {
+                "$numberInt": "1"
+              }
+            }
+          }
+        ]
+      }
+    },
+    {
+      "description": "change stream resumes after StaleShardVersion",
+      "minServerVersion": "4.3.1",
+      "failPoint": {
+        "configureFailPoint": "failGetMoreAfterCursorCheckout",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "errorCode": 63,
+          "closeConnection": false
+        }
+      },
+      "target": "collection",
+      "topology": [
+        "replicaset",
+        "sharded"
+      ],
+      "changeStreamPipeline": [],
+      "changeStreamOptions": {},
+      "operations": [
+        {
+          "database": "change-stream-tests",
+          "collection": "test",
+          "name": "insertOne",
+          "arguments": {
+            "document": {
+              "x": 1
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "command_name": "aggregate",
+            "database_name": "change-stream-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "getMore": 42,
+              "collection": "test"
+            },
+            "command_name": "getMore",
+            "database_name": "change-stream-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "command_name": "aggregate",
+            "database_name": "change-stream-tests"
+          }
+        }
+      ],
+      "result": {
+        "success": [
+          {
+            "_id": "42",
+            "documentKey": "42",
+            "operationType": "insert",
+            "ns": {
+              "db": "change-stream-tests",
+              "coll": "test"
+            },
+            "fullDocument": {
+              "x": {
+                "$numberInt": "1"
+              }
+            }
+          }
+        ]
+      }
+    },
+    {
+      "description": "change stream resumes after StaleEpoch",
+      "minServerVersion": "4.3.1",
+      "failPoint": {
+        "configureFailPoint": "failGetMoreAfterCursorCheckout",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "errorCode": 150,
+          "closeConnection": false
+        }
+      },
+      "target": "collection",
+      "topology": [
+        "replicaset",
+        "sharded"
+      ],
+      "changeStreamPipeline": [],
+      "changeStreamOptions": {},
+      "operations": [
+        {
+          "database": "change-stream-tests",
+          "collection": "test",
+          "name": "insertOne",
+          "arguments": {
+            "document": {
+              "x": 1
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "command_name": "aggregate",
+            "database_name": "change-stream-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "getMore": 42,
+              "collection": "test"
+            },
+            "command_name": "getMore",
+            "database_name": "change-stream-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "command_name": "aggregate",
+            "database_name": "change-stream-tests"
+          }
+        }
+      ],
+      "result": {
+        "success": [
+          {
+            "_id": "42",
+            "documentKey": "42",
+            "operationType": "insert",
+            "ns": {
+              "db": "change-stream-tests",
+              "coll": "test"
+            },
+            "fullDocument": {
+              "x": {
+                "$numberInt": "1"
+              }
+            }
+          }
+        ]
+      }
+    },
+    {
+      "description": "change stream resumes after RetryChangeStream",
+      "minServerVersion": "4.3.1",
+      "failPoint": {
+        "configureFailPoint": "failGetMoreAfterCursorCheckout",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "errorCode": 234,
+          "closeConnection": false
+        }
+      },
+      "target": "collection",
+      "topology": [
+        "replicaset",
+        "sharded"
+      ],
+      "changeStreamPipeline": [],
+      "changeStreamOptions": {},
+      "operations": [
+        {
+          "database": "change-stream-tests",
+          "collection": "test",
+          "name": "insertOne",
+          "arguments": {
+            "document": {
+              "x": 1
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "command_name": "aggregate",
+            "database_name": "change-stream-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "getMore": 42,
+              "collection": "test"
+            },
+            "command_name": "getMore",
+            "database_name": "change-stream-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "command_name": "aggregate",
+            "database_name": "change-stream-tests"
+          }
+        }
+      ],
+      "result": {
+        "success": [
+          {
+            "_id": "42",
+            "documentKey": "42",
+            "operationType": "insert",
+            "ns": {
+              "db": "change-stream-tests",
+              "coll": "test"
+            },
+            "fullDocument": {
+              "x": {
+                "$numberInt": "1"
+              }
+            }
+          }
+        ]
+      }
+    },
+    {
+      "description": "change stream resumes after FailedToSatisfyReadPreference",
+      "minServerVersion": "4.3.1",
+      "failPoint": {
+        "configureFailPoint": "failGetMoreAfterCursorCheckout",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "errorCode": 133,
+          "closeConnection": false
+        }
+      },
+      "target": "collection",
+      "topology": [
+        "replicaset",
+        "sharded"
+      ],
+      "changeStreamPipeline": [],
+      "changeStreamOptions": {},
+      "operations": [
+        {
+          "database": "change-stream-tests",
+          "collection": "test",
+          "name": "insertOne",
+          "arguments": {
+            "document": {
+              "x": 1
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "command_name": "aggregate",
+            "database_name": "change-stream-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "getMore": 42,
+              "collection": "test"
+            },
+            "command_name": "getMore",
+            "database_name": "change-stream-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "command_name": "aggregate",
+            "database_name": "change-stream-tests"
+          }
+        }
+      ],
+      "result": {
+        "success": [
+          {
+            "_id": "42",
+            "documentKey": "42",
+            "operationType": "insert",
+            "ns": {
+              "db": "change-stream-tests",
+              "coll": "test"
+            },
+            "fullDocument": {
+              "x": {
+                "$numberInt": "1"
+              }
+            }
+          }
+        ]
+      }
+    },
+    {
+      "description": "change stream resumes if error contains ResumableChangeStreamError",
+      "minServerVersion": "4.3.1",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "getMore"
+          ],
+          "errorCode": 50,
+          "closeConnection": false,
+          "errorLabels": [
+            "ResumableChangeStreamError"
+          ]
+        }
+      },
+      "target": "collection",
+      "topology": [
+        "replicaset",
+        "sharded"
+      ],
+      "changeStreamPipeline": [],
+      "changeStreamOptions": {},
+      "operations": [
+        {
+          "database": "change-stream-tests",
+          "collection": "test",
+          "name": "insertOne",
+          "arguments": {
+            "document": {
+              "x": 1
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "command_name": "aggregate",
+            "database_name": "change-stream-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "getMore": 42,
+              "collection": "test"
+            },
+            "command_name": "getMore",
+            "database_name": "change-stream-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "command_name": "aggregate",
+            "database_name": "change-stream-tests"
+          }
+        }
+      ],
+      "result": {
+        "success": [
+          {
+            "_id": "42",
+            "documentKey": "42",
+            "operationType": "insert",
+            "ns": {
+              "db": "change-stream-tests",
+              "coll": "test"
+            },
+            "fullDocument": {
+              "x": {
+                "$numberInt": "1"
+              }
+            }
+          }
+        ]
+      }
+    },
+    {
+      "description": "change stream does not resume if error does not contain ResumableChangeStreamError",
+      "minServerVersion": "4.3.1",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "getMore"
+          ],
+          "errorCode": 6,
+          "closeConnection": false
+        }
+      },
+      "target": "collection",
+      "topology": [
+        "replicaset",
+        "sharded"
+      ],
+      "changeStreamPipeline": [],
+      "changeStreamOptions": {},
+      "operations": [
+        {
+          "database": "change-stream-tests",
+          "collection": "test",
+          "name": "insertOne",
+          "arguments": {
+            "document": {
+              "x": 1
+            }
+          }
+        }
+      ],
+      "result": {
+        "error": {
+          "code": 6
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/change-streams/change-streams-resume-whitelist.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/change-streams/change-streams-resume-whitelist.json
new file mode 100644
index 0000000000000000000000000000000000000000..39f883ee5ec47ee9b8c59f5ef86a43614dacab21
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/change-streams/change-streams-resume-whitelist.json	
@@ -0,0 +1,1749 @@
+{
+  "collection_name": "test",
+  "database_name": "change-stream-tests",
+  "tests": [
+    {
+      "description": "change stream resumes after a network error",
+      "minServerVersion": "4.2",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "getMore"
+          ],
+          "closeConnection": true
+        }
+      },
+      "target": "collection",
+      "topology": [
+        "replicaset",
+        "sharded"
+      ],
+      "changeStreamPipeline": [],
+      "changeStreamOptions": {},
+      "operations": [
+        {
+          "database": "change-stream-tests",
+          "collection": "test",
+          "name": "insertOne",
+          "arguments": {
+            "document": {
+              "x": 1
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "command_name": "aggregate",
+            "database_name": "change-stream-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "getMore": 42,
+              "collection": "test"
+            },
+            "command_name": "getMore",
+            "database_name": "change-stream-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "command_name": "aggregate",
+            "database_name": "change-stream-tests"
+          }
+        }
+      ],
+      "result": {
+        "success": [
+          {
+            "_id": "42",
+            "documentKey": "42",
+            "operationType": "insert",
+            "ns": {
+              "db": "change-stream-tests",
+              "coll": "test"
+            },
+            "fullDocument": {
+              "x": {
+                "$numberInt": "1"
+              }
+            }
+          }
+        ]
+      }
+    },
+    {
+      "description": "change stream resumes after HostUnreachable",
+      "minServerVersion": "4.2",
+      "maxServerVersion": "4.2.99",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "getMore"
+          ],
+          "errorCode": 6,
+          "closeConnection": false
+        }
+      },
+      "target": "collection",
+      "topology": [
+        "replicaset",
+        "sharded"
+      ],
+      "changeStreamPipeline": [],
+      "changeStreamOptions": {},
+      "operations": [
+        {
+          "database": "change-stream-tests",
+          "collection": "test",
+          "name": "insertOne",
+          "arguments": {
+            "document": {
+              "x": 1
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "command_name": "aggregate",
+            "database_name": "change-stream-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "getMore": 42,
+              "collection": "test"
+            },
+            "command_name": "getMore",
+            "database_name": "change-stream-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "command_name": "aggregate",
+            "database_name": "change-stream-tests"
+          }
+        }
+      ],
+      "result": {
+        "success": [
+          {
+            "_id": "42",
+            "documentKey": "42",
+            "operationType": "insert",
+            "ns": {
+              "db": "change-stream-tests",
+              "coll": "test"
+            },
+            "fullDocument": {
+              "x": {
+                "$numberInt": "1"
+              }
+            }
+          }
+        ]
+      }
+    },
+    {
+      "description": "change stream resumes after HostNotFound",
+      "minServerVersion": "4.2",
+      "maxServerVersion": "4.2.99",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "getMore"
+          ],
+          "errorCode": 7,
+          "closeConnection": false
+        }
+      },
+      "target": "collection",
+      "topology": [
+        "replicaset",
+        "sharded"
+      ],
+      "changeStreamPipeline": [],
+      "changeStreamOptions": {},
+      "operations": [
+        {
+          "database": "change-stream-tests",
+          "collection": "test",
+          "name": "insertOne",
+          "arguments": {
+            "document": {
+              "x": 1
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "command_name": "aggregate",
+            "database_name": "change-stream-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "getMore": 42,
+              "collection": "test"
+            },
+            "command_name": "getMore",
+            "database_name": "change-stream-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "command_name": "aggregate",
+            "database_name": "change-stream-tests"
+          }
+        }
+      ],
+      "result": {
+        "success": [
+          {
+            "_id": "42",
+            "documentKey": "42",
+            "operationType": "insert",
+            "ns": {
+              "db": "change-stream-tests",
+              "coll": "test"
+            },
+            "fullDocument": {
+              "x": {
+                "$numberInt": "1"
+              }
+            }
+          }
+        ]
+      }
+    },
+    {
+      "description": "change stream resumes after NetworkTimeout",
+      "minServerVersion": "4.2",
+      "maxServerVersion": "4.2.99",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "getMore"
+          ],
+          "errorCode": 89,
+          "closeConnection": false
+        }
+      },
+      "target": "collection",
+      "topology": [
+        "replicaset",
+        "sharded"
+      ],
+      "changeStreamPipeline": [],
+      "changeStreamOptions": {},
+      "operations": [
+        {
+          "database": "change-stream-tests",
+          "collection": "test",
+          "name": "insertOne",
+          "arguments": {
+            "document": {
+              "x": 1
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "command_name": "aggregate",
+            "database_name": "change-stream-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "getMore": 42,
+              "collection": "test"
+            },
+            "command_name": "getMore",
+            "database_name": "change-stream-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "command_name": "aggregate",
+            "database_name": "change-stream-tests"
+          }
+        }
+      ],
+      "result": {
+        "success": [
+          {
+            "_id": "42",
+            "documentKey": "42",
+            "operationType": "insert",
+            "ns": {
+              "db": "change-stream-tests",
+              "coll": "test"
+            },
+            "fullDocument": {
+              "x": {
+                "$numberInt": "1"
+              }
+            }
+          }
+        ]
+      }
+    },
+    {
+      "description": "change stream resumes after ShutdownInProgress",
+      "minServerVersion": "4.2",
+      "maxServerVersion": "4.2.99",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "getMore"
+          ],
+          "errorCode": 91,
+          "closeConnection": false
+        }
+      },
+      "target": "collection",
+      "topology": [
+        "replicaset",
+        "sharded"
+      ],
+      "changeStreamPipeline": [],
+      "changeStreamOptions": {},
+      "operations": [
+        {
+          "database": "change-stream-tests",
+          "collection": "test",
+          "name": "insertOne",
+          "arguments": {
+            "document": {
+              "x": 1
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "command_name": "aggregate",
+            "database_name": "change-stream-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "getMore": 42,
+              "collection": "test"
+            },
+            "command_name": "getMore",
+            "database_name": "change-stream-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "command_name": "aggregate",
+            "database_name": "change-stream-tests"
+          }
+        }
+      ],
+      "result": {
+        "success": [
+          {
+            "_id": "42",
+            "documentKey": "42",
+            "operationType": "insert",
+            "ns": {
+              "db": "change-stream-tests",
+              "coll": "test"
+            },
+            "fullDocument": {
+              "x": {
+                "$numberInt": "1"
+              }
+            }
+          }
+        ]
+      }
+    },
+    {
+      "description": "change stream resumes after PrimarySteppedDown",
+      "minServerVersion": "4.2",
+      "maxServerVersion": "4.2.99",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "getMore"
+          ],
+          "errorCode": 189,
+          "closeConnection": false
+        }
+      },
+      "target": "collection",
+      "topology": [
+        "replicaset",
+        "sharded"
+      ],
+      "changeStreamPipeline": [],
+      "changeStreamOptions": {},
+      "operations": [
+        {
+          "database": "change-stream-tests",
+          "collection": "test",
+          "name": "insertOne",
+          "arguments": {
+            "document": {
+              "x": 1
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "command_name": "aggregate",
+            "database_name": "change-stream-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "getMore": 42,
+              "collection": "test"
+            },
+            "command_name": "getMore",
+            "database_name": "change-stream-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "command_name": "aggregate",
+            "database_name": "change-stream-tests"
+          }
+        }
+      ],
+      "result": {
+        "success": [
+          {
+            "_id": "42",
+            "documentKey": "42",
+            "operationType": "insert",
+            "ns": {
+              "db": "change-stream-tests",
+              "coll": "test"
+            },
+            "fullDocument": {
+              "x": {
+                "$numberInt": "1"
+              }
+            }
+          }
+        ]
+      }
+    },
+    {
+      "description": "change stream resumes after ExceededTimeLimit",
+      "minServerVersion": "4.2",
+      "maxServerVersion": "4.2.99",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "getMore"
+          ],
+          "errorCode": 262,
+          "closeConnection": false
+        }
+      },
+      "target": "collection",
+      "topology": [
+        "replicaset",
+        "sharded"
+      ],
+      "changeStreamPipeline": [],
+      "changeStreamOptions": {},
+      "operations": [
+        {
+          "database": "change-stream-tests",
+          "collection": "test",
+          "name": "insertOne",
+          "arguments": {
+            "document": {
+              "x": 1
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "command_name": "aggregate",
+            "database_name": "change-stream-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "getMore": 42,
+              "collection": "test"
+            },
+            "command_name": "getMore",
+            "database_name": "change-stream-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "command_name": "aggregate",
+            "database_name": "change-stream-tests"
+          }
+        }
+      ],
+      "result": {
+        "success": [
+          {
+            "_id": "42",
+            "documentKey": "42",
+            "operationType": "insert",
+            "ns": {
+              "db": "change-stream-tests",
+              "coll": "test"
+            },
+            "fullDocument": {
+              "x": {
+                "$numberInt": "1"
+              }
+            }
+          }
+        ]
+      }
+    },
+    {
+      "description": "change stream resumes after SocketException",
+      "minServerVersion": "4.2",
+      "maxServerVersion": "4.2.99",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "getMore"
+          ],
+          "errorCode": 9001,
+          "closeConnection": false
+        }
+      },
+      "target": "collection",
+      "topology": [
+        "replicaset",
+        "sharded"
+      ],
+      "changeStreamPipeline": [],
+      "changeStreamOptions": {},
+      "operations": [
+        {
+          "database": "change-stream-tests",
+          "collection": "test",
+          "name": "insertOne",
+          "arguments": {
+            "document": {
+              "x": 1
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "command_name": "aggregate",
+            "database_name": "change-stream-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "getMore": 42,
+              "collection": "test"
+            },
+            "command_name": "getMore",
+            "database_name": "change-stream-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "command_name": "aggregate",
+            "database_name": "change-stream-tests"
+          }
+        }
+      ],
+      "result": {
+        "success": [
+          {
+            "_id": "42",
+            "documentKey": "42",
+            "operationType": "insert",
+            "ns": {
+              "db": "change-stream-tests",
+              "coll": "test"
+            },
+            "fullDocument": {
+              "x": {
+                "$numberInt": "1"
+              }
+            }
+          }
+        ]
+      }
+    },
+    {
+      "description": "change stream resumes after NotMaster",
+      "minServerVersion": "4.2",
+      "maxServerVersion": "4.2.99",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "getMore"
+          ],
+          "errorCode": 10107,
+          "closeConnection": false
+        }
+      },
+      "target": "collection",
+      "topology": [
+        "replicaset",
+        "sharded"
+      ],
+      "changeStreamPipeline": [],
+      "changeStreamOptions": {},
+      "operations": [
+        {
+          "database": "change-stream-tests",
+          "collection": "test",
+          "name": "insertOne",
+          "arguments": {
+            "document": {
+              "x": 1
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "command_name": "aggregate",
+            "database_name": "change-stream-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "getMore": 42,
+              "collection": "test"
+            },
+            "command_name": "getMore",
+            "database_name": "change-stream-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "command_name": "aggregate",
+            "database_name": "change-stream-tests"
+          }
+        }
+      ],
+      "result": {
+        "success": [
+          {
+            "_id": "42",
+            "documentKey": "42",
+            "operationType": "insert",
+            "ns": {
+              "db": "change-stream-tests",
+              "coll": "test"
+            },
+            "fullDocument": {
+              "x": {
+                "$numberInt": "1"
+              }
+            }
+          }
+        ]
+      }
+    },
+    {
+      "description": "change stream resumes after InterruptedAtShutdown",
+      "minServerVersion": "4.2",
+      "maxServerVersion": "4.2.99",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "getMore"
+          ],
+          "errorCode": 11600,
+          "closeConnection": false
+        }
+      },
+      "target": "collection",
+      "topology": [
+        "replicaset",
+        "sharded"
+      ],
+      "changeStreamPipeline": [],
+      "changeStreamOptions": {},
+      "operations": [
+        {
+          "database": "change-stream-tests",
+          "collection": "test",
+          "name": "insertOne",
+          "arguments": {
+            "document": {
+              "x": 1
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "command_name": "aggregate",
+            "database_name": "change-stream-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "getMore": 42,
+              "collection": "test"
+            },
+            "command_name": "getMore",
+            "database_name": "change-stream-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "command_name": "aggregate",
+            "database_name": "change-stream-tests"
+          }
+        }
+      ],
+      "result": {
+        "success": [
+          {
+            "_id": "42",
+            "documentKey": "42",
+            "operationType": "insert",
+            "ns": {
+              "db": "change-stream-tests",
+              "coll": "test"
+            },
+            "fullDocument": {
+              "x": {
+                "$numberInt": "1"
+              }
+            }
+          }
+        ]
+      }
+    },
+    {
+      "description": "change stream resumes after InterruptedDueToReplStateChange",
+      "minServerVersion": "4.2",
+      "maxServerVersion": "4.2.99",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "getMore"
+          ],
+          "errorCode": 11602,
+          "closeConnection": false
+        }
+      },
+      "target": "collection",
+      "topology": [
+        "replicaset",
+        "sharded"
+      ],
+      "changeStreamPipeline": [],
+      "changeStreamOptions": {},
+      "operations": [
+        {
+          "database": "change-stream-tests",
+          "collection": "test",
+          "name": "insertOne",
+          "arguments": {
+            "document": {
+              "x": 1
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "command_name": "aggregate",
+            "database_name": "change-stream-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "getMore": 42,
+              "collection": "test"
+            },
+            "command_name": "getMore",
+            "database_name": "change-stream-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "command_name": "aggregate",
+            "database_name": "change-stream-tests"
+          }
+        }
+      ],
+      "result": {
+        "success": [
+          {
+            "_id": "42",
+            "documentKey": "42",
+            "operationType": "insert",
+            "ns": {
+              "db": "change-stream-tests",
+              "coll": "test"
+            },
+            "fullDocument": {
+              "x": {
+                "$numberInt": "1"
+              }
+            }
+          }
+        ]
+      }
+    },
+    {
+      "description": "change stream resumes after NotMasterNoSlaveOk",
+      "minServerVersion": "4.2",
+      "maxServerVersion": "4.2.99",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "getMore"
+          ],
+          "errorCode": 13435,
+          "closeConnection": false
+        }
+      },
+      "target": "collection",
+      "topology": [
+        "replicaset",
+        "sharded"
+      ],
+      "changeStreamPipeline": [],
+      "changeStreamOptions": {},
+      "operations": [
+        {
+          "database": "change-stream-tests",
+          "collection": "test",
+          "name": "insertOne",
+          "arguments": {
+            "document": {
+              "x": 1
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "command_name": "aggregate",
+            "database_name": "change-stream-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "getMore": 42,
+              "collection": "test"
+            },
+            "command_name": "getMore",
+            "database_name": "change-stream-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "command_name": "aggregate",
+            "database_name": "change-stream-tests"
+          }
+        }
+      ],
+      "result": {
+        "success": [
+          {
+            "_id": "42",
+            "documentKey": "42",
+            "operationType": "insert",
+            "ns": {
+              "db": "change-stream-tests",
+              "coll": "test"
+            },
+            "fullDocument": {
+              "x": {
+                "$numberInt": "1"
+              }
+            }
+          }
+        ]
+      }
+    },
+    {
+      "description": "change stream resumes after NotMasterOrSecondary",
+      "minServerVersion": "4.2",
+      "maxServerVersion": "4.2.99",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "getMore"
+          ],
+          "errorCode": 13436,
+          "closeConnection": false
+        }
+      },
+      "target": "collection",
+      "topology": [
+        "replicaset",
+        "sharded"
+      ],
+      "changeStreamPipeline": [],
+      "changeStreamOptions": {},
+      "operations": [
+        {
+          "database": "change-stream-tests",
+          "collection": "test",
+          "name": "insertOne",
+          "arguments": {
+            "document": {
+              "x": 1
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "command_name": "aggregate",
+            "database_name": "change-stream-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "getMore": 42,
+              "collection": "test"
+            },
+            "command_name": "getMore",
+            "database_name": "change-stream-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "command_name": "aggregate",
+            "database_name": "change-stream-tests"
+          }
+        }
+      ],
+      "result": {
+        "success": [
+          {
+            "_id": "42",
+            "documentKey": "42",
+            "operationType": "insert",
+            "ns": {
+              "db": "change-stream-tests",
+              "coll": "test"
+            },
+            "fullDocument": {
+              "x": {
+                "$numberInt": "1"
+              }
+            }
+          }
+        ]
+      }
+    },
+    {
+      "description": "change stream resumes after StaleShardVersion",
+      "minServerVersion": "4.2",
+      "maxServerVersion": "4.2.99",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "getMore"
+          ],
+          "errorCode": 63,
+          "closeConnection": false
+        }
+      },
+      "target": "collection",
+      "topology": [
+        "replicaset",
+        "sharded"
+      ],
+      "changeStreamPipeline": [],
+      "changeStreamOptions": {},
+      "operations": [
+        {
+          "database": "change-stream-tests",
+          "collection": "test",
+          "name": "insertOne",
+          "arguments": {
+            "document": {
+              "x": 1
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "command_name": "aggregate",
+            "database_name": "change-stream-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "getMore": 42,
+              "collection": "test"
+            },
+            "command_name": "getMore",
+            "database_name": "change-stream-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "command_name": "aggregate",
+            "database_name": "change-stream-tests"
+          }
+        }
+      ],
+      "result": {
+        "success": [
+          {
+            "_id": "42",
+            "documentKey": "42",
+            "operationType": "insert",
+            "ns": {
+              "db": "change-stream-tests",
+              "coll": "test"
+            },
+            "fullDocument": {
+              "x": {
+                "$numberInt": "1"
+              }
+            }
+          }
+        ]
+      }
+    },
+    {
+      "description": "change stream resumes after StaleEpoch",
+      "minServerVersion": "4.2",
+      "maxServerVersion": "4.2.99",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "getMore"
+          ],
+          "errorCode": 150,
+          "closeConnection": false
+        }
+      },
+      "target": "collection",
+      "topology": [
+        "replicaset",
+        "sharded"
+      ],
+      "changeStreamPipeline": [],
+      "changeStreamOptions": {},
+      "operations": [
+        {
+          "database": "change-stream-tests",
+          "collection": "test",
+          "name": "insertOne",
+          "arguments": {
+            "document": {
+              "x": 1
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "command_name": "aggregate",
+            "database_name": "change-stream-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "getMore": 42,
+              "collection": "test"
+            },
+            "command_name": "getMore",
+            "database_name": "change-stream-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "command_name": "aggregate",
+            "database_name": "change-stream-tests"
+          }
+        }
+      ],
+      "result": {
+        "success": [
+          {
+            "_id": "42",
+            "documentKey": "42",
+            "operationType": "insert",
+            "ns": {
+              "db": "change-stream-tests",
+              "coll": "test"
+            },
+            "fullDocument": {
+              "x": {
+                "$numberInt": "1"
+              }
+            }
+          }
+        ]
+      }
+    },
+    {
+      "description": "change stream resumes after RetryChangeStream",
+      "minServerVersion": "4.2",
+      "maxServerVersion": "4.2.99",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "getMore"
+          ],
+          "errorCode": 234,
+          "closeConnection": false
+        }
+      },
+      "target": "collection",
+      "topology": [
+        "replicaset",
+        "sharded"
+      ],
+      "changeStreamPipeline": [],
+      "changeStreamOptions": {},
+      "operations": [
+        {
+          "database": "change-stream-tests",
+          "collection": "test",
+          "name": "insertOne",
+          "arguments": {
+            "document": {
+              "x": 1
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "command_name": "aggregate",
+            "database_name": "change-stream-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "getMore": 42,
+              "collection": "test"
+            },
+            "command_name": "getMore",
+            "database_name": "change-stream-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "command_name": "aggregate",
+            "database_name": "change-stream-tests"
+          }
+        }
+      ],
+      "result": {
+        "success": [
+          {
+            "_id": "42",
+            "documentKey": "42",
+            "operationType": "insert",
+            "ns": {
+              "db": "change-stream-tests",
+              "coll": "test"
+            },
+            "fullDocument": {
+              "x": {
+                "$numberInt": "1"
+              }
+            }
+          }
+        ]
+      }
+    },
+    {
+      "description": "change stream resumes after FailedToSatisfyReadPreference",
+      "minServerVersion": "4.2",
+      "maxServerVersion": "4.2.99",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "getMore"
+          ],
+          "errorCode": 133,
+          "closeConnection": false
+        }
+      },
+      "target": "collection",
+      "topology": [
+        "replicaset",
+        "sharded"
+      ],
+      "changeStreamPipeline": [],
+      "changeStreamOptions": {},
+      "operations": [
+        {
+          "database": "change-stream-tests",
+          "collection": "test",
+          "name": "insertOne",
+          "arguments": {
+            "document": {
+              "x": 1
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "command_name": "aggregate",
+            "database_name": "change-stream-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "getMore": 42,
+              "collection": "test"
+            },
+            "command_name": "getMore",
+            "database_name": "change-stream-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "command_name": "aggregate",
+            "database_name": "change-stream-tests"
+          }
+        }
+      ],
+      "result": {
+        "success": [
+          {
+            "_id": "42",
+            "documentKey": "42",
+            "operationType": "insert",
+            "ns": {
+              "db": "change-stream-tests",
+              "coll": "test"
+            },
+            "fullDocument": {
+              "x": {
+                "$numberInt": "1"
+              }
+            }
+          }
+        ]
+      }
+    },
+    {
+      "description": "change stream resumes after CursorNotFound",
+      "minServerVersion": "4.2",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "getMore"
+          ],
+          "errorCode": 43,
+          "closeConnection": false
+        }
+      },
+      "target": "collection",
+      "topology": [
+        "replicaset",
+        "sharded"
+      ],
+      "changeStreamPipeline": [],
+      "changeStreamOptions": {},
+      "operations": [
+        {
+          "database": "change-stream-tests",
+          "collection": "test",
+          "name": "insertOne",
+          "arguments": {
+            "document": {
+              "x": 1
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "command_name": "aggregate",
+            "database_name": "change-stream-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "getMore": 42,
+              "collection": "test"
+            },
+            "command_name": "getMore",
+            "database_name": "change-stream-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "command_name": "aggregate",
+            "database_name": "change-stream-tests"
+          }
+        }
+      ],
+      "result": {
+        "success": [
+          {
+            "_id": "42",
+            "documentKey": "42",
+            "operationType": "insert",
+            "ns": {
+              "db": "change-stream-tests",
+              "coll": "test"
+            },
+            "fullDocument": {
+              "x": {
+                "$numberInt": "1"
+              }
+            }
+          }
+        ]
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/change-streams/change-streams.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/change-streams/change-streams.json
new file mode 100644
index 0000000000000000000000000000000000000000..54b76af0a3d1a15b4c744079100a781b56f29348
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/change-streams/change-streams.json	
@@ -0,0 +1,795 @@
+{
+  "collection_name": "test",
+  "database_name": "change-stream-tests",
+  "collection2_name": "test2",
+  "database2_name": "change-stream-tests-2",
+  "tests": [
+    {
+      "description": "$changeStream must be the first stage in a change stream pipeline sent to the server",
+      "minServerVersion": "3.6.0",
+      "target": "collection",
+      "topology": [
+        "replicaset"
+      ],
+      "changeStreamPipeline": [],
+      "changeStreamOptions": {},
+      "operations": [
+        {
+          "database": "change-stream-tests",
+          "collection": "test",
+          "name": "insertOne",
+          "arguments": {
+            "document": {
+              "x": 1
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "command_name": "aggregate",
+            "database_name": "change-stream-tests"
+          }
+        }
+      ],
+      "result": {
+        "success": [
+          {
+            "_id": "42",
+            "documentKey": "42",
+            "operationType": "insert",
+            "ns": {
+              "db": "change-stream-tests",
+              "coll": "test"
+            },
+            "fullDocument": {
+              "x": {
+                "$numberInt": "1"
+              }
+            }
+          }
+        ]
+      }
+    },
+    {
+      "description": "The server returns change stream responses in the specified server response format",
+      "minServerVersion": "3.6.0",
+      "target": "collection",
+      "topology": [
+        "replicaset"
+      ],
+      "changeStreamPipeline": [],
+      "changeStreamOptions": {},
+      "operations": [
+        {
+          "database": "change-stream-tests",
+          "collection": "test",
+          "name": "insertOne",
+          "arguments": {
+            "document": {
+              "x": 1
+            }
+          }
+        }
+      ],
+      "expectations": null,
+      "result": {
+        "success": [
+          {
+            "_id": "42",
+            "documentKey": "42",
+            "operationType": "insert",
+            "ns": {
+              "db": "change-stream-tests",
+              "coll": "test"
+            },
+            "fullDocument": {
+              "x": {
+                "$numberInt": "1"
+              }
+            }
+          }
+        ]
+      }
+    },
+    {
+      "description": "Executing a watch helper on a Collection results in notifications for changes to the specified collection",
+      "minServerVersion": "3.6.0",
+      "target": "collection",
+      "topology": [
+        "replicaset"
+      ],
+      "changeStreamPipeline": [],
+      "changeStreamOptions": {},
+      "operations": [
+        {
+          "database": "change-stream-tests",
+          "collection": "test2",
+          "name": "insertOne",
+          "arguments": {
+            "document": {
+              "x": 1
+            }
+          }
+        },
+        {
+          "database": "change-stream-tests-2",
+          "collection": "test",
+          "name": "insertOne",
+          "arguments": {
+            "document": {
+              "y": 2
+            }
+          }
+        },
+        {
+          "database": "change-stream-tests",
+          "collection": "test",
+          "name": "insertOne",
+          "arguments": {
+            "document": {
+              "z": 3
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "command_name": "aggregate",
+            "database_name": "change-stream-tests"
+          }
+        }
+      ],
+      "result": {
+        "success": [
+          {
+            "operationType": "insert",
+            "ns": {
+              "db": "change-stream-tests",
+              "coll": "test"
+            },
+            "fullDocument": {
+              "z": {
+                "$numberInt": "3"
+              }
+            }
+          }
+        ]
+      }
+    },
+    {
+      "description": "Change Stream should allow valid aggregate pipeline stages",
+      "minServerVersion": "3.6.0",
+      "target": "collection",
+      "topology": [
+        "replicaset"
+      ],
+      "changeStreamPipeline": [
+        {
+          "$match": {
+            "fullDocument.z": 3
+          }
+        }
+      ],
+      "changeStreamOptions": {},
+      "operations": [
+        {
+          "database": "change-stream-tests",
+          "collection": "test",
+          "name": "insertOne",
+          "arguments": {
+            "document": {
+              "y": 2
+            }
+          }
+        },
+        {
+          "database": "change-stream-tests",
+          "collection": "test",
+          "name": "insertOne",
+          "arguments": {
+            "document": {
+              "z": 3
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                },
+                {
+                  "$match": {
+                    "fullDocument.z": {
+                      "$numberInt": "3"
+                    }
+                  }
+                }
+              ]
+            },
+            "command_name": "aggregate",
+            "database_name": "change-stream-tests"
+          }
+        }
+      ],
+      "result": {
+        "success": [
+          {
+            "operationType": "insert",
+            "ns": {
+              "db": "change-stream-tests",
+              "coll": "test"
+            },
+            "fullDocument": {
+              "z": {
+                "$numberInt": "3"
+              }
+            }
+          }
+        ]
+      }
+    },
+    {
+      "description": "Executing a watch helper on a Database results in notifications for changes to all collections in the specified database.",
+      "minServerVersion": "3.8.0",
+      "target": "database",
+      "topology": [
+        "replicaset"
+      ],
+      "changeStreamPipeline": [],
+      "changeStreamOptions": {},
+      "operations": [
+        {
+          "database": "change-stream-tests",
+          "collection": "test2",
+          "name": "insertOne",
+          "arguments": {
+            "document": {
+              "x": 1
+            }
+          }
+        },
+        {
+          "database": "change-stream-tests-2",
+          "collection": "test",
+          "name": "insertOne",
+          "arguments": {
+            "document": {
+              "y": 2
+            }
+          }
+        },
+        {
+          "database": "change-stream-tests",
+          "collection": "test",
+          "name": "insertOne",
+          "arguments": {
+            "document": {
+              "z": 3
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": {
+                "$numberInt": "1"
+              },
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "command_name": "aggregate",
+            "database_name": "change-stream-tests"
+          }
+        }
+      ],
+      "result": {
+        "success": [
+          {
+            "operationType": "insert",
+            "ns": {
+              "db": "change-stream-tests",
+              "coll": "test2"
+            },
+            "fullDocument": {
+              "x": {
+                "$numberInt": "1"
+              }
+            }
+          },
+          {
+            "operationType": "insert",
+            "ns": {
+              "db": "change-stream-tests",
+              "coll": "test"
+            },
+            "fullDocument": {
+              "z": {
+                "$numberInt": "3"
+              }
+            }
+          }
+        ]
+      }
+    },
+    {
+      "description": "Executing a watch helper on a MongoClient results in notifications for changes to all collections in all databases in the cluster.",
+      "minServerVersion": "3.8.0",
+      "target": "client",
+      "topology": [
+        "replicaset"
+      ],
+      "changeStreamPipeline": [],
+      "changeStreamOptions": {},
+      "operations": [
+        {
+          "database": "change-stream-tests",
+          "collection": "test2",
+          "name": "insertOne",
+          "arguments": {
+            "document": {
+              "x": 1
+            }
+          }
+        },
+        {
+          "database": "change-stream-tests-2",
+          "collection": "test",
+          "name": "insertOne",
+          "arguments": {
+            "document": {
+              "y": 2
+            }
+          }
+        },
+        {
+          "database": "change-stream-tests",
+          "collection": "test",
+          "name": "insertOne",
+          "arguments": {
+            "document": {
+              "z": 3
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": {
+                "$numberInt": "1"
+              },
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {
+                    "allChangesForCluster": true
+                  }
+                }
+              ]
+            },
+            "command_name": "aggregate",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "result": {
+        "success": [
+          {
+            "operationType": "insert",
+            "ns": {
+              "db": "change-stream-tests",
+              "coll": "test2"
+            },
+            "fullDocument": {
+              "x": {
+                "$numberInt": "1"
+              }
+            }
+          },
+          {
+            "operationType": "insert",
+            "ns": {
+              "db": "change-stream-tests-2",
+              "coll": "test"
+            },
+            "fullDocument": {
+              "y": {
+                "$numberInt": "2"
+              }
+            }
+          },
+          {
+            "operationType": "insert",
+            "ns": {
+              "db": "change-stream-tests",
+              "coll": "test"
+            },
+            "fullDocument": {
+              "z": {
+                "$numberInt": "3"
+              }
+            }
+          }
+        ]
+      }
+    },
+    {
+      "description": "Test insert, update, replace, and delete event types",
+      "minServerVersion": "3.6.0",
+      "target": "collection",
+      "topology": [
+        "replicaset"
+      ],
+      "changeStreamPipeline": [],
+      "changeStreamOptions": {},
+      "operations": [
+        {
+          "database": "change-stream-tests",
+          "collection": "test",
+          "name": "insertOne",
+          "arguments": {
+            "document": {
+              "x": 1
+            }
+          }
+        },
+        {
+          "database": "change-stream-tests",
+          "collection": "test",
+          "name": "updateOne",
+          "arguments": {
+            "filter": {
+              "x": 1
+            },
+            "update": {
+              "$set": {
+                "x": 2
+              }
+            }
+          }
+        },
+        {
+          "database": "change-stream-tests",
+          "collection": "test",
+          "name": "replaceOne",
+          "arguments": {
+            "filter": {
+              "x": 2
+            },
+            "replacement": {
+              "x": 3
+            }
+          }
+        },
+        {
+          "database": "change-stream-tests",
+          "collection": "test",
+          "name": "deleteOne",
+          "arguments": {
+            "filter": {
+              "x": 3
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "command_name": "aggregate",
+            "database_name": "change-stream-tests"
+          }
+        }
+      ],
+      "result": {
+        "success": [
+          {
+            "operationType": "insert",
+            "ns": {
+              "db": "change-stream-tests",
+              "coll": "test"
+            },
+            "fullDocument": {
+              "x": {
+                "$numberInt": "1"
+              }
+            }
+          },
+          {
+            "operationType": "update",
+            "ns": {
+              "db": "change-stream-tests",
+              "coll": "test"
+            },
+            "updateDescription": {
+              "updatedFields": {
+                "x": {
+                  "$numberInt": "2"
+                }
+              }
+            }
+          },
+          {
+            "operationType": "replace",
+            "ns": {
+              "db": "change-stream-tests",
+              "coll": "test"
+            },
+            "fullDocument": {
+              "x": {
+                "$numberInt": "3"
+              }
+            }
+          },
+          {
+            "operationType": "delete",
+            "ns": {
+              "db": "change-stream-tests",
+              "coll": "test"
+            }
+          }
+        ]
+      }
+    },
+    {
+      "description": "Test rename and invalidate event types",
+      "minServerVersion": "4.0.1",
+      "target": "collection",
+      "topology": [
+        "replicaset"
+      ],
+      "changeStreamPipeline": [],
+      "changeStreamOptions": {},
+      "operations": [
+        {
+          "database": "change-stream-tests",
+          "collection": "test",
+          "name": "rename",
+          "arguments": {
+            "to": "test2"
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "command_name": "aggregate",
+            "database_name": "change-stream-tests"
+          }
+        }
+      ],
+      "result": {
+        "success": [
+          {
+            "operationType": "rename",
+            "ns": {
+              "db": "change-stream-tests",
+              "coll": "test"
+            },
+            "to": {
+              "db": "change-stream-tests",
+              "coll": "test2"
+            }
+          },
+          {
+            "operationType": "invalidate"
+          }
+        ]
+      }
+    },
+    {
+      "description": "Test drop and invalidate event types",
+      "minServerVersion": "4.0.1",
+      "target": "collection",
+      "topology": [
+        "replicaset"
+      ],
+      "changeStreamPipeline": [],
+      "changeStreamOptions": {},
+      "operations": [
+        {
+          "database": "change-stream-tests",
+          "collection": "test",
+          "name": "drop"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "command_name": "aggregate",
+            "database_name": "change-stream-tests"
+          }
+        }
+      ],
+      "result": {
+        "success": [
+          {
+            "operationType": "drop",
+            "ns": {
+              "db": "change-stream-tests",
+              "coll": "test"
+            }
+          },
+          {
+            "operationType": "invalidate"
+          }
+        ]
+      }
+    },
+    {
+      "description": "Test consecutive resume",
+      "minServerVersion": "4.1.7",
+      "target": "collection",
+      "topology": [
+        "replicaset"
+      ],
+      "changeStreamPipeline": [],
+      "changeStreamOptions": {
+        "batchSize": 1
+      },
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 2
+        },
+        "data": {
+          "failCommands": [
+            "getMore"
+          ],
+          "closeConnection": true
+        }
+      },
+      "operations": [
+        {
+          "database": "change-stream-tests",
+          "collection": "test",
+          "name": "insertOne",
+          "arguments": {
+            "document": {
+              "x": 1
+            }
+          }
+        },
+        {
+          "database": "change-stream-tests",
+          "collection": "test",
+          "name": "insertOne",
+          "arguments": {
+            "document": {
+              "x": 2
+            }
+          }
+        },
+        {
+          "database": "change-stream-tests",
+          "collection": "test",
+          "name": "insertOne",
+          "arguments": {
+            "document": {
+              "x": 3
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test",
+              "cursor": {
+                "batchSize": 1
+              },
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "command_name": "aggregate",
+            "database_name": "change-stream-tests"
+          }
+        }
+      ],
+      "result": {
+        "success": [
+          {
+            "operationType": "insert",
+            "ns": {
+              "db": "change-stream-tests",
+              "coll": "test"
+            },
+            "fullDocument": {
+              "x": {
+                "$numberInt": "1"
+              }
+            }
+          },
+          {
+            "operationType": "insert",
+            "ns": {
+              "db": "change-stream-tests",
+              "coll": "test"
+            },
+            "fullDocument": {
+              "x": {
+                "$numberInt": "2"
+              }
+            }
+          },
+          {
+            "operationType": "insert",
+            "ns": {
+              "db": "change-stream-tests",
+              "coll": "test"
+            },
+            "fullDocument": {
+              "x": {
+                "$numberInt": "3"
+              }
+            }
+          }
+        ]
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/corpus/corpus-encrypted.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/corpus/corpus-encrypted.json
new file mode 100644
index 0000000000000000000000000000000000000000..998b058b0f64e96eaabeb79d34ebbf7cef7c62eb
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/corpus/corpus-encrypted.json	
@@ -0,0 +1,4025 @@
+{
+  "_id": "client_side_encryption_corpus",
+  "altname_aws": "aws",
+  "altname_local": "local",
+  "aws_double_rand_auto_id": {
+    "kms": "aws",
+    "type": "double",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AgFkgAAAAAAAAAAAAAAAAAABchrWPF5OPeuFpk4tUV325TmoNpGW+L5iPSXcLQIr319WJFIp3EDy5QiAHBfz2rThI7imU4eLXndIUrsjM0S/vg==",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_double_rand_auto_altname": {
+    "kms": "aws",
+    "type": "double",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AgFkgAAAAAAAAAAAAAAAAAABga5hXFiFvH/wOr0wOHSHFWRZ4pEs/UCC1XJWf46Dod3GY9Ry5j1ZyzeHueJxc4Ym5M8UHKSmJuXmNo9m9ZnkiA==",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_double_rand_explicit_id": {
+    "kms": "aws",
+    "type": "double",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AgFkgAAAAAAAAAAAAAAAAAABjTYZbsro/YxLWBb88qPXEIDQdzY7UZyK4UaZZ8h62OTxp43Zp9j6WvOEzKhXt4oJPMxlAxyTdqO6MllX5bsDrw==",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_double_rand_explicit_altname": {
+    "kms": "aws",
+    "type": "double",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AgFkgAAAAAAAAAAAAAAAAAABqkyXdeS3aWH2tRFoKxsIIL3ZH05gkiAEbutrjrdfw0b110iPhuCCOb0gP/nX/NRNCg1kCFZ543Vu0xZ0BRXlvQ==",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_double_det_explicit_id": {
+    "kms": "aws",
+    "type": "double",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": false,
+    "value": { "$numberDouble": "1.234" }
+  },
+  "aws_double_det_explicit_altname": {
+    "kms": "aws",
+    "type": "double",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": false,
+    "value": { "$numberDouble": "1.234" }
+  },
+  "aws_string_rand_auto_id": {
+    "kms": "aws",
+    "type": "string",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AgFkgAAAAAAAAAAAAAAAAAACAsI5E0rVT8TpIONY3TnbRvIxUjKsiy9ynVd/fE7U1lndE7KR6dTzs8QWK13kdKxO+njKPeC2ObBX904QmJ65Sw==",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_string_rand_auto_altname": {
+    "kms": "aws",
+    "type": "string",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AgFkgAAAAAAAAAAAAAAAAAACgBE6J6MRxPSDe+gfJPL8nBvuEIRBYxNS/73LqBTDJYyN/lsHQ6UlFDT5B4EkIPmHPTe+UBMOhZQ1bsP+DK8Aog==",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_string_rand_explicit_id": {
+    "kms": "aws",
+    "type": "string",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AgFkgAAAAAAAAAAAAAAAAAACbdTVDBWn35M5caKZgLFoiSVeFGKRj5K/QtupKNc8/dPIyCE+/a4PU51G/YIzFpYmp91nLpyq7lD/eJ/V0q66Zw==",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_string_rand_explicit_altname": {
+    "kms": "aws",
+    "type": "string",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AgFkgAAAAAAAAAAAAAAAAAACa4O+kE2BaqM0E+yiBrbCuE0YEGTrZ7L/+SuWm9gN3UupxwAQpRfxXAuUCTc9u1CXnvL+ga+VJMcWD2bawnn/Rg==",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_string_det_auto_id": {
+    "kms": "aws",
+    "type": "string",
+    "algo": "det",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AQFkgAAAAAAAAAAAAAAAAAACyvOW8NcqRkZYzujivwVmYptJkic27PWr3Nq3Yv5Njz8cJdoyesVaQan6mn+U3wdfGEH8zbUUISdCx5qgvXEpvw==",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_string_det_explicit_id": {
+    "kms": "aws",
+    "type": "string",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AQFkgAAAAAAAAAAAAAAAAAACyvOW8NcqRkZYzujivwVmYptJkic27PWr3Nq3Yv5Njz8cJdoyesVaQan6mn+U3wdfGEH8zbUUISdCx5qgvXEpvw==",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_string_det_explicit_altname": {
+    "kms": "aws",
+    "type": "string",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AQFkgAAAAAAAAAAAAAAAAAACyvOW8NcqRkZYzujivwVmYptJkic27PWr3Nq3Yv5Njz8cJdoyesVaQan6mn+U3wdfGEH8zbUUISdCx5qgvXEpvw==",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_object_rand_auto_id": {
+    "kms": "aws",
+    "type": "object",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AgFkgAAAAAAAAAAAAAAAAAADI+/afY6Eka8j1VNThWIeGkDZ7vo4/l66a01Z+lVUFFnVLeUV/nz9kM6uTTplNRUa+RXmNmwkoR/BHRnGc7wRNA==",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_object_rand_auto_altname": {
+    "kms": "aws",
+    "type": "object",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AgFkgAAAAAAAAAAAAAAAAAADzN4hVXWXKerhggRRtwWnDu2W2wQ5KIWb/X1WCZJKTjQSQ5LNHVasabBCa4U1q46PQ5pDDM1PkVjW6o+zzl/4xw==",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_object_rand_explicit_id": {
+    "kms": "aws",
+    "type": "object",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AgFkgAAAAAAAAAAAAAAAAAADhSs5zKFMuuux3fqFFuPito3N+bp5TgmkUtJtFXjmA/EnLuexGARvEeGUsMJ/n0VzKbbsiE8+AsUNY3o9YXutqQ==",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_object_rand_explicit_altname": {
+    "kms": "aws",
+    "type": "object",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AgFkgAAAAAAAAAAAAAAAAAADpj8MSov16h26bFDrHepsNkW+tOLOjRP7oj1Tnj75qZ+uqxxVkQ5B/t/Ihk5fikHTJGAcRBR5Vv6kJ/ulMaDnvQ==",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_object_det_explicit_id": {
+    "kms": "aws",
+    "type": "object",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": false,
+    "value": { "x": { "$numberInt": "1" } }
+  },
+  "aws_object_det_explicit_altname": {
+    "kms": "aws",
+    "type": "object",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": false,
+    "value": { "x": { "$numberInt": "1" } }
+  },
+  "aws_array_rand_auto_id": {
+    "kms": "aws",
+    "type": "array",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AgFkgAAAAAAAAAAAAAAAAAAETWDOZ6zV39H2+W+BkwZIoxI3BNF6phKoiBZ9+i4T9uEoyU3TmoTPjuI0YNwR1v/p5/9rlVCG0KLZd16eeMb3zxZXjqh6IAJqfhsBQ7bzBYI=",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_array_rand_auto_altname": {
+    "kms": "aws",
+    "type": "array",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AgFkgAAAAAAAAAAAAAAAAAAE1xeHbld2JjUiPB1k+xMZuIzNSai7mv1iusCswxKEfYCZ7YtR0GDQTxN4676CwhcodSDiysjgOxSFIGlptKCvl0k46LNq0EGypP9yWBLvdjQ=",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_array_rand_explicit_id": {
+    "kms": "aws",
+    "type": "array",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AgFkgAAAAAAAAAAAAAAAAAAEFVa4U2uW65MGihhdOmpZFgnwGTs3VeN5TXXbXJ5cfm0CwXF3EPlzAVjy5WO/+lbvFufpQnIiLH59/kVygmwn+2P9zPNJnSGIJW9gaV8Vye8=",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_array_rand_explicit_altname": {
+    "kms": "aws",
+    "type": "array",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AgFkgAAAAAAAAAAAAAAAAAAE11VXbfg7DJQ5/CB9XdBO0hCrxOkK3RrEjPGJ0FXlUo76IMna1uo+NVmDnM63CRlGE3/TEbZPpp0w0jn4vZLKvBmGr7o7WQusRY4jnRf5oH4=",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_array_det_explicit_id": {
+    "kms": "aws",
+    "type": "array",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": false,
+    "value": [
+      { "$numberInt": "1" },
+      { "$numberInt": "2" },
+      { "$numberInt": "3" }
+    ]
+  },
+  "aws_array_det_explicit_altname": {
+    "kms": "aws",
+    "type": "array",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": false,
+    "value": [
+      { "$numberInt": "1" },
+      { "$numberInt": "2" },
+      { "$numberInt": "3" }
+    ]
+  },
+  "aws_binData=00_rand_auto_id": {
+    "kms": "aws",
+    "type": "binData=00",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AgFkgAAAAAAAAAAAAAAAAAAFpZYSktIHzGLZ6mcBFxywICqxdurqLVJcQR34ngix5YIOOulCYEhBSDzzSEyixEPCuU6cEzeuafpZRHX4qgcr9Q==",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_binData=00_rand_auto_altname": {
+    "kms": "aws",
+    "type": "binData=00",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AgFkgAAAAAAAAAAAAAAAAAAFshzESR9SyR++9r2yeaEjJYScMDez414s8pZkB3C8ihDa+rsyaxNy4yrF7qNEWjFrdFaH7zD2LdlPx+TKZgROlg==",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_binData=00_rand_explicit_id": {
+    "kms": "aws",
+    "type": "binData=00",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AgFkgAAAAAAAAAAAAAAAAAAFpYwZRPDom7qyAe5WW/QNSq97/OYgRT8xUEaaR5pkbQEFd/Cwtl8Aib/3Bs1CT3MVaHVWna2u5Gcc4s/v18zLhg==",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_binData=00_rand_explicit_altname": {
+    "kms": "aws",
+    "type": "binData=00",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AgFkgAAAAAAAAAAAAAAAAAAFBq1RIU1YGHKAS1SAtS42fKtQBHQ/BCQzRutirNdvWlrXxF81LSaS7QgQyycZ2ePiOLsSm2vZS4xaQETeCgRC4g==",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_binData=00_det_auto_id": {
+    "kms": "aws",
+    "type": "binData=00",
+    "algo": "det",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AQFkgAAAAAAAAAAAAAAAAAAF6SJGmfD3hLVc4tLPm4v2zFuHoRxUDLumBR8Q0AlKK2nQPyvuHEPVBD3vQdDi+Q7PwFxmovJsHccr59VnzvpJeg==",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_binData=00_det_explicit_id": {
+    "kms": "aws",
+    "type": "binData=00",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AQFkgAAAAAAAAAAAAAAAAAAF6SJGmfD3hLVc4tLPm4v2zFuHoRxUDLumBR8Q0AlKK2nQPyvuHEPVBD3vQdDi+Q7PwFxmovJsHccr59VnzvpJeg==",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_binData=00_det_explicit_altname": {
+    "kms": "aws",
+    "type": "binData=00",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AQFkgAAAAAAAAAAAAAAAAAAF6SJGmfD3hLVc4tLPm4v2zFuHoRxUDLumBR8Q0AlKK2nQPyvuHEPVBD3vQdDi+Q7PwFxmovJsHccr59VnzvpJeg==",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_binData=04_rand_auto_id": {
+    "kms": "aws",
+    "type": "binData=04",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AgFkgAAAAAAAAAAAAAAAAAAFM5685zqlM8pc3xubtCFuf724g/bWXsebpNzw5E5HrxUqSBBVOvjs3IJH74+Supe169qejY358nOG41mLZvO2wJByvT14qmgUGpgBaLaxPR0=",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_binData=04_rand_auto_altname": {
+    "kms": "aws",
+    "type": "binData=04",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AgFkgAAAAAAAAAAAAAAAAAAFfLqOzpfjz/XYHDLnliUAA5ehi6s+OIjvrLa59ubqEf8DuoCEWlO13Dl8X42IBB4hoSsO2RUeWtc9MeH4SdIUh/xJN3qS7qzjh/H+GvZRdAM=",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_binData=04_rand_explicit_id": {
+    "kms": "aws",
+    "type": "binData=04",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AgFkgAAAAAAAAAAAAAAAAAAFkmKfKAbz9tqVaiM9MRhYttiY3vgDwXpdYLQ4uUgWX89KRayLADWortYL+Oq+roFhO3oiwB9vjeWGIdgbj5wSh/50JT/2Gs85TXFe1GFjfWs=",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_binData=04_rand_explicit_altname": {
+    "kms": "aws",
+    "type": "binData=04",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AgFkgAAAAAAAAAAAAAAAAAAFKbufv83ddN+07Q5Ocq0VxUEV+BesSrVM7Bol3cMlWjHi7P+MrdwhNEa94xlxlDwU3b+RD6kW+AuNEQ2byA3CX2JjZE1gHwN7l0ukXuqpD0A=",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_binData=04_det_auto_id": {
+    "kms": "aws",
+    "type": "binData=04",
+    "algo": "det",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AQFkgAAAAAAAAAAAAAAAAAAFlg7ceq9w/JMhHcNzQks6UrKYAffpUyeWuBIpcuLoB7YbFO61Dphseh77pzZbk3OvmveUq6EtCP2pmsq7hA+QV4hkv6BTn4m6wnXw6ss/qfE=",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_binData=04_det_explicit_id": {
+    "kms": "aws",
+    "type": "binData=04",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AQFkgAAAAAAAAAAAAAAAAAAFlg7ceq9w/JMhHcNzQks6UrKYAffpUyeWuBIpcuLoB7YbFO61Dphseh77pzZbk3OvmveUq6EtCP2pmsq7hA+QV4hkv6BTn4m6wnXw6ss/qfE=",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_binData=04_det_explicit_altname": {
+    "kms": "aws",
+    "type": "binData=04",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AQFkgAAAAAAAAAAAAAAAAAAFlg7ceq9w/JMhHcNzQks6UrKYAffpUyeWuBIpcuLoB7YbFO61Dphseh77pzZbk3OvmveUq6EtCP2pmsq7hA+QV4hkv6BTn4m6wnXw6ss/qfE=",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_undefined_rand_explicit_id": {
+    "kms": "aws",
+    "type": "undefined",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": false,
+    "value": { "$undefined": true }
+  },
+  "aws_undefined_rand_explicit_altname": {
+    "kms": "aws",
+    "type": "undefined",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": false,
+    "value": { "$undefined": true }
+  },
+  "aws_undefined_det_explicit_id": {
+    "kms": "aws",
+    "type": "undefined",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": false,
+    "value": { "$undefined": true }
+  },
+  "aws_undefined_det_explicit_altname": {
+    "kms": "aws",
+    "type": "undefined",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": false,
+    "value": { "$undefined": true }
+  },
+  "aws_objectId_rand_auto_id": {
+    "kms": "aws",
+    "type": "objectId",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AgFkgAAAAAAAAAAAAAAAAAAHASE+V+LlkmwgF9QNjBK8QBvC973NaTMk6wbd57VB2EpQzrgxMtR5gYzVeqq4xaaHqrncyZCOIxDJkFlaim2NqA==",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_objectId_rand_auto_altname": {
+    "kms": "aws",
+    "type": "objectId",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AgFkgAAAAAAAAAAAAAAAAAAHf/+9Qj/ozcDoUb8RNBnajU1d9hJ/6fE17IEZnw+ma6v5yH8LqZk9w3dtm6Sfw1unMhcMKrmIgs6kxqRWhNREJg==",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_objectId_rand_explicit_id": {
+    "kms": "aws",
+    "type": "objectId",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AgFkgAAAAAAAAAAAAAAAAAAHzX8ejVLhoarQ5xgWsJitU/9eBm/Hlt2IIbZtS0SBc80qzkkWTaP9Zl9wrILH/Hwwx8RFnts855eKII3NJFa3BA==",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_objectId_rand_explicit_altname": {
+    "kms": "aws",
+    "type": "objectId",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AgFkgAAAAAAAAAAAAAAAAAAHG5l6nUCY8f/6xO6TsPDrZHcdPRyMe3muMlY2DxHwv9GJNDR5Ne5VEAzUjnbgoy+B29SX4oY8cXJ6XhVz8mt3Eg==",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_objectId_det_auto_id": {
+    "kms": "aws",
+    "type": "objectId",
+    "algo": "det",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AQFkgAAAAAAAAAAAAAAAAAAHTMY2l+gY8glm4HeSsGfCSfOsTVTzYU8qnQV8iqEFHrO5SBJac59gv3N/jukMwAnt0j6vIIQrROkVetU24YY7sQ==",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_objectId_det_explicit_id": {
+    "kms": "aws",
+    "type": "objectId",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AQFkgAAAAAAAAAAAAAAAAAAHTMY2l+gY8glm4HeSsGfCSfOsTVTzYU8qnQV8iqEFHrO5SBJac59gv3N/jukMwAnt0j6vIIQrROkVetU24YY7sQ==",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_objectId_det_explicit_altname": {
+    "kms": "aws",
+    "type": "objectId",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AQFkgAAAAAAAAAAAAAAAAAAHTMY2l+gY8glm4HeSsGfCSfOsTVTzYU8qnQV8iqEFHrO5SBJac59gv3N/jukMwAnt0j6vIIQrROkVetU24YY7sQ==",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_bool_rand_auto_id": {
+    "kms": "aws",
+    "type": "bool",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AgFkgAAAAAAAAAAAAAAAAAAISm4UFt1HC2j0ObpTBg7SvF2Dq31i9To2ED4F3JcTihhq0fVzaSCsUz9VTJ0ziHmeNPNdfPPZO6qA/CDEZBO4jg==",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_bool_rand_auto_altname": {
+    "kms": "aws",
+    "type": "bool",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AgFkgAAAAAAAAAAAAAAAAAAIj93KeAa96DmZXdB8boFvW19jhJSMmtSs5ag5FDSkH8MdKG2d2VoBOdUlBrL+LHYELqeDHCszY7qCirvb5mIgZg==",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_bool_rand_explicit_id": {
+    "kms": "aws",
+    "type": "bool",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AgFkgAAAAAAAAAAAAAAAAAAIMbDFEuHIl5MNEsWnYLIand1vpK6EMv7Mso6qxrN4wHSVVwmxK+GCPgrKoUQsNuTssFWNCu0IhwrXOagDEfmlxw==",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_bool_rand_explicit_altname": {
+    "kms": "aws",
+    "type": "bool",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AgFkgAAAAAAAAAAAAAAAAAAIkIaWfmPdxgAV5Rtb6on6T0NGt9GPFDScQD5I/Ch0ngiTCCKceJOjU0ljd3YTgfWRA1p/MlMIV0I5YAWZXKTHlg==",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_bool_det_explicit_id": {
+    "kms": "aws",
+    "type": "bool",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": false,
+    "value": true
+  },
+  "aws_bool_det_explicit_altname": {
+    "kms": "aws",
+    "type": "bool",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": false,
+    "value": true
+  },
+  "aws_date_rand_auto_id": {
+    "kms": "aws",
+    "type": "date",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AgFkgAAAAAAAAAAAAAAAAAAJz1VG4+QnQXEE+TGu/pzfPugGMVTiC1xnenG1ByRdPvsERVw9WComWl1tb9tt9oblD7H/q0y1+y8HevkDqohB2Q==",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_date_rand_auto_altname": {
+    "kms": "aws",
+    "type": "date",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AgFkgAAAAAAAAAAAAAAAAAAJa1kI2mIIYWjf7zjf5dD9+psvAQpjZ3nnsoXA5upcIwEtZaC8bxKKHVpOLOP3rTbvT5EV6vLhXkferGoyaqd/8w==",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_date_rand_explicit_id": {
+    "kms": "aws",
+    "type": "date",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AgFkgAAAAAAAAAAAAAAAAAAJ9Q5Xe4UuOLQTUwosk47A6xx40XJcNoICCNtKrHqsUYy0QLCFRc5v4nA0160BVghURizbUtX8iuIp11pnsDyRtA==",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_date_rand_explicit_altname": {
+    "kms": "aws",
+    "type": "date",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AgFkgAAAAAAAAAAAAAAAAAAJkHOdUc/4U82wxWJZ0SYABkJjQqNApkH2Iy/5S+PoatPgynoeSFTU9FmAbuWV/gbtIfBiaCOIjlsdonl/gf9+5w==",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_date_det_auto_id": {
+    "kms": "aws",
+    "type": "date",
+    "algo": "det",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AQFkgAAAAAAAAAAAAAAAAAAJEEpQNsiqMWPqD4lhMkiOJHGE8FxOeYrKPiiAp/bZTrLKyCSS0ZL1WT9H3cGzxWPm5veihCjKqWhjatC/pjtzbQ==",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_date_det_explicit_id": {
+    "kms": "aws",
+    "type": "date",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AQFkgAAAAAAAAAAAAAAAAAAJEEpQNsiqMWPqD4lhMkiOJHGE8FxOeYrKPiiAp/bZTrLKyCSS0ZL1WT9H3cGzxWPm5veihCjKqWhjatC/pjtzbQ==",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_date_det_explicit_altname": {
+    "kms": "aws",
+    "type": "date",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AQFkgAAAAAAAAAAAAAAAAAAJEEpQNsiqMWPqD4lhMkiOJHGE8FxOeYrKPiiAp/bZTrLKyCSS0ZL1WT9H3cGzxWPm5veihCjKqWhjatC/pjtzbQ==",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_null_rand_explicit_id": {
+    "kms": "aws",
+    "type": "null",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": false,
+    "value": null
+  },
+  "aws_null_rand_explicit_altname": {
+    "kms": "aws",
+    "type": "null",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": false,
+    "value": null
+  },
+  "aws_null_det_explicit_id": {
+    "kms": "aws",
+    "type": "null",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": false,
+    "value": null
+  },
+  "aws_null_det_explicit_altname": {
+    "kms": "aws",
+    "type": "null",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": false,
+    "value": null
+  },
+  "aws_regex_rand_auto_id": {
+    "kms": "aws",
+    "type": "regex",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AgFkgAAAAAAAAAAAAAAAAAALnhViSt3HqTDzyLN4mWO9srBU8TjRvPWsAJYfj/5sgI/yFuWdrggMs3Aq6G+K3tRrX3Yb+osy5CLiFCxq9WIvAA==",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_regex_rand_auto_altname": {
+    "kms": "aws",
+    "type": "regex",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AgFkgAAAAAAAAAAAAAAAAAALbL2RS2tGQLBZ+6LtXLKAWFKcoKui+u4+gMIlFemLgpdO2eLqrMJB53ccqZImX8ons9UgAwDkiD68hWy8e7KHfg==",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_regex_rand_explicit_id": {
+    "kms": "aws",
+    "type": "regex",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AgFkgAAAAAAAAAAAAAAAAAALa0+ftF6W/0Ul4J9VT/3chXFktE1o+OK4S14h2kyOqDVNA8yMKuyCK5nWl1yZvjJ76TuhEABte23oxcBP5QwalQ==",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_regex_rand_explicit_altname": {
+    "kms": "aws",
+    "type": "regex",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AgFkgAAAAAAAAAAAAAAAAAALS4Yo9Fwk6OTx2CWdnObFT2L4rHngeIbdCyT4/YMJYd+jLU3mph14M1ptZZg+TBIgSPHq+BkvpRDifbMmOVr/Hg==",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_regex_det_auto_id": {
+    "kms": "aws",
+    "type": "regex",
+    "algo": "det",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AQFkgAAAAAAAAAAAAAAAAAALpwNlokiTCUtTa2Kx9NVGvXR/aKPGhR5iaCT7nHEk4BOiZ9Kr4cRHdPCeZ7A+gjG4cKoT62sm3Fj1FwSOl8J8aQ==",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_regex_det_explicit_id": {
+    "kms": "aws",
+    "type": "regex",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AQFkgAAAAAAAAAAAAAAAAAALpwNlokiTCUtTa2Kx9NVGvXR/aKPGhR5iaCT7nHEk4BOiZ9Kr4cRHdPCeZ7A+gjG4cKoT62sm3Fj1FwSOl8J8aQ==",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_regex_det_explicit_altname": {
+    "kms": "aws",
+    "type": "regex",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AQFkgAAAAAAAAAAAAAAAAAALpwNlokiTCUtTa2Kx9NVGvXR/aKPGhR5iaCT7nHEk4BOiZ9Kr4cRHdPCeZ7A+gjG4cKoT62sm3Fj1FwSOl8J8aQ==",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_dbPointer_rand_auto_id": {
+    "kms": "aws",
+    "type": "dbPointer",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AgFkgAAAAAAAAAAAAAAAAAAMfCVAnMNbRGsThnoVGb2KDsCIU2ehcPtebk/TFG4GZvEmculscLLih813lEz5NHS2sAXBn721EzUS7d0TKAPbmEYFwUBnijIQIPvUoUO8AQM=",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_dbPointer_rand_auto_altname": {
+    "kms": "aws",
+    "type": "dbPointer",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AgFkgAAAAAAAAAAAAAAAAAAMvYJ5BtaMLVXV+qj85q5WqKRlzlHOBIIxZfUE/BBXUwqSTpJLdQQD++DDh6F2dtorBeYa3oUv2ef3ImASk5j23joU35Pm3Zt9Ci1pMNGodWs=",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_dbPointer_rand_explicit_id": {
+    "kms": "aws",
+    "type": "dbPointer",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AgFkgAAAAAAAAAAAAAAAAAAMdsmYtPDw8kKjfB2kWfx5W1oNEkWWct1lRpesN303pUWsawDJpfBx40lg18So2X/g4yGIwpY3qfEKQZA4vCJeT+MTjhRXFjXA7eS/mxv8f3E=",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_dbPointer_rand_explicit_altname": {
+    "kms": "aws",
+    "type": "dbPointer",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AgFkgAAAAAAAAAAAAAAAAAAM0hcvS5zmY3mlTp0SfME/rINlflF/sx2KvP0eJTdH+Uk0WHuTkFIJAza+bXvV/gB7iNC350qyzUX3M6NHx/9s/5yBpY8MawTZTZ7WCQIA+ZI=",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_dbPointer_det_auto_id": {
+    "kms": "aws",
+    "type": "dbPointer",
+    "algo": "det",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AQFkgAAAAAAAAAAAAAAAAAAMp4QxbaEOij66L+RtaMekrDSm6QbfJBTQ8lQFhxfq9n7SVuQ9Zwdy14Ja8tyI3cGgQzQ/73rHUJ3CKA4+OYr63skYUkkkdlHxUrIMd5j5woc=",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_dbPointer_det_explicit_id": {
+    "kms": "aws",
+    "type": "dbPointer",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AQFkgAAAAAAAAAAAAAAAAAAMp4QxbaEOij66L+RtaMekrDSm6QbfJBTQ8lQFhxfq9n7SVuQ9Zwdy14Ja8tyI3cGgQzQ/73rHUJ3CKA4+OYr63skYUkkkdlHxUrIMd5j5woc=",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_dbPointer_det_explicit_altname": {
+    "kms": "aws",
+    "type": "dbPointer",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AQFkgAAAAAAAAAAAAAAAAAAMp4QxbaEOij66L+RtaMekrDSm6QbfJBTQ8lQFhxfq9n7SVuQ9Zwdy14Ja8tyI3cGgQzQ/73rHUJ3CKA4+OYr63skYUkkkdlHxUrIMd5j5woc=",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_javascript_rand_auto_id": {
+    "kms": "aws",
+    "type": "javascript",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AgFkgAAAAAAAAAAAAAAAAAAN3HzAC9BTD7Jgi0PR4RS/Z6L6QtAQ7VhbKRbX+1smmnYniH6jVBM6zyxMDM8h9YjMPNs8EJrGDnisuf33w5KI/A==",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_javascript_rand_auto_altname": {
+    "kms": "aws",
+    "type": "javascript",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AgFkgAAAAAAAAAAAAAAAAAANJpw+znlu3ecSiNyZ0EerVsow4aDRF2auI3Wy69EVexJkQlHO753PjRn8hG/x2kY8ROy5IUU43jaugP5AN1bwNQ==",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_javascript_rand_explicit_id": {
+    "kms": "aws",
+    "type": "javascript",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AgFkgAAAAAAAAAAAAAAAAAANzoDiq8uI0+l8COY8YdM9S3rpLvPOHOWmJqJNtOyS0ZXUx1SB5paRJ4W3Eg8KuXEeoFwvBDe9cW9YT66CzkjlBw==",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_javascript_rand_explicit_altname": {
+    "kms": "aws",
+    "type": "javascript",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AgFkgAAAAAAAAAAAAAAAAAAN/JhtRongJweLC5SdrXHhsFz3p82q3cwXf8Sru21DK6S39S997y3uhVLn0xlX5d94PxK1XVYSjz1oVuMxZouZ7Q==",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_javascript_det_auto_id": {
+    "kms": "aws",
+    "type": "javascript",
+    "algo": "det",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AQFkgAAAAAAAAAAAAAAAAAANE39aEGiuUZ1WyakVEBgkGzLp5whkIjJ4uiaFLXniRszJL70FRkcf+aFXlA5Y4So9/ODKF76qbSsH4Jk6L+3mog==",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_javascript_det_explicit_id": {
+    "kms": "aws",
+    "type": "javascript",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AQFkgAAAAAAAAAAAAAAAAAANE39aEGiuUZ1WyakVEBgkGzLp5whkIjJ4uiaFLXniRszJL70FRkcf+aFXlA5Y4So9/ODKF76qbSsH4Jk6L+3mog==",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_javascript_det_explicit_altname": {
+    "kms": "aws",
+    "type": "javascript",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AQFkgAAAAAAAAAAAAAAAAAANE39aEGiuUZ1WyakVEBgkGzLp5whkIjJ4uiaFLXniRszJL70FRkcf+aFXlA5Y4So9/ODKF76qbSsH4Jk6L+3mog==",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_symbol_rand_auto_id": {
+    "kms": "aws",
+    "type": "symbol",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AgFkgAAAAAAAAAAAAAAAAAAOBv1T9tleM0xwNe7efg/MlShyzvXe3Pmg1GzPl3gjFRHZGWXR578KqX+8oiz65eXGzNuyOFvcpnR2gYCs3NeKeQfctO5plEiIva6nzCI5SK8=",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_symbol_rand_auto_altname": {
+    "kms": "aws",
+    "type": "symbol",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AgFkgAAAAAAAAAAAAAAAAAAOwLgGws8CMh+GgkEJFAx8tDIflyjsgG+/1FmZZobKAg8NOKqfXjtbnNCbvR28OCk6g/8SqBm8m53G6JciwvthJ0DirdfEexiUqu7IPtaeeyw=",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_symbol_rand_explicit_id": {
+    "kms": "aws",
+    "type": "symbol",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AgFkgAAAAAAAAAAAAAAAAAAORQi3dNkXzZeruWu19kEhDu6fFD/h47ILzk+OVKQMoriAQC5YFyVRp1yAkIaWsrsPcyCHlfZ99FySSQeqSYbZZNj5FqyonWvDuPTduHDy3CI=",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_symbol_rand_explicit_altname": {
+    "kms": "aws",
+    "type": "symbol",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AgFkgAAAAAAAAAAAAAAAAAAOj+Yl1pQPiJ6mESOISOyUYsKN/VIvC8f0derhxIPakXkwn57U0sxv+geUkrl3JZDxY3+cX5M1JZmY+PfjaYQhbTorf9RZaVC2Wwo2lMftWi0=",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_symbol_det_auto_id": {
+    "kms": "aws",
+    "type": "symbol",
+    "algo": "det",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AQFkgAAAAAAAAAAAAAAAAAAO5IHripygBGEsVK8RFWZ1rIIVUap8KVDuqOspZpERaj+5ZEfqIcyrP/WK9KdvwOfdOWXfP/mOwuImYgNdbaQe+ejkYe4W0Y0uneCuw88k95Q=",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_symbol_det_explicit_id": {
+    "kms": "aws",
+    "type": "symbol",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AQFkgAAAAAAAAAAAAAAAAAAO5IHripygBGEsVK8RFWZ1rIIVUap8KVDuqOspZpERaj+5ZEfqIcyrP/WK9KdvwOfdOWXfP/mOwuImYgNdbaQe+ejkYe4W0Y0uneCuw88k95Q=",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_symbol_det_explicit_altname": {
+    "kms": "aws",
+    "type": "symbol",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AQFkgAAAAAAAAAAAAAAAAAAO5IHripygBGEsVK8RFWZ1rIIVUap8KVDuqOspZpERaj+5ZEfqIcyrP/WK9KdvwOfdOWXfP/mOwuImYgNdbaQe+ejkYe4W0Y0uneCuw88k95Q=",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_javascriptWithScope_rand_auto_id": {
+    "kms": "aws",
+    "type": "javascriptWithScope",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AgFkgAAAAAAAAAAAAAAAAAAPT31GSNkY1RM43miv1XPYtDX1vU/xORiM3U0pumjqA+JLU/HMhH++75OcMhcAQqMjm2nZtZScxdGJsJJPEEzqjbFNMJgYc9sqR5uLnzk+2dg=",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_javascriptWithScope_rand_auto_altname": {
+    "kms": "aws",
+    "type": "javascriptWithScope",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AgFkgAAAAAAAAAAAAAAAAAAPUxgaKAxSQ1uzOZtzsbtrxtDT2P/zWY6lYsbChXuRUooqvyjXSkNDqKBBA7Gp5BdGiVB/JLR47Tihpbcw1s1yGhwQRvnqeDvPrf91nvElXRY=",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_javascriptWithScope_rand_explicit_id": {
+    "kms": "aws",
+    "type": "javascriptWithScope",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AgFkgAAAAAAAAAAAAAAAAAAPv8W0ZtquFCLTG0TqvRjdzKa/4mvqT2FuEGQ0mXG2k2BZh2LY5APr/kgW0tP4eLjHzVld6OLiM9ZKAvENCZ6/fKOvqSwpIfkdLWUIeB4REQg=",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_javascriptWithScope_rand_explicit_altname": {
+    "kms": "aws",
+    "type": "javascriptWithScope",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AgFkgAAAAAAAAAAAAAAAAAAPMVhWjaxLffdAOkVgIJpjgNIldMS451NQs3C1jb+pzopHp3DlfZ+AHQpK9reMVVKjaqanhWBpL25q+feA60XVgZPCUDroiRYqMFqU//y0amw=",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_javascriptWithScope_det_explicit_id": {
+    "kms": "aws",
+    "type": "javascriptWithScope",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": false,
+    "value": { "$code": "x=1", "$scope": {} }
+  },
+  "aws_javascriptWithScope_det_explicit_altname": {
+    "kms": "aws",
+    "type": "javascriptWithScope",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": false,
+    "value": { "$code": "x=1", "$scope": {} }
+  },
+  "aws_int_rand_auto_id": {
+    "kms": "aws",
+    "type": "int",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AgFkgAAAAAAAAAAAAAAAAAAQFV5b3vsoZe+MT4z8soetpmrWJpm7be41FNu/rdEqHWTG32jCym6762PCNYH5+vA7ldCWQkdt+ncneHsxzPrm9w==",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_int_rand_auto_altname": {
+    "kms": "aws",
+    "type": "int",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AgFkgAAAAAAAAAAAAAAAAAAQY9+QenvU1Tk/dEGZP11uOZJLHAJ9hWHbEhxbtxItt1LsdU/8gOZfypilIO5BUkLT/15PUuXV28GISNh6yIuWhw==",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_int_rand_explicit_id": {
+    "kms": "aws",
+    "type": "int",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AgFkgAAAAAAAAAAAAAAAAAAQruCugbneumhcinuXm89WW1PXVuSOewttp9cpsPPsCRVqe/uAkZOdJnZ2KaEZ9zki2GeqaJTs1qDmaJofc6GMEA==",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_int_rand_explicit_altname": {
+    "kms": "aws",
+    "type": "int",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AgFkgAAAAAAAAAAAAAAAAAAQb15qXl/tejk4pmgkc4pUxzt4eJrv/cetgzgcPVaROAQSzd8ptbgCjaV8vP46uqozRoaDFZbQ06t65c3f0x/Ucw==",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_int_det_auto_id": {
+    "kms": "aws",
+    "type": "int",
+    "algo": "det",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AQFkgAAAAAAAAAAAAAAAAAAQCXo6ieWvfoqkG+rP7J2BV013AVf/oNMmmGWe44VEHahF+qZHzW5I/F2qIA+xgKkk172pFq0iTSOpe+K2WHMKFw==",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_int_det_explicit_id": {
+    "kms": "aws",
+    "type": "int",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AQFkgAAAAAAAAAAAAAAAAAAQCXo6ieWvfoqkG+rP7J2BV013AVf/oNMmmGWe44VEHahF+qZHzW5I/F2qIA+xgKkk172pFq0iTSOpe+K2WHMKFw==",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_int_det_explicit_altname": {
+    "kms": "aws",
+    "type": "int",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AQFkgAAAAAAAAAAAAAAAAAAQCXo6ieWvfoqkG+rP7J2BV013AVf/oNMmmGWe44VEHahF+qZHzW5I/F2qIA+xgKkk172pFq0iTSOpe+K2WHMKFw==",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_timestamp_rand_auto_id": {
+    "kms": "aws",
+    "type": "timestamp",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AgFkgAAAAAAAAAAAAAAAAAAR63xXG8mrlixkQzD5VBIPE6NHicaWcS5CBhiIJDcZ0x8D9c5TgRJUfCeWhKvWFD4o0DoxcBQ2opPormFDpvmq/g==",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_timestamp_rand_auto_altname": {
+    "kms": "aws",
+    "type": "timestamp",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AgFkgAAAAAAAAAAAAAAAAAARAgY9LsUxP6gP4gYRvvzZ4iaHVQRNbycATiVag1YNSiDmEr4LYserYuBscdrIy4v3zgGaulFM9KV86bx0ItycZA==",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_timestamp_rand_explicit_id": {
+    "kms": "aws",
+    "type": "timestamp",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AgFkgAAAAAAAAAAAAAAAAAARLneAZqPcHdzGGnXz2Ne5E7HP9cDC1+yoIwcA8OSF/IlzEjrrMAi3z6Izol6gWDlD7VOh7QYL3sASJOXyzF1hPQ==",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_timestamp_rand_explicit_altname": {
+    "kms": "aws",
+    "type": "timestamp",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AgFkgAAAAAAAAAAAAAAAAAARH2bU7KNo5SHxiO8JFEcT9wryuHNXyM7ADop1oPcESyay1Nc0WHPD3nr0yMAK481NxOkE3qXyaslu7bcP/744WA==",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_timestamp_det_auto_id": {
+    "kms": "aws",
+    "type": "timestamp",
+    "algo": "det",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AQFkgAAAAAAAAAAAAAAAAAARG7kGfx0ky+d4Hl/fRBu8oUR1Mph26Dkv3J7fxGYanpzOFMiHIfVO0uwYMvsfzG54y0DDNlS3FmmS13DzepbzGQ==",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_timestamp_det_explicit_id": {
+    "kms": "aws",
+    "type": "timestamp",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AQFkgAAAAAAAAAAAAAAAAAARG7kGfx0ky+d4Hl/fRBu8oUR1Mph26Dkv3J7fxGYanpzOFMiHIfVO0uwYMvsfzG54y0DDNlS3FmmS13DzepbzGQ==",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_timestamp_det_explicit_altname": {
+    "kms": "aws",
+    "type": "timestamp",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AQFkgAAAAAAAAAAAAAAAAAARG7kGfx0ky+d4Hl/fRBu8oUR1Mph26Dkv3J7fxGYanpzOFMiHIfVO0uwYMvsfzG54y0DDNlS3FmmS13DzepbzGQ==",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_long_rand_auto_id": {
+    "kms": "aws",
+    "type": "long",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AgFkgAAAAAAAAAAAAAAAAAASZbes2EdR78crt2pXVElW2YwAQh8HEBapYYeav2VQeg2syXaV/qZuD8ofnAVn4v/DydTTMVMmK+sVU/TlnAu2eA==",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_long_rand_auto_altname": {
+    "kms": "aws",
+    "type": "long",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AgFkgAAAAAAAAAAAAAAAAAASt+7fmMYH+fLHgybc+sng8/UmKP3YPUEPCz1SXVQljQp6orsCILSgtgGPsdeGnN5NSxh3XzerHs6zlR92fWpZCw==",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_long_rand_explicit_id": {
+    "kms": "aws",
+    "type": "long",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AgFkgAAAAAAAAAAAAAAAAAAS01fF1uo6zYDToJnOT/EbDipzk7YZ6I+IspZF+avjU3XYfpRxT9NdAgKr0euWJwyAsdpWqqCwFummfrPeZOy04A==",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_long_rand_explicit_altname": {
+    "kms": "aws",
+    "type": "long",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AgFkgAAAAAAAAAAAAAAAAAAS6tpH796bqy58mXf38rJvVtA1uBcxBE5yIGQ4RN44oypc/pvw0ouhFI1dkoneKMtAFU/5RygZV+RvQhRtgKn76A==",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_long_det_auto_id": {
+    "kms": "aws",
+    "type": "long",
+    "algo": "det",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AQFkgAAAAAAAAAAAAAAAAAASC7O/8JeB4WTqQFPuMpFRsAuonPS3yu7IAPZeRPIr03CmM6HNndYIKMoFM13eELNZTdJSgg9u9ItGqRw+/XMHzQ==",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_long_det_explicit_id": {
+    "kms": "aws",
+    "type": "long",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AQFkgAAAAAAAAAAAAAAAAAASC7O/8JeB4WTqQFPuMpFRsAuonPS3yu7IAPZeRPIr03CmM6HNndYIKMoFM13eELNZTdJSgg9u9ItGqRw+/XMHzQ==",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_long_det_explicit_altname": {
+    "kms": "aws",
+    "type": "long",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AQFkgAAAAAAAAAAAAAAAAAASC7O/8JeB4WTqQFPuMpFRsAuonPS3yu7IAPZeRPIr03CmM6HNndYIKMoFM13eELNZTdJSgg9u9ItGqRw+/XMHzQ==",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_decimal_rand_auto_id": {
+    "kms": "aws",
+    "type": "decimal",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AgFkgAAAAAAAAAAAAAAAAAATgf5zW9EgnWHPxj4HAGt472eN9UXP41TaF8V2J7S2zqSpiBZGKDuOIjw2FBSqaNp53vvfl9HpwAuQBJZhrwkBCKRkKV/AAR3/pTpuoqhSKaM=",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_decimal_rand_auto_altname": {
+    "kms": "aws",
+    "type": "decimal",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AgFkgAAAAAAAAAAAAAAAAAATPRfvZWdupE2N0W1DXUx7X8Zz7g43jawJL7PbQtTYetI78xRETkMdygwSEHgs+cvnUBBtYIeKRVkOGZQkwf568OclhDiPxUeD38cR5blBq/U=",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_decimal_rand_explicit_id": {
+    "kms": "aws",
+    "type": "decimal",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AgFkgAAAAAAAAAAAAAAAAAAT+ZnCg2lSMIohZ9RJ4CNs3LZ0g+nV04cYAmrxTSrTSBPGlZ7Ywh5A2rCss7AUijYZiKiYyZbuAzukbOuVRhdCtm+xo9+DyLAwTezF18okk6Y=",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_decimal_rand_explicit_altname": {
+    "kms": "aws",
+    "type": "decimal",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AgFkgAAAAAAAAAAAAAAAAAATlnQYASsTZRRHzFjcbCClXartcXBVRrYv7JImMkDmAj6EAjf/ZqpjeykkS/wohMhXaNwyZBdREr+n+GDV7imYoL4WRBOLnqB6hrYidlWqNzE=",
+        "subType": "06"
+      }
+    }
+  },
+  "aws_decimal_det_explicit_id": {
+    "kms": "aws",
+    "type": "decimal",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": false,
+    "value": { "$numberDecimal": "1.234" }
+  },
+  "aws_decimal_det_explicit_altname": {
+    "kms": "aws",
+    "type": "decimal",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": false,
+    "value": { "$numberDecimal": "1.234" }
+  },
+  "aws_minKey_rand_explicit_id": {
+    "kms": "aws",
+    "type": "minKey",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": false,
+    "value": { "$minKey": 1 }
+  },
+  "aws_minKey_rand_explicit_altname": {
+    "kms": "aws",
+    "type": "minKey",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": false,
+    "value": { "$minKey": 1 }
+  },
+  "aws_minKey_det_explicit_id": {
+    "kms": "aws",
+    "type": "minKey",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": false,
+    "value": { "$minKey": 1 }
+  },
+  "aws_minKey_det_explicit_altname": {
+    "kms": "aws",
+    "type": "minKey",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": false,
+    "value": { "$minKey": 1 }
+  },
+  "aws_maxKey_rand_explicit_id": {
+    "kms": "aws",
+    "type": "maxKey",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": false,
+    "value": { "$maxKey": 1 }
+  },
+  "aws_maxKey_rand_explicit_altname": {
+    "kms": "aws",
+    "type": "maxKey",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": false,
+    "value": { "$maxKey": 1 }
+  },
+  "aws_maxKey_det_explicit_id": {
+    "kms": "aws",
+    "type": "maxKey",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": false,
+    "value": { "$maxKey": 1 }
+  },
+  "aws_maxKey_det_explicit_altname": {
+    "kms": "aws",
+    "type": "maxKey",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": false,
+    "value": { "$maxKey": 1 }
+  },
+  "local_double_rand_auto_id": {
+    "kms": "local",
+    "type": "double",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AizggCwAAAAAAAAAAAAAAAABGF195CB8nRmK9+KxYO7T96MeXucC/ILQtEEQAS4zrwj3Qz7YEQrf/apvbKTCkn3siN2XSDLQ/7dmddZa9xa9yQ==",
+        "subType": "06"
+      }
+    }
+  },
+  "local_double_rand_auto_altname": {
+    "kms": "local",
+    "type": "double",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AizggCwAAAAAAAAAAAAAAAABY8g18z6ZOjGtfNxaAmU95tXMdoM6qbtDMpB72paqiHZTW1UGB22HPXiEnVz05JTBzzX4fc6tOldX6aJel812Zg==",
+        "subType": "06"
+      }
+    }
+  },
+  "local_double_rand_explicit_id": {
+    "kms": "local",
+    "type": "double",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AizggCwAAAAAAAAAAAAAAAABDlHwN8hYyScEhhx64TdJ2Qp2rmKRg8983zdqIL1914tyPwRQq7ySCOhmFif2S7v4KT+r0uOfimYvKD1n9rKHlg==",
+        "subType": "06"
+      }
+    }
+  },
+  "local_double_rand_explicit_altname": {
+    "kms": "local",
+    "type": "double",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AizggCwAAAAAAAAAAAAAAAAB2VnTFlaCRzAZZTQiMWQORFNgXIuAJlHJXIHiYow2eO6JbVghWTpH+MsdafBNPVnc0zKuZBL0Qs2Nuk1xiQaqhA==",
+        "subType": "06"
+      }
+    }
+  },
+  "local_double_det_explicit_id": {
+    "kms": "local",
+    "type": "double",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": false,
+    "value": { "$numberDouble": "1.234" }
+  },
+  "local_double_det_explicit_altname": {
+    "kms": "local",
+    "type": "double",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": false,
+    "value": { "$numberDouble": "1.234" }
+  },
+  "local_string_rand_auto_id": {
+    "kms": "local",
+    "type": "string",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AizggCwAAAAAAAAAAAAAAAAC5NBAPM8q2n9fnkwQfE9so/XcO51plPBNs5VlBRbDw68k9T6/uZ2TWsAvTYtVooY59zHHr2QS3usKbGQB6J61rA==",
+        "subType": "06"
+      }
+    }
+  },
+  "local_string_rand_auto_altname": {
+    "kms": "local",
+    "type": "string",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AizggCwAAAAAAAAAAAAAAAACM/EjGMrkYHvSZra26m74upuvLkfKXTs+tTWquGzrgWYLnLt8I6XBIwx1VymS9EybrCU/ewmtgjLUNUFQacIeXA==",
+        "subType": "06"
+      }
+    }
+  },
+  "local_string_rand_explicit_id": {
+    "kms": "local",
+    "type": "string",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AizggCwAAAAAAAAAAAAAAAACn4tD26UG8lO9gTZaxen6yXzHo/a2lokeY1ClxHMtJODoJr2JZzIDHP3A9aZ8L4+Vu+nyqphaWyGaGONKu8gpcQ==",
+        "subType": "06"
+      }
+    }
+  },
+  "local_string_rand_explicit_altname": {
+    "kms": "local",
+    "type": "string",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AizggCwAAAAAAAAAAAAAAAACZfoO2LjY+IB31FZ1Tq7pHr0DCFKGJqWcXcOrnZ7bV9Euc9f101motJc31sp8nF5CTCfd83VQE0319eQrxDDaSw==",
+        "subType": "06"
+      }
+    }
+  },
+  "local_string_det_auto_id": {
+    "kms": "local",
+    "type": "string",
+    "algo": "det",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "ASzggCwAAAAAAAAAAAAAAAACW0cZMYWOY3eoqQQkSdBtS9iHC4CSQA27dy6XJGcmTV8EDuhGNnPmbx0EKFTDb0PCSyCjMyuE4nsgmNYgjTaSuw==",
+        "subType": "06"
+      }
+    }
+  },
+  "local_string_det_explicit_id": {
+    "kms": "local",
+    "type": "string",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "ASzggCwAAAAAAAAAAAAAAAACW0cZMYWOY3eoqQQkSdBtS9iHC4CSQA27dy6XJGcmTV8EDuhGNnPmbx0EKFTDb0PCSyCjMyuE4nsgmNYgjTaSuw==",
+        "subType": "06"
+      }
+    }
+  },
+  "local_string_det_explicit_altname": {
+    "kms": "local",
+    "type": "string",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "ASzggCwAAAAAAAAAAAAAAAACW0cZMYWOY3eoqQQkSdBtS9iHC4CSQA27dy6XJGcmTV8EDuhGNnPmbx0EKFTDb0PCSyCjMyuE4nsgmNYgjTaSuw==",
+        "subType": "06"
+      }
+    }
+  },
+  "local_object_rand_auto_id": {
+    "kms": "local",
+    "type": "object",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AizggCwAAAAAAAAAAAAAAAADlekcUsETAkkKTjCVx5EISJN+sftrQax/VhaWXLyRgRz97adXXmwZkMyt+035SHZsF91i2LaXziMA4RHoP+nKFw==",
+        "subType": "06"
+      }
+    }
+  },
+  "local_object_rand_auto_altname": {
+    "kms": "local",
+    "type": "object",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AizggCwAAAAAAAAAAAAAAAADpaQmy5r6q9gLqEm+FIi/OyQgcuUnrICCP9rC4S3wR6qUHd82IW/3dFQUzwTkaXxgStjopamQMuZ4ESRj0xx0bA==",
+        "subType": "06"
+      }
+    }
+  },
+  "local_object_rand_explicit_id": {
+    "kms": "local",
+    "type": "object",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AizggCwAAAAAAAAAAAAAAAADCHRJCINzWY0u4gZPWEmHg/JoQ8IW4yMfUyzYJCQrEMp4rUeupIuxqSuq2QyLBYZBBv0r7t3lNH49I5qDeav2vA==",
+        "subType": "06"
+      }
+    }
+  },
+  "local_object_rand_explicit_altname": {
+    "kms": "local",
+    "type": "object",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AizggCwAAAAAAAAAAAAAAAADrHQQUnLF1jdNmFY/V266cS28XAB4nOKetHAcSbwkeUxNzgZT1g+XMQaYfcNMMv/ywypKU1KpgLMsEOpm4qcPkQ==",
+        "subType": "06"
+      }
+    }
+  },
+  "local_object_det_explicit_id": {
+    "kms": "local",
+    "type": "object",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": false,
+    "value": { "x": { "$numberInt": "1" } }
+  },
+  "local_object_det_explicit_altname": {
+    "kms": "local",
+    "type": "object",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": false,
+    "value": { "x": { "$numberInt": "1" } }
+  },
+  "local_array_rand_auto_id": {
+    "kms": "local",
+    "type": "array",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AizggCwAAAAAAAAAAAAAAAAEXa7bQ5vGPNsLdklM/H+sop8aCL4vlDiVUoVjTAGjTngn2WLcdKLWxaNSyMdJpsI/NsxQJ58YrcwP+yHzi9rZVtRdbg7m8p+CYcq1vUm6UoQ=",
+        "subType": "06"
+      }
+    }
+  },
+  "local_array_rand_auto_altname": {
+    "kms": "local",
+    "type": "array",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AizggCwAAAAAAAAAAAAAAAAEVlZlOvtRmGIhcYi/qPl3HKi/qf0yRQrkbVo9rScYkxDCBN9wA55pAWHDQ/5Sjy4d0DwL57k+M1G9e7xSIrv8xXKwoIuuabhSWaIX2eJHroY=",
+        "subType": "06"
+      }
+    }
+  },
+  "local_array_rand_explicit_id": {
+    "kms": "local",
+    "type": "array",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AizggCwAAAAAAAAAAAAAAAAEYBLSYHHt2rohezMF4lMjNdqy9CY33EHf+pgRbJwVXZScLDgn9CcqeRsdU8bW5h2qgNpQvoSMBB7pW+Dgp1RauTHZSOd4PcZpAGjwoFDWSSM=",
+        "subType": "06"
+      }
+    }
+  },
+  "local_array_rand_explicit_altname": {
+    "kms": "local",
+    "type": "array",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AizggCwAAAAAAAAAAAAAAAAES1IJ8S2NxWekolQockxLJvzFSGfKQ9Xbi55vO8LyWo0sIG9ZgPQXtVQkZ301CsdFduvx9A0vDqQ0MGYc4plxNnpUTizJPRUDyez5dOgZ9tI=",
+        "subType": "06"
+      }
+    }
+  },
+  "local_array_det_explicit_id": {
+    "kms": "local",
+    "type": "array",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": false,
+    "value": [
+      { "$numberInt": "1" },
+      { "$numberInt": "2" },
+      { "$numberInt": "3" }
+    ]
+  },
+  "local_array_det_explicit_altname": {
+    "kms": "local",
+    "type": "array",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": false,
+    "value": [
+      { "$numberInt": "1" },
+      { "$numberInt": "2" },
+      { "$numberInt": "3" }
+    ]
+  },
+  "local_binData=00_rand_auto_id": {
+    "kms": "local",
+    "type": "binData=00",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AizggCwAAAAAAAAAAAAAAAAF+hgWs4ZCo9GnmhSM9SDSWzWX4E7Tlp4TwlEy3zfO/rrMREECGB4u8LD8Ju9b8YP+xcZhMI1tcz/vrQS87NffUg==",
+        "subType": "06"
+      }
+    }
+  },
+  "local_binData=00_rand_auto_altname": {
+    "kms": "local",
+    "type": "binData=00",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AizggCwAAAAAAAAAAAAAAAAFtEvaXWpGfXC1GlKu0AeRDaeBKHryGoS0tAUr48vfYk7umCr+fJKyXCY9vSv7wCiQxWLe8V/EZWkHsu0zqhJw9w==",
+        "subType": "06"
+      }
+    }
+  },
+  "local_binData=00_rand_explicit_id": {
+    "kms": "local",
+    "type": "binData=00",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AizggCwAAAAAAAAAAAAAAAAF/1L5bvmMX3Bk2nAw8KvvRd/7nZ82XHVasT0jrlPhSiJU7ehJMeUCOb7HCHU6KgCzZB9C2W3NoVhLKIhE9ZnYdg==",
+        "subType": "06"
+      }
+    }
+  },
+  "local_binData=00_rand_explicit_altname": {
+    "kms": "local",
+    "type": "binData=00",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AizggCwAAAAAAAAAAAAAAAAFK0W5IWKzggR4UU+fhwA2p8YCHLfmx5y1OEtHc/9be9eEYTORACDmWY6207Vd4LhBJCedd+Q5qMm7NRZjjhyLEQ==",
+        "subType": "06"
+      }
+    }
+  },
+  "local_binData=00_det_auto_id": {
+    "kms": "local",
+    "type": "binData=00",
+    "algo": "det",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "ASzggCwAAAAAAAAAAAAAAAAF1ofBnK9+ERP29P/i14GQ/y3muic6tNKY532zCkzQkJSktYCOeXS8DdY1DdaOP/asZWzPTdgwby6/iZcAxJU+xQ==",
+        "subType": "06"
+      }
+    }
+  },
+  "local_binData=00_det_explicit_id": {
+    "kms": "local",
+    "type": "binData=00",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "ASzggCwAAAAAAAAAAAAAAAAF1ofBnK9+ERP29P/i14GQ/y3muic6tNKY532zCkzQkJSktYCOeXS8DdY1DdaOP/asZWzPTdgwby6/iZcAxJU+xQ==",
+        "subType": "06"
+      }
+    }
+  },
+  "local_binData=00_det_explicit_altname": {
+    "kms": "local",
+    "type": "binData=00",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "ASzggCwAAAAAAAAAAAAAAAAF1ofBnK9+ERP29P/i14GQ/y3muic6tNKY532zCkzQkJSktYCOeXS8DdY1DdaOP/asZWzPTdgwby6/iZcAxJU+xQ==",
+        "subType": "06"
+      }
+    }
+  },
+  "local_binData=04_rand_auto_id": {
+    "kms": "local",
+    "type": "binData=04",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AizggCwAAAAAAAAAAAAAAAAFxq38aA4k/tYHPwJFRK0pahlo/3zjCe3VHJRqURRA+04lbJCvdkQTawxWlf8o+3Pcetl1UcPTQigdYp5KbIkstuPstLbT+TZXHVD1os9LTRw=",
+        "subType": "06"
+      }
+    }
+  },
+  "local_binData=04_rand_auto_altname": {
+    "kms": "local",
+    "type": "binData=04",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AizggCwAAAAAAAAAAAAAAAAFTXNWchCPmCSY0+AL22/kCBmAoDJDX5T18jpJHLdvZtHs0zwD64b9hLvfRK268BlNu4P37KDFE6LT0QzjG7brqzFJf3ZaadDCKeIw1q7DWQs=",
+        "subType": "06"
+      }
+    }
+  },
+  "local_binData=04_rand_explicit_id": {
+    "kms": "local",
+    "type": "binData=04",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AizggCwAAAAAAAAAAAAAAAAF7XgMgKjQmWYWmobrYWKiGYCKsy5kTgVweFBuzvFISaZjFsq2hrZB2DwUaOeT6XUPH/Onrdjc3fNElf3FdQDHif4rt+1lh9jEX+nMbRw9i3s=",
+        "subType": "06"
+      }
+    }
+  },
+  "local_binData=04_rand_explicit_altname": {
+    "kms": "local",
+    "type": "binData=04",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AizggCwAAAAAAAAAAAAAAAAFGoA/1H0waFLor6LbkUCLC2Wm9j/ZT7yifPbf0G7WvO0+gBLlffr3aJIQ9ik5vxPbmDDMCoYlbEYgb8i9I5tKC17WPhjVH2N2+4l9y7aEmS4=",
+        "subType": "06"
+      }
+    }
+  },
+  "local_binData=04_det_auto_id": {
+    "kms": "local",
+    "type": "binData=04",
+    "algo": "det",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "ASzggCwAAAAAAAAAAAAAAAAFwO3hsD8ee/uwgUiHWem8fGe54LsTJWqgbRCacIe6sxrsyLT6EsVIqg4Sn7Ou+FC3WJbFld5kx8euLe/MHa8FGYjxD97z5j+rUx5tt3T6YbA=",
+        "subType": "06"
+      }
+    }
+  },
+  "local_binData=04_det_explicit_id": {
+    "kms": "local",
+    "type": "binData=04",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "ASzggCwAAAAAAAAAAAAAAAAFwO3hsD8ee/uwgUiHWem8fGe54LsTJWqgbRCacIe6sxrsyLT6EsVIqg4Sn7Ou+FC3WJbFld5kx8euLe/MHa8FGYjxD97z5j+rUx5tt3T6YbA=",
+        "subType": "06"
+      }
+    }
+  },
+  "local_binData=04_det_explicit_altname": {
+    "kms": "local",
+    "type": "binData=04",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "ASzggCwAAAAAAAAAAAAAAAAFwO3hsD8ee/uwgUiHWem8fGe54LsTJWqgbRCacIe6sxrsyLT6EsVIqg4Sn7Ou+FC3WJbFld5kx8euLe/MHa8FGYjxD97z5j+rUx5tt3T6YbA=",
+        "subType": "06"
+      }
+    }
+  },
+  "local_undefined_rand_explicit_id": {
+    "kms": "local",
+    "type": "undefined",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": false,
+    "value": { "$undefined": true }
+  },
+  "local_undefined_rand_explicit_altname": {
+    "kms": "local",
+    "type": "undefined",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": false,
+    "value": { "$undefined": true }
+  },
+  "local_undefined_det_explicit_id": {
+    "kms": "local",
+    "type": "undefined",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": false,
+    "value": { "$undefined": true }
+  },
+  "local_undefined_det_explicit_altname": {
+    "kms": "local",
+    "type": "undefined",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": false,
+    "value": { "$undefined": true }
+  },
+  "local_objectId_rand_auto_id": {
+    "kms": "local",
+    "type": "objectId",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AizggCwAAAAAAAAAAAAAAAAHfvxWRZOzfao3faE3RglL0IcDpBcNwqiGL5KgSokmRxWjjWeiel88Mbo5Plo0SswwNQ2H7C5GVG21L+UbvcW63g==",
+        "subType": "06"
+      }
+    }
+  },
+  "local_objectId_rand_auto_altname": {
+    "kms": "local",
+    "type": "objectId",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AizggCwAAAAAAAAAAAAAAAAHhd9lSOO7bHE7PM+Uxa2v3X1FF66IwyEr0wqnyTaOM+cHQLmec/RlEaRIQ1x2AiW7LwmmVgZ0xBMK9CMh0Lhbyw==",
+        "subType": "06"
+      }
+    }
+  },
+  "local_objectId_rand_explicit_id": {
+    "kms": "local",
+    "type": "objectId",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AizggCwAAAAAAAAAAAAAAAAHETwT9bo+JtboBVW/8GzzMQCpn22iiNJnlxYfyO45jvYJQRs29RRIouCsnFkmC7cfAO3GlVxv113euYjIO7AlAg==",
+        "subType": "06"
+      }
+    }
+  },
+  "local_objectId_rand_explicit_altname": {
+    "kms": "local",
+    "type": "objectId",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AizggCwAAAAAAAAAAAAAAAAHhsguAMBzQUFBAitpJDzKEaMDGUGfvCzmUUhf4rnp8xeall/p91TUudaSMcU11XEgJ0Mym4IbYRd8+TfUai0nvw==",
+        "subType": "06"
+      }
+    }
+  },
+  "local_objectId_det_auto_id": {
+    "kms": "local",
+    "type": "objectId",
+    "algo": "det",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "ASzggCwAAAAAAAAAAAAAAAAH4ElF4AvQ+kkGfhadgKNy3GcYrDZPN6RpzaMYIhcCGDvC9W+cIS9dH1aJbPU7vTPmEZnnynPTDWjw3rAj2+9mOA==",
+        "subType": "06"
+      }
+    }
+  },
+  "local_objectId_det_explicit_id": {
+    "kms": "local",
+    "type": "objectId",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "ASzggCwAAAAAAAAAAAAAAAAH4ElF4AvQ+kkGfhadgKNy3GcYrDZPN6RpzaMYIhcCGDvC9W+cIS9dH1aJbPU7vTPmEZnnynPTDWjw3rAj2+9mOA==",
+        "subType": "06"
+      }
+    }
+  },
+  "local_objectId_det_explicit_altname": {
+    "kms": "local",
+    "type": "objectId",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "ASzggCwAAAAAAAAAAAAAAAAH4ElF4AvQ+kkGfhadgKNy3GcYrDZPN6RpzaMYIhcCGDvC9W+cIS9dH1aJbPU7vTPmEZnnynPTDWjw3rAj2+9mOA==",
+        "subType": "06"
+      }
+    }
+  },
+  "local_bool_rand_auto_id": {
+    "kms": "local",
+    "type": "bool",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AizggCwAAAAAAAAAAAAAAAAIxGld4J/2vSWg5tjQulpkm9C6WeUcLbv2yfKRXPAbmLpv3u4Yrmr5qisJtqmDPTcb993WosvCYAh0UGW+zpsdEg==",
+        "subType": "06"
+      }
+    }
+  },
+  "local_bool_rand_auto_altname": {
+    "kms": "local",
+    "type": "bool",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AizggCwAAAAAAAAAAAAAAAAIpUFPiS2uoW1Aqs0WQkBa201OBmsuJ8WUKcv5aBPASkcwfaw9qSWs3QrbEDR2GyoU4SeYOByCAQMzXCPoIYAFdQ==",
+        "subType": "06"
+      }
+    }
+  },
+  "local_bool_rand_explicit_id": {
+    "kms": "local",
+    "type": "bool",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AizggCwAAAAAAAAAAAAAAAAIJuzu1a60meYlU3LMjw/7G4Vh/lqKopxdpGWoLXEmY/NoHgX6Fkv9iTwxv/Nv8rZwtawpFV+mQUG/6A1IHMBASQ==",
+        "subType": "06"
+      }
+    }
+  },
+  "local_bool_rand_explicit_altname": {
+    "kms": "local",
+    "type": "bool",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AizggCwAAAAAAAAAAAAAAAAIn9VjxL5TdGgJLckNHRrIaL32L31q5OERRZG2M5OYKk66TnrlfEs+ykcDvGwMGKpr/PYjY5kBHDc/oELGJJbWRQ==",
+        "subType": "06"
+      }
+    }
+  },
+  "local_bool_det_explicit_id": {
+    "kms": "local",
+    "type": "bool",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": false,
+    "value": true
+  },
+  "local_bool_det_explicit_altname": {
+    "kms": "local",
+    "type": "bool",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": false,
+    "value": true
+  },
+  "local_date_rand_auto_id": {
+    "kms": "local",
+    "type": "date",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AizggCwAAAAAAAAAAAAAAAAJPPv4MC5xzt2uxPGBHH9g2z03o9SQjjmuxt97Ub1UcKCCHsGED3bx6YSrocuEMiFFI4d5Fqgl8HNeS4j0PR0tYA==",
+        "subType": "06"
+      }
+    }
+  },
+  "local_date_rand_auto_altname": {
+    "kms": "local",
+    "type": "date",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AizggCwAAAAAAAAAAAAAAAAJ6i2A9Hi4xWlOMjFMGpwaRctR1VFnb4El166n18RvjKic46V+WoadvLHS32RhPOvkLVYwIeU4C+vrO5isBNoUdw==",
+        "subType": "06"
+      }
+    }
+  },
+  "local_date_rand_explicit_id": {
+    "kms": "local",
+    "type": "date",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AizggCwAAAAAAAAAAAAAAAAJHcniV7Q0C8ZTWrE0hp5i5bUPlrrRdNLZckfODw8XNVtVPDjbznglccQmI7w1t8kOVp65eKzVzUOXN0YkqA+1QA==",
+        "subType": "06"
+      }
+    }
+  },
+  "local_date_rand_explicit_altname": {
+    "kms": "local",
+    "type": "date",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AizggCwAAAAAAAAAAAAAAAAJKCUCjC3hsmEKKYwGP3ceh3zR+ArE8LYFOQfN87aEsTr60VrzHXmsE8PvizRhhMnrp07ljzQkuat39L+0QSR2qQ==",
+        "subType": "06"
+      }
+    }
+  },
+  "local_date_det_auto_id": {
+    "kms": "local",
+    "type": "date",
+    "algo": "det",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "ASzggCwAAAAAAAAAAAAAAAAJ1GMYQTruoKr6fv9XCbcVkx/3yivymPSMEkPCRDYxQv45w4TqBKMDfpRd1TOLOv1qvcb+gjH+z5IfVBMp2IpG/Q==",
+        "subType": "06"
+      }
+    }
+  },
+  "local_date_det_explicit_id": {
+    "kms": "local",
+    "type": "date",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "ASzggCwAAAAAAAAAAAAAAAAJ1GMYQTruoKr6fv9XCbcVkx/3yivymPSMEkPCRDYxQv45w4TqBKMDfpRd1TOLOv1qvcb+gjH+z5IfVBMp2IpG/Q==",
+        "subType": "06"
+      }
+    }
+  },
+  "local_date_det_explicit_altname": {
+    "kms": "local",
+    "type": "date",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "ASzggCwAAAAAAAAAAAAAAAAJ1GMYQTruoKr6fv9XCbcVkx/3yivymPSMEkPCRDYxQv45w4TqBKMDfpRd1TOLOv1qvcb+gjH+z5IfVBMp2IpG/Q==",
+        "subType": "06"
+      }
+    }
+  },
+  "local_null_rand_explicit_id": {
+    "kms": "local",
+    "type": "null",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": false,
+    "value": null
+  },
+  "local_null_rand_explicit_altname": {
+    "kms": "local",
+    "type": "null",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": false,
+    "value": null
+  },
+  "local_null_det_explicit_id": {
+    "kms": "local",
+    "type": "null",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": false,
+    "value": null
+  },
+  "local_null_det_explicit_altname": {
+    "kms": "local",
+    "type": "null",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": false,
+    "value": null
+  },
+  "local_regex_rand_auto_id": {
+    "kms": "local",
+    "type": "regex",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AizggCwAAAAAAAAAAAAAAAALXKw7zSgqQj1AKoWO0MoMxsBuu0cMB6KdJQCRKdupoLV/Y22owwsVpDDMv5sgUpkG5YIV+Fz7taHodXE07qHopw==",
+        "subType": "06"
+      }
+    }
+  },
+  "local_regex_rand_auto_altname": {
+    "kms": "local",
+    "type": "regex",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AizggCwAAAAAAAAAAAAAAAALntOLXq7VW1+jwba/dSbidMo2bewNo7AtK9A1CPwk9XrjUQaEOQxfRpho3BYQEo2U67fQdsY/tyhaj4jduHn9JQ==",
+        "subType": "06"
+      }
+    }
+  },
+  "local_regex_rand_explicit_id": {
+    "kms": "local",
+    "type": "regex",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AizggCwAAAAAAAAAAAAAAAALlMMG2iS/gEOEsVKR7sxBJP2IUzZ+aRbozDSkqADncresBvaPBSE17lng5NG7H1JRCAcP1rH/Te+0CrMd7JpRAQ==",
+        "subType": "06"
+      }
+    }
+  },
+  "local_regex_rand_explicit_altname": {
+    "kms": "local",
+    "type": "regex",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AizggCwAAAAAAAAAAAAAAAAL1YNnlVu5+njDLxh1LMhIPOH19RykAXhxrUbCy6TI5MLQsAOSgAJbXOTXeKr0D8/Ff0phToWOKl193gOOIp8yZQ==",
+        "subType": "06"
+      }
+    }
+  },
+  "local_regex_det_auto_id": {
+    "kms": "local",
+    "type": "regex",
+    "algo": "det",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "ASzggCwAAAAAAAAAAAAAAAALiZbL5nFIZl7cSLH5E3wK3jJeAeFc7hLHNITtLAu+o10raEs5i/UCihMHmkf8KHZxghs056pfm5BjPzlL9x7IHQ==",
+        "subType": "06"
+      }
+    }
+  },
+  "local_regex_det_explicit_id": {
+    "kms": "local",
+    "type": "regex",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "ASzggCwAAAAAAAAAAAAAAAALiZbL5nFIZl7cSLH5E3wK3jJeAeFc7hLHNITtLAu+o10raEs5i/UCihMHmkf8KHZxghs056pfm5BjPzlL9x7IHQ==",
+        "subType": "06"
+      }
+    }
+  },
+  "local_regex_det_explicit_altname": {
+    "kms": "local",
+    "type": "regex",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "ASzggCwAAAAAAAAAAAAAAAALiZbL5nFIZl7cSLH5E3wK3jJeAeFc7hLHNITtLAu+o10raEs5i/UCihMHmkf8KHZxghs056pfm5BjPzlL9x7IHQ==",
+        "subType": "06"
+      }
+    }
+  },
+  "local_dbPointer_rand_auto_id": {
+    "kms": "local",
+    "type": "dbPointer",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AizggCwAAAAAAAAAAAAAAAAMUdAA9uOSk1tXJVe/CG3Ps6avYTEF1eHj1wSlCHkFxqlMtTO+rIQpikpjH0MrcXvEEdAO8g5hFZ01I7DWyK5AAxTxDqVF+kOaQ2VfKs6hyuo=",
+        "subType": "06"
+      }
+    }
+  },
+  "local_dbPointer_rand_auto_altname": {
+    "kms": "local",
+    "type": "dbPointer",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AizggCwAAAAAAAAAAAAAAAAMiNqvqLwZrPnsF235z+Obl1K9iEXdJ5GucMGpJdRG4lRvRE0Oy1vh6ztNTpYPY/tXyUFTBWlzl/lITalSEm/dT1Bnlh0iPAFrAiNySf662og=",
+        "subType": "06"
+      }
+    }
+  },
+  "local_dbPointer_rand_explicit_id": {
+    "kms": "local",
+    "type": "dbPointer",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AizggCwAAAAAAAAAAAAAAAAM+Tn31YcKiowBTJWRYCYAEO7UARDE2/jTVGEKXCpiwEqqP3JSAS0b80zYt8dxo5mVhUo2a02ClKrB8vs+B6sU1kXrahSaVSEHZlRSGN9fWgo=",
+        "subType": "06"
+      }
+    }
+  },
+  "local_dbPointer_rand_explicit_altname": {
+    "kms": "local",
+    "type": "dbPointer",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AizggCwAAAAAAAAAAAAAAAAMdOZZUvpJIqG9qiOLy5x4BdftyHipPDZn/eeLEc7ir3v4jJsY3dsv6fQERo5U9lMynNGA9PJePVzq5tWsIMX0EcCQcMfGmosfkYDzN1OX99A=",
+        "subType": "06"
+      }
+    }
+  },
+  "local_dbPointer_det_auto_id": {
+    "kms": "local",
+    "type": "dbPointer",
+    "algo": "det",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "ASzggCwAAAAAAAAAAAAAAAAMQWace2C1w3yqtmo/rgz3YtIDnx1Ia/oDsoHnnMZlEy5RoK3uosi1hvNAZCSg3Sen0H7MH3XVhGGMCL4cS69uJ0ENSvh+K6fiZzAXCKUPfvM=",
+        "subType": "06"
+      }
+    }
+  },
+  "local_dbPointer_det_explicit_id": {
+    "kms": "local",
+    "type": "dbPointer",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "ASzggCwAAAAAAAAAAAAAAAAMQWace2C1w3yqtmo/rgz3YtIDnx1Ia/oDsoHnnMZlEy5RoK3uosi1hvNAZCSg3Sen0H7MH3XVhGGMCL4cS69uJ0ENSvh+K6fiZzAXCKUPfvM=",
+        "subType": "06"
+      }
+    }
+  },
+  "local_dbPointer_det_explicit_altname": {
+    "kms": "local",
+    "type": "dbPointer",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "ASzggCwAAAAAAAAAAAAAAAAMQWace2C1w3yqtmo/rgz3YtIDnx1Ia/oDsoHnnMZlEy5RoK3uosi1hvNAZCSg3Sen0H7MH3XVhGGMCL4cS69uJ0ENSvh+K6fiZzAXCKUPfvM=",
+        "subType": "06"
+      }
+    }
+  },
+  "local_javascript_rand_auto_id": {
+    "kms": "local",
+    "type": "javascript",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AizggCwAAAAAAAAAAAAAAAANNL2AMKwTDyMIvxLKhBxZKx50C0tBdkLwuXmuMcrUqZeH8bsvjtttoM9LWkkileMyeTWgxblJ1b+uQ+V+4VT6fA==",
+        "subType": "06"
+      }
+    }
+  },
+  "local_javascript_rand_auto_altname": {
+    "kms": "local",
+    "type": "javascript",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AizggCwAAAAAAAAAAAAAAAANBjBlHGw3K3TWQHpvfa1z0bKhNnVFC/lZArIexo3wjdGq3MdkGA5cuBIp87HHmOIv6o/pvQ9K74v48RQl+JH44A==",
+        "subType": "06"
+      }
+    }
+  },
+  "local_javascript_rand_explicit_id": {
+    "kms": "local",
+    "type": "javascript",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AizggCwAAAAAAAAAAAAAAAANjvM7u3vNVyKpyI7g5kbzBpHPzXzOQToDSng5/c9yjMG+qi4TPtOyassobJOnMmDYBLyqRXCl/GsDLprbg5jxuA==",
+        "subType": "06"
+      }
+    }
+  },
+  "local_javascript_rand_explicit_altname": {
+    "kms": "local",
+    "type": "javascript",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AizggCwAAAAAAAAAAAAAAAANMtO7KneuVx4gSOjX4MQjKL80zJhnt+efDBylkpNsqKyxBXB60nkiredGzwaK3/4QhIfGJrC1fQpwUwu/v1L17g==",
+        "subType": "06"
+      }
+    }
+  },
+  "local_javascript_det_auto_id": {
+    "kms": "local",
+    "type": "javascript",
+    "algo": "det",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "ASzggCwAAAAAAAAAAAAAAAANmQsg9E/BzGJVNVhSNyunS/TH0332oVFdPS6gjX0Cp/JC0YhB97DLz3N4e/q8ECaz7tTdQt9JacNUgxo+YCULUA==",
+        "subType": "06"
+      }
+    }
+  },
+  "local_javascript_det_explicit_id": {
+    "kms": "local",
+    "type": "javascript",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "ASzggCwAAAAAAAAAAAAAAAANmQsg9E/BzGJVNVhSNyunS/TH0332oVFdPS6gjX0Cp/JC0YhB97DLz3N4e/q8ECaz7tTdQt9JacNUgxo+YCULUA==",
+        "subType": "06"
+      }
+    }
+  },
+  "local_javascript_det_explicit_altname": {
+    "kms": "local",
+    "type": "javascript",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "ASzggCwAAAAAAAAAAAAAAAANmQsg9E/BzGJVNVhSNyunS/TH0332oVFdPS6gjX0Cp/JC0YhB97DLz3N4e/q8ECaz7tTdQt9JacNUgxo+YCULUA==",
+        "subType": "06"
+      }
+    }
+  },
+  "local_symbol_rand_auto_id": {
+    "kms": "local",
+    "type": "symbol",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AizggCwAAAAAAAAAAAAAAAAOOuO2b23mekwI8b6gWeEgRy1lLOCsNyBKvdmizK7/oOVKCvd+3kwUn9a6TxygooiVAN/Aohr1cjb8jRlMPWpkP0iO0+Tt6+vkizgFsQW4iio=",
+        "subType": "06"
+      }
+    }
+  },
+  "local_symbol_rand_auto_altname": {
+    "kms": "local",
+    "type": "symbol",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AizggCwAAAAAAAAAAAAAAAAOhN4QPOcmGnFKGvTfhz6TQleDA02X6oWULLHTnOUJYfE3OUSyf2ULEQh1yhdKdwXMuYVgGl28pMosiwkBShrXYe5ZlMjiZCIMZWSdUMV0tXk=",
+        "subType": "06"
+      }
+    }
+  },
+  "local_symbol_rand_explicit_id": {
+    "kms": "local",
+    "type": "symbol",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AizggCwAAAAAAAAAAAAAAAAO9aWi9RliwQHdXHoJME9VyN6XgyGd95Eclx+ZFYfLxBGAuUnPNjSfVuNZwYdyKC8JX79+mYhk7IXmcGV4z+4486sxyLk3idi4Kmpz2ESqV5g=",
+        "subType": "06"
+      }
+    }
+  },
+  "local_symbol_rand_explicit_altname": {
+    "kms": "local",
+    "type": "symbol",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AizggCwAAAAAAAAAAAAAAAAO/qev3DPfpkQoSW9aHOyalwfI/VYDQVN5VMINx4kw2vEqHiI1HRdZRPOz3q74TlQEy3TMNMTYdCvh5bpN/PptRZCTQbzP6ugz9dTp79w5/Ok=",
+        "subType": "06"
+      }
+    }
+  },
+  "local_symbol_det_auto_id": {
+    "kms": "local",
+    "type": "symbol",
+    "algo": "det",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "ASzggCwAAAAAAAAAAAAAAAAOsg5cs6VpZWoTOFg4ztZmpj8kSTeCArVcI1Zz2pOnmMqNv/vcKQGhKSBbfniMripr7iuiYtlgkHGsdO2FqUp6Jb8NEWm5uWqdNU21zR9SRkE=",
+        "subType": "06"
+      }
+    }
+  },
+  "local_symbol_det_explicit_id": {
+    "kms": "local",
+    "type": "symbol",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "ASzggCwAAAAAAAAAAAAAAAAOsg5cs6VpZWoTOFg4ztZmpj8kSTeCArVcI1Zz2pOnmMqNv/vcKQGhKSBbfniMripr7iuiYtlgkHGsdO2FqUp6Jb8NEWm5uWqdNU21zR9SRkE=",
+        "subType": "06"
+      }
+    }
+  },
+  "local_symbol_det_explicit_altname": {
+    "kms": "local",
+    "type": "symbol",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "ASzggCwAAAAAAAAAAAAAAAAOsg5cs6VpZWoTOFg4ztZmpj8kSTeCArVcI1Zz2pOnmMqNv/vcKQGhKSBbfniMripr7iuiYtlgkHGsdO2FqUp6Jb8NEWm5uWqdNU21zR9SRkE=",
+        "subType": "06"
+      }
+    }
+  },
+  "local_javascriptWithScope_rand_auto_id": {
+    "kms": "local",
+    "type": "javascriptWithScope",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AizggCwAAAAAAAAAAAAAAAAP5gLMvLOAc6vGAvC7bGmEC4eweptAiX3A7L0iCoHps/wm0FBLkfpF6F4pCjVYiY1lTID38wliRLPyhntCj+cfvlMfKSjouNgXMIWyQ8GKZ2c=",
+        "subType": "06"
+      }
+    }
+  },
+  "local_javascriptWithScope_rand_auto_altname": {
+    "kms": "local",
+    "type": "javascriptWithScope",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AizggCwAAAAAAAAAAAAAAAAPVsw9Opn/P5SAdJhX4MTxIcsmaG8isIN4NKPi9k1u/Vj7AVkcxYqwurAghaJpmfoAgMruvzi1hcKvd05yHd9Nk0vkvODwDgnjJB6QO+qUce8=",
+        "subType": "06"
+      }
+    }
+  },
+  "local_javascriptWithScope_rand_explicit_id": {
+    "kms": "local",
+    "type": "javascriptWithScope",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AizggCwAAAAAAAAAAAAAAAAPLUa+nsrqiHkVdE5K1xl/ZsiZqQznG2yVXyA3b3loBylbcL2NEBp1JUeGnPZ0y5ZK4AmoL6NMH2Io313rW3V8FTArs/OOQWPRJSe6h0M3wXk=",
+        "subType": "06"
+      }
+    }
+  },
+  "local_javascriptWithScope_rand_explicit_altname": {
+    "kms": "local",
+    "type": "javascriptWithScope",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AizggCwAAAAAAAAAAAAAAAAPzUKaXCH0JImSlY73HVop9g9c0YssNEiA7Dy7Vji61avxvnuJJfghDchdwwaY7Vc8+0bymoanUWcErRctLzjm+1uKeMnFQokR8wFtnS3PgpQ=",
+        "subType": "06"
+      }
+    }
+  },
+  "local_javascriptWithScope_det_explicit_id": {
+    "kms": "local",
+    "type": "javascriptWithScope",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": false,
+    "value": { "$code": "x=1", "$scope": {} }
+  },
+  "local_javascriptWithScope_det_explicit_altname": {
+    "kms": "local",
+    "type": "javascriptWithScope",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": false,
+    "value": { "$code": "x=1", "$scope": {} }
+  },
+  "local_int_rand_auto_id": {
+    "kms": "local",
+    "type": "int",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AizggCwAAAAAAAAAAAAAAAAQHXpXb3KlHA2KFTBgl0VoLCu0CUf1ae4DckkwDorbredVSqxvA5e+NvVudY5yuea6bC9F57JlbjI8NWYAUw4q0Q==",
+        "subType": "06"
+      }
+    }
+  },
+  "local_int_rand_auto_altname": {
+    "kms": "local",
+    "type": "int",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AizggCwAAAAAAAAAAAAAAAAQSxXMF4+TKV+a3lcxXky8VepEqdg5wI/jg+C4CAUgNurq2XhgrxyqiMjkU8z07tfyoLYyX6P+dTrwj6nzvvchCw==",
+        "subType": "06"
+      }
+    }
+  },
+  "local_int_rand_explicit_id": {
+    "kms": "local",
+    "type": "int",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AizggCwAAAAAAAAAAAAAAAAQmzteYnshCI8HBGd7UYUKvcg4xl6M8PRyi1xX/WHbjyQkAJXxczS8hO91wuqStE3tBNSmulUejz9S691ufTd6ZA==",
+        "subType": "06"
+      }
+    }
+  },
+  "local_int_rand_explicit_altname": {
+    "kms": "local",
+    "type": "int",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AizggCwAAAAAAAAAAAAAAAAQLCHLru//++QSoWVEyw2v6TUfCnlrPJXrpLLezWf16vK85jTfm8vJbb2X2UzX04wGzVL9tCFFsWX6Z5gHXhgSBg==",
+        "subType": "06"
+      }
+    }
+  },
+  "local_int_det_auto_id": {
+    "kms": "local",
+    "type": "int",
+    "algo": "det",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "ASzggCwAAAAAAAAAAAAAAAAQIxWjLBromNUgiOoeoZ4RUJUYIfhfOmab0sa4qYlS9bgYI41FU6BtzaOevR16O9i+uACbiHL0X6FMXKjOmiRAug==",
+        "subType": "06"
+      }
+    }
+  },
+  "local_int_det_explicit_id": {
+    "kms": "local",
+    "type": "int",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "ASzggCwAAAAAAAAAAAAAAAAQIxWjLBromNUgiOoeoZ4RUJUYIfhfOmab0sa4qYlS9bgYI41FU6BtzaOevR16O9i+uACbiHL0X6FMXKjOmiRAug==",
+        "subType": "06"
+      }
+    }
+  },
+  "local_int_det_explicit_altname": {
+    "kms": "local",
+    "type": "int",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "ASzggCwAAAAAAAAAAAAAAAAQIxWjLBromNUgiOoeoZ4RUJUYIfhfOmab0sa4qYlS9bgYI41FU6BtzaOevR16O9i+uACbiHL0X6FMXKjOmiRAug==",
+        "subType": "06"
+      }
+    }
+  },
+  "local_timestamp_rand_auto_id": {
+    "kms": "local",
+    "type": "timestamp",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AizggCwAAAAAAAAAAAAAAAARntIycg0Xkd16GEa//VSJI4Rkl7dT6MpRa+D3MiTEeio5Yy8zGK0u2BtEP/9MCRQw2hJDYj5znVqwhdduM0OTiA==",
+        "subType": "06"
+      }
+    }
+  },
+  "local_timestamp_rand_auto_altname": {
+    "kms": "local",
+    "type": "timestamp",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AizggCwAAAAAAAAAAAAAAAARWA9Ox5ejDPeWxfjbRgcGCtF/G5yrPMbBJD9ESDFc0NaVe0sdNNTisEVxsSkn7M/S4FCibKh+C8femr7xhu1iTw==",
+        "subType": "06"
+      }
+    }
+  },
+  "local_timestamp_rand_explicit_id": {
+    "kms": "local",
+    "type": "timestamp",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AizggCwAAAAAAAAAAAAAAAARrEfOL4+4Qh7IkhHnHcBEANGfMF8n2wUDnsZ0lXEb0fACKzaN5OKaxMIQBs/3pFBw721qRfCHY+ByKeaQuABbzg==",
+        "subType": "06"
+      }
+    }
+  },
+  "local_timestamp_rand_explicit_altname": {
+    "kms": "local",
+    "type": "timestamp",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AizggCwAAAAAAAAAAAAAAAARW8nwmnBt+LFIAcFWvOzX8llrGcveQKFhyYUIth9d7wtpTyc9myFp8GBQCnjDpKzA6lPmbqVYeLU0L9q0h6SHGQ==",
+        "subType": "06"
+      }
+    }
+  },
+  "local_timestamp_det_auto_id": {
+    "kms": "local",
+    "type": "timestamp",
+    "algo": "det",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "ASzggCwAAAAAAAAAAAAAAAAR6uMylGytMq8QDr5Yz3w9HlW2MkGt6yIgUKcXYSaXru8eer+EkLv66/vy5rHqTfV0+8ryoi+d+PWO5U6b3Ng5Gg==",
+        "subType": "06"
+      }
+    }
+  },
+  "local_timestamp_det_explicit_id": {
+    "kms": "local",
+    "type": "timestamp",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "ASzggCwAAAAAAAAAAAAAAAAR6uMylGytMq8QDr5Yz3w9HlW2MkGt6yIgUKcXYSaXru8eer+EkLv66/vy5rHqTfV0+8ryoi+d+PWO5U6b3Ng5Gg==",
+        "subType": "06"
+      }
+    }
+  },
+  "local_timestamp_det_explicit_altname": {
+    "kms": "local",
+    "type": "timestamp",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "ASzggCwAAAAAAAAAAAAAAAAR6uMylGytMq8QDr5Yz3w9HlW2MkGt6yIgUKcXYSaXru8eer+EkLv66/vy5rHqTfV0+8ryoi+d+PWO5U6b3Ng5Gg==",
+        "subType": "06"
+      }
+    }
+  },
+  "local_long_rand_auto_id": {
+    "kms": "local",
+    "type": "long",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AizggCwAAAAAAAAAAAAAAAASrinKUOpHIB7MNRmCAPWcP4CjZwfr5JaRT3G/GqY9B/6csj3+N9jmo1fYvM8uHcnmf5hzDDOamaE2FF1jDKkrHw==",
+        "subType": "06"
+      }
+    }
+  },
+  "local_long_rand_auto_altname": {
+    "kms": "local",
+    "type": "long",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AizggCwAAAAAAAAAAAAAAAAShWMPYDkCpTC2XLYyykPJMihASLKn6HHcB2Eh7jFwQb/8D1HCQoPmOHMyXaN4AtIKm1oqEfma6FSnEPENQoledQ==",
+        "subType": "06"
+      }
+    }
+  },
+  "local_long_rand_explicit_id": {
+    "kms": "local",
+    "type": "long",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AizggCwAAAAAAAAAAAAAAAASd2h34ZLib+GiYayrm/FIZ/weg8wF41T0PfF8NCLTJCoT7gIkdpNRz2zkkQgZMR31efNKtsM8Bs4wgZbkrXsXWg==",
+        "subType": "06"
+      }
+    }
+  },
+  "local_long_rand_explicit_altname": {
+    "kms": "local",
+    "type": "long",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AizggCwAAAAAAAAAAAAAAAASPAvdjz+a3FvXqDSjazaGqwZxrfXlfFB5/VjQFXQB0gpodCEaz1qaLSKfCWBg83ftrYKa/1sa44gU5NBthDfDwQ==",
+        "subType": "06"
+      }
+    }
+  },
+  "local_long_det_auto_id": {
+    "kms": "local",
+    "type": "long",
+    "algo": "det",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "ASzggCwAAAAAAAAAAAAAAAASQk372m/hW3WX82/GH+ikPv3QUwK7Hh/RBpAguiNxMdNhkgA/y2gznVNm17t6djyub7+d5zN4P5PLS/EOm2kjtw==",
+        "subType": "06"
+      }
+    }
+  },
+  "local_long_det_explicit_id": {
+    "kms": "local",
+    "type": "long",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "ASzggCwAAAAAAAAAAAAAAAASQk372m/hW3WX82/GH+ikPv3QUwK7Hh/RBpAguiNxMdNhkgA/y2gznVNm17t6djyub7+d5zN4P5PLS/EOm2kjtw==",
+        "subType": "06"
+      }
+    }
+  },
+  "local_long_det_explicit_altname": {
+    "kms": "local",
+    "type": "long",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "ASzggCwAAAAAAAAAAAAAAAASQk372m/hW3WX82/GH+ikPv3QUwK7Hh/RBpAguiNxMdNhkgA/y2gznVNm17t6djyub7+d5zN4P5PLS/EOm2kjtw==",
+        "subType": "06"
+      }
+    }
+  },
+  "local_decimal_rand_auto_id": {
+    "kms": "local",
+    "type": "decimal",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AizggCwAAAAAAAAAAAAAAAATLnMMDZhnGSn5F5xHhsJXxiTGXd61Eq6fgppOlxUNVlsZNYyr5tZ3owfTTqRuD9yRg97x65WiHewBBnJJSeirCTAy9zZxWPVlJSiC0gO7rbM=",
+        "subType": "06"
+      }
+    }
+  },
+  "local_decimal_rand_auto_altname": {
+    "kms": "local",
+    "type": "decimal",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AizggCwAAAAAAAAAAAAAAAATenMh7NKQioGjpuEojIrYKFaJhbuGxUgu2yTTbe3TndhgHryhW9GXiUqo8WTpnXqpC5E/z03ZYLWfCbe7qGdL6T7bbrTpaTaWZnnAm3XaCqY=",
+        "subType": "06"
+      }
+    }
+  },
+  "local_decimal_rand_explicit_id": {
+    "kms": "local",
+    "type": "decimal",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AizggCwAAAAAAAAAAAAAAAAT9vqXuKRh+2HxeCMr+pQYdhYNw7xrTdU4dySWz0X6tCK7LZO5AV72utmRJxID7Bqv1ZlXAk00V92oDLyKG9kHeG5+S34QE/aLCPsAWcppfxY=",
+        "subType": "06"
+      }
+    }
+  },
+  "local_decimal_rand_explicit_altname": {
+    "kms": "local",
+    "type": "decimal",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AizggCwAAAAAAAAAAAAAAAATtqOCFMbOkls3LikQNXlnlkRr5gJns1+5Kvbt7P7texMa/QlXkYSHhtwESyfOcCQ2sw1T0eZ9DDuNaznpdK2KIqZBkVEC9iMoxqIqXF7Nab0=",
+        "subType": "06"
+      }
+    }
+  },
+  "local_decimal_det_explicit_id": {
+    "kms": "local",
+    "type": "decimal",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": false,
+    "value": { "$numberDecimal": "1.234" }
+  },
+  "local_decimal_det_explicit_altname": {
+    "kms": "local",
+    "type": "decimal",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": false,
+    "value": { "$numberDecimal": "1.234" }
+  },
+  "local_minKey_rand_explicit_id": {
+    "kms": "local",
+    "type": "minKey",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": false,
+    "value": { "$minKey": 1 }
+  },
+  "local_minKey_rand_explicit_altname": {
+    "kms": "local",
+    "type": "minKey",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": false,
+    "value": { "$minKey": 1 }
+  },
+  "local_minKey_det_explicit_id": {
+    "kms": "local",
+    "type": "minKey",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": false,
+    "value": { "$minKey": 1 }
+  },
+  "local_minKey_det_explicit_altname": {
+    "kms": "local",
+    "type": "minKey",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": false,
+    "value": { "$minKey": 1 }
+  },
+  "local_maxKey_rand_explicit_id": {
+    "kms": "local",
+    "type": "maxKey",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": false,
+    "value": { "$maxKey": 1 }
+  },
+  "local_maxKey_rand_explicit_altname": {
+    "kms": "local",
+    "type": "maxKey",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": false,
+    "value": { "$maxKey": 1 }
+  },
+  "local_maxKey_det_explicit_id": {
+    "kms": "local",
+    "type": "maxKey",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": false,
+    "value": { "$maxKey": 1 }
+  },
+  "local_maxKey_det_explicit_altname": {
+    "kms": "local",
+    "type": "maxKey",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": false,
+    "value": { "$maxKey": 1 }
+  },
+  "payload=0,algo=rand": {
+    "kms": "local",
+    "type": "string",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AizggCwAAAAAAAAAAAAAAAACcsBdT93ivCyvtkfQz9qb1A9Ll+I6hnGE0kFy3rmVG6xAvipmRJSoVq3iv7iUEDvaqmPXfjeH8h8cPYT86v3XSg==",
+        "subType": "06"
+      }
+    }
+  },
+  "payload=1,algo=rand": {
+    "kms": "local",
+    "type": "string",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AizggCwAAAAAAAAAAAAAAAACQOzpNBEGSrANr3Wl8uYpqeIc7pjc8e2LS2FaSrb8tM9F3mR1FqGgfJtn3eD+HZf3Y3WEDGK8975a/1BufkMqIQ==",
+        "subType": "06"
+      }
+    }
+  },
+  "payload=2,algo=rand": {
+    "kms": "local",
+    "type": "string",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AizggCwAAAAAAAAAAAAAAAACyGJEcuN1pG5oSEyxuKFwqddGHVU5Untbib7LkmtoJe9HngTofkOpeHZH/hV6Z3CFxLu6WFliJoySsFFbnFy9ag==",
+        "subType": "06"
+      }
+    }
+  },
+  "payload=3,algo=rand": {
+    "kms": "local",
+    "type": "string",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AizggCwAAAAAAAAAAAAAAAACLbp4w6mx45lR1vvgmeRja/y8U+WnR2oH4IpfrDi4lKM+JPVnJweiN3/1wAy+sXSy0S1Yh9yxmhh9ISoTkAuVxw==",
+        "subType": "06"
+      }
+    }
+  },
+  "payload=4,algo=rand": {
+    "kms": "local",
+    "type": "string",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AizggCwAAAAAAAAAAAAAAAACG0qMY/GPZ/2CR61cxbuizywefyMZVdeTCn5KFjqwejgxeBwX0JmGNHKKWbQIDQykRFv0q0WHUgsRmRhaotNCyQ==",
+        "subType": "06"
+      }
+    }
+  },
+  "payload=5,algo=rand": {
+    "kms": "local",
+    "type": "string",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AizggCwAAAAAAAAAAAAAAAACJI1onNpQfZhaYWrPEzHvNaJRqUDZK2xoyonB5E473BPgp3zvn0Jmz1deL8GzS+HlkjCrx39OvHyVt3+3S0kYYw==",
+        "subType": "06"
+      }
+    }
+  },
+  "payload=6,algo=rand": {
+    "kms": "local",
+    "type": "string",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AizggCwAAAAAAAAAAAAAAAAClyKY9tZBjl7SewSXr3MdoWRDUNgLaXDUjENpjyYvi/54EQ9a+J/LAAh1892i+mLpYxEUAmcftPyfX3VhbCgUQw==",
+        "subType": "06"
+      }
+    }
+  },
+  "payload=7,algo=rand": {
+    "kms": "local",
+    "type": "string",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AizggCwAAAAAAAAAAAAAAAACAMbEA+kNvnVV7B//ds2/QoVot061kbazoMwB/psB5eFdLVB5qApAXEWgQEMwkNnsTUYbtSduQz6uGwdagtNBRw==",
+        "subType": "06"
+      }
+    }
+  },
+  "payload=8,algo=rand": {
+    "kms": "local",
+    "type": "string",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AizggCwAAAAAAAAAAAAAAAACzdSK/d7Ni6D8qUgNopnEU5ia1K5llhBGk3O1Tf71t4ThnQjYW9eI/rIohWmev5CGWLHhwuvvKUtFcTAe+NMQww==",
+        "subType": "06"
+      }
+    }
+  },
+  "payload=9,algo=rand": {
+    "kms": "local",
+    "type": "string",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AizggCwAAAAAAAAAAAAAAAACzQcEa+ktF2EZf35TtyatnSGGaIVvFhZNuo5P3VwQvoONJrK2cSad7PBDAv3xDAB+VPZAigXAGQvd051sHooOHg==",
+        "subType": "06"
+      }
+    }
+  },
+  "payload=10,algo=rand": {
+    "kms": "local",
+    "type": "string",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AizggCwAAAAAAAAAAAAAAAACpfoDmApsR5xOD3TDhcHeD7Jco3kPFuuWjDpHtMepMOJ3S0c+ngGGhzPGZtEz2xuD/E7AQn1ryp/WAQ+WwkaJkQ==",
+        "subType": "06"
+      }
+    }
+  },
+  "payload=11,algo=rand": {
+    "kms": "local",
+    "type": "string",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AizggCwAAAAAAAAAAAAAAAACICMRXmx3oKqYv0IpmzkSMBIGT4Li3MPBF4Lw1s5F69WvZApD58glIKB6b7koIrF5qc2Wrb1/Nw+stRv0zvQ8Y9CcFV4OHm6WoEw+XDlWXJ4=",
+        "subType": "06"
+      }
+    }
+  },
+  "payload=12,algo=rand": {
+    "kms": "local",
+    "type": "string",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AizggCwAAAAAAAAAAAAAAAACTArUn0WUTojQC4fSvq3TwJVTsZNhWAK2WB057u2EnkUzMC0xsbU6611W6Okx6idZ7pMudXpBC34fRDrJPXOu3BxK+ZLCOWS2FqsvWq3HeTY=",
+        "subType": "06"
+      }
+    }
+  },
+  "payload=13,algo=rand": {
+    "kms": "local",
+    "type": "string",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AizggCwAAAAAAAAAAAAAAAACU1Ojn7EM2i+5KK2Beh1gPLhryK3Y7PtaZ/v4JvstxuAV4OHOR9yROP7pwenHXxczkWXvcyMY9OCdmHO8pkQkXO21798IPkDDN/ejJUFI0Uw=",
+        "subType": "06"
+      }
+    }
+  },
+  "payload=14,algo=rand": {
+    "kms": "local",
+    "type": "string",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AizggCwAAAAAAAAAAAAAAAAC0ZLwSliCbcr/e1uiYWk6gRuD/5qiyulQ7IUNWjhpBR6SLUfX2+yExLzps9hoOp53j9zRSKIzyleZ8yGLTLeN+Lz9BUe2ZT+sV8NiqZz3pkA=",
+        "subType": "06"
+      }
+    }
+  },
+  "payload=15,algo=rand": {
+    "kms": "local",
+    "type": "string",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AizggCwAAAAAAAAAAAAAAAACQ9pmlQeFDr+jEhFwjL/eGVxdv70JdnkLaKdJ3/jkvCX1VPU5HmQIi+JWY3Rrw844E/6sBR6zIODn5aM0WfyP8a2zKRAWaVQZ7n+QE9hDN/8=",
+        "subType": "06"
+      }
+    }
+  },
+  "payload=16,algo=rand": {
+    "kms": "local",
+    "type": "string",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "AizggCwAAAAAAAAAAAAAAAACiOcItInDGHqvkH0I3udp5nnX32XzDeqya/3KDjgZPT5GHek1vFTZ4924JVxFqFQz+No9rOVmyxm8O2fxjTK2vsjtADzKGnMTtFYZqghYCuc=",
+        "subType": "06"
+      }
+    }
+  },
+  "payload=0,algo=det": {
+    "kms": "local",
+    "type": "string",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "ASzggCwAAAAAAAAAAAAAAAACijFptWQy7a1Y0rpXEvamXWI9v9dnx0Qj84/mKUsVpc3agkQ0B04uPYeROdt2MeEeiZoEKVWV0NjBocAQCEz7dw==",
+        "subType": "06"
+      }
+    }
+  },
+  "payload=1,algo=det": {
+    "kms": "local",
+    "type": "string",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "ASzggCwAAAAAAAAAAAAAAAAChR90taVWsZk+++sgibX6CnFeQQHNoB8V+n2gmDe3CIT/t+WvhMf9D+mQipbAlrUyHgGihKMHcvAZ5RZ/spaH4Q==",
+        "subType": "06"
+      }
+    }
+  },
+  "payload=2,algo=det": {
+    "kms": "local",
+    "type": "string",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "ASzggCwAAAAAAAAAAAAAAAAC67wemDv1Xdu7+EMR9LMBTOxfyAqsGaxQibwamZItzplslL/Dp3t9g9vPuNzq0dWwhnfxQ9GBe8OA3dtRaifYCA==",
+        "subType": "06"
+      }
+    }
+  },
+  "payload=3,algo=det": {
+    "kms": "local",
+    "type": "string",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "ASzggCwAAAAAAAAAAAAAAAACVLxch+uC7weXrbtylCo1m4HYZmh0sd9JCrlTECO2M56JK1X9a30i2BDUdhPuoTvvODv74CGXkZKdist3o0mGAQ==",
+        "subType": "06"
+      }
+    }
+  },
+  "payload=4,algo=det": {
+    "kms": "local",
+    "type": "string",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "ASzggCwAAAAAAAAAAAAAAAACexfIZGkOYaCGktOUc6cgAYg7Bd/C5ZYmdb7b8+rd5BKWbthW6N6CxhDIyh/DHvkPAeIzfTYA2/9w6tsjfD/TPQ==",
+        "subType": "06"
+      }
+    }
+  },
+  "payload=5,algo=det": {
+    "kms": "local",
+    "type": "string",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "ASzggCwAAAAAAAAAAAAAAAACjUH/dPW4egOvFMJJnpWK8v27MeLkbXC4GFl1j+wPqTsIEeIWkzEmcXjHLTQGE2GplHHc/zxwRwD2dXdbzvsCDw==",
+        "subType": "06"
+      }
+    }
+  },
+  "payload=6,algo=det": {
+    "kms": "local",
+    "type": "string",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "ASzggCwAAAAAAAAAAAAAAAACzvS+QkGlvb05pNn+vBMml09yKmE8yM6lwccNIST5uZSsUxXf2hrxPtO7Ylc4lmBAJt/9bcM59JIeT9fpYMc75w==",
+        "subType": "06"
+      }
+    }
+  },
+  "payload=7,algo=det": {
+    "kms": "local",
+    "type": "string",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "ASzggCwAAAAAAAAAAAAAAAACSf2RxHJpRuh4j8nS1dfonUtsJEwgqfWrwOsfuT/tAGXgDN0ObUpzL2K7G2vmePjP4dwycCSIL3+2j34bqBJK1Q==",
+        "subType": "06"
+      }
+    }
+  },
+  "payload=8,algo=det": {
+    "kms": "local",
+    "type": "string",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "ASzggCwAAAAAAAAAAAAAAAACu96YYeLXXoYdEZYNU9UAZjSd6G4fOE1edrA6/RjZKVGWKxftmvj5g1VAOiom0XuTZUe1ihbnwhvKexeoa3Vc8Q==",
+        "subType": "06"
+      }
+    }
+  },
+  "payload=9,algo=det": {
+    "kms": "local",
+    "type": "string",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "ASzggCwAAAAAAAAAAAAAAAACX+UjBKo9+N0Z+mbyqZqkQv2ETMSn6aPTONWgJtw5nWklcxKjUSSLI+8LW/6M6Xf9a7177GsqmV2f/yCRF58Xtw==",
+        "subType": "06"
+      }
+    }
+  },
+  "payload=10,algo=det": {
+    "kms": "local",
+    "type": "string",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "ASzggCwAAAAAAAAAAAAAAAACL6TVscFzIJ9+Zj6LsCZ9xhaZuTZdvz1nJe4l69nKyj9hCjnyuiV6Ve4AXwQ5W1wiPfkJ0fCZS33NwiHw7QQ/vg==",
+        "subType": "06"
+      }
+    }
+  },
+  "payload=11,algo=det": {
+    "kms": "local",
+    "type": "string",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "ASzggCwAAAAAAAAAAAAAAAACPLq7IcWhTVwkKmy0flN7opoQzx7tTe1eD9JIc25FC9B6KGQkdcRDglDDR7/m6+kBtTnq88y63vBgomTxA8ZxQE+3pB7zCiBhX0QznuXvP44=",
+        "subType": "06"
+      }
+    }
+  },
+  "payload=12,algo=det": {
+    "kms": "local",
+    "type": "string",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "ASzggCwAAAAAAAAAAAAAAAACxv7v4pKtom5z1g9FUuyjEWAbdzJ3ytPNZlOfVr6KZnUPhIH7PfCz3/lTdYYWBTj01+SUZiC/7ruof9QDhsSiNWP7nUyHpQ/C3joI/BBjtDA=",
+        "subType": "06"
+      }
+    }
+  },
+  "payload=13,algo=det": {
+    "kms": "local",
+    "type": "string",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "ASzggCwAAAAAAAAAAAAAAAACZhiElQ/MvyVMwMkZPu8pT54Ap6TlpVSEbE4nIQzzeU3XKVuspMdI5IXvvgfULXKXc+AOu6oQXZ+wAJ1tErVOsb48HF1g0wbXbBA31C5qLEM=",
+        "subType": "06"
+      }
+    }
+  },
+  "payload=14,algo=det": {
+    "kms": "local",
+    "type": "string",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "ASzggCwAAAAAAAAAAAAAAAACdp8mDOeDuDLhE0LzTOT2p0CMaUsAQrGCzmiK6Ab9xvaIcPPcejUcpdO3XXAS/pPab4+TUwO5GbI5pDJ29zwaOiOz2H3OJ2m2p5BHQp9mCys=",
+        "subType": "06"
+      }
+    }
+  },
+  "payload=15,algo=det": {
+    "kms": "local",
+    "type": "string",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "ASzggCwAAAAAAAAAAAAAAAACmtLohoP/gotuon2IvnGeLEfCWHRMhG9Wp4tPu/vbJJkJkbQTP35HRG9VrMV7KKrEQbOsJ2Y6UDBra4tyjn0fIkwwc/0X9i+xaP+TrwpNabE=",
+        "subType": "06"
+      }
+    }
+  },
+  "payload=16,algo=det": {
+    "kms": "local",
+    "type": "string",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": {
+        "base64": "ASzggCwAAAAAAAAAAAAAAAAC6s9eUtSneKWj3/A7S+bPZLj3t1WtUh7ltW80b8jCRzA+kOI26j1MEb1tt68HgcnH1IJ3YQ/+UHlV95OgwSnIxlib/HJn3U0s8mpuCWe1Auo=",
+        "subType": "06"
+      }
+    }
+  }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/corpus/corpus-key-aws.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/corpus/corpus-key-aws.json
new file mode 100644
index 0000000000000000000000000000000000000000..06f2f06dc8a769def762473cc3cc8dd9125f55e2
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/corpus/corpus-key-aws.json	
@@ -0,0 +1,33 @@
+{
+    "status": {
+        "$numberInt": "1"
+    },
+    "_id": {
+        "$binary": {
+            "base64": "AWSAAAAAAAAAAAAAAAAAAA==",
+            "subType": "04"
+        }
+    },
+    "masterKey": {
+        "region": "us-east-1",
+        "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0",
+        "provider": "aws"
+    },
+    "updateDate": {
+        "$date": {
+            "$numberLong": "1557827033449"
+        }
+    },
+    "keyMaterial": {
+        "$binary": {
+            "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO",
+            "subType": "00"
+        }
+    },
+    "creationDate": {
+        "$date": {
+            "$numberLong": "1557827033449"
+        }
+    },
+    "keyAltNames": ["aws"]
+}
\ No newline at end of file
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/corpus/corpus-key-local.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/corpus/corpus-key-local.json
new file mode 100644
index 0000000000000000000000000000000000000000..5da84ab6b496ef6b458d13ba9fcc603979ae5c15
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/corpus/corpus-key-local.json	
@@ -0,0 +1,31 @@
+{
+    "status": {
+        "$numberInt": "1"
+    },
+    "_id": {
+        "$binary": {
+            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+            "subType": "04"
+        }
+    },
+    "masterKey": {
+        "provider": "local"
+    },
+    "updateDate": {
+        "$date": {
+            "$numberLong": "1557827033449"
+        }
+    },
+    "keyMaterial": {
+        "$binary": {
+            "base64": "Ce9HSz/HKKGkIt4uyy+jDuKGA+rLC2cycykMo6vc8jXxqa1UVDYHWq1r+vZKbnnSRBfB981akzRKZCFpC05CTyFqDhXv6OnMjpG97OZEREGIsHEYiJkBW0jJJvfLLgeLsEpBzsro9FztGGXASxyxFRZFhXvHxyiLOKrdWfs7X1O/iK3pEoHMx6uSNSfUOgbebLfIqW7TO++iQS5g1xovXA==",
+            "subType": "00"
+        }
+    },
+    "creationDate": {
+        "$date": {
+            "$numberLong": "1557827033449"
+        }
+    },
+    "keyAltNames": [ "local" ]
+}
\ No newline at end of file
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/corpus/corpus-schema.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/corpus/corpus-schema.json
new file mode 100644
index 0000000000000000000000000000000000000000..e4838d8aaeaaf52283205ef57bdb0c9578c7b166
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/corpus/corpus-schema.json	
@@ -0,0 +1,2057 @@
+{
+  "bsonType": "object",
+  "properties": {
+    "aws_double_rand_auto_id": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": [
+              {
+                "$binary": {
+                  "base64": "AWSAAAAAAAAAAAAAAAAAAA==",
+                  "subType": "04"
+                }
+              }
+            ],
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random",
+            "bsonType": "double"
+          }
+        }
+      }
+    },
+    "aws_double_rand_auto_altname": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": "/altname_aws",
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random",
+            "bsonType": "double"
+          }
+        }
+      }
+    },
+    "aws_double_rand_explicit_id": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "aws_double_rand_explicit_altname": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "aws_string_rand_auto_id": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": [
+              {
+                "$binary": {
+                  "base64": "AWSAAAAAAAAAAAAAAAAAAA==",
+                  "subType": "04"
+                }
+              }
+            ],
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random",
+            "bsonType": "string"
+          }
+        }
+      }
+    },
+    "aws_string_rand_auto_altname": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": "/altname_aws",
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random",
+            "bsonType": "string"
+          }
+        }
+      }
+    },
+    "aws_string_rand_explicit_id": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "aws_string_rand_explicit_altname": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "aws_string_det_auto_id": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": [
+              {
+                "$binary": {
+                  "base64": "AWSAAAAAAAAAAAAAAAAAAA==",
+                  "subType": "04"
+                }
+              }
+            ],
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic",
+            "bsonType": "string"
+          }
+        }
+      }
+    },
+    "aws_string_det_explicit_id": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "aws_string_det_explicit_altname": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "aws_object_rand_auto_id": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": [
+              {
+                "$binary": {
+                  "base64": "AWSAAAAAAAAAAAAAAAAAAA==",
+                  "subType": "04"
+                }
+              }
+            ],
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random",
+            "bsonType": "object"
+          }
+        }
+      }
+    },
+    "aws_object_rand_auto_altname": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": "/altname_aws",
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random",
+            "bsonType": "object"
+          }
+        }
+      }
+    },
+    "aws_object_rand_explicit_id": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "aws_object_rand_explicit_altname": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "aws_array_rand_auto_id": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": [
+              {
+                "$binary": {
+                  "base64": "AWSAAAAAAAAAAAAAAAAAAA==",
+                  "subType": "04"
+                }
+              }
+            ],
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random",
+            "bsonType": "array"
+          }
+        }
+      }
+    },
+    "aws_array_rand_auto_altname": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": "/altname_aws",
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random",
+            "bsonType": "array"
+          }
+        }
+      }
+    },
+    "aws_array_rand_explicit_id": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "aws_array_rand_explicit_altname": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "aws_binData=00_rand_auto_id": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": [
+              {
+                "$binary": {
+                  "base64": "AWSAAAAAAAAAAAAAAAAAAA==",
+                  "subType": "04"
+                }
+              }
+            ],
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random",
+            "bsonType": "binData"
+          }
+        }
+      }
+    },
+    "aws_binData=00_rand_auto_altname": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": "/altname_aws",
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random",
+            "bsonType": "binData"
+          }
+        }
+      }
+    },
+    "aws_binData=00_rand_explicit_id": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "aws_binData=00_rand_explicit_altname": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "aws_binData=00_det_auto_id": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": [
+              {
+                "$binary": {
+                  "base64": "AWSAAAAAAAAAAAAAAAAAAA==",
+                  "subType": "04"
+                }
+              }
+            ],
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic",
+            "bsonType": "binData"
+          }
+        }
+      }
+    },
+    "aws_binData=00_det_explicit_id": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "aws_binData=00_det_explicit_altname": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "aws_binData=04_rand_auto_id": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": [
+              {
+                "$binary": {
+                  "base64": "AWSAAAAAAAAAAAAAAAAAAA==",
+                  "subType": "04"
+                }
+              }
+            ],
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random",
+            "bsonType": "binData"
+          }
+        }
+      }
+    },
+    "aws_binData=04_rand_auto_altname": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": "/altname_aws",
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random",
+            "bsonType": "binData"
+          }
+        }
+      }
+    },
+    "aws_binData=04_rand_explicit_id": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "aws_binData=04_rand_explicit_altname": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "aws_binData=04_det_auto_id": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": [
+              {
+                "$binary": {
+                  "base64": "AWSAAAAAAAAAAAAAAAAAAA==",
+                  "subType": "04"
+                }
+              }
+            ],
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic",
+            "bsonType": "binData"
+          }
+        }
+      }
+    },
+    "aws_binData=04_det_explicit_id": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "aws_binData=04_det_explicit_altname": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "aws_objectId_rand_auto_id": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": [
+              {
+                "$binary": {
+                  "base64": "AWSAAAAAAAAAAAAAAAAAAA==",
+                  "subType": "04"
+                }
+              }
+            ],
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random",
+            "bsonType": "objectId"
+          }
+        }
+      }
+    },
+    "aws_objectId_rand_auto_altname": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": "/altname_aws",
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random",
+            "bsonType": "objectId"
+          }
+        }
+      }
+    },
+    "aws_objectId_rand_explicit_id": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "aws_objectId_rand_explicit_altname": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "aws_objectId_det_auto_id": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": [
+              {
+                "$binary": {
+                  "base64": "AWSAAAAAAAAAAAAAAAAAAA==",
+                  "subType": "04"
+                }
+              }
+            ],
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic",
+            "bsonType": "objectId"
+          }
+        }
+      }
+    },
+    "aws_objectId_det_explicit_id": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "aws_objectId_det_explicit_altname": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "aws_bool_rand_auto_id": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": [
+              {
+                "$binary": {
+                  "base64": "AWSAAAAAAAAAAAAAAAAAAA==",
+                  "subType": "04"
+                }
+              }
+            ],
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random",
+            "bsonType": "bool"
+          }
+        }
+      }
+    },
+    "aws_bool_rand_auto_altname": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": "/altname_aws",
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random",
+            "bsonType": "bool"
+          }
+        }
+      }
+    },
+    "aws_bool_rand_explicit_id": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "aws_bool_rand_explicit_altname": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "aws_date_rand_auto_id": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": [
+              {
+                "$binary": {
+                  "base64": "AWSAAAAAAAAAAAAAAAAAAA==",
+                  "subType": "04"
+                }
+              }
+            ],
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random",
+            "bsonType": "date"
+          }
+        }
+      }
+    },
+    "aws_date_rand_auto_altname": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": "/altname_aws",
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random",
+            "bsonType": "date"
+          }
+        }
+      }
+    },
+    "aws_date_rand_explicit_id": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "aws_date_rand_explicit_altname": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "aws_date_det_auto_id": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": [
+              {
+                "$binary": {
+                  "base64": "AWSAAAAAAAAAAAAAAAAAAA==",
+                  "subType": "04"
+                }
+              }
+            ],
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic",
+            "bsonType": "date"
+          }
+        }
+      }
+    },
+    "aws_date_det_explicit_id": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "aws_date_det_explicit_altname": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "aws_regex_rand_auto_id": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": [
+              {
+                "$binary": {
+                  "base64": "AWSAAAAAAAAAAAAAAAAAAA==",
+                  "subType": "04"
+                }
+              }
+            ],
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random",
+            "bsonType": "regex"
+          }
+        }
+      }
+    },
+    "aws_regex_rand_auto_altname": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": "/altname_aws",
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random",
+            "bsonType": "regex"
+          }
+        }
+      }
+    },
+    "aws_regex_rand_explicit_id": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "aws_regex_rand_explicit_altname": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "aws_regex_det_auto_id": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": [
+              {
+                "$binary": {
+                  "base64": "AWSAAAAAAAAAAAAAAAAAAA==",
+                  "subType": "04"
+                }
+              }
+            ],
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic",
+            "bsonType": "regex"
+          }
+        }
+      }
+    },
+    "aws_regex_det_explicit_id": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "aws_regex_det_explicit_altname": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "aws_dbPointer_rand_auto_id": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": [
+              {
+                "$binary": {
+                  "base64": "AWSAAAAAAAAAAAAAAAAAAA==",
+                  "subType": "04"
+                }
+              }
+            ],
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random",
+            "bsonType": "dbPointer"
+          }
+        }
+      }
+    },
+    "aws_dbPointer_rand_auto_altname": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": "/altname_aws",
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random",
+            "bsonType": "dbPointer"
+          }
+        }
+      }
+    },
+    "aws_dbPointer_rand_explicit_id": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "aws_dbPointer_rand_explicit_altname": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "aws_dbPointer_det_auto_id": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": [
+              {
+                "$binary": {
+                  "base64": "AWSAAAAAAAAAAAAAAAAAAA==",
+                  "subType": "04"
+                }
+              }
+            ],
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic",
+            "bsonType": "dbPointer"
+          }
+        }
+      }
+    },
+    "aws_dbPointer_det_explicit_id": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "aws_dbPointer_det_explicit_altname": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "aws_javascript_rand_auto_id": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": [
+              {
+                "$binary": {
+                  "base64": "AWSAAAAAAAAAAAAAAAAAAA==",
+                  "subType": "04"
+                }
+              }
+            ],
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random",
+            "bsonType": "javascript"
+          }
+        }
+      }
+    },
+    "aws_javascript_rand_auto_altname": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": "/altname_aws",
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random",
+            "bsonType": "javascript"
+          }
+        }
+      }
+    },
+    "aws_javascript_rand_explicit_id": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "aws_javascript_rand_explicit_altname": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "aws_javascript_det_auto_id": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": [
+              {
+                "$binary": {
+                  "base64": "AWSAAAAAAAAAAAAAAAAAAA==",
+                  "subType": "04"
+                }
+              }
+            ],
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic",
+            "bsonType": "javascript"
+          }
+        }
+      }
+    },
+    "aws_javascript_det_explicit_id": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "aws_javascript_det_explicit_altname": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "aws_symbol_rand_auto_id": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": [
+              {
+                "$binary": {
+                  "base64": "AWSAAAAAAAAAAAAAAAAAAA==",
+                  "subType": "04"
+                }
+              }
+            ],
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random",
+            "bsonType": "symbol"
+          }
+        }
+      }
+    },
+    "aws_symbol_rand_auto_altname": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": "/altname_aws",
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random",
+            "bsonType": "symbol"
+          }
+        }
+      }
+    },
+    "aws_symbol_rand_explicit_id": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "aws_symbol_rand_explicit_altname": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "aws_symbol_det_auto_id": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": [
+              {
+                "$binary": {
+                  "base64": "AWSAAAAAAAAAAAAAAAAAAA==",
+                  "subType": "04"
+                }
+              }
+            ],
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic",
+            "bsonType": "symbol"
+          }
+        }
+      }
+    },
+    "aws_symbol_det_explicit_id": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "aws_symbol_det_explicit_altname": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "aws_javascriptWithScope_rand_auto_id": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": [
+              {
+                "$binary": {
+                  "base64": "AWSAAAAAAAAAAAAAAAAAAA==",
+                  "subType": "04"
+                }
+              }
+            ],
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random",
+            "bsonType": "javascriptWithScope"
+          }
+        }
+      }
+    },
+    "aws_javascriptWithScope_rand_auto_altname": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": "/altname_aws",
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random",
+            "bsonType": "javascriptWithScope"
+          }
+        }
+      }
+    },
+    "aws_javascriptWithScope_rand_explicit_id": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "aws_javascriptWithScope_rand_explicit_altname": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "aws_int_rand_auto_id": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": [
+              {
+                "$binary": {
+                  "base64": "AWSAAAAAAAAAAAAAAAAAAA==",
+                  "subType": "04"
+                }
+              }
+            ],
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random",
+            "bsonType": "int"
+          }
+        }
+      }
+    },
+    "aws_int_rand_auto_altname": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": "/altname_aws",
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random",
+            "bsonType": "int"
+          }
+        }
+      }
+    },
+    "aws_int_rand_explicit_id": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "aws_int_rand_explicit_altname": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "aws_int_det_auto_id": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": [
+              {
+                "$binary": {
+                  "base64": "AWSAAAAAAAAAAAAAAAAAAA==",
+                  "subType": "04"
+                }
+              }
+            ],
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic",
+            "bsonType": "int"
+          }
+        }
+      }
+    },
+    "aws_int_det_explicit_id": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "aws_int_det_explicit_altname": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "aws_timestamp_rand_auto_id": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": [
+              {
+                "$binary": {
+                  "base64": "AWSAAAAAAAAAAAAAAAAAAA==",
+                  "subType": "04"
+                }
+              }
+            ],
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random",
+            "bsonType": "timestamp"
+          }
+        }
+      }
+    },
+    "aws_timestamp_rand_auto_altname": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": "/altname_aws",
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random",
+            "bsonType": "timestamp"
+          }
+        }
+      }
+    },
+    "aws_timestamp_rand_explicit_id": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "aws_timestamp_rand_explicit_altname": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "aws_timestamp_det_auto_id": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": [
+              {
+                "$binary": {
+                  "base64": "AWSAAAAAAAAAAAAAAAAAAA==",
+                  "subType": "04"
+                }
+              }
+            ],
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic",
+            "bsonType": "timestamp"
+          }
+        }
+      }
+    },
+    "aws_timestamp_det_explicit_id": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "aws_timestamp_det_explicit_altname": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "aws_long_rand_auto_id": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": [
+              {
+                "$binary": {
+                  "base64": "AWSAAAAAAAAAAAAAAAAAAA==",
+                  "subType": "04"
+                }
+              }
+            ],
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random",
+            "bsonType": "long"
+          }
+        }
+      }
+    },
+    "aws_long_rand_auto_altname": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": "/altname_aws",
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random",
+            "bsonType": "long"
+          }
+        }
+      }
+    },
+    "aws_long_rand_explicit_id": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "aws_long_rand_explicit_altname": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "aws_long_det_auto_id": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": [
+              {
+                "$binary": {
+                  "base64": "AWSAAAAAAAAAAAAAAAAAAA==",
+                  "subType": "04"
+                }
+              }
+            ],
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic",
+            "bsonType": "long"
+          }
+        }
+      }
+    },
+    "aws_long_det_explicit_id": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "aws_long_det_explicit_altname": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "aws_decimal_rand_auto_id": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": [
+              {
+                "$binary": {
+                  "base64": "AWSAAAAAAAAAAAAAAAAAAA==",
+                  "subType": "04"
+                }
+              }
+            ],
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random",
+            "bsonType": "decimal"
+          }
+        }
+      }
+    },
+    "aws_decimal_rand_auto_altname": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": "/altname_aws",
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random",
+            "bsonType": "decimal"
+          }
+        }
+      }
+    },
+    "aws_decimal_rand_explicit_id": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "aws_decimal_rand_explicit_altname": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "local_double_rand_auto_id": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": [
+              {
+                "$binary": {
+                  "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                  "subType": "04"
+                }
+              }
+            ],
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random",
+            "bsonType": "double"
+          }
+        }
+      }
+    },
+    "local_double_rand_auto_altname": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": "/altname_local",
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random",
+            "bsonType": "double"
+          }
+        }
+      }
+    },
+    "local_double_rand_explicit_id": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "local_double_rand_explicit_altname": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "local_string_rand_auto_id": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": [
+              {
+                "$binary": {
+                  "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                  "subType": "04"
+                }
+              }
+            ],
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random",
+            "bsonType": "string"
+          }
+        }
+      }
+    },
+    "local_string_rand_auto_altname": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": "/altname_local",
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random",
+            "bsonType": "string"
+          }
+        }
+      }
+    },
+    "local_string_rand_explicit_id": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "local_string_rand_explicit_altname": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "local_string_det_auto_id": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": [
+              {
+                "$binary": {
+                  "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                  "subType": "04"
+                }
+              }
+            ],
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic",
+            "bsonType": "string"
+          }
+        }
+      }
+    },
+    "local_string_det_explicit_id": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "local_string_det_explicit_altname": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "local_object_rand_auto_id": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": [
+              {
+                "$binary": {
+                  "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                  "subType": "04"
+                }
+              }
+            ],
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random",
+            "bsonType": "object"
+          }
+        }
+      }
+    },
+    "local_object_rand_auto_altname": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": "/altname_local",
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random",
+            "bsonType": "object"
+          }
+        }
+      }
+    },
+    "local_object_rand_explicit_id": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "local_object_rand_explicit_altname": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "local_array_rand_auto_id": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": [
+              {
+                "$binary": {
+                  "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                  "subType": "04"
+                }
+              }
+            ],
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random",
+            "bsonType": "array"
+          }
+        }
+      }
+    },
+    "local_array_rand_auto_altname": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": "/altname_local",
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random",
+            "bsonType": "array"
+          }
+        }
+      }
+    },
+    "local_array_rand_explicit_id": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "local_array_rand_explicit_altname": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "local_binData=00_rand_auto_id": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": [
+              {
+                "$binary": {
+                  "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                  "subType": "04"
+                }
+              }
+            ],
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random",
+            "bsonType": "binData"
+          }
+        }
+      }
+    },
+    "local_binData=00_rand_auto_altname": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": "/altname_local",
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random",
+            "bsonType": "binData"
+          }
+        }
+      }
+    },
+    "local_binData=00_rand_explicit_id": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "local_binData=00_rand_explicit_altname": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "local_binData=00_det_auto_id": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": [
+              {
+                "$binary": {
+                  "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                  "subType": "04"
+                }
+              }
+            ],
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic",
+            "bsonType": "binData"
+          }
+        }
+      }
+    },
+    "local_binData=00_det_explicit_id": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "local_binData=00_det_explicit_altname": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "local_binData=04_rand_auto_id": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": [
+              {
+                "$binary": {
+                  "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                  "subType": "04"
+                }
+              }
+            ],
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random",
+            "bsonType": "binData"
+          }
+        }
+      }
+    },
+    "local_binData=04_rand_auto_altname": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": "/altname_local",
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random",
+            "bsonType": "binData"
+          }
+        }
+      }
+    },
+    "local_binData=04_rand_explicit_id": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "local_binData=04_rand_explicit_altname": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "local_binData=04_det_auto_id": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": [
+              {
+                "$binary": {
+                  "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                  "subType": "04"
+                }
+              }
+            ],
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic",
+            "bsonType": "binData"
+          }
+        }
+      }
+    },
+    "local_binData=04_det_explicit_id": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "local_binData=04_det_explicit_altname": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "local_objectId_rand_auto_id": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": [
+              {
+                "$binary": {
+                  "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                  "subType": "04"
+                }
+              }
+            ],
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random",
+            "bsonType": "objectId"
+          }
+        }
+      }
+    },
+    "local_objectId_rand_auto_altname": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": "/altname_local",
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random",
+            "bsonType": "objectId"
+          }
+        }
+      }
+    },
+    "local_objectId_rand_explicit_id": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "local_objectId_rand_explicit_altname": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "local_objectId_det_auto_id": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": [
+              {
+                "$binary": {
+                  "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                  "subType": "04"
+                }
+              }
+            ],
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic",
+            "bsonType": "objectId"
+          }
+        }
+      }
+    },
+    "local_objectId_det_explicit_id": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "local_objectId_det_explicit_altname": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "local_bool_rand_auto_id": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": [
+              {
+                "$binary": {
+                  "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                  "subType": "04"
+                }
+              }
+            ],
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random",
+            "bsonType": "bool"
+          }
+        }
+      }
+    },
+    "local_bool_rand_auto_altname": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": "/altname_local",
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random",
+            "bsonType": "bool"
+          }
+        }
+      }
+    },
+    "local_bool_rand_explicit_id": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "local_bool_rand_explicit_altname": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "local_date_rand_auto_id": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": [
+              {
+                "$binary": {
+                  "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                  "subType": "04"
+                }
+              }
+            ],
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random",
+            "bsonType": "date"
+          }
+        }
+      }
+    },
+    "local_date_rand_auto_altname": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": "/altname_local",
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random",
+            "bsonType": "date"
+          }
+        }
+      }
+    },
+    "local_date_rand_explicit_id": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "local_date_rand_explicit_altname": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "local_date_det_auto_id": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": [
+              {
+                "$binary": {
+                  "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                  "subType": "04"
+                }
+              }
+            ],
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic",
+            "bsonType": "date"
+          }
+        }
+      }
+    },
+    "local_date_det_explicit_id": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "local_date_det_explicit_altname": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "local_regex_rand_auto_id": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": [
+              {
+                "$binary": {
+                  "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                  "subType": "04"
+                }
+              }
+            ],
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random",
+            "bsonType": "regex"
+          }
+        }
+      }
+    },
+    "local_regex_rand_auto_altname": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": "/altname_local",
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random",
+            "bsonType": "regex"
+          }
+        }
+      }
+    },
+    "local_regex_rand_explicit_id": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "local_regex_rand_explicit_altname": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "local_regex_det_auto_id": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": [
+              {
+                "$binary": {
+                  "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                  "subType": "04"
+                }
+              }
+            ],
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic",
+            "bsonType": "regex"
+          }
+        }
+      }
+    },
+    "local_regex_det_explicit_id": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "local_regex_det_explicit_altname": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "local_dbPointer_rand_auto_id": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": [
+              {
+                "$binary": {
+                  "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                  "subType": "04"
+                }
+              }
+            ],
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random",
+            "bsonType": "dbPointer"
+          }
+        }
+      }
+    },
+    "local_dbPointer_rand_auto_altname": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": "/altname_local",
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random",
+            "bsonType": "dbPointer"
+          }
+        }
+      }
+    },
+    "local_dbPointer_rand_explicit_id": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "local_dbPointer_rand_explicit_altname": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "local_dbPointer_det_auto_id": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": [
+              {
+                "$binary": {
+                  "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                  "subType": "04"
+                }
+              }
+            ],
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic",
+            "bsonType": "dbPointer"
+          }
+        }
+      }
+    },
+    "local_dbPointer_det_explicit_id": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "local_dbPointer_det_explicit_altname": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "local_javascript_rand_auto_id": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": [
+              {
+                "$binary": {
+                  "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                  "subType": "04"
+                }
+              }
+            ],
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random",
+            "bsonType": "javascript"
+          }
+        }
+      }
+    },
+    "local_javascript_rand_auto_altname": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": "/altname_local",
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random",
+            "bsonType": "javascript"
+          }
+        }
+      }
+    },
+    "local_javascript_rand_explicit_id": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "local_javascript_rand_explicit_altname": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "local_javascript_det_auto_id": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": [
+              {
+                "$binary": {
+                  "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                  "subType": "04"
+                }
+              }
+            ],
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic",
+            "bsonType": "javascript"
+          }
+        }
+      }
+    },
+    "local_javascript_det_explicit_id": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "local_javascript_det_explicit_altname": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "local_symbol_rand_auto_id": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": [
+              {
+                "$binary": {
+                  "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                  "subType": "04"
+                }
+              }
+            ],
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random",
+            "bsonType": "symbol"
+          }
+        }
+      }
+    },
+    "local_symbol_rand_auto_altname": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": "/altname_local",
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random",
+            "bsonType": "symbol"
+          }
+        }
+      }
+    },
+    "local_symbol_rand_explicit_id": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "local_symbol_rand_explicit_altname": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "local_symbol_det_auto_id": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": [
+              {
+                "$binary": {
+                  "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                  "subType": "04"
+                }
+              }
+            ],
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic",
+            "bsonType": "symbol"
+          }
+        }
+      }
+    },
+    "local_symbol_det_explicit_id": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "local_symbol_det_explicit_altname": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "local_javascriptWithScope_rand_auto_id": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": [
+              {
+                "$binary": {
+                  "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                  "subType": "04"
+                }
+              }
+            ],
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random",
+            "bsonType": "javascriptWithScope"
+          }
+        }
+      }
+    },
+    "local_javascriptWithScope_rand_auto_altname": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": "/altname_local",
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random",
+            "bsonType": "javascriptWithScope"
+          }
+        }
+      }
+    },
+    "local_javascriptWithScope_rand_explicit_id": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "local_javascriptWithScope_rand_explicit_altname": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "local_int_rand_auto_id": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": [
+              {
+                "$binary": {
+                  "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                  "subType": "04"
+                }
+              }
+            ],
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random",
+            "bsonType": "int"
+          }
+        }
+      }
+    },
+    "local_int_rand_auto_altname": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": "/altname_local",
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random",
+            "bsonType": "int"
+          }
+        }
+      }
+    },
+    "local_int_rand_explicit_id": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "local_int_rand_explicit_altname": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "local_int_det_auto_id": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": [
+              {
+                "$binary": {
+                  "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                  "subType": "04"
+                }
+              }
+            ],
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic",
+            "bsonType": "int"
+          }
+        }
+      }
+    },
+    "local_int_det_explicit_id": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "local_int_det_explicit_altname": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "local_timestamp_rand_auto_id": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": [
+              {
+                "$binary": {
+                  "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                  "subType": "04"
+                }
+              }
+            ],
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random",
+            "bsonType": "timestamp"
+          }
+        }
+      }
+    },
+    "local_timestamp_rand_auto_altname": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": "/altname_local",
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random",
+            "bsonType": "timestamp"
+          }
+        }
+      }
+    },
+    "local_timestamp_rand_explicit_id": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "local_timestamp_rand_explicit_altname": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "local_timestamp_det_auto_id": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": [
+              {
+                "$binary": {
+                  "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                  "subType": "04"
+                }
+              }
+            ],
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic",
+            "bsonType": "timestamp"
+          }
+        }
+      }
+    },
+    "local_timestamp_det_explicit_id": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "local_timestamp_det_explicit_altname": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "local_long_rand_auto_id": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": [
+              {
+                "$binary": {
+                  "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                  "subType": "04"
+                }
+              }
+            ],
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random",
+            "bsonType": "long"
+          }
+        }
+      }
+    },
+    "local_long_rand_auto_altname": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": "/altname_local",
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random",
+            "bsonType": "long"
+          }
+        }
+      }
+    },
+    "local_long_rand_explicit_id": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "local_long_rand_explicit_altname": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "local_long_det_auto_id": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": [
+              {
+                "$binary": {
+                  "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                  "subType": "04"
+                }
+              }
+            ],
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic",
+            "bsonType": "long"
+          }
+        }
+      }
+    },
+    "local_long_det_explicit_id": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "local_long_det_explicit_altname": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "local_decimal_rand_auto_id": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": [
+              {
+                "$binary": {
+                  "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                  "subType": "04"
+                }
+              }
+            ],
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random",
+            "bsonType": "decimal"
+          }
+        }
+      }
+    },
+    "local_decimal_rand_auto_altname": {
+      "bsonType": "object",
+      "properties": {
+        "value": {
+          "encrypt": {
+            "keyId": "/altname_local",
+            "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random",
+            "bsonType": "decimal"
+          }
+        }
+      }
+    },
+    "local_decimal_rand_explicit_id": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    },
+    "local_decimal_rand_explicit_altname": {
+      "bsonType": "object",
+      "properties": { "value": { "bsonType": "binData" } }
+    }
+  }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/corpus/corpus.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/corpus/corpus.json
new file mode 100644
index 0000000000000000000000000000000000000000..cbf7a091a1a9e19ff0b401fe79f38ae4a14dc37a
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/corpus/corpus.json	
@@ -0,0 +1,2905 @@
+{
+  "_id": "client_side_encryption_corpus",
+  "altname_aws": "aws",
+  "altname_local": "local",
+  "aws_double_rand_auto_id": {
+    "kms": "aws",
+    "type": "double",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": { "$numberDouble": "1.234" }
+  },
+  "aws_double_rand_auto_altname": {
+    "kms": "aws",
+    "type": "double",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "altname",
+    "allowed": true,
+    "value": { "$numberDouble": "1.234" }
+  },
+  "aws_double_rand_explicit_id": {
+    "kms": "aws",
+    "type": "double",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": { "$numberDouble": "1.234" }
+  },
+  "aws_double_rand_explicit_altname": {
+    "kms": "aws",
+    "type": "double",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": { "$numberDouble": "1.234" }
+  },
+  "aws_double_det_explicit_id": {
+    "kms": "aws",
+    "type": "double",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": false,
+    "value": { "$numberDouble": "1.234" }
+  },
+  "aws_double_det_explicit_altname": {
+    "kms": "aws",
+    "type": "double",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": false,
+    "value": { "$numberDouble": "1.234" }
+  },
+  "aws_string_rand_auto_id": {
+    "kms": "aws",
+    "type": "string",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": "mongodb"
+  },
+  "aws_string_rand_auto_altname": {
+    "kms": "aws",
+    "type": "string",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "altname",
+    "allowed": true,
+    "value": "mongodb"
+  },
+  "aws_string_rand_explicit_id": {
+    "kms": "aws",
+    "type": "string",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": "mongodb"
+  },
+  "aws_string_rand_explicit_altname": {
+    "kms": "aws",
+    "type": "string",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": "mongodb"
+  },
+  "aws_string_det_auto_id": {
+    "kms": "aws",
+    "type": "string",
+    "algo": "det",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": "mongodb"
+  },
+  "aws_string_det_explicit_id": {
+    "kms": "aws",
+    "type": "string",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": "mongodb"
+  },
+  "aws_string_det_explicit_altname": {
+    "kms": "aws",
+    "type": "string",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": "mongodb"
+  },
+  "aws_object_rand_auto_id": {
+    "kms": "aws",
+    "type": "object",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": { "x": { "$numberInt": "1" } }
+  },
+  "aws_object_rand_auto_altname": {
+    "kms": "aws",
+    "type": "object",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "altname",
+    "allowed": true,
+    "value": { "x": { "$numberInt": "1" } }
+  },
+  "aws_object_rand_explicit_id": {
+    "kms": "aws",
+    "type": "object",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": { "x": { "$numberInt": "1" } }
+  },
+  "aws_object_rand_explicit_altname": {
+    "kms": "aws",
+    "type": "object",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": { "x": { "$numberInt": "1" } }
+  },
+  "aws_object_det_explicit_id": {
+    "kms": "aws",
+    "type": "object",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": false,
+    "value": { "x": { "$numberInt": "1" } }
+  },
+  "aws_object_det_explicit_altname": {
+    "kms": "aws",
+    "type": "object",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": false,
+    "value": { "x": { "$numberInt": "1" } }
+  },
+  "aws_array_rand_auto_id": {
+    "kms": "aws",
+    "type": "array",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": [
+      { "$numberInt": "1" },
+      { "$numberInt": "2" },
+      { "$numberInt": "3" }
+    ]
+  },
+  "aws_array_rand_auto_altname": {
+    "kms": "aws",
+    "type": "array",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "altname",
+    "allowed": true,
+    "value": [
+      { "$numberInt": "1" },
+      { "$numberInt": "2" },
+      { "$numberInt": "3" }
+    ]
+  },
+  "aws_array_rand_explicit_id": {
+    "kms": "aws",
+    "type": "array",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": [
+      { "$numberInt": "1" },
+      { "$numberInt": "2" },
+      { "$numberInt": "3" }
+    ]
+  },
+  "aws_array_rand_explicit_altname": {
+    "kms": "aws",
+    "type": "array",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": [
+      { "$numberInt": "1" },
+      { "$numberInt": "2" },
+      { "$numberInt": "3" }
+    ]
+  },
+  "aws_array_det_explicit_id": {
+    "kms": "aws",
+    "type": "array",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": false,
+    "value": [
+      { "$numberInt": "1" },
+      { "$numberInt": "2" },
+      { "$numberInt": "3" }
+    ]
+  },
+  "aws_array_det_explicit_altname": {
+    "kms": "aws",
+    "type": "array",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": false,
+    "value": [
+      { "$numberInt": "1" },
+      { "$numberInt": "2" },
+      { "$numberInt": "3" }
+    ]
+  },
+  "aws_binData=00_rand_auto_id": {
+    "kms": "aws",
+    "type": "binData=00",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": { "$binary": { "base64": "AQIDBA==", "subType": "00" } }
+  },
+  "aws_binData=00_rand_auto_altname": {
+    "kms": "aws",
+    "type": "binData=00",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "altname",
+    "allowed": true,
+    "value": { "$binary": { "base64": "AQIDBA==", "subType": "00" } }
+  },
+  "aws_binData=00_rand_explicit_id": {
+    "kms": "aws",
+    "type": "binData=00",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": { "$binary": { "base64": "AQIDBA==", "subType": "00" } }
+  },
+  "aws_binData=00_rand_explicit_altname": {
+    "kms": "aws",
+    "type": "binData=00",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": { "$binary": { "base64": "AQIDBA==", "subType": "00" } }
+  },
+  "aws_binData=00_det_auto_id": {
+    "kms": "aws",
+    "type": "binData=00",
+    "algo": "det",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": { "$binary": { "base64": "AQIDBA==", "subType": "00" } }
+  },
+  "aws_binData=00_det_explicit_id": {
+    "kms": "aws",
+    "type": "binData=00",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": { "$binary": { "base64": "AQIDBA==", "subType": "00" } }
+  },
+  "aws_binData=00_det_explicit_altname": {
+    "kms": "aws",
+    "type": "binData=00",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": { "$binary": { "base64": "AQIDBA==", "subType": "00" } }
+  },
+  "aws_binData=04_rand_auto_id": {
+    "kms": "aws",
+    "type": "binData=04",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": { "base64": "AAECAwQFBgcICQoLDA0ODw==", "subType": "04" }
+    }
+  },
+  "aws_binData=04_rand_auto_altname": {
+    "kms": "aws",
+    "type": "binData=04",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": { "base64": "AAECAwQFBgcICQoLDA0ODw==", "subType": "04" }
+    }
+  },
+  "aws_binData=04_rand_explicit_id": {
+    "kms": "aws",
+    "type": "binData=04",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": { "base64": "AAECAwQFBgcICQoLDA0ODw==", "subType": "04" }
+    }
+  },
+  "aws_binData=04_rand_explicit_altname": {
+    "kms": "aws",
+    "type": "binData=04",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": { "base64": "AAECAwQFBgcICQoLDA0ODw==", "subType": "04" }
+    }
+  },
+  "aws_binData=04_det_auto_id": {
+    "kms": "aws",
+    "type": "binData=04",
+    "algo": "det",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": { "base64": "AAECAwQFBgcICQoLDA0ODw==", "subType": "04" }
+    }
+  },
+  "aws_binData=04_det_explicit_id": {
+    "kms": "aws",
+    "type": "binData=04",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": { "base64": "AAECAwQFBgcICQoLDA0ODw==", "subType": "04" }
+    }
+  },
+  "aws_binData=04_det_explicit_altname": {
+    "kms": "aws",
+    "type": "binData=04",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": { "base64": "AAECAwQFBgcICQoLDA0ODw==", "subType": "04" }
+    }
+  },
+  "aws_undefined_rand_explicit_id": {
+    "kms": "aws",
+    "type": "undefined",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": false,
+    "value": { "$undefined": true }
+  },
+  "aws_undefined_rand_explicit_altname": {
+    "kms": "aws",
+    "type": "undefined",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": false,
+    "value": { "$undefined": true }
+  },
+  "aws_undefined_det_explicit_id": {
+    "kms": "aws",
+    "type": "undefined",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": false,
+    "value": { "$undefined": true }
+  },
+  "aws_undefined_det_explicit_altname": {
+    "kms": "aws",
+    "type": "undefined",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": false,
+    "value": { "$undefined": true }
+  },
+  "aws_objectId_rand_auto_id": {
+    "kms": "aws",
+    "type": "objectId",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": { "$oid": "01234567890abcdef0123456" }
+  },
+  "aws_objectId_rand_auto_altname": {
+    "kms": "aws",
+    "type": "objectId",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "altname",
+    "allowed": true,
+    "value": { "$oid": "01234567890abcdef0123456" }
+  },
+  "aws_objectId_rand_explicit_id": {
+    "kms": "aws",
+    "type": "objectId",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": { "$oid": "01234567890abcdef0123456" }
+  },
+  "aws_objectId_rand_explicit_altname": {
+    "kms": "aws",
+    "type": "objectId",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": { "$oid": "01234567890abcdef0123456" }
+  },
+  "aws_objectId_det_auto_id": {
+    "kms": "aws",
+    "type": "objectId",
+    "algo": "det",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": { "$oid": "01234567890abcdef0123456" }
+  },
+  "aws_objectId_det_explicit_id": {
+    "kms": "aws",
+    "type": "objectId",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": { "$oid": "01234567890abcdef0123456" }
+  },
+  "aws_objectId_det_explicit_altname": {
+    "kms": "aws",
+    "type": "objectId",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": { "$oid": "01234567890abcdef0123456" }
+  },
+  "aws_bool_rand_auto_id": {
+    "kms": "aws",
+    "type": "bool",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": true
+  },
+  "aws_bool_rand_auto_altname": {
+    "kms": "aws",
+    "type": "bool",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "altname",
+    "allowed": true,
+    "value": true
+  },
+  "aws_bool_rand_explicit_id": {
+    "kms": "aws",
+    "type": "bool",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": true
+  },
+  "aws_bool_rand_explicit_altname": {
+    "kms": "aws",
+    "type": "bool",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": true
+  },
+  "aws_bool_det_explicit_id": {
+    "kms": "aws",
+    "type": "bool",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": false,
+    "value": true
+  },
+  "aws_bool_det_explicit_altname": {
+    "kms": "aws",
+    "type": "bool",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": false,
+    "value": true
+  },
+  "aws_date_rand_auto_id": {
+    "kms": "aws",
+    "type": "date",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": { "$date": { "$numberLong": "12345" } }
+  },
+  "aws_date_rand_auto_altname": {
+    "kms": "aws",
+    "type": "date",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "altname",
+    "allowed": true,
+    "value": { "$date": { "$numberLong": "12345" } }
+  },
+  "aws_date_rand_explicit_id": {
+    "kms": "aws",
+    "type": "date",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": { "$date": { "$numberLong": "12345" } }
+  },
+  "aws_date_rand_explicit_altname": {
+    "kms": "aws",
+    "type": "date",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": { "$date": { "$numberLong": "12345" } }
+  },
+  "aws_date_det_auto_id": {
+    "kms": "aws",
+    "type": "date",
+    "algo": "det",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": { "$date": { "$numberLong": "12345" } }
+  },
+  "aws_date_det_explicit_id": {
+    "kms": "aws",
+    "type": "date",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": { "$date": { "$numberLong": "12345" } }
+  },
+  "aws_date_det_explicit_altname": {
+    "kms": "aws",
+    "type": "date",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": { "$date": { "$numberLong": "12345" } }
+  },
+  "aws_null_rand_explicit_id": {
+    "kms": "aws",
+    "type": "null",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": false,
+    "value": null
+  },
+  "aws_null_rand_explicit_altname": {
+    "kms": "aws",
+    "type": "null",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": false,
+    "value": null
+  },
+  "aws_null_det_explicit_id": {
+    "kms": "aws",
+    "type": "null",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": false,
+    "value": null
+  },
+  "aws_null_det_explicit_altname": {
+    "kms": "aws",
+    "type": "null",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": false,
+    "value": null
+  },
+  "aws_regex_rand_auto_id": {
+    "kms": "aws",
+    "type": "regex",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": { "$regularExpression": { "pattern": ".*", "options": "" } }
+  },
+  "aws_regex_rand_auto_altname": {
+    "kms": "aws",
+    "type": "regex",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "altname",
+    "allowed": true,
+    "value": { "$regularExpression": { "pattern": ".*", "options": "" } }
+  },
+  "aws_regex_rand_explicit_id": {
+    "kms": "aws",
+    "type": "regex",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": { "$regularExpression": { "pattern": ".*", "options": "" } }
+  },
+  "aws_regex_rand_explicit_altname": {
+    "kms": "aws",
+    "type": "regex",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": { "$regularExpression": { "pattern": ".*", "options": "" } }
+  },
+  "aws_regex_det_auto_id": {
+    "kms": "aws",
+    "type": "regex",
+    "algo": "det",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": { "$regularExpression": { "pattern": ".*", "options": "" } }
+  },
+  "aws_regex_det_explicit_id": {
+    "kms": "aws",
+    "type": "regex",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": { "$regularExpression": { "pattern": ".*", "options": "" } }
+  },
+  "aws_regex_det_explicit_altname": {
+    "kms": "aws",
+    "type": "regex",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": { "$regularExpression": { "pattern": ".*", "options": "" } }
+  },
+  "aws_dbPointer_rand_auto_id": {
+    "kms": "aws",
+    "type": "dbPointer",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$dbPointer": {
+        "$ref": "db.example",
+        "$id": { "$oid": "01234567890abcdef0123456" }
+      }
+    }
+  },
+  "aws_dbPointer_rand_auto_altname": {
+    "kms": "aws",
+    "type": "dbPointer",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$dbPointer": {
+        "$ref": "db.example",
+        "$id": { "$oid": "01234567890abcdef0123456" }
+      }
+    }
+  },
+  "aws_dbPointer_rand_explicit_id": {
+    "kms": "aws",
+    "type": "dbPointer",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$dbPointer": {
+        "$ref": "db.example",
+        "$id": { "$oid": "01234567890abcdef0123456" }
+      }
+    }
+  },
+  "aws_dbPointer_rand_explicit_altname": {
+    "kms": "aws",
+    "type": "dbPointer",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$dbPointer": {
+        "$ref": "db.example",
+        "$id": { "$oid": "01234567890abcdef0123456" }
+      }
+    }
+  },
+  "aws_dbPointer_det_auto_id": {
+    "kms": "aws",
+    "type": "dbPointer",
+    "algo": "det",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$dbPointer": {
+        "$ref": "db.example",
+        "$id": { "$oid": "01234567890abcdef0123456" }
+      }
+    }
+  },
+  "aws_dbPointer_det_explicit_id": {
+    "kms": "aws",
+    "type": "dbPointer",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$dbPointer": {
+        "$ref": "db.example",
+        "$id": { "$oid": "01234567890abcdef0123456" }
+      }
+    }
+  },
+  "aws_dbPointer_det_explicit_altname": {
+    "kms": "aws",
+    "type": "dbPointer",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$dbPointer": {
+        "$ref": "db.example",
+        "$id": { "$oid": "01234567890abcdef0123456" }
+      }
+    }
+  },
+  "aws_javascript_rand_auto_id": {
+    "kms": "aws",
+    "type": "javascript",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": { "$code": "x=1" }
+  },
+  "aws_javascript_rand_auto_altname": {
+    "kms": "aws",
+    "type": "javascript",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "altname",
+    "allowed": true,
+    "value": { "$code": "x=1" }
+  },
+  "aws_javascript_rand_explicit_id": {
+    "kms": "aws",
+    "type": "javascript",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": { "$code": "x=1" }
+  },
+  "aws_javascript_rand_explicit_altname": {
+    "kms": "aws",
+    "type": "javascript",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": { "$code": "x=1" }
+  },
+  "aws_javascript_det_auto_id": {
+    "kms": "aws",
+    "type": "javascript",
+    "algo": "det",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": { "$code": "x=1" }
+  },
+  "aws_javascript_det_explicit_id": {
+    "kms": "aws",
+    "type": "javascript",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": { "$code": "x=1" }
+  },
+  "aws_javascript_det_explicit_altname": {
+    "kms": "aws",
+    "type": "javascript",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": { "$code": "x=1" }
+  },
+  "aws_symbol_rand_auto_id": {
+    "kms": "aws",
+    "type": "symbol",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": { "$symbol": "mongodb-symbol" }
+  },
+  "aws_symbol_rand_auto_altname": {
+    "kms": "aws",
+    "type": "symbol",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "altname",
+    "allowed": true,
+    "value": { "$symbol": "mongodb-symbol" }
+  },
+  "aws_symbol_rand_explicit_id": {
+    "kms": "aws",
+    "type": "symbol",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": { "$symbol": "mongodb-symbol" }
+  },
+  "aws_symbol_rand_explicit_altname": {
+    "kms": "aws",
+    "type": "symbol",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": { "$symbol": "mongodb-symbol" }
+  },
+  "aws_symbol_det_auto_id": {
+    "kms": "aws",
+    "type": "symbol",
+    "algo": "det",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": { "$symbol": "mongodb-symbol" }
+  },
+  "aws_symbol_det_explicit_id": {
+    "kms": "aws",
+    "type": "symbol",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": { "$symbol": "mongodb-symbol" }
+  },
+  "aws_symbol_det_explicit_altname": {
+    "kms": "aws",
+    "type": "symbol",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": { "$symbol": "mongodb-symbol" }
+  },
+  "aws_javascriptWithScope_rand_auto_id": {
+    "kms": "aws",
+    "type": "javascriptWithScope",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": { "$code": "x=1", "$scope": {} }
+  },
+  "aws_javascriptWithScope_rand_auto_altname": {
+    "kms": "aws",
+    "type": "javascriptWithScope",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "altname",
+    "allowed": true,
+    "value": { "$code": "x=1", "$scope": {} }
+  },
+  "aws_javascriptWithScope_rand_explicit_id": {
+    "kms": "aws",
+    "type": "javascriptWithScope",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": { "$code": "x=1", "$scope": {} }
+  },
+  "aws_javascriptWithScope_rand_explicit_altname": {
+    "kms": "aws",
+    "type": "javascriptWithScope",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": { "$code": "x=1", "$scope": {} }
+  },
+  "aws_javascriptWithScope_det_explicit_id": {
+    "kms": "aws",
+    "type": "javascriptWithScope",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": false,
+    "value": { "$code": "x=1", "$scope": {} }
+  },
+  "aws_javascriptWithScope_det_explicit_altname": {
+    "kms": "aws",
+    "type": "javascriptWithScope",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": false,
+    "value": { "$code": "x=1", "$scope": {} }
+  },
+  "aws_int_rand_auto_id": {
+    "kms": "aws",
+    "type": "int",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": { "$numberInt": "123" }
+  },
+  "aws_int_rand_auto_altname": {
+    "kms": "aws",
+    "type": "int",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "altname",
+    "allowed": true,
+    "value": { "$numberInt": "123" }
+  },
+  "aws_int_rand_explicit_id": {
+    "kms": "aws",
+    "type": "int",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": { "$numberInt": "123" }
+  },
+  "aws_int_rand_explicit_altname": {
+    "kms": "aws",
+    "type": "int",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": { "$numberInt": "123" }
+  },
+  "aws_int_det_auto_id": {
+    "kms": "aws",
+    "type": "int",
+    "algo": "det",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": { "$numberInt": "123" }
+  },
+  "aws_int_det_explicit_id": {
+    "kms": "aws",
+    "type": "int",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": { "$numberInt": "123" }
+  },
+  "aws_int_det_explicit_altname": {
+    "kms": "aws",
+    "type": "int",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": { "$numberInt": "123" }
+  },
+  "aws_timestamp_rand_auto_id": {
+    "kms": "aws",
+    "type": "timestamp",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": { "$timestamp": { "t": 0, "i": 12345 } }
+  },
+  "aws_timestamp_rand_auto_altname": {
+    "kms": "aws",
+    "type": "timestamp",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "altname",
+    "allowed": true,
+    "value": { "$timestamp": { "t": 0, "i": 12345 } }
+  },
+  "aws_timestamp_rand_explicit_id": {
+    "kms": "aws",
+    "type": "timestamp",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": { "$timestamp": { "t": 0, "i": 12345 } }
+  },
+  "aws_timestamp_rand_explicit_altname": {
+    "kms": "aws",
+    "type": "timestamp",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": { "$timestamp": { "t": 0, "i": 12345 } }
+  },
+  "aws_timestamp_det_auto_id": {
+    "kms": "aws",
+    "type": "timestamp",
+    "algo": "det",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": { "$timestamp": { "t": 0, "i": 12345 } }
+  },
+  "aws_timestamp_det_explicit_id": {
+    "kms": "aws",
+    "type": "timestamp",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": { "$timestamp": { "t": 0, "i": 12345 } }
+  },
+  "aws_timestamp_det_explicit_altname": {
+    "kms": "aws",
+    "type": "timestamp",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": { "$timestamp": { "t": 0, "i": 12345 } }
+  },
+  "aws_long_rand_auto_id": {
+    "kms": "aws",
+    "type": "long",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": { "$numberLong": "456" }
+  },
+  "aws_long_rand_auto_altname": {
+    "kms": "aws",
+    "type": "long",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "altname",
+    "allowed": true,
+    "value": { "$numberLong": "456" }
+  },
+  "aws_long_rand_explicit_id": {
+    "kms": "aws",
+    "type": "long",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": { "$numberLong": "456" }
+  },
+  "aws_long_rand_explicit_altname": {
+    "kms": "aws",
+    "type": "long",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": { "$numberLong": "456" }
+  },
+  "aws_long_det_auto_id": {
+    "kms": "aws",
+    "type": "long",
+    "algo": "det",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": { "$numberLong": "456" }
+  },
+  "aws_long_det_explicit_id": {
+    "kms": "aws",
+    "type": "long",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": { "$numberLong": "456" }
+  },
+  "aws_long_det_explicit_altname": {
+    "kms": "aws",
+    "type": "long",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": { "$numberLong": "456" }
+  },
+  "aws_decimal_rand_auto_id": {
+    "kms": "aws",
+    "type": "decimal",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": { "$numberDecimal": "1.234" }
+  },
+  "aws_decimal_rand_auto_altname": {
+    "kms": "aws",
+    "type": "decimal",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "altname",
+    "allowed": true,
+    "value": { "$numberDecimal": "1.234" }
+  },
+  "aws_decimal_rand_explicit_id": {
+    "kms": "aws",
+    "type": "decimal",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": { "$numberDecimal": "1.234" }
+  },
+  "aws_decimal_rand_explicit_altname": {
+    "kms": "aws",
+    "type": "decimal",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": { "$numberDecimal": "1.234" }
+  },
+  "aws_decimal_det_explicit_id": {
+    "kms": "aws",
+    "type": "decimal",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": false,
+    "value": { "$numberDecimal": "1.234" }
+  },
+  "aws_decimal_det_explicit_altname": {
+    "kms": "aws",
+    "type": "decimal",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": false,
+    "value": { "$numberDecimal": "1.234" }
+  },
+  "aws_minKey_rand_explicit_id": {
+    "kms": "aws",
+    "type": "minKey",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": false,
+    "value": { "$minKey": 1 }
+  },
+  "aws_minKey_rand_explicit_altname": {
+    "kms": "aws",
+    "type": "minKey",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": false,
+    "value": { "$minKey": 1 }
+  },
+  "aws_minKey_det_explicit_id": {
+    "kms": "aws",
+    "type": "minKey",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": false,
+    "value": { "$minKey": 1 }
+  },
+  "aws_minKey_det_explicit_altname": {
+    "kms": "aws",
+    "type": "minKey",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": false,
+    "value": { "$minKey": 1 }
+  },
+  "aws_maxKey_rand_explicit_id": {
+    "kms": "aws",
+    "type": "maxKey",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": false,
+    "value": { "$maxKey": 1 }
+  },
+  "aws_maxKey_rand_explicit_altname": {
+    "kms": "aws",
+    "type": "maxKey",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": false,
+    "value": { "$maxKey": 1 }
+  },
+  "aws_maxKey_det_explicit_id": {
+    "kms": "aws",
+    "type": "maxKey",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": false,
+    "value": { "$maxKey": 1 }
+  },
+  "aws_maxKey_det_explicit_altname": {
+    "kms": "aws",
+    "type": "maxKey",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": false,
+    "value": { "$maxKey": 1 }
+  },
+  "local_double_rand_auto_id": {
+    "kms": "local",
+    "type": "double",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": { "$numberDouble": "1.234" }
+  },
+  "local_double_rand_auto_altname": {
+    "kms": "local",
+    "type": "double",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "altname",
+    "allowed": true,
+    "value": { "$numberDouble": "1.234" }
+  },
+  "local_double_rand_explicit_id": {
+    "kms": "local",
+    "type": "double",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": { "$numberDouble": "1.234" }
+  },
+  "local_double_rand_explicit_altname": {
+    "kms": "local",
+    "type": "double",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": { "$numberDouble": "1.234" }
+  },
+  "local_double_det_explicit_id": {
+    "kms": "local",
+    "type": "double",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": false,
+    "value": { "$numberDouble": "1.234" }
+  },
+  "local_double_det_explicit_altname": {
+    "kms": "local",
+    "type": "double",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": false,
+    "value": { "$numberDouble": "1.234" }
+  },
+  "local_string_rand_auto_id": {
+    "kms": "local",
+    "type": "string",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": "mongodb"
+  },
+  "local_string_rand_auto_altname": {
+    "kms": "local",
+    "type": "string",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "altname",
+    "allowed": true,
+    "value": "mongodb"
+  },
+  "local_string_rand_explicit_id": {
+    "kms": "local",
+    "type": "string",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": "mongodb"
+  },
+  "local_string_rand_explicit_altname": {
+    "kms": "local",
+    "type": "string",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": "mongodb"
+  },
+  "local_string_det_auto_id": {
+    "kms": "local",
+    "type": "string",
+    "algo": "det",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": "mongodb"
+  },
+  "local_string_det_explicit_id": {
+    "kms": "local",
+    "type": "string",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": "mongodb"
+  },
+  "local_string_det_explicit_altname": {
+    "kms": "local",
+    "type": "string",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": "mongodb"
+  },
+  "local_object_rand_auto_id": {
+    "kms": "local",
+    "type": "object",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": { "x": { "$numberInt": "1" } }
+  },
+  "local_object_rand_auto_altname": {
+    "kms": "local",
+    "type": "object",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "altname",
+    "allowed": true,
+    "value": { "x": { "$numberInt": "1" } }
+  },
+  "local_object_rand_explicit_id": {
+    "kms": "local",
+    "type": "object",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": { "x": { "$numberInt": "1" } }
+  },
+  "local_object_rand_explicit_altname": {
+    "kms": "local",
+    "type": "object",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": { "x": { "$numberInt": "1" } }
+  },
+  "local_object_det_explicit_id": {
+    "kms": "local",
+    "type": "object",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": false,
+    "value": { "x": { "$numberInt": "1" } }
+  },
+  "local_object_det_explicit_altname": {
+    "kms": "local",
+    "type": "object",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": false,
+    "value": { "x": { "$numberInt": "1" } }
+  },
+  "local_array_rand_auto_id": {
+    "kms": "local",
+    "type": "array",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": [
+      { "$numberInt": "1" },
+      { "$numberInt": "2" },
+      { "$numberInt": "3" }
+    ]
+  },
+  "local_array_rand_auto_altname": {
+    "kms": "local",
+    "type": "array",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "altname",
+    "allowed": true,
+    "value": [
+      { "$numberInt": "1" },
+      { "$numberInt": "2" },
+      { "$numberInt": "3" }
+    ]
+  },
+  "local_array_rand_explicit_id": {
+    "kms": "local",
+    "type": "array",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": [
+      { "$numberInt": "1" },
+      { "$numberInt": "2" },
+      { "$numberInt": "3" }
+    ]
+  },
+  "local_array_rand_explicit_altname": {
+    "kms": "local",
+    "type": "array",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": [
+      { "$numberInt": "1" },
+      { "$numberInt": "2" },
+      { "$numberInt": "3" }
+    ]
+  },
+  "local_array_det_explicit_id": {
+    "kms": "local",
+    "type": "array",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": false,
+    "value": [
+      { "$numberInt": "1" },
+      { "$numberInt": "2" },
+      { "$numberInt": "3" }
+    ]
+  },
+  "local_array_det_explicit_altname": {
+    "kms": "local",
+    "type": "array",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": false,
+    "value": [
+      { "$numberInt": "1" },
+      { "$numberInt": "2" },
+      { "$numberInt": "3" }
+    ]
+  },
+  "local_binData=00_rand_auto_id": {
+    "kms": "local",
+    "type": "binData=00",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": { "$binary": { "base64": "AQIDBA==", "subType": "00" } }
+  },
+  "local_binData=00_rand_auto_altname": {
+    "kms": "local",
+    "type": "binData=00",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "altname",
+    "allowed": true,
+    "value": { "$binary": { "base64": "AQIDBA==", "subType": "00" } }
+  },
+  "local_binData=00_rand_explicit_id": {
+    "kms": "local",
+    "type": "binData=00",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": { "$binary": { "base64": "AQIDBA==", "subType": "00" } }
+  },
+  "local_binData=00_rand_explicit_altname": {
+    "kms": "local",
+    "type": "binData=00",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": { "$binary": { "base64": "AQIDBA==", "subType": "00" } }
+  },
+  "local_binData=00_det_auto_id": {
+    "kms": "local",
+    "type": "binData=00",
+    "algo": "det",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": { "$binary": { "base64": "AQIDBA==", "subType": "00" } }
+  },
+  "local_binData=00_det_explicit_id": {
+    "kms": "local",
+    "type": "binData=00",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": { "$binary": { "base64": "AQIDBA==", "subType": "00" } }
+  },
+  "local_binData=00_det_explicit_altname": {
+    "kms": "local",
+    "type": "binData=00",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": { "$binary": { "base64": "AQIDBA==", "subType": "00" } }
+  },
+  "local_binData=04_rand_auto_id": {
+    "kms": "local",
+    "type": "binData=04",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": { "base64": "AAECAwQFBgcICQoLDA0ODw==", "subType": "04" }
+    }
+  },
+  "local_binData=04_rand_auto_altname": {
+    "kms": "local",
+    "type": "binData=04",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": { "base64": "AAECAwQFBgcICQoLDA0ODw==", "subType": "04" }
+    }
+  },
+  "local_binData=04_rand_explicit_id": {
+    "kms": "local",
+    "type": "binData=04",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": { "base64": "AAECAwQFBgcICQoLDA0ODw==", "subType": "04" }
+    }
+  },
+  "local_binData=04_rand_explicit_altname": {
+    "kms": "local",
+    "type": "binData=04",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": { "base64": "AAECAwQFBgcICQoLDA0ODw==", "subType": "04" }
+    }
+  },
+  "local_binData=04_det_auto_id": {
+    "kms": "local",
+    "type": "binData=04",
+    "algo": "det",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": { "base64": "AAECAwQFBgcICQoLDA0ODw==", "subType": "04" }
+    }
+  },
+  "local_binData=04_det_explicit_id": {
+    "kms": "local",
+    "type": "binData=04",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$binary": { "base64": "AAECAwQFBgcICQoLDA0ODw==", "subType": "04" }
+    }
+  },
+  "local_binData=04_det_explicit_altname": {
+    "kms": "local",
+    "type": "binData=04",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$binary": { "base64": "AAECAwQFBgcICQoLDA0ODw==", "subType": "04" }
+    }
+  },
+  "local_undefined_rand_explicit_id": {
+    "kms": "local",
+    "type": "undefined",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": false,
+    "value": { "$undefined": true }
+  },
+  "local_undefined_rand_explicit_altname": {
+    "kms": "local",
+    "type": "undefined",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": false,
+    "value": { "$undefined": true }
+  },
+  "local_undefined_det_explicit_id": {
+    "kms": "local",
+    "type": "undefined",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": false,
+    "value": { "$undefined": true }
+  },
+  "local_undefined_det_explicit_altname": {
+    "kms": "local",
+    "type": "undefined",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": false,
+    "value": { "$undefined": true }
+  },
+  "local_objectId_rand_auto_id": {
+    "kms": "local",
+    "type": "objectId",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": { "$oid": "01234567890abcdef0123456" }
+  },
+  "local_objectId_rand_auto_altname": {
+    "kms": "local",
+    "type": "objectId",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "altname",
+    "allowed": true,
+    "value": { "$oid": "01234567890abcdef0123456" }
+  },
+  "local_objectId_rand_explicit_id": {
+    "kms": "local",
+    "type": "objectId",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": { "$oid": "01234567890abcdef0123456" }
+  },
+  "local_objectId_rand_explicit_altname": {
+    "kms": "local",
+    "type": "objectId",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": { "$oid": "01234567890abcdef0123456" }
+  },
+  "local_objectId_det_auto_id": {
+    "kms": "local",
+    "type": "objectId",
+    "algo": "det",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": { "$oid": "01234567890abcdef0123456" }
+  },
+  "local_objectId_det_explicit_id": {
+    "kms": "local",
+    "type": "objectId",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": { "$oid": "01234567890abcdef0123456" }
+  },
+  "local_objectId_det_explicit_altname": {
+    "kms": "local",
+    "type": "objectId",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": { "$oid": "01234567890abcdef0123456" }
+  },
+  "local_bool_rand_auto_id": {
+    "kms": "local",
+    "type": "bool",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": true
+  },
+  "local_bool_rand_auto_altname": {
+    "kms": "local",
+    "type": "bool",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "altname",
+    "allowed": true,
+    "value": true
+  },
+  "local_bool_rand_explicit_id": {
+    "kms": "local",
+    "type": "bool",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": true
+  },
+  "local_bool_rand_explicit_altname": {
+    "kms": "local",
+    "type": "bool",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": true
+  },
+  "local_bool_det_explicit_id": {
+    "kms": "local",
+    "type": "bool",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": false,
+    "value": true
+  },
+  "local_bool_det_explicit_altname": {
+    "kms": "local",
+    "type": "bool",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": false,
+    "value": true
+  },
+  "local_date_rand_auto_id": {
+    "kms": "local",
+    "type": "date",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": { "$date": { "$numberLong": "12345" } }
+  },
+  "local_date_rand_auto_altname": {
+    "kms": "local",
+    "type": "date",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "altname",
+    "allowed": true,
+    "value": { "$date": { "$numberLong": "12345" } }
+  },
+  "local_date_rand_explicit_id": {
+    "kms": "local",
+    "type": "date",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": { "$date": { "$numberLong": "12345" } }
+  },
+  "local_date_rand_explicit_altname": {
+    "kms": "local",
+    "type": "date",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": { "$date": { "$numberLong": "12345" } }
+  },
+  "local_date_det_auto_id": {
+    "kms": "local",
+    "type": "date",
+    "algo": "det",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": { "$date": { "$numberLong": "12345" } }
+  },
+  "local_date_det_explicit_id": {
+    "kms": "local",
+    "type": "date",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": { "$date": { "$numberLong": "12345" } }
+  },
+  "local_date_det_explicit_altname": {
+    "kms": "local",
+    "type": "date",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": { "$date": { "$numberLong": "12345" } }
+  },
+  "local_null_rand_explicit_id": {
+    "kms": "local",
+    "type": "null",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": false,
+    "value": null
+  },
+  "local_null_rand_explicit_altname": {
+    "kms": "local",
+    "type": "null",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": false,
+    "value": null
+  },
+  "local_null_det_explicit_id": {
+    "kms": "local",
+    "type": "null",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": false,
+    "value": null
+  },
+  "local_null_det_explicit_altname": {
+    "kms": "local",
+    "type": "null",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": false,
+    "value": null
+  },
+  "local_regex_rand_auto_id": {
+    "kms": "local",
+    "type": "regex",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": { "$regularExpression": { "pattern": ".*", "options": "" } }
+  },
+  "local_regex_rand_auto_altname": {
+    "kms": "local",
+    "type": "regex",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "altname",
+    "allowed": true,
+    "value": { "$regularExpression": { "pattern": ".*", "options": "" } }
+  },
+  "local_regex_rand_explicit_id": {
+    "kms": "local",
+    "type": "regex",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": { "$regularExpression": { "pattern": ".*", "options": "" } }
+  },
+  "local_regex_rand_explicit_altname": {
+    "kms": "local",
+    "type": "regex",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": { "$regularExpression": { "pattern": ".*", "options": "" } }
+  },
+  "local_regex_det_auto_id": {
+    "kms": "local",
+    "type": "regex",
+    "algo": "det",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": { "$regularExpression": { "pattern": ".*", "options": "" } }
+  },
+  "local_regex_det_explicit_id": {
+    "kms": "local",
+    "type": "regex",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": { "$regularExpression": { "pattern": ".*", "options": "" } }
+  },
+  "local_regex_det_explicit_altname": {
+    "kms": "local",
+    "type": "regex",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": { "$regularExpression": { "pattern": ".*", "options": "" } }
+  },
+  "local_dbPointer_rand_auto_id": {
+    "kms": "local",
+    "type": "dbPointer",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$dbPointer": {
+        "$ref": "db.example",
+        "$id": { "$oid": "01234567890abcdef0123456" }
+      }
+    }
+  },
+  "local_dbPointer_rand_auto_altname": {
+    "kms": "local",
+    "type": "dbPointer",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$dbPointer": {
+        "$ref": "db.example",
+        "$id": { "$oid": "01234567890abcdef0123456" }
+      }
+    }
+  },
+  "local_dbPointer_rand_explicit_id": {
+    "kms": "local",
+    "type": "dbPointer",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$dbPointer": {
+        "$ref": "db.example",
+        "$id": { "$oid": "01234567890abcdef0123456" }
+      }
+    }
+  },
+  "local_dbPointer_rand_explicit_altname": {
+    "kms": "local",
+    "type": "dbPointer",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$dbPointer": {
+        "$ref": "db.example",
+        "$id": { "$oid": "01234567890abcdef0123456" }
+      }
+    }
+  },
+  "local_dbPointer_det_auto_id": {
+    "kms": "local",
+    "type": "dbPointer",
+    "algo": "det",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$dbPointer": {
+        "$ref": "db.example",
+        "$id": { "$oid": "01234567890abcdef0123456" }
+      }
+    }
+  },
+  "local_dbPointer_det_explicit_id": {
+    "kms": "local",
+    "type": "dbPointer",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": {
+      "$dbPointer": {
+        "$ref": "db.example",
+        "$id": { "$oid": "01234567890abcdef0123456" }
+      }
+    }
+  },
+  "local_dbPointer_det_explicit_altname": {
+    "kms": "local",
+    "type": "dbPointer",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": {
+      "$dbPointer": {
+        "$ref": "db.example",
+        "$id": { "$oid": "01234567890abcdef0123456" }
+      }
+    }
+  },
+  "local_javascript_rand_auto_id": {
+    "kms": "local",
+    "type": "javascript",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": { "$code": "x=1" }
+  },
+  "local_javascript_rand_auto_altname": {
+    "kms": "local",
+    "type": "javascript",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "altname",
+    "allowed": true,
+    "value": { "$code": "x=1" }
+  },
+  "local_javascript_rand_explicit_id": {
+    "kms": "local",
+    "type": "javascript",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": { "$code": "x=1" }
+  },
+  "local_javascript_rand_explicit_altname": {
+    "kms": "local",
+    "type": "javascript",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": { "$code": "x=1" }
+  },
+  "local_javascript_det_auto_id": {
+    "kms": "local",
+    "type": "javascript",
+    "algo": "det",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": { "$code": "x=1" }
+  },
+  "local_javascript_det_explicit_id": {
+    "kms": "local",
+    "type": "javascript",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": { "$code": "x=1" }
+  },
+  "local_javascript_det_explicit_altname": {
+    "kms": "local",
+    "type": "javascript",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": { "$code": "x=1" }
+  },
+  "local_symbol_rand_auto_id": {
+    "kms": "local",
+    "type": "symbol",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": { "$symbol": "mongodb-symbol" }
+  },
+  "local_symbol_rand_auto_altname": {
+    "kms": "local",
+    "type": "symbol",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "altname",
+    "allowed": true,
+    "value": { "$symbol": "mongodb-symbol" }
+  },
+  "local_symbol_rand_explicit_id": {
+    "kms": "local",
+    "type": "symbol",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": { "$symbol": "mongodb-symbol" }
+  },
+  "local_symbol_rand_explicit_altname": {
+    "kms": "local",
+    "type": "symbol",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": { "$symbol": "mongodb-symbol" }
+  },
+  "local_symbol_det_auto_id": {
+    "kms": "local",
+    "type": "symbol",
+    "algo": "det",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": { "$symbol": "mongodb-symbol" }
+  },
+  "local_symbol_det_explicit_id": {
+    "kms": "local",
+    "type": "symbol",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": { "$symbol": "mongodb-symbol" }
+  },
+  "local_symbol_det_explicit_altname": {
+    "kms": "local",
+    "type": "symbol",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": { "$symbol": "mongodb-symbol" }
+  },
+  "local_javascriptWithScope_rand_auto_id": {
+    "kms": "local",
+    "type": "javascriptWithScope",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": { "$code": "x=1", "$scope": {} }
+  },
+  "local_javascriptWithScope_rand_auto_altname": {
+    "kms": "local",
+    "type": "javascriptWithScope",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "altname",
+    "allowed": true,
+    "value": { "$code": "x=1", "$scope": {} }
+  },
+  "local_javascriptWithScope_rand_explicit_id": {
+    "kms": "local",
+    "type": "javascriptWithScope",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": { "$code": "x=1", "$scope": {} }
+  },
+  "local_javascriptWithScope_rand_explicit_altname": {
+    "kms": "local",
+    "type": "javascriptWithScope",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": { "$code": "x=1", "$scope": {} }
+  },
+  "local_javascriptWithScope_det_explicit_id": {
+    "kms": "local",
+    "type": "javascriptWithScope",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": false,
+    "value": { "$code": "x=1", "$scope": {} }
+  },
+  "local_javascriptWithScope_det_explicit_altname": {
+    "kms": "local",
+    "type": "javascriptWithScope",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": false,
+    "value": { "$code": "x=1", "$scope": {} }
+  },
+  "local_int_rand_auto_id": {
+    "kms": "local",
+    "type": "int",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": { "$numberInt": "123" }
+  },
+  "local_int_rand_auto_altname": {
+    "kms": "local",
+    "type": "int",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "altname",
+    "allowed": true,
+    "value": { "$numberInt": "123" }
+  },
+  "local_int_rand_explicit_id": {
+    "kms": "local",
+    "type": "int",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": { "$numberInt": "123" }
+  },
+  "local_int_rand_explicit_altname": {
+    "kms": "local",
+    "type": "int",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": { "$numberInt": "123" }
+  },
+  "local_int_det_auto_id": {
+    "kms": "local",
+    "type": "int",
+    "algo": "det",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": { "$numberInt": "123" }
+  },
+  "local_int_det_explicit_id": {
+    "kms": "local",
+    "type": "int",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": { "$numberInt": "123" }
+  },
+  "local_int_det_explicit_altname": {
+    "kms": "local",
+    "type": "int",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": { "$numberInt": "123" }
+  },
+  "local_timestamp_rand_auto_id": {
+    "kms": "local",
+    "type": "timestamp",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": { "$timestamp": { "t": 0, "i": 12345 } }
+  },
+  "local_timestamp_rand_auto_altname": {
+    "kms": "local",
+    "type": "timestamp",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "altname",
+    "allowed": true,
+    "value": { "$timestamp": { "t": 0, "i": 12345 } }
+  },
+  "local_timestamp_rand_explicit_id": {
+    "kms": "local",
+    "type": "timestamp",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": { "$timestamp": { "t": 0, "i": 12345 } }
+  },
+  "local_timestamp_rand_explicit_altname": {
+    "kms": "local",
+    "type": "timestamp",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": { "$timestamp": { "t": 0, "i": 12345 } }
+  },
+  "local_timestamp_det_auto_id": {
+    "kms": "local",
+    "type": "timestamp",
+    "algo": "det",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": { "$timestamp": { "t": 0, "i": 12345 } }
+  },
+  "local_timestamp_det_explicit_id": {
+    "kms": "local",
+    "type": "timestamp",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": { "$timestamp": { "t": 0, "i": 12345 } }
+  },
+  "local_timestamp_det_explicit_altname": {
+    "kms": "local",
+    "type": "timestamp",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": { "$timestamp": { "t": 0, "i": 12345 } }
+  },
+  "local_long_rand_auto_id": {
+    "kms": "local",
+    "type": "long",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": { "$numberLong": "456" }
+  },
+  "local_long_rand_auto_altname": {
+    "kms": "local",
+    "type": "long",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "altname",
+    "allowed": true,
+    "value": { "$numberLong": "456" }
+  },
+  "local_long_rand_explicit_id": {
+    "kms": "local",
+    "type": "long",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": { "$numberLong": "456" }
+  },
+  "local_long_rand_explicit_altname": {
+    "kms": "local",
+    "type": "long",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": { "$numberLong": "456" }
+  },
+  "local_long_det_auto_id": {
+    "kms": "local",
+    "type": "long",
+    "algo": "det",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": { "$numberLong": "456" }
+  },
+  "local_long_det_explicit_id": {
+    "kms": "local",
+    "type": "long",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": { "$numberLong": "456" }
+  },
+  "local_long_det_explicit_altname": {
+    "kms": "local",
+    "type": "long",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": { "$numberLong": "456" }
+  },
+  "local_decimal_rand_auto_id": {
+    "kms": "local",
+    "type": "decimal",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "id",
+    "allowed": true,
+    "value": { "$numberDecimal": "1.234" }
+  },
+  "local_decimal_rand_auto_altname": {
+    "kms": "local",
+    "type": "decimal",
+    "algo": "rand",
+    "method": "auto",
+    "identifier": "altname",
+    "allowed": true,
+    "value": { "$numberDecimal": "1.234" }
+  },
+  "local_decimal_rand_explicit_id": {
+    "kms": "local",
+    "type": "decimal",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": { "$numberDecimal": "1.234" }
+  },
+  "local_decimal_rand_explicit_altname": {
+    "kms": "local",
+    "type": "decimal",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": true,
+    "value": { "$numberDecimal": "1.234" }
+  },
+  "local_decimal_det_explicit_id": {
+    "kms": "local",
+    "type": "decimal",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": false,
+    "value": { "$numberDecimal": "1.234" }
+  },
+  "local_decimal_det_explicit_altname": {
+    "kms": "local",
+    "type": "decimal",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": false,
+    "value": { "$numberDecimal": "1.234" }
+  },
+  "local_minKey_rand_explicit_id": {
+    "kms": "local",
+    "type": "minKey",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": false,
+    "value": { "$minKey": 1 }
+  },
+  "local_minKey_rand_explicit_altname": {
+    "kms": "local",
+    "type": "minKey",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": false,
+    "value": { "$minKey": 1 }
+  },
+  "local_minKey_det_explicit_id": {
+    "kms": "local",
+    "type": "minKey",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": false,
+    "value": { "$minKey": 1 }
+  },
+  "local_minKey_det_explicit_altname": {
+    "kms": "local",
+    "type": "minKey",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": false,
+    "value": { "$minKey": 1 }
+  },
+  "local_maxKey_rand_explicit_id": {
+    "kms": "local",
+    "type": "maxKey",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": false,
+    "value": { "$maxKey": 1 }
+  },
+  "local_maxKey_rand_explicit_altname": {
+    "kms": "local",
+    "type": "maxKey",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": false,
+    "value": { "$maxKey": 1 }
+  },
+  "local_maxKey_det_explicit_id": {
+    "kms": "local",
+    "type": "maxKey",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": false,
+    "value": { "$maxKey": 1 }
+  },
+  "local_maxKey_det_explicit_altname": {
+    "kms": "local",
+    "type": "maxKey",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "altname",
+    "allowed": false,
+    "value": { "$maxKey": 1 }
+  },
+  "payload=0,algo=rand": {
+    "kms": "local",
+    "type": "string",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": ""
+  },
+  "payload=1,algo=rand": {
+    "kms": "local",
+    "type": "string",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": "a"
+  },
+  "payload=2,algo=rand": {
+    "kms": "local",
+    "type": "string",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": "aa"
+  },
+  "payload=3,algo=rand": {
+    "kms": "local",
+    "type": "string",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": "aaa"
+  },
+  "payload=4,algo=rand": {
+    "kms": "local",
+    "type": "string",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": "aaaa"
+  },
+  "payload=5,algo=rand": {
+    "kms": "local",
+    "type": "string",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": "aaaaa"
+  },
+  "payload=6,algo=rand": {
+    "kms": "local",
+    "type": "string",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": "aaaaaa"
+  },
+  "payload=7,algo=rand": {
+    "kms": "local",
+    "type": "string",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": "aaaaaaa"
+  },
+  "payload=8,algo=rand": {
+    "kms": "local",
+    "type": "string",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": "aaaaaaaa"
+  },
+  "payload=9,algo=rand": {
+    "kms": "local",
+    "type": "string",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": "aaaaaaaaa"
+  },
+  "payload=10,algo=rand": {
+    "kms": "local",
+    "type": "string",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": "aaaaaaaaaa"
+  },
+  "payload=11,algo=rand": {
+    "kms": "local",
+    "type": "string",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": "aaaaaaaaaaa"
+  },
+  "payload=12,algo=rand": {
+    "kms": "local",
+    "type": "string",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": "aaaaaaaaaaaa"
+  },
+  "payload=13,algo=rand": {
+    "kms": "local",
+    "type": "string",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": "aaaaaaaaaaaaa"
+  },
+  "payload=14,algo=rand": {
+    "kms": "local",
+    "type": "string",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": "aaaaaaaaaaaaaa"
+  },
+  "payload=15,algo=rand": {
+    "kms": "local",
+    "type": "string",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": "aaaaaaaaaaaaaaa"
+  },
+  "payload=16,algo=rand": {
+    "kms": "local",
+    "type": "string",
+    "algo": "rand",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": "aaaaaaaaaaaaaaaa"
+  },
+  "payload=0,algo=det": {
+    "kms": "local",
+    "type": "string",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": ""
+  },
+  "payload=1,algo=det": {
+    "kms": "local",
+    "type": "string",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": "a"
+  },
+  "payload=2,algo=det": {
+    "kms": "local",
+    "type": "string",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": "aa"
+  },
+  "payload=3,algo=det": {
+    "kms": "local",
+    "type": "string",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": "aaa"
+  },
+  "payload=4,algo=det": {
+    "kms": "local",
+    "type": "string",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": "aaaa"
+  },
+  "payload=5,algo=det": {
+    "kms": "local",
+    "type": "string",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": "aaaaa"
+  },
+  "payload=6,algo=det": {
+    "kms": "local",
+    "type": "string",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": "aaaaaa"
+  },
+  "payload=7,algo=det": {
+    "kms": "local",
+    "type": "string",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": "aaaaaaa"
+  },
+  "payload=8,algo=det": {
+    "kms": "local",
+    "type": "string",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": "aaaaaaaa"
+  },
+  "payload=9,algo=det": {
+    "kms": "local",
+    "type": "string",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": "aaaaaaaaa"
+  },
+  "payload=10,algo=det": {
+    "kms": "local",
+    "type": "string",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": "aaaaaaaaaa"
+  },
+  "payload=11,algo=det": {
+    "kms": "local",
+    "type": "string",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": "aaaaaaaaaaa"
+  },
+  "payload=12,algo=det": {
+    "kms": "local",
+    "type": "string",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": "aaaaaaaaaaaa"
+  },
+  "payload=13,algo=det": {
+    "kms": "local",
+    "type": "string",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": "aaaaaaaaaaaaa"
+  },
+  "payload=14,algo=det": {
+    "kms": "local",
+    "type": "string",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": "aaaaaaaaaaaaaa"
+  },
+  "payload=15,algo=det": {
+    "kms": "local",
+    "type": "string",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": "aaaaaaaaaaaaaaa"
+  },
+  "payload=16,algo=det": {
+    "kms": "local",
+    "type": "string",
+    "algo": "det",
+    "method": "explicit",
+    "identifier": "id",
+    "allowed": true,
+    "value": "aaaaaaaaaaaaaaaa"
+  }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/external/external-key.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/external/external-key.json
new file mode 100644
index 0000000000000000000000000000000000000000..5da84ab6b496ef6b458d13ba9fcc603979ae5c15
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/external/external-key.json	
@@ -0,0 +1,31 @@
+{
+    "status": {
+        "$numberInt": "1"
+    },
+    "_id": {
+        "$binary": {
+            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+            "subType": "04"
+        }
+    },
+    "masterKey": {
+        "provider": "local"
+    },
+    "updateDate": {
+        "$date": {
+            "$numberLong": "1557827033449"
+        }
+    },
+    "keyMaterial": {
+        "$binary": {
+            "base64": "Ce9HSz/HKKGkIt4uyy+jDuKGA+rLC2cycykMo6vc8jXxqa1UVDYHWq1r+vZKbnnSRBfB981akzRKZCFpC05CTyFqDhXv6OnMjpG97OZEREGIsHEYiJkBW0jJJvfLLgeLsEpBzsro9FztGGXASxyxFRZFhXvHxyiLOKrdWfs7X1O/iK3pEoHMx6uSNSfUOgbebLfIqW7TO++iQS5g1xovXA==",
+            "subType": "00"
+        }
+    },
+    "creationDate": {
+        "$date": {
+            "$numberLong": "1557827033449"
+        }
+    },
+    "keyAltNames": [ "local" ]
+}
\ No newline at end of file
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/external/external-schema.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/external/external-schema.json
new file mode 100644
index 0000000000000000000000000000000000000000..52f524a18859e1ebb761b1e562b1b0f2214f6d04
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/external/external-schema.json	
@@ -0,0 +1,19 @@
+{
+    "properties": {
+       "encrypted": {
+           "encrypt": {
+               "keyId": [
+                   {
+                       "$binary": {
+                           "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                           "subType": "04"
+                       }
+                   }
+               ],
+               "bsonType": "string",
+               "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+           }
+       }
+    },
+    "bsonType": "object"
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/limits/limits-doc.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/limits/limits-doc.json
new file mode 100644
index 0000000000000000000000000000000000000000..3c556aee01056dea0d45dcbce2393008eba2f682
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/limits/limits-doc.json	
@@ -0,0 +1,102 @@
+{
+    "00": "a",
+    "01": "a",
+    "02": "a",
+    "03": "a",
+    "04": "a",
+    "05": "a",
+    "06": "a",
+    "07": "a",
+    "08": "a",
+    "09": "a",
+    "10": "a",
+    "11": "a",
+    "12": "a",
+    "13": "a",
+    "14": "a",
+    "15": "a",
+    "16": "a",
+    "17": "a",
+    "18": "a",
+    "19": "a",
+    "20": "a",
+    "21": "a",
+    "22": "a",
+    "23": "a",
+    "24": "a",
+    "25": "a",
+    "26": "a",
+    "27": "a",
+    "28": "a",
+    "29": "a",
+    "30": "a",
+    "31": "a",
+    "32": "a",
+    "33": "a",
+    "34": "a",
+    "35": "a",
+    "36": "a",
+    "37": "a",
+    "38": "a",
+    "39": "a",
+    "40": "a",
+    "41": "a",
+    "42": "a",
+    "43": "a",
+    "44": "a",
+    "45": "a",
+    "46": "a",
+    "47": "a",
+    "48": "a",
+    "49": "a",
+    "50": "a",
+    "51": "a",
+    "52": "a",
+    "53": "a",
+    "54": "a",
+    "55": "a",
+    "56": "a",
+    "57": "a",
+    "58": "a",
+    "59": "a",
+    "60": "a",
+    "61": "a",
+    "62": "a",
+    "63": "a",
+    "64": "a",
+    "65": "a",
+    "66": "a",
+    "67": "a",
+    "68": "a",
+    "69": "a",
+    "70": "a",
+    "71": "a",
+    "72": "a",
+    "73": "a",
+    "74": "a",
+    "75": "a",
+    "76": "a",
+    "77": "a",
+    "78": "a",
+    "79": "a",
+    "80": "a",
+    "81": "a",
+    "82": "a",
+    "83": "a",
+    "84": "a",
+    "85": "a",
+    "86": "a",
+    "87": "a",
+    "88": "a",
+    "89": "a",
+    "90": "a",
+    "91": "a",
+    "92": "a",
+    "93": "a",
+    "94": "a",
+    "95": "a",
+    "96": "a",
+    "97": "a",
+    "98": "a",
+    "99": "a"
+}
\ No newline at end of file
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/limits/limits-key.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/limits/limits-key.json
new file mode 100644
index 0000000000000000000000000000000000000000..5da84ab6b496ef6b458d13ba9fcc603979ae5c15
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/limits/limits-key.json	
@@ -0,0 +1,31 @@
+{
+    "status": {
+        "$numberInt": "1"
+    },
+    "_id": {
+        "$binary": {
+            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+            "subType": "04"
+        }
+    },
+    "masterKey": {
+        "provider": "local"
+    },
+    "updateDate": {
+        "$date": {
+            "$numberLong": "1557827033449"
+        }
+    },
+    "keyMaterial": {
+        "$binary": {
+            "base64": "Ce9HSz/HKKGkIt4uyy+jDuKGA+rLC2cycykMo6vc8jXxqa1UVDYHWq1r+vZKbnnSRBfB981akzRKZCFpC05CTyFqDhXv6OnMjpG97OZEREGIsHEYiJkBW0jJJvfLLgeLsEpBzsro9FztGGXASxyxFRZFhXvHxyiLOKrdWfs7X1O/iK3pEoHMx6uSNSfUOgbebLfIqW7TO++iQS5g1xovXA==",
+            "subType": "00"
+        }
+    },
+    "creationDate": {
+        "$date": {
+            "$numberLong": "1557827033449"
+        }
+    },
+    "keyAltNames": [ "local" ]
+}
\ No newline at end of file
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/limits/limits-schema.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/limits/limits-schema.json
new file mode 100644
index 0000000000000000000000000000000000000000..7af0979b844d3a6e4f23b24140056503a6137b9b
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/limits/limits-schema.json	
@@ -0,0 +1,1405 @@
+{
+    "properties": {
+        "00": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "01": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "02": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "03": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "04": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "05": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "06": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "07": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "08": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "09": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "10": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "11": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "12": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "13": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "14": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "15": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "16": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "17": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "18": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "19": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "20": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "21": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "22": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "23": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "24": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "25": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "26": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "27": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "28": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "29": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "30": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "31": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "32": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "33": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "34": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "35": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "36": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "37": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "38": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "39": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "40": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "41": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "42": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "43": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "44": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "45": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "46": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "47": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "48": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "49": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "50": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "51": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "52": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "53": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "54": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "55": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "56": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "57": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "58": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "59": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "60": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "61": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "62": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "63": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "64": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "65": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "66": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "67": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "68": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "69": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "70": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "71": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "72": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "73": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "74": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "75": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "76": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "77": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "78": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "79": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "80": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "81": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "82": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "83": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "84": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "85": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "86": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "87": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "88": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "89": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "90": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "91": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "92": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "93": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "94": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "95": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "96": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "97": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "98": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        },
+        "99": {
+            "encrypt": {
+                "keyId": [
+                    {
+                        "$binary": {
+                            "base64": "LOCALAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                        }
+                    }
+                ],
+                "bsonType": "string",
+                "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+            }
+        }
+    },
+    "bsonType": "object"
+}
\ No newline at end of file
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/tests/aggregate.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/tests/aggregate.json
new file mode 100644
index 0000000000000000000000000000000000000000..a9e79f9edbf9d76137989de9b8d10930a273a8bb
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/tests/aggregate.json	
@@ -0,0 +1,414 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.1.10"
+    }
+  ],
+  "database_name": "default",
+  "collection_name": "default",
+  "data": [
+    {
+      "_id": 1,
+      "encrypted_string": {
+        "$binary": {
+          "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==",
+          "subType": "06"
+        }
+      }
+    }
+  ],
+  "json_schema": {
+    "properties": {
+      "encrypted_w_altname": {
+        "encrypt": {
+          "keyId": "/altname",
+          "bsonType": "string",
+          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random"
+        }
+      },
+      "encrypted_string": {
+        "encrypt": {
+          "keyId": [
+            {
+              "$binary": {
+                "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                "subType": "04"
+              }
+            }
+          ],
+          "bsonType": "string",
+          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+        }
+      },
+      "random": {
+        "encrypt": {
+          "keyId": [
+            {
+              "$binary": {
+                "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                "subType": "04"
+              }
+            }
+          ],
+          "bsonType": "string",
+          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random"
+        }
+      },
+      "encrypted_string_equivalent": {
+        "encrypt": {
+          "keyId": [
+            {
+              "$binary": {
+                "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                "subType": "04"
+              }
+            }
+          ],
+          "bsonType": "string",
+          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+        }
+      }
+    },
+    "bsonType": "object"
+  },
+  "key_vault_data": [
+    {
+      "status": 1,
+      "_id": {
+        "$binary": {
+          "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+          "subType": "04"
+        }
+      },
+      "masterKey": {
+        "provider": "aws",
+        "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0",
+        "region": "us-east-1"
+      },
+      "updateDate": {
+        "$date": {
+          "$numberLong": "1552949630483"
+        }
+      },
+      "keyMaterial": {
+        "$binary": {
+          "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO",
+          "subType": "00"
+        }
+      },
+      "creationDate": {
+        "$date": {
+          "$numberLong": "1552949630483"
+        }
+      },
+      "keyAltNames": [
+        "altname",
+        "another_altname"
+      ]
+    }
+  ],
+  "tests": [
+    {
+      "description": "Aggregate with deterministic encryption",
+      "skipReason": "SERVER-39395",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "kmsProviders": {
+            "aws": {}
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "aggregate",
+          "arguments": {
+            "pipeline": [
+              {
+                "$match": {
+                  "encrypted_string": "457-55-5642"
+                }
+              }
+            ]
+          },
+          "result": [
+            {
+              "_id": 1,
+              "encrypted_string": "string0"
+            }
+          ]
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1,
+              "filter": {
+                "name": "default"
+              }
+            },
+            "command_name": "listCollections"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1,
+              "filter": {
+                "name": "datakeys"
+              },
+              "$db": "keyvault"
+            },
+            "command_name": "listCollections"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "datakeys",
+              "filter": {
+                "$or": [
+                  {
+                    "_id": {
+                      "$in": [
+                        {
+                          "$binary": {
+                            "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                          }
+                        }
+                      ]
+                    }
+                  },
+                  {
+                    "keyAltNames": {
+                      "$in": []
+                    }
+                  }
+                ]
+              },
+              "$db": "keyvault",
+              "readConcern": {
+                "level": "majority"
+              }
+            },
+            "command_name": "find"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "default",
+              "pipeline": [
+                {
+                  "$match": {
+                    "encrypted_string": "457-55-5642"
+                  }
+                }
+              ]
+            },
+            "command_name": "aggregate"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "encrypted_string": {
+                "$binary": {
+                  "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==",
+                  "subType": "06"
+                }
+              }
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "Aggregate with empty pipeline",
+      "skipReason": "SERVER-40829 hides agg support behind enableTestCommands flag.",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "kmsProviders": {
+            "aws": {}
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "aggregate",
+          "arguments": {
+            "pipeline": []
+          },
+          "result": [
+            {
+              "_id": 1,
+              "encrypted_string": "string0"
+            }
+          ]
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1,
+              "filter": {
+                "name": "default"
+              }
+            },
+            "command_name": "listCollections"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "default",
+              "pipeline": [],
+              "cursor": {}
+            },
+            "command_name": "aggregate"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1,
+              "filter": {
+                "name": "datakeys"
+              },
+              "$db": "keyvault"
+            },
+            "command_name": "listCollections"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "datakeys",
+              "filter": {
+                "$or": [
+                  {
+                    "_id": {
+                      "$in": [
+                        {
+                          "$binary": {
+                            "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                          }
+                        }
+                      ]
+                    }
+                  },
+                  {
+                    "keyAltNames": {
+                      "$in": []
+                    }
+                  }
+                ]
+              },
+              "$db": "keyvault",
+              "readConcern": {
+                "level": "majority"
+              }
+            },
+            "command_name": "find"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "encrypted_string": {
+                "$binary": {
+                  "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==",
+                  "subType": "06"
+                }
+              }
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "Aggregate should fail with random encryption",
+      "skipReason": "SERVER-39395",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "kmsProviders": {
+            "aws": {}
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "aggregate",
+          "arguments": {
+            "pipeline": [
+              {
+                "$match": {
+                  "random": "abc"
+                }
+              }
+            ]
+          },
+          "result": {
+            "errorContains": "Cannot query on fields encrypted with the randomized encryption"
+          }
+        }
+      ]
+    },
+    {
+      "description": "Database aggregate should fail",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "kmsProviders": {
+            "aws": {}
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "aggregate",
+          "object": "database",
+          "arguments": {
+            "pipeline": [
+              {
+                "$currentOp": {
+                  "allUsers": false,
+                  "idleConnections": false,
+                  "localOps": true
+                }
+              },
+              {
+                "$match": {
+                  "command.aggregate": {
+                    "$eq": 1
+                  }
+                }
+              },
+              {
+                "$project": {
+                  "command": 1
+                }
+              },
+              {
+                "$project": {
+                  "command.lsid": 0
+                }
+              }
+            ]
+          },
+          "result": {
+            "errorContains": "non-collection command not supported for auto encryption: aggregate"
+          }
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/tests/badQueries.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/tests/badQueries.json
new file mode 100644
index 0000000000000000000000000000000000000000..824a53c00b156ee22a82b5c6e8f73cda28ba7582
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/tests/badQueries.json	
@@ -0,0 +1,1446 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.1.10"
+    }
+  ],
+  "database_name": "default",
+  "collection_name": "default",
+  "data": [
+    {
+      "_id": 1,
+      "encrypted_string": {
+        "$binary": {
+          "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==",
+          "subType": "06"
+        }
+      }
+    },
+    {
+      "_id": 2,
+      "encrypted_string": {
+        "$binary": {
+          "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==",
+          "subType": "06"
+        }
+      }
+    }
+  ],
+  "json_schema": {
+    "properties": {
+      "encrypted_w_altname": {
+        "encrypt": {
+          "keyId": "/altname",
+          "bsonType": "string",
+          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random"
+        }
+      },
+      "encrypted_string": {
+        "encrypt": {
+          "keyId": [
+            {
+              "$binary": {
+                "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                "subType": "04"
+              }
+            }
+          ],
+          "bsonType": "string",
+          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+        }
+      },
+      "random": {
+        "encrypt": {
+          "keyId": [
+            {
+              "$binary": {
+                "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                "subType": "04"
+              }
+            }
+          ],
+          "bsonType": "string",
+          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random"
+        }
+      },
+      "encrypted_string_equivalent": {
+        "encrypt": {
+          "keyId": [
+            {
+              "$binary": {
+                "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                "subType": "04"
+              }
+            }
+          ],
+          "bsonType": "string",
+          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+        }
+      }
+    },
+    "bsonType": "object"
+  },
+  "key_vault_data": [
+    {
+      "status": 1,
+      "_id": {
+        "$binary": {
+          "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+          "subType": "04"
+        }
+      },
+      "masterKey": {
+        "provider": "aws",
+        "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0",
+        "region": "us-east-1"
+      },
+      "updateDate": {
+        "$date": {
+          "$numberLong": "1552949630483"
+        }
+      },
+      "keyMaterial": {
+        "$binary": {
+          "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO",
+          "subType": "00"
+        }
+      },
+      "creationDate": {
+        "$date": {
+          "$numberLong": "1552949630483"
+        }
+      },
+      "keyAltNames": [
+        "altname",
+        "another_altname"
+      ]
+    }
+  ],
+  "tests": [
+    {
+      "description": "$text unconditionally fails",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "kmsProviders": {
+            "aws": {}
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "find",
+          "arguments": {
+            "filter": {
+              "$text": {
+                "$search": "search text"
+              }
+            }
+          },
+          "result": {
+            "errorContains": "Unsupported match expression operator for encryption"
+          }
+        }
+      ]
+    },
+    {
+      "description": "$where unconditionally fails",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "kmsProviders": {
+            "aws": {}
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "find",
+          "arguments": {
+            "filter": {
+              "$where": {
+                "$code": "function() { return true }"
+              }
+            }
+          },
+          "result": {
+            "errorContains": "Unsupported match expression operator for encryption"
+          }
+        }
+      ]
+    },
+    {
+      "description": "$bit operators succeed on unencrypted, error on encrypted",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "kmsProviders": {
+            "aws": {}
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "find",
+          "arguments": {
+            "filter": {
+              "unencrypted": {
+                "$bitsAllClear": 35
+              }
+            }
+          },
+          "result": []
+        },
+        {
+          "name": "find",
+          "arguments": {
+            "filter": {
+              "encrypted_string": {
+                "$bitsAllClear": 35
+              }
+            }
+          },
+          "result": {
+            "errorContains": "Invalid match expression operator on encrypted field"
+          }
+        },
+        {
+          "name": "find",
+          "arguments": {
+            "filter": {
+              "unencrypted": {
+                "$bitsAllSet": 35
+              }
+            }
+          },
+          "result": []
+        },
+        {
+          "name": "find",
+          "arguments": {
+            "filter": {
+              "encrypted_string": {
+                "$bitsAllSet": 35
+              }
+            }
+          },
+          "result": {
+            "errorContains": "Invalid match expression operator on encrypted field"
+          }
+        },
+        {
+          "name": "find",
+          "arguments": {
+            "filter": {
+              "unencrypted": {
+                "$bitsAnyClear": 35
+              }
+            }
+          },
+          "result": []
+        },
+        {
+          "name": "find",
+          "arguments": {
+            "filter": {
+              "encrypted_string": {
+                "$bitsAnyClear": 35
+              }
+            }
+          },
+          "result": {
+            "errorContains": "Invalid match expression operator on encrypted field"
+          }
+        },
+        {
+          "name": "find",
+          "arguments": {
+            "filter": {
+              "unencrypted": {
+                "$bitsAnySet": 35
+              }
+            }
+          },
+          "result": []
+        },
+        {
+          "name": "find",
+          "arguments": {
+            "filter": {
+              "encrypted_string": {
+                "$bitsAnySet": 35
+              }
+            }
+          },
+          "result": {
+            "errorContains": "Invalid match expression operator on encrypted field"
+          }
+        }
+      ]
+    },
+    {
+      "description": "geo operators succeed on unencrypted, error on encrypted",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "kmsProviders": {
+            "aws": {}
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "find",
+          "arguments": {
+            "filter": {
+              "unencrypted": {
+                "$near": [
+                  0,
+                  0
+                ]
+              }
+            }
+          },
+          "result": {
+            "errorContains": "unable to find index"
+          }
+        },
+        {
+          "name": "find",
+          "arguments": {
+            "filter": {
+              "encrypted_string": {
+                "$near": [
+                  0,
+                  0
+                ]
+              }
+            }
+          },
+          "result": {
+            "errorContains": "Invalid match expression operator on encrypted field"
+          }
+        },
+        {
+          "name": "find",
+          "arguments": {
+            "filter": {
+              "unencrypted": {
+                "$nearSphere": [
+                  0,
+                  0
+                ]
+              }
+            }
+          },
+          "result": {
+            "errorContains": "unable to find index"
+          }
+        },
+        {
+          "name": "find",
+          "arguments": {
+            "filter": {
+              "encrypted_string": {
+                "$nearSphere": [
+                  0,
+                  0
+                ]
+              }
+            }
+          },
+          "result": {
+            "errorContains": "Invalid match expression operator on encrypted field"
+          }
+        },
+        {
+          "name": "find",
+          "arguments": {
+            "filter": {
+              "unencrypted": {
+                "$geoIntersects": {
+                  "$geometry": {
+                    "type": "Polygon",
+                    "coordinates": [
+                      [
+                        [
+                          0,
+                          0
+                        ],
+                        [
+                          1,
+                          0
+                        ],
+                        [
+                          1,
+                          1
+                        ],
+                        [
+                          0,
+                          0
+                        ]
+                      ]
+                    ]
+                  }
+                }
+              }
+            }
+          },
+          "result": []
+        },
+        {
+          "name": "find",
+          "arguments": {
+            "filter": {
+              "encrypted_string": {
+                "$geoIntersects": {
+                  "$geometry": {
+                    "type": "Polygon",
+                    "coordinates": [
+                      [
+                        [
+                          0,
+                          0
+                        ],
+                        [
+                          1,
+                          0
+                        ],
+                        [
+                          1,
+                          1
+                        ],
+                        [
+                          0,
+                          0
+                        ]
+                      ]
+                    ]
+                  }
+                }
+              }
+            }
+          },
+          "result": {
+            "errorContains": "Invalid match expression operator on encrypted field"
+          }
+        },
+        {
+          "name": "find",
+          "arguments": {
+            "filter": {
+              "unencrypted": {
+                "$geoWithin": {
+                  "$geometry": {
+                    "type": "Polygon",
+                    "coordinates": [
+                      [
+                        [
+                          0,
+                          0
+                        ],
+                        [
+                          1,
+                          0
+                        ],
+                        [
+                          1,
+                          1
+                        ],
+                        [
+                          0,
+                          0
+                        ]
+                      ]
+                    ]
+                  }
+                }
+              }
+            }
+          },
+          "result": []
+        },
+        {
+          "name": "find",
+          "arguments": {
+            "filter": {
+              "encrypted_string": {
+                "$geoWithin": {
+                  "$geometry": {
+                    "type": "Polygon",
+                    "coordinates": [
+                      [
+                        [
+                          0,
+                          0
+                        ],
+                        [
+                          1,
+                          0
+                        ],
+                        [
+                          1,
+                          1
+                        ],
+                        [
+                          0,
+                          0
+                        ]
+                      ]
+                    ]
+                  }
+                }
+              }
+            }
+          },
+          "result": {
+            "errorContains": "Invalid match expression operator on encrypted field"
+          }
+        }
+      ]
+    },
+    {
+      "description": "inequality operators succeed on unencrypted, error on encrypted",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "kmsProviders": {
+            "aws": {}
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "find",
+          "arguments": {
+            "filter": {
+              "unencrypted": {
+                "$gt": 1
+              }
+            }
+          },
+          "result": []
+        },
+        {
+          "name": "find",
+          "arguments": {
+            "filter": {
+              "encrypted_string": {
+                "$gt": 1
+              }
+            }
+          },
+          "result": {
+            "errorContains": "Invalid match expression operator on encrypted field"
+          }
+        },
+        {
+          "name": "find",
+          "arguments": {
+            "filter": {
+              "unencrypted": {
+                "$lt": 1
+              }
+            }
+          },
+          "result": []
+        },
+        {
+          "name": "find",
+          "arguments": {
+            "filter": {
+              "encrypted_string": {
+                "$lt": 1
+              }
+            }
+          },
+          "result": {
+            "errorContains": "Invalid match expression operator on encrypted field"
+          }
+        },
+        {
+          "name": "find",
+          "arguments": {
+            "filter": {
+              "unencrypted": {
+                "$gte": 1
+              }
+            }
+          },
+          "result": []
+        },
+        {
+          "name": "find",
+          "arguments": {
+            "filter": {
+              "encrypted_string": {
+                "$gte": 1
+              }
+            }
+          },
+          "result": {
+            "errorContains": "Invalid match expression operator on encrypted field"
+          }
+        },
+        {
+          "name": "find",
+          "arguments": {
+            "filter": {
+              "unencrypted": {
+                "$lte": 1
+              }
+            }
+          },
+          "result": []
+        },
+        {
+          "name": "find",
+          "arguments": {
+            "filter": {
+              "encrypted_string": {
+                "$lte": 1
+              }
+            }
+          },
+          "result": {
+            "errorContains": "Invalid match expression operator on encrypted field"
+          }
+        }
+      ]
+    },
+    {
+      "description": "other misc operators succeed on unencrypted, error on encrypted",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "kmsProviders": {
+            "aws": {}
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "find",
+          "arguments": {
+            "filter": {
+              "unencrypted": {
+                "$mod": [
+                  3,
+                  1
+                ]
+              }
+            }
+          },
+          "result": []
+        },
+        {
+          "name": "find",
+          "arguments": {
+            "filter": {
+              "encrypted_string": {
+                "$mod": [
+                  3,
+                  1
+                ]
+              }
+            }
+          },
+          "result": {
+            "errorContains": "Invalid match expression operator on encrypted field"
+          }
+        },
+        {
+          "name": "find",
+          "arguments": {
+            "filter": {
+              "unencrypted": {
+                "$regex": "pattern",
+                "$options": ""
+              }
+            }
+          },
+          "result": []
+        },
+        {
+          "name": "find",
+          "arguments": {
+            "filter": {
+              "encrypted_string": {
+                "$regex": "pattern",
+                "$options": ""
+              }
+            }
+          },
+          "result": {
+            "errorContains": "Invalid match expression operator on encrypted field"
+          }
+        },
+        {
+          "name": "find",
+          "arguments": {
+            "filter": {
+              "unencrypted": {
+                "$size": 2
+              }
+            }
+          },
+          "result": []
+        },
+        {
+          "name": "find",
+          "arguments": {
+            "filter": {
+              "encrypted_string": {
+                "$size": 2
+              }
+            }
+          },
+          "result": {
+            "errorContains": "Invalid match expression operator on encrypted field"
+          }
+        },
+        {
+          "name": "find",
+          "arguments": {
+            "filter": {
+              "unencrypted": {
+                "$type": 2
+              }
+            }
+          },
+          "result": []
+        },
+        {
+          "name": "find",
+          "arguments": {
+            "filter": {
+              "encrypted_string": {
+                "$type": 2
+              }
+            }
+          },
+          "result": {
+            "errorContains": "Invalid match expression operator on encrypted field"
+          }
+        },
+        {
+          "name": "find",
+          "arguments": {
+            "filter": {
+              "unencrypted": {
+                "$eq": null
+              }
+            }
+          },
+          "result": [
+            {
+              "_id": 1,
+              "encrypted_string": "string0"
+            },
+            {
+              "_id": 2,
+              "encrypted_string": "string1"
+            }
+          ]
+        },
+        {
+          "name": "find",
+          "arguments": {
+            "filter": {
+              "encrypted_string": {
+                "$eq": null
+              }
+            }
+          },
+          "result": {
+            "errorContains": "Illegal equality to null predicate for encrypted field"
+          }
+        },
+        {
+          "name": "find",
+          "arguments": {
+            "filter": {
+              "unencrypted": {
+                "$in": [
+                  null
+                ]
+              }
+            }
+          },
+          "result": [
+            {
+              "_id": 1,
+              "encrypted_string": "string0"
+            },
+            {
+              "_id": 2,
+              "encrypted_string": "string1"
+            }
+          ]
+        },
+        {
+          "name": "find",
+          "arguments": {
+            "filter": {
+              "encrypted_string": {
+                "$in": [
+                  null
+                ]
+              }
+            }
+          },
+          "result": {
+            "errorContains": "Illegal equality to null inside $in against an encrypted field"
+          }
+        }
+      ]
+    },
+    {
+      "description": "$addToSet succeeds on unencrypted, error on encrypted",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "kmsProviders": {
+            "aws": {}
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "updateOne",
+          "arguments": {
+            "filter": {},
+            "update": {
+              "$addToSet": {
+                "unencrypted": [
+                  "a"
+                ]
+              }
+            }
+          },
+          "result": {
+            "matchedCount": 1,
+            "modifiedCount": 1,
+            "upsertedCount": 0
+          }
+        },
+        {
+          "name": "updateOne",
+          "arguments": {
+            "filter": {},
+            "update": {
+              "$addToSet": {
+                "encrypted_string": [
+                  "a"
+                ]
+              }
+            }
+          },
+          "result": {
+            "errorContains": "$addToSet not allowed on encrypted values"
+          }
+        }
+      ]
+    },
+    {
+      "description": "$inc succeeds on unencrypted, error on encrypted",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "kmsProviders": {
+            "aws": {}
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "updateOne",
+          "arguments": {
+            "filter": {},
+            "update": {
+              "$inc": {
+                "unencrypted": 1
+              }
+            }
+          },
+          "result": {
+            "matchedCount": 1,
+            "modifiedCount": 1,
+            "upsertedCount": 0
+          }
+        },
+        {
+          "name": "updateOne",
+          "arguments": {
+            "filter": {},
+            "update": {
+              "$inc": {
+                "encrypted_string": 1
+              }
+            }
+          },
+          "result": {
+            "errorContains": "$inc and $mul not allowed on encrypted values"
+          }
+        }
+      ]
+    },
+    {
+      "description": "$mul succeeds on unencrypted, error on encrypted",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "kmsProviders": {
+            "aws": {}
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "updateOne",
+          "arguments": {
+            "filter": {},
+            "update": {
+              "$mul": {
+                "unencrypted": 1
+              }
+            }
+          },
+          "result": {
+            "matchedCount": 1,
+            "modifiedCount": 1,
+            "upsertedCount": 0
+          }
+        },
+        {
+          "name": "updateOne",
+          "arguments": {
+            "filter": {},
+            "update": {
+              "$mul": {
+                "encrypted_string": 1
+              }
+            }
+          },
+          "result": {
+            "errorContains": "$inc and $mul not allowed on encrypted values"
+          }
+        }
+      ]
+    },
+    {
+      "description": "$max succeeds on unencrypted, error on encrypted",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "kmsProviders": {
+            "aws": {}
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "updateOne",
+          "arguments": {
+            "filter": {},
+            "update": {
+              "$max": {
+                "unencrypted": 1
+              }
+            }
+          },
+          "result": {
+            "matchedCount": 1,
+            "modifiedCount": 1,
+            "upsertedCount": 0
+          }
+        },
+        {
+          "name": "updateOne",
+          "arguments": {
+            "filter": {},
+            "update": {
+              "$max": {
+                "encrypted_string": 1
+              }
+            }
+          },
+          "result": {
+            "errorContains": "$max and $min not allowed on encrypted values"
+          }
+        }
+      ]
+    },
+    {
+      "description": "$min succeeds on unencrypted, error on encrypted",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "kmsProviders": {
+            "aws": {}
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "updateOne",
+          "arguments": {
+            "filter": {},
+            "update": {
+              "$min": {
+                "unencrypted": 1
+              }
+            }
+          },
+          "result": {
+            "matchedCount": 1,
+            "modifiedCount": 1,
+            "upsertedCount": 0
+          }
+        },
+        {
+          "name": "updateOne",
+          "arguments": {
+            "filter": {},
+            "update": {
+              "$min": {
+                "encrypted_string": 1
+              }
+            }
+          },
+          "result": {
+            "errorContains": "$max and $min not allowed on encrypted values"
+          }
+        }
+      ]
+    },
+    {
+      "description": "$currentDate succeeds on unencrypted, error on encrypted",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "kmsProviders": {
+            "aws": {}
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "updateOne",
+          "arguments": {
+            "filter": {},
+            "update": {
+              "$currentDate": {
+                "unencrypted": true
+              }
+            }
+          },
+          "result": {
+            "matchedCount": 1,
+            "modifiedCount": 1,
+            "upsertedCount": 0
+          }
+        },
+        {
+          "name": "updateOne",
+          "arguments": {
+            "filter": {},
+            "update": {
+              "$currentDate": {
+                "encrypted_string": true
+              }
+            }
+          },
+          "result": {
+            "errorContains": "$currentDate not allowed on encrypted values"
+          }
+        }
+      ]
+    },
+    {
+      "description": "$pop succeeds on unencrypted, error on encrypted",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "kmsProviders": {
+            "aws": {}
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "updateOne",
+          "arguments": {
+            "filter": {},
+            "update": {
+              "$pop": {
+                "unencrypted": 1
+              }
+            }
+          },
+          "result": {
+            "matchedCount": 1,
+            "modifiedCount": 0,
+            "upsertedCount": 0
+          }
+        },
+        {
+          "name": "updateOne",
+          "arguments": {
+            "filter": {},
+            "update": {
+              "$pop": {
+                "encrypted_string": 1
+              }
+            }
+          },
+          "result": {
+            "errorContains": "$pop not allowed on encrypted values"
+          }
+        }
+      ]
+    },
+    {
+      "description": "$pull succeeds on unencrypted, error on encrypted",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "kmsProviders": {
+            "aws": {}
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "updateOne",
+          "arguments": {
+            "filter": {},
+            "update": {
+              "$pull": {
+                "unencrypted": 1
+              }
+            }
+          },
+          "result": {
+            "matchedCount": 1,
+            "modifiedCount": 0,
+            "upsertedCount": 0
+          }
+        },
+        {
+          "name": "updateOne",
+          "arguments": {
+            "filter": {},
+            "update": {
+              "$pull": {
+                "encrypted_string": 1
+              }
+            }
+          },
+          "result": {
+            "errorContains": "$pull not allowed on encrypted values"
+          }
+        }
+      ]
+    },
+    {
+      "description": "$pullAll succeeds on unencrypted, error on encrypted",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "kmsProviders": {
+            "aws": {}
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "updateOne",
+          "arguments": {
+            "filter": {},
+            "update": {
+              "$pullAll": {
+                "unencrypted": [
+                  1
+                ]
+              }
+            }
+          },
+          "result": {
+            "matchedCount": 1,
+            "modifiedCount": 0,
+            "upsertedCount": 0
+          }
+        },
+        {
+          "name": "updateOne",
+          "arguments": {
+            "filter": {},
+            "update": {
+              "$pullAll": {
+                "encrypted_string": [
+                  1
+                ]
+              }
+            }
+          },
+          "result": {
+            "errorContains": "$pullAll not allowed on encrypted values"
+          }
+        }
+      ]
+    },
+    {
+      "description": "$push succeeds on unencrypted, error on encrypted",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "kmsProviders": {
+            "aws": {}
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "updateOne",
+          "arguments": {
+            "filter": {},
+            "update": {
+              "$push": {
+                "unencrypted": 1
+              }
+            }
+          },
+          "result": {
+            "matchedCount": 1,
+            "modifiedCount": 1,
+            "upsertedCount": 0
+          }
+        },
+        {
+          "name": "updateOne",
+          "arguments": {
+            "filter": {},
+            "update": {
+              "$push": {
+                "encrypted_string": 1
+              }
+            }
+          },
+          "result": {
+            "errorContains": "$push not allowed on encrypted values"
+          }
+        }
+      ]
+    },
+    {
+      "description": "array filters on encrypted fields does not error in mongocryptd, but errors in mongod",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "kmsProviders": {
+            "aws": {}
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "updateOne",
+          "arguments": {
+            "filter": {},
+            "update": {
+              "$set": {
+                "encrypted_string.$[i].x": 1
+              }
+            },
+            "arrayFilters": [
+              {
+                "i.x": 1
+              }
+            ]
+          },
+          "result": {
+            "errorContains": "Array update operations not allowed on encrypted values"
+          }
+        }
+      ]
+    },
+    {
+      "description": "positional operator succeeds on unencrypted, errors on encrypted",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "kmsProviders": {
+            "aws": {}
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "updateOne",
+          "arguments": {
+            "filter": {
+              "unencrypted": 1
+            },
+            "update": {
+              "$set": {
+                "unencrypted.$": 1
+              }
+            }
+          },
+          "result": {
+            "matchedCount": 0,
+            "modifiedCount": 0,
+            "upsertedCount": 0
+          }
+        },
+        {
+          "name": "updateOne",
+          "arguments": {
+            "filter": {
+              "encrypted_string": "abc"
+            },
+            "update": {
+              "$set": {
+                "encrypted_string.$": "abc"
+              }
+            }
+          },
+          "result": {
+            "errorContains": "Cannot encrypt fields below '$' positional update operator"
+          }
+        }
+      ]
+    },
+    {
+      "description": "an update that would produce an array on an encrypted field errors",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "kmsProviders": {
+            "aws": {}
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "updateOne",
+          "arguments": {
+            "filter": {},
+            "update": {
+              "$set": {
+                "encrypted_string": [
+                  1,
+                  2
+                ]
+              }
+            }
+          },
+          "result": {
+            "errorContains": "Cannot encrypt element of type array"
+          }
+        }
+      ]
+    },
+    {
+      "description": "an insert with encrypted field on _id errors",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "kmsProviders": {
+            "aws": {}
+          },
+          "schemaMap": {
+            "default.default": {
+              "properties": {
+                "_id": {
+                  "encrypt": {
+                    "keyId": [
+                      {
+                        "$binary": {
+                          "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                          "subType": "04"
+                        }
+                      }
+                    ],
+                    "bsonType": "string",
+                    "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+                  }
+                }
+              }
+            }
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "insertOne",
+          "arguments": {
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "errorContains": "Invalid schema containing the 'encrypt' keyword."
+          }
+        }
+      ]
+    },
+    {
+      "description": "an insert with an array value for an encrypted field fails",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "kmsProviders": {
+            "aws": {}
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "insertOne",
+          "arguments": {
+            "document": {
+              "encrypted_string": [
+                "123",
+                "456"
+              ]
+            }
+          },
+          "result": {
+            "errorContains": "Cannot encrypt element of type array"
+          }
+        }
+      ]
+    },
+    {
+      "description": "an insert with a Timestamp(0,0) value in the top-level fails",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "kmsProviders": {
+            "aws": {}
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "insertOne",
+          "arguments": {
+            "document": {
+              "random": {
+                "$timestamp": {
+                  "t": 0,
+                  "i": 0
+                }
+              }
+            }
+          },
+          "result": {
+            "errorContains": "A command that inserts cannot supply Timestamp(0, 0) for an encrypted"
+          }
+        }
+      ]
+    },
+    {
+      "description": "distinct with the key referring to a field where the keyID is a JSON Pointer errors",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "kmsProviders": {
+            "aws": {}
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "distinct",
+          "arguments": {
+            "filter": {},
+            "fieldName": "encrypted_w_altname"
+          },
+          "result": {
+            "errorContains": "The distinct key is not allowed to be marked for encryption with a non-UUID keyId"
+          }
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/tests/badSchema.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/tests/badSchema.json
new file mode 100644
index 0000000000000000000000000000000000000000..1fd0f8ed3f991bc67b28fff2009ec200d6effe6e
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/tests/badSchema.json	
@@ -0,0 +1,254 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.1.10"
+    }
+  ],
+  "database_name": "default",
+  "collection_name": "default",
+  "data": [],
+  "key_vault_data": [
+    {
+      "status": 1,
+      "_id": {
+        "$binary": {
+          "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+          "subType": "04"
+        }
+      },
+      "masterKey": {
+        "provider": "aws",
+        "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0",
+        "region": "us-east-1"
+      },
+      "updateDate": {
+        "$date": {
+          "$numberLong": "1552949630483"
+        }
+      },
+      "keyMaterial": {
+        "$binary": {
+          "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO",
+          "subType": "00"
+        }
+      },
+      "creationDate": {
+        "$date": {
+          "$numberLong": "1552949630483"
+        }
+      },
+      "keyAltNames": [
+        "altname",
+        "another_altname"
+      ]
+    }
+  ],
+  "tests": [
+    {
+      "description": "Schema with an encrypted field in an array",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "schemaMap": {
+            "default.default": {
+              "properties": {
+                "encrypted_string": {
+                  "encrypt": {
+                    "keyId": [
+                      {
+                        "$binary": {
+                          "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                          "subType": "04"
+                        }
+                      }
+                    ],
+                    "bsonType": "string",
+                    "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random"
+                  }
+                }
+              },
+              "bsonType": "array"
+            }
+          },
+          "kmsProviders": {
+            "aws": {}
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "insertOne",
+          "arguments": {
+            "document": {
+              "_id": 1,
+              "encrypted_string": "string0"
+            }
+          },
+          "result": {
+            "errorContains": "Invalid schema"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": []
+        }
+      }
+    },
+    {
+      "description": "Schema without specifying parent object types",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "schemaMap": {
+            "default.default": {
+              "properties": {
+                "foo": {
+                  "properties": {
+                    "bar": {
+                      "encrypt": {
+                        "keyId": [
+                          {
+                            "$binary": {
+                              "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                              "subType": "04"
+                            }
+                          }
+                        ],
+                        "bsonType": "string",
+                        "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random"
+                      }
+                    }
+                  }
+                }
+              }
+            }
+          },
+          "kmsProviders": {
+            "aws": {}
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "insertOne",
+          "arguments": {
+            "document": {
+              "_id": 1,
+              "encrypted_string": "string0"
+            }
+          },
+          "result": {
+            "errorContains": "Invalid schema"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": []
+        }
+      }
+    },
+    {
+      "description": "Schema with siblings of encrypt document",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "schemaMap": {
+            "default.default": {
+              "properties": {
+                "encrypted_string": {
+                  "encrypt": {
+                    "keyId": [
+                      {
+                        "$binary": {
+                          "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                          "subType": "04"
+                        }
+                      }
+                    ],
+                    "bsonType": "string",
+                    "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random"
+                  },
+                  "bsonType": "object"
+                }
+              }
+            }
+          },
+          "kmsProviders": {
+            "aws": {}
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "insertOne",
+          "arguments": {
+            "document": {
+              "_id": 1,
+              "encrypted_string": "string0"
+            }
+          },
+          "result": {
+            "errorContains": "'encrypt' cannot be used in conjunction with 'bsonType'"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": []
+        }
+      }
+    },
+    {
+      "description": "Schema with logical keywords",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "schemaMap": {
+            "default.default": {
+              "anyOf": [
+                {
+                  "properties": {
+                    "encrypted_string": {
+                      "encrypt": {
+                        "keyId": [
+                          {
+                            "$binary": {
+                              "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                              "subType": "04"
+                            }
+                          }
+                        ],
+                        "bsonType": "string",
+                        "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random"
+                      }
+                    }
+                  }
+                }
+              ]
+            }
+          },
+          "kmsProviders": {
+            "aws": {}
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "insertOne",
+          "arguments": {
+            "document": {
+              "_id": 1,
+              "encrypted_string": "string0"
+            }
+          },
+          "result": {
+            "errorContains": "Invalid schema"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": []
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/tests/basic.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/tests/basic.json
new file mode 100644
index 0000000000000000000000000000000000000000..3f9895fd5dbc73f28139b83dc55766864a9a18c0
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/tests/basic.json	
@@ -0,0 +1,374 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.1.10"
+    }
+  ],
+  "database_name": "default",
+  "collection_name": "default",
+  "data": [],
+  "json_schema": {
+    "properties": {
+      "encrypted_w_altname": {
+        "encrypt": {
+          "keyId": "/altname",
+          "bsonType": "string",
+          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random"
+        }
+      },
+      "encrypted_string": {
+        "encrypt": {
+          "keyId": [
+            {
+              "$binary": {
+                "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                "subType": "04"
+              }
+            }
+          ],
+          "bsonType": "string",
+          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+        }
+      },
+      "random": {
+        "encrypt": {
+          "keyId": [
+            {
+              "$binary": {
+                "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                "subType": "04"
+              }
+            }
+          ],
+          "bsonType": "string",
+          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random"
+        }
+      },
+      "encrypted_string_equivalent": {
+        "encrypt": {
+          "keyId": [
+            {
+              "$binary": {
+                "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                "subType": "04"
+              }
+            }
+          ],
+          "bsonType": "string",
+          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+        }
+      }
+    },
+    "bsonType": "object"
+  },
+  "key_vault_data": [
+    {
+      "status": 1,
+      "_id": {
+        "$binary": {
+          "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+          "subType": "04"
+        }
+      },
+      "masterKey": {
+        "provider": "aws",
+        "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0",
+        "region": "us-east-1"
+      },
+      "updateDate": {
+        "$date": {
+          "$numberLong": "1552949630483"
+        }
+      },
+      "keyMaterial": {
+        "$binary": {
+          "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO",
+          "subType": "00"
+        }
+      },
+      "creationDate": {
+        "$date": {
+          "$numberLong": "1552949630483"
+        }
+      },
+      "keyAltNames": [
+        "altname",
+        "another_altname"
+      ]
+    }
+  ],
+  "tests": [
+    {
+      "description": "Insert with deterministic encryption, then find it",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "kmsProviders": {
+            "aws": {}
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "insertOne",
+          "arguments": {
+            "document": {
+              "_id": 1,
+              "encrypted_string": "string0"
+            }
+          }
+        },
+        {
+          "name": "find",
+          "arguments": {
+            "filter": {
+              "_id": 1
+            }
+          },
+          "result": [
+            {
+              "_id": 1,
+              "encrypted_string": "string0"
+            }
+          ]
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1,
+              "filter": {
+                "name": "default"
+              }
+            },
+            "command_name": "listCollections"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1,
+              "filter": {
+                "name": "datakeys"
+              },
+              "$db": "keyvault"
+            },
+            "command_name": "listCollections"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "datakeys",
+              "filter": {
+                "$or": [
+                  {
+                    "_id": {
+                      "$in": [
+                        {
+                          "$binary": {
+                            "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                          }
+                        }
+                      ]
+                    }
+                  },
+                  {
+                    "keyAltNames": {
+                      "$in": []
+                    }
+                  }
+                ]
+              },
+              "$db": "keyvault",
+              "readConcern": {
+                "level": "majority"
+              }
+            },
+            "command_name": "find"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "default",
+              "documents": [
+                {
+                  "_id": 1,
+                  "encrypted_string": {
+                    "$binary": {
+                      "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==",
+                      "subType": "06"
+                    }
+                  }
+                }
+              ],
+              "ordered": true
+            },
+            "command_name": "insert"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "default",
+              "filter": {
+                "_id": 1
+              }
+            },
+            "command_name": "find"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "encrypted_string": {
+                "$binary": {
+                  "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==",
+                  "subType": "06"
+                }
+              }
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "Insert with randomized encryption, then find it",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "kmsProviders": {
+            "aws": {}
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "insertOne",
+          "arguments": {
+            "document": {
+              "_id": 1,
+              "random": "123"
+            }
+          }
+        },
+        {
+          "name": "find",
+          "arguments": {
+            "filter": {
+              "_id": 1
+            }
+          },
+          "result": [
+            {
+              "_id": 1,
+              "random": "123"
+            }
+          ]
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1,
+              "filter": {
+                "name": "default"
+              }
+            },
+            "command_name": "listCollections"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1,
+              "filter": {
+                "name": "datakeys"
+              },
+              "$db": "keyvault"
+            },
+            "command_name": "listCollections"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "datakeys",
+              "filter": {
+                "$or": [
+                  {
+                    "_id": {
+                      "$in": [
+                        {
+                          "$binary": {
+                            "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                          }
+                        }
+                      ]
+                    }
+                  },
+                  {
+                    "keyAltNames": {
+                      "$in": []
+                    }
+                  }
+                ]
+              },
+              "$db": "keyvault",
+              "readConcern": {
+                "level": "majority"
+              }
+            },
+            "command_name": "find"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "default",
+              "documents": [
+                {
+                  "_id": 1,
+                  "random": {
+                    "$$type": "binData"
+                  }
+                }
+              ],
+              "ordered": true
+            },
+            "command_name": "insert"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "default",
+              "filter": {
+                "_id": 1
+              }
+            },
+            "command_name": "find"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "random": {
+                "$$type": "binData"
+              }
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/tests/bulk.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/tests/bulk.json
new file mode 100644
index 0000000000000000000000000000000000000000..ead90985a1611daee63f29a2669e878d2f5132ac
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/tests/bulk.json	
@@ -0,0 +1,345 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.1.10"
+    }
+  ],
+  "database_name": "default",
+  "collection_name": "default",
+  "data": [],
+  "json_schema": {
+    "properties": {
+      "encrypted_w_altname": {
+        "encrypt": {
+          "keyId": "/altname",
+          "bsonType": "string",
+          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random"
+        }
+      },
+      "encrypted_string": {
+        "encrypt": {
+          "keyId": [
+            {
+              "$binary": {
+                "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                "subType": "04"
+              }
+            }
+          ],
+          "bsonType": "string",
+          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+        }
+      },
+      "random": {
+        "encrypt": {
+          "keyId": [
+            {
+              "$binary": {
+                "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                "subType": "04"
+              }
+            }
+          ],
+          "bsonType": "string",
+          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random"
+        }
+      },
+      "encrypted_string_equivalent": {
+        "encrypt": {
+          "keyId": [
+            {
+              "$binary": {
+                "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                "subType": "04"
+              }
+            }
+          ],
+          "bsonType": "string",
+          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+        }
+      }
+    },
+    "bsonType": "object"
+  },
+  "key_vault_data": [
+    {
+      "status": 1,
+      "_id": {
+        "$binary": {
+          "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+          "subType": "04"
+        }
+      },
+      "masterKey": {
+        "provider": "aws",
+        "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0",
+        "region": "us-east-1"
+      },
+      "updateDate": {
+        "$date": {
+          "$numberLong": "1552949630483"
+        }
+      },
+      "keyMaterial": {
+        "$binary": {
+          "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO",
+          "subType": "00"
+        }
+      },
+      "creationDate": {
+        "$date": {
+          "$numberLong": "1552949630483"
+        }
+      },
+      "keyAltNames": [
+        "altname",
+        "another_altname"
+      ]
+    }
+  ],
+  "tests": [
+    {
+      "description": "Bulk write with encryption",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "kmsProviders": {
+            "aws": {}
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "bulkWrite",
+          "arguments": {
+            "requests": [
+              {
+                "name": "insertOne",
+                "arguments": {
+                  "document": {
+                    "_id": 1,
+                    "encrypted_string": "string0",
+                    "random": "abc"
+                  }
+                }
+              },
+              {
+                "name": "insertOne",
+                "arguments": {
+                  "document": {
+                    "_id": 2,
+                    "encrypted_string": "string1"
+                  }
+                }
+              },
+              {
+                "name": "updateOne",
+                "arguments": {
+                  "filter": {
+                    "encrypted_string": "string0"
+                  },
+                  "update": {
+                    "$set": {
+                      "encrypted_string": "string1"
+                    }
+                  }
+                }
+              },
+              {
+                "name": "deleteOne",
+                "arguments": {
+                  "filter": {
+                    "$and": [
+                      {
+                        "encrypted_string": "string1"
+                      },
+                      {
+                        "_id": 2
+                      }
+                    ]
+                  }
+                }
+              }
+            ],
+            "options": {
+              "ordered": true
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1,
+              "filter": {
+                "name": "default"
+              }
+            },
+            "command_name": "listCollections"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1,
+              "filter": {
+                "name": "datakeys"
+              },
+              "$db": "keyvault"
+            },
+            "command_name": "listCollections"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "datakeys",
+              "filter": {
+                "$or": [
+                  {
+                    "_id": {
+                      "$in": [
+                        {
+                          "$binary": {
+                            "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                          }
+                        }
+                      ]
+                    }
+                  },
+                  {
+                    "keyAltNames": {
+                      "$in": []
+                    }
+                  }
+                ]
+              },
+              "$db": "keyvault",
+              "readConcern": {
+                "level": "majority"
+              }
+            },
+            "command_name": "find"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "default",
+              "documents": [
+                {
+                  "_id": 1,
+                  "encrypted_string": {
+                    "$binary": {
+                      "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==",
+                      "subType": "06"
+                    }
+                  },
+                  "random": {
+                    "$$type": "binData"
+                  }
+                },
+                {
+                  "_id": 2,
+                  "encrypted_string": {
+                    "$binary": {
+                      "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==",
+                      "subType": "06"
+                    }
+                  }
+                }
+              ],
+              "ordered": true
+            },
+            "command_name": "insert"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "update": "default",
+              "updates": [
+                {
+                  "q": {
+                    "encrypted_string": {
+                      "$eq": {
+                        "$binary": {
+                          "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==",
+                          "subType": "06"
+                        }
+                      }
+                    }
+                  },
+                  "u": {
+                    "$set": {
+                      "encrypted_string": {
+                        "$binary": {
+                          "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==",
+                          "subType": "06"
+                        }
+                      }
+                    }
+                  }
+                }
+              ],
+              "ordered": true
+            },
+            "command_name": "update"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "delete": "default",
+              "deletes": [
+                {
+                  "q": {
+                    "$and": [
+                      {
+                        "encrypted_string": {
+                          "$eq": {
+                            "$binary": {
+                              "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==",
+                              "subType": "06"
+                            }
+                          }
+                        }
+                      },
+                      {
+                        "_id": {
+                          "$eq": 2
+                        }
+                      }
+                    ]
+                  },
+                  "limit": 1
+                }
+              ],
+              "ordered": true
+            },
+            "command_name": "delete"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "encrypted_string": {
+                "$binary": {
+                  "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==",
+                  "subType": "06"
+                }
+              },
+              "random": {
+                "$$type": "binData"
+              }
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/tests/bypassAutoEncryption.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/tests/bypassAutoEncryption.json
new file mode 100644
index 0000000000000000000000000000000000000000..9d09cb3fa9243299cfe0d99d833ef621da0c1a55
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/tests/bypassAutoEncryption.json	
@@ -0,0 +1,402 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.1.10"
+    }
+  ],
+  "database_name": "default",
+  "collection_name": "default",
+  "data": [
+    {
+      "_id": 1,
+      "encrypted_string": {
+        "$binary": {
+          "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==",
+          "subType": "06"
+        }
+      }
+    }
+  ],
+  "json_schema": {
+    "properties": {
+      "encrypted_w_altname": {
+        "encrypt": {
+          "keyId": "/altname",
+          "bsonType": "string",
+          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random"
+        }
+      },
+      "encrypted_string": {
+        "encrypt": {
+          "keyId": [
+            {
+              "$binary": {
+                "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                "subType": "04"
+              }
+            }
+          ],
+          "bsonType": "string",
+          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+        }
+      },
+      "random": {
+        "encrypt": {
+          "keyId": [
+            {
+              "$binary": {
+                "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                "subType": "04"
+              }
+            }
+          ],
+          "bsonType": "string",
+          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random"
+        }
+      },
+      "encrypted_string_equivalent": {
+        "encrypt": {
+          "keyId": [
+            {
+              "$binary": {
+                "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                "subType": "04"
+              }
+            }
+          ],
+          "bsonType": "string",
+          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+        }
+      }
+    },
+    "bsonType": "object"
+  },
+  "key_vault_data": [
+    {
+      "status": 1,
+      "_id": {
+        "$binary": {
+          "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+          "subType": "04"
+        }
+      },
+      "masterKey": {
+        "provider": "aws",
+        "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0",
+        "region": "us-east-1"
+      },
+      "updateDate": {
+        "$date": {
+          "$numberLong": "1552949630483"
+        }
+      },
+      "keyMaterial": {
+        "$binary": {
+          "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO",
+          "subType": "00"
+        }
+      },
+      "creationDate": {
+        "$date": {
+          "$numberLong": "1552949630483"
+        }
+      },
+      "keyAltNames": [
+        "altname",
+        "another_altname"
+      ]
+    }
+  ],
+  "tests": [
+    {
+      "description": "Insert with bypassAutoEncryption",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "bypassAutoEncryption": true,
+          "kmsProviders": {
+            "aws": {}
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "insertOne",
+          "arguments": {
+            "document": {
+              "_id": 2,
+              "encrypted_string": "string0"
+            },
+            "bypassDocumentValidation": true
+          }
+        },
+        {
+          "name": "find",
+          "arguments": {
+            "filter": {}
+          },
+          "result": [
+            {
+              "_id": 1,
+              "encrypted_string": "string0"
+            },
+            {
+              "_id": 2,
+              "encrypted_string": "string0"
+            }
+          ]
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "default",
+              "documents": [
+                {
+                  "_id": 2,
+                  "encrypted_string": "string0"
+                }
+              ],
+              "ordered": true
+            },
+            "command_name": "insert"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "default",
+              "filter": {}
+            },
+            "command_name": "find"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "datakeys",
+              "filter": {
+                "$or": [
+                  {
+                    "_id": {
+                      "$in": [
+                        {
+                          "$binary": {
+                            "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                          }
+                        }
+                      ]
+                    }
+                  },
+                  {
+                    "keyAltNames": {
+                      "$in": []
+                    }
+                  }
+                ]
+              },
+              "$db": "keyvault",
+              "readConcern": {
+                "level": "majority"
+              }
+            },
+            "command_name": "find"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "encrypted_string": {
+                "$binary": {
+                  "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==",
+                  "subType": "06"
+                }
+              }
+            },
+            {
+              "_id": 2,
+              "encrypted_string": "string0"
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "Insert with bypassAutoEncryption for local schema",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "schemaMap": {
+            "default.default": {
+              "properties": {
+                "encrypted_w_altname": {
+                  "encrypt": {
+                    "keyId": "/altname",
+                    "bsonType": "string",
+                    "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random"
+                  }
+                },
+                "encrypted_string": {
+                  "encrypt": {
+                    "keyId": [
+                      {
+                        "$binary": {
+                          "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                          "subType": "04"
+                        }
+                      }
+                    ],
+                    "bsonType": "string",
+                    "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+                  }
+                },
+                "random": {
+                  "encrypt": {
+                    "keyId": [
+                      {
+                        "$binary": {
+                          "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                          "subType": "04"
+                        }
+                      }
+                    ],
+                    "bsonType": "string",
+                    "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random"
+                  }
+                },
+                "encrypted_string_equivalent": {
+                  "encrypt": {
+                    "keyId": [
+                      {
+                        "$binary": {
+                          "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                          "subType": "04"
+                        }
+                      }
+                    ],
+                    "bsonType": "string",
+                    "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+                  }
+                }
+              },
+              "bsonType": "object"
+            }
+          },
+          "bypassAutoEncryption": true,
+          "kmsProviders": {
+            "aws": {}
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "insertOne",
+          "arguments": {
+            "document": {
+              "_id": 2,
+              "encrypted_string": "string0"
+            },
+            "bypassDocumentValidation": true
+          }
+        },
+        {
+          "name": "find",
+          "arguments": {
+            "filter": {}
+          },
+          "result": [
+            {
+              "_id": 1,
+              "encrypted_string": "string0"
+            },
+            {
+              "_id": 2,
+              "encrypted_string": "string0"
+            }
+          ]
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "default",
+              "documents": [
+                {
+                  "_id": 2,
+                  "encrypted_string": "string0"
+                }
+              ],
+              "ordered": true
+            },
+            "command_name": "insert"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "default",
+              "filter": {}
+            },
+            "command_name": "find"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "datakeys",
+              "filter": {
+                "$or": [
+                  {
+                    "_id": {
+                      "$in": [
+                        {
+                          "$binary": {
+                            "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                          }
+                        }
+                      ]
+                    }
+                  },
+                  {
+                    "keyAltNames": {
+                      "$in": []
+                    }
+                  }
+                ]
+              },
+              "$db": "keyvault",
+              "readConcern": {
+                "level": "majority"
+              }
+            },
+            "command_name": "find"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "encrypted_string": {
+                "$binary": {
+                  "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==",
+                  "subType": "06"
+                }
+              }
+            },
+            {
+              "_id": 2,
+              "encrypted_string": "string0"
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/tests/bypassedCommand.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/tests/bypassedCommand.json
new file mode 100644
index 0000000000000000000000000000000000000000..bd0b1c565d7db25829c7378433bdf17f2b9aa260
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/tests/bypassedCommand.json	
@@ -0,0 +1,106 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.1.10"
+    }
+  ],
+  "database_name": "default",
+  "collection_name": "default",
+  "data": [],
+  "json_schema": {},
+  "key_vault_data": [
+    {
+      "status": 1,
+      "_id": {
+        "$binary": {
+          "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+          "subType": "04"
+        }
+      },
+      "masterKey": {
+        "provider": "aws",
+        "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0",
+        "region": "us-east-1"
+      },
+      "updateDate": {
+        "$date": {
+          "$numberLong": "1552949630483"
+        }
+      },
+      "keyMaterial": {
+        "$binary": {
+          "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO",
+          "subType": "00"
+        }
+      },
+      "creationDate": {
+        "$date": {
+          "$numberLong": "1552949630483"
+        }
+      },
+      "keyAltNames": [
+        "altname",
+        "another_altname"
+      ]
+    }
+  ],
+  "tests": [
+    {
+      "description": "ping is bypassed",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "kmsProviders": {
+            "aws": {}
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "runCommand",
+          "object": "database",
+          "command_name": "ping",
+          "arguments": {
+            "command": {
+              "ping": 1
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "ping": 1
+            },
+            "command_name": "ping"
+          }
+        }
+      ]
+    },
+    {
+      "description": "current op is not bypassed",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "kmsProviders": {
+            "aws": {}
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "runCommand",
+          "object": "database",
+          "command_name": "currentOp",
+          "arguments": {
+            "command": {
+              "currentOp": 1
+            }
+          },
+          "result": {
+            "errorContains": "command not supported for auto encryption: currentOp"
+          }
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/tests/count.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/tests/count.json
new file mode 100644
index 0000000000000000000000000000000000000000..24f46a110a7530dc70afe5065bad78c107da9539
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/tests/count.json	
@@ -0,0 +1,241 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.1.10"
+    }
+  ],
+  "database_name": "default",
+  "collection_name": "default",
+  "data": [
+    {
+      "_id": 1,
+      "encrypted_string": {
+        "$binary": {
+          "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==",
+          "subType": "06"
+        }
+      }
+    },
+    {
+      "_id": 2,
+      "encrypted_string": {
+        "$binary": {
+          "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==",
+          "subType": "06"
+        }
+      }
+    }
+  ],
+  "json_schema": {
+    "properties": {
+      "encrypted_w_altname": {
+        "encrypt": {
+          "keyId": "/altname",
+          "bsonType": "string",
+          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random"
+        }
+      },
+      "encrypted_string": {
+        "encrypt": {
+          "keyId": [
+            {
+              "$binary": {
+                "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                "subType": "04"
+              }
+            }
+          ],
+          "bsonType": "string",
+          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+        }
+      },
+      "random": {
+        "encrypt": {
+          "keyId": [
+            {
+              "$binary": {
+                "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                "subType": "04"
+              }
+            }
+          ],
+          "bsonType": "string",
+          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random"
+        }
+      },
+      "encrypted_string_equivalent": {
+        "encrypt": {
+          "keyId": [
+            {
+              "$binary": {
+                "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                "subType": "04"
+              }
+            }
+          ],
+          "bsonType": "string",
+          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+        }
+      }
+    },
+    "bsonType": "object"
+  },
+  "key_vault_data": [
+    {
+      "status": 1,
+      "_id": {
+        "$binary": {
+          "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+          "subType": "04"
+        }
+      },
+      "masterKey": {
+        "provider": "aws",
+        "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0",
+        "region": "us-east-1"
+      },
+      "updateDate": {
+        "$date": {
+          "$numberLong": "1552949630483"
+        }
+      },
+      "keyMaterial": {
+        "$binary": {
+          "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO",
+          "subType": "00"
+        }
+      },
+      "creationDate": {
+        "$date": {
+          "$numberLong": "1552949630483"
+        }
+      },
+      "keyAltNames": [
+        "altname",
+        "another_altname"
+      ]
+    }
+  ],
+  "tests": [
+    {
+      "description": "Count with deterministic encryption",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "kmsProviders": {
+            "aws": {}
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "count",
+          "arguments": {
+            "filter": {
+              "encrypted_string": "string0"
+            }
+          },
+          "result": 2
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1,
+              "filter": {
+                "name": "default"
+              }
+            },
+            "command_name": "listCollections"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1,
+              "filter": {
+                "name": "datakeys"
+              },
+              "$db": "keyvault"
+            },
+            "command_name": "listCollections"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "datakeys",
+              "filter": {
+                "$or": [
+                  {
+                    "_id": {
+                      "$in": [
+                        {
+                          "$binary": {
+                            "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                          }
+                        }
+                      ]
+                    }
+                  },
+                  {
+                    "keyAltNames": {
+                      "$in": []
+                    }
+                  }
+                ]
+              },
+              "$db": "keyvault",
+              "readConcern": {
+                "level": "majority"
+              }
+            },
+            "command_name": "find"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "count": "default",
+              "query": {
+                "encrypted_string": {
+                  "$eq": {
+                    "$binary": {
+                      "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==",
+                      "subType": "06"
+                    }
+                  }
+                }
+              }
+            },
+            "command_name": "count"
+          }
+        }
+      ]
+    },
+    {
+      "description": "Count fails when filtering on a random encrypted field",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "kmsProviders": {
+            "aws": {}
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "count",
+          "arguments": {
+            "filter": {
+              "random": "abc"
+            }
+          },
+          "result": {
+            "errorContains": "Cannot query on fields encrypted with the randomized encryption"
+          }
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/tests/countDocuments.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/tests/countDocuments.json
new file mode 100644
index 0000000000000000000000000000000000000000..3cf5fbca8b6bf9865446987d959f2d450c1e8dda
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/tests/countDocuments.json	
@@ -0,0 +1,253 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.1.10"
+    }
+  ],
+  "database_name": "default",
+  "collection_name": "default",
+  "data": [
+    {
+      "_id": 1,
+      "encrypted_string": {
+        "$binary": {
+          "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==",
+          "subType": "06"
+        }
+      }
+    },
+    {
+      "_id": 2,
+      "encrypted_string": {
+        "$binary": {
+          "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==",
+          "subType": "06"
+        }
+      }
+    }
+  ],
+  "json_schema": {
+    "properties": {
+      "encrypted_w_altname": {
+        "encrypt": {
+          "keyId": "/altname",
+          "bsonType": "string",
+          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random"
+        }
+      },
+      "encrypted_string": {
+        "encrypt": {
+          "keyId": [
+            {
+              "$binary": {
+                "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                "subType": "04"
+              }
+            }
+          ],
+          "bsonType": "string",
+          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+        }
+      },
+      "random": {
+        "encrypt": {
+          "keyId": [
+            {
+              "$binary": {
+                "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                "subType": "04"
+              }
+            }
+          ],
+          "bsonType": "string",
+          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random"
+        }
+      },
+      "encrypted_string_equivalent": {
+        "encrypt": {
+          "keyId": [
+            {
+              "$binary": {
+                "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                "subType": "04"
+              }
+            }
+          ],
+          "bsonType": "string",
+          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+        }
+      }
+    },
+    "bsonType": "object"
+  },
+  "key_vault_data": [
+    {
+      "status": 1,
+      "_id": {
+        "$binary": {
+          "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+          "subType": "04"
+        }
+      },
+      "masterKey": {
+        "provider": "aws",
+        "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0",
+        "region": "us-east-1"
+      },
+      "updateDate": {
+        "$date": {
+          "$numberLong": "1552949630483"
+        }
+      },
+      "keyMaterial": {
+        "$binary": {
+          "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO",
+          "subType": "00"
+        }
+      },
+      "creationDate": {
+        "$date": {
+          "$numberLong": "1552949630483"
+        }
+      },
+      "keyAltNames": [
+        "altname",
+        "another_altname"
+      ]
+    }
+  ],
+  "tests": [
+    {
+      "description": "countDocuments with deterministic encryption",
+      "skipReason": "waiting on SERVER-39395",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "kmsProviders": {
+            "aws": {}
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "countDocuments",
+          "arguments": {
+            "filter": {
+              "encrypted_string": "string0"
+            }
+          },
+          "result": 1
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1,
+              "filter": {
+                "name": "default"
+              }
+            },
+            "command_name": "listCollections"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1,
+              "filter": {
+                "name": "datakeys"
+              },
+              "$db": "keyvault"
+            },
+            "command_name": "listCollections"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "datakeys",
+              "filter": {
+                "$or": [
+                  {
+                    "_id": {
+                      "$in": [
+                        {
+                          "$binary": {
+                            "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                          }
+                        }
+                      ]
+                    }
+                  },
+                  {
+                    "keyAltNames": {
+                      "$in": []
+                    }
+                  }
+                ]
+              },
+              "$db": "keyvault",
+              "readConcern": {
+                "level": "majority"
+              }
+            },
+            "command_name": "find"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "default",
+              "pipeline": [
+                {
+                  "$match": {
+                    "encrypted_string": {
+                      "$binary": {
+                        "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==",
+                        "subType": "06"
+                      }
+                    }
+                  }
+                },
+                {
+                  "$group": {
+                    "_id": 1,
+                    "n": {
+                      "$sum": 1
+                    }
+                  }
+                }
+              ]
+            },
+            "command_name": "aggregate"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "encrypted_string": {
+                "$binary": {
+                  "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==",
+                  "subType": "06"
+                }
+              }
+            },
+            {
+              "_id": 2,
+              "encrypted_string": {
+                "$binary": {
+                  "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==",
+                  "subType": "06"
+                }
+              }
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/tests/delete.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/tests/delete.json
new file mode 100644
index 0000000000000000000000000000000000000000..30fb453a9364a0f03c929235a07ae0c5db03e5a9
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/tests/delete.json	
@@ -0,0 +1,364 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.1.10"
+    }
+  ],
+  "database_name": "default",
+  "collection_name": "default",
+  "data": [
+    {
+      "_id": 1,
+      "encrypted_string": {
+        "$binary": {
+          "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==",
+          "subType": "06"
+        }
+      }
+    },
+    {
+      "_id": 2,
+      "encrypted_string": {
+        "$binary": {
+          "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==",
+          "subType": "06"
+        }
+      }
+    }
+  ],
+  "json_schema": {
+    "properties": {
+      "encrypted_w_altname": {
+        "encrypt": {
+          "keyId": "/altname",
+          "bsonType": "string",
+          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random"
+        }
+      },
+      "encrypted_string": {
+        "encrypt": {
+          "keyId": [
+            {
+              "$binary": {
+                "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                "subType": "04"
+              }
+            }
+          ],
+          "bsonType": "string",
+          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+        }
+      },
+      "random": {
+        "encrypt": {
+          "keyId": [
+            {
+              "$binary": {
+                "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                "subType": "04"
+              }
+            }
+          ],
+          "bsonType": "string",
+          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random"
+        }
+      },
+      "encrypted_string_equivalent": {
+        "encrypt": {
+          "keyId": [
+            {
+              "$binary": {
+                "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                "subType": "04"
+              }
+            }
+          ],
+          "bsonType": "string",
+          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+        }
+      }
+    },
+    "bsonType": "object"
+  },
+  "key_vault_data": [
+    {
+      "status": 1,
+      "_id": {
+        "$binary": {
+          "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+          "subType": "04"
+        }
+      },
+      "masterKey": {
+        "provider": "aws",
+        "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0",
+        "region": "us-east-1"
+      },
+      "updateDate": {
+        "$date": {
+          "$numberLong": "1552949630483"
+        }
+      },
+      "keyMaterial": {
+        "$binary": {
+          "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO",
+          "subType": "00"
+        }
+      },
+      "creationDate": {
+        "$date": {
+          "$numberLong": "1552949630483"
+        }
+      },
+      "keyAltNames": [
+        "altname",
+        "another_altname"
+      ]
+    }
+  ],
+  "tests": [
+    {
+      "description": "deleteOne with deterministic encryption",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "kmsProviders": {
+            "aws": {}
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "deleteOne",
+          "arguments": {
+            "filter": {
+              "encrypted_string": "string0"
+            }
+          },
+          "result": {
+            "deletedCount": 1
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1,
+              "filter": {
+                "name": "default"
+              }
+            },
+            "command_name": "listCollections"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1,
+              "filter": {
+                "name": "datakeys"
+              },
+              "$db": "keyvault"
+            },
+            "command_name": "listCollections"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "datakeys",
+              "filter": {
+                "$or": [
+                  {
+                    "_id": {
+                      "$in": [
+                        {
+                          "$binary": {
+                            "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                          }
+                        }
+                      ]
+                    }
+                  },
+                  {
+                    "keyAltNames": {
+                      "$in": []
+                    }
+                  }
+                ]
+              },
+              "$db": "keyvault",
+              "readConcern": {
+                "level": "majority"
+              }
+            },
+            "command_name": "find"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "delete": "default",
+              "deletes": [
+                {
+                  "q": {
+                    "encrypted_string": {
+                      "$eq": {
+                        "$binary": {
+                          "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==",
+                          "subType": "06"
+                        }
+                      }
+                    }
+                  },
+                  "limit": 1
+                }
+              ],
+              "ordered": true
+            },
+            "command_name": "delete"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 2,
+              "encrypted_string": {
+                "$binary": {
+                  "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==",
+                  "subType": "06"
+                }
+              }
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "deleteMany with deterministic encryption",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "kmsProviders": {
+            "aws": {}
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "deleteMany",
+          "arguments": {
+            "filter": {
+              "encrypted_string": {
+                "$in": [
+                  "string0",
+                  "string1"
+                ]
+              }
+            }
+          },
+          "result": {
+            "deletedCount": 2
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1,
+              "filter": {
+                "name": "default"
+              }
+            },
+            "command_name": "listCollections"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1,
+              "filter": {
+                "name": "datakeys"
+              },
+              "$db": "keyvault"
+            },
+            "command_name": "listCollections"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "datakeys",
+              "filter": {
+                "$or": [
+                  {
+                    "_id": {
+                      "$in": [
+                        {
+                          "$binary": {
+                            "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                          }
+                        }
+                      ]
+                    }
+                  },
+                  {
+                    "keyAltNames": {
+                      "$in": []
+                    }
+                  }
+                ]
+              },
+              "$db": "keyvault",
+              "readConcern": {
+                "level": "majority"
+              }
+            },
+            "command_name": "find"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "delete": "default",
+              "deletes": [
+                {
+                  "q": {
+                    "encrypted_string": {
+                      "$in": [
+                        {
+                          "$binary": {
+                            "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==",
+                            "subType": "06"
+                          }
+                        },
+                        {
+                          "$binary": {
+                            "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==",
+                            "subType": "06"
+                          }
+                        }
+                      ]
+                    }
+                  },
+                  "limit": 0
+                }
+              ],
+              "ordered": true
+            },
+            "command_name": "delete"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": []
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/tests/distinct.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/tests/distinct.json
new file mode 100644
index 0000000000000000000000000000000000000000..7a5f75c4a51905e4596723d9d3e93149d29bcd48
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/tests/distinct.json	
@@ -0,0 +1,288 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.1.10"
+    }
+  ],
+  "database_name": "default",
+  "collection_name": "default",
+  "data": [
+    {
+      "_id": 1,
+      "encrypted_string": {
+        "$binary": {
+          "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==",
+          "subType": "06"
+        }
+      }
+    },
+    {
+      "_id": 2,
+      "encrypted_string": {
+        "$binary": {
+          "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==",
+          "subType": "06"
+        }
+      }
+    },
+    {
+      "_id": 3,
+      "encrypted_string": {
+        "$binary": {
+          "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==",
+          "subType": "06"
+        }
+      }
+    }
+  ],
+  "json_schema": {
+    "properties": {
+      "encrypted_w_altname": {
+        "encrypt": {
+          "keyId": "/altname",
+          "bsonType": "string",
+          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random"
+        }
+      },
+      "encrypted_string": {
+        "encrypt": {
+          "keyId": [
+            {
+              "$binary": {
+                "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                "subType": "04"
+              }
+            }
+          ],
+          "bsonType": "string",
+          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+        }
+      },
+      "random": {
+        "encrypt": {
+          "keyId": [
+            {
+              "$binary": {
+                "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                "subType": "04"
+              }
+            }
+          ],
+          "bsonType": "string",
+          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random"
+        }
+      },
+      "encrypted_string_equivalent": {
+        "encrypt": {
+          "keyId": [
+            {
+              "$binary": {
+                "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                "subType": "04"
+              }
+            }
+          ],
+          "bsonType": "string",
+          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+        }
+      }
+    },
+    "bsonType": "object"
+  },
+  "key_vault_data": [
+    {
+      "status": 1,
+      "_id": {
+        "$binary": {
+          "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+          "subType": "04"
+        }
+      },
+      "masterKey": {
+        "provider": "aws",
+        "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0",
+        "region": "us-east-1"
+      },
+      "updateDate": {
+        "$date": {
+          "$numberLong": "1552949630483"
+        }
+      },
+      "keyMaterial": {
+        "$binary": {
+          "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO",
+          "subType": "00"
+        }
+      },
+      "creationDate": {
+        "$date": {
+          "$numberLong": "1552949630483"
+        }
+      },
+      "keyAltNames": [
+        "altname",
+        "another_altname"
+      ]
+    }
+  ],
+  "tests": [
+    {
+      "description": "distinct with deterministic encryption",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "kmsProviders": {
+            "aws": {}
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "distinct",
+          "arguments": {
+            "filter": {
+              "encrypted_string": "string0"
+            },
+            "fieldName": "encrypted_string"
+          },
+          "result": [
+            "string0"
+          ]
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1,
+              "filter": {
+                "name": "default"
+              }
+            },
+            "command_name": "listCollections"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1,
+              "filter": {
+                "name": "datakeys"
+              },
+              "$db": "keyvault"
+            },
+            "command_name": "listCollections"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "datakeys",
+              "filter": {
+                "$or": [
+                  {
+                    "_id": {
+                      "$in": [
+                        {
+                          "$binary": {
+                            "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                          }
+                        }
+                      ]
+                    }
+                  },
+                  {
+                    "keyAltNames": {
+                      "$in": []
+                    }
+                  }
+                ]
+              },
+              "$db": "keyvault",
+              "readConcern": {
+                "level": "majority"
+              }
+            },
+            "command_name": "find"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "distinct": "default",
+              "key": "encrypted_string",
+              "query": {
+                "encrypted_string": {
+                  "$eq": {
+                    "$binary": {
+                      "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==",
+                      "subType": "06"
+                    }
+                  }
+                }
+              }
+            },
+            "command_name": "distinct"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "encrypted_string": {
+                "$binary": {
+                  "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==",
+                  "subType": "06"
+                }
+              }
+            },
+            {
+              "_id": 2,
+              "encrypted_string": {
+                "$binary": {
+                  "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==",
+                  "subType": "06"
+                }
+              }
+            },
+            {
+              "_id": 3,
+              "encrypted_string": {
+                "$binary": {
+                  "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==",
+                  "subType": "06"
+                }
+              }
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "Distinct fails when filtering on a random encrypted field",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "kmsProviders": {
+            "aws": {}
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "distinct",
+          "arguments": {
+            "filter": {
+              "random": "abc"
+            },
+            "fieldName": "encrypted_string"
+          },
+          "result": {
+            "errorContains": "Cannot query on fields encrypted with the randomized encryption"
+          }
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/tests/explain.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/tests/explain.json
new file mode 100644
index 0000000000000000000000000000000000000000..5ad46bc238beb05c2f4cbc3b7c7b8c5605b07785
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/tests/explain.json	
@@ -0,0 +1,251 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.1.10"
+    }
+  ],
+  "database_name": "default",
+  "collection_name": "default",
+  "data": [
+    {
+      "_id": 1,
+      "encrypted_string": {
+        "$binary": {
+          "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==",
+          "subType": "06"
+        }
+      }
+    },
+    {
+      "_id": 2,
+      "encrypted_string": {
+        "$binary": {
+          "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==",
+          "subType": "06"
+        }
+      }
+    }
+  ],
+  "json_schema": {
+    "properties": {
+      "encrypted_w_altname": {
+        "encrypt": {
+          "keyId": "/altname",
+          "bsonType": "string",
+          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random"
+        }
+      },
+      "encrypted_string": {
+        "encrypt": {
+          "keyId": [
+            {
+              "$binary": {
+                "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                "subType": "04"
+              }
+            }
+          ],
+          "bsonType": "string",
+          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+        }
+      },
+      "random": {
+        "encrypt": {
+          "keyId": [
+            {
+              "$binary": {
+                "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                "subType": "04"
+              }
+            }
+          ],
+          "bsonType": "string",
+          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random"
+        }
+      },
+      "encrypted_string_equivalent": {
+        "encrypt": {
+          "keyId": [
+            {
+              "$binary": {
+                "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                "subType": "04"
+              }
+            }
+          ],
+          "bsonType": "string",
+          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+        }
+      }
+    },
+    "bsonType": "object"
+  },
+  "key_vault_data": [
+    {
+      "status": 1,
+      "_id": {
+        "$binary": {
+          "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+          "subType": "04"
+        }
+      },
+      "masterKey": {
+        "provider": "aws",
+        "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0",
+        "region": "us-east-1"
+      },
+      "updateDate": {
+        "$date": {
+          "$numberLong": "1552949630483"
+        }
+      },
+      "keyMaterial": {
+        "$binary": {
+          "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO",
+          "subType": "00"
+        }
+      },
+      "creationDate": {
+        "$date": {
+          "$numberLong": "1552949630483"
+        }
+      },
+      "keyAltNames": [
+        "altname",
+        "another_altname"
+      ]
+    }
+  ],
+  "tests": [
+    {
+      "description": "Explain a find with deterministic encryption",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "kmsProviders": {
+            "aws": {}
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "runCommand",
+          "object": "database",
+          "command_name": "explain",
+          "arguments": {
+            "command": {
+              "explain": {
+                "find": "default",
+                "filter": {
+                  "encrypted_string": "string1"
+                }
+              }
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1,
+              "filter": {
+                "name": "default"
+              }
+            },
+            "command_name": "listCollections"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1,
+              "filter": {
+                "name": "datakeys"
+              },
+              "$db": "keyvault"
+            },
+            "command_name": "listCollections"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "datakeys",
+              "filter": {
+                "$or": [
+                  {
+                    "_id": {
+                      "$in": [
+                        {
+                          "$binary": {
+                            "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                          }
+                        }
+                      ]
+                    }
+                  },
+                  {
+                    "keyAltNames": {
+                      "$in": []
+                    }
+                  }
+                ]
+              },
+              "$db": "keyvault",
+              "readConcern": {
+                "level": "majority"
+              }
+            },
+            "command_name": "find"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "explain": {
+                "find": "default",
+                "filter": {
+                  "encrypted_string": {
+                    "$eq": {
+                      "$binary": {
+                        "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==",
+                        "subType": "06"
+                      }
+                    }
+                  }
+                }
+              },
+              "verbosity": "allPlansExecution"
+            },
+            "command_name": "explain"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "encrypted_string": {
+                "$binary": {
+                  "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==",
+                  "subType": "06"
+                }
+              }
+            },
+            {
+              "_id": 2,
+              "encrypted_string": {
+                "$binary": {
+                  "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==",
+                  "subType": "06"
+                }
+              }
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/tests/find.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/tests/find.json
new file mode 100644
index 0000000000000000000000000000000000000000..b7c5258a13c9624f2e5e40fa696a459e7dcd277f
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/tests/find.json	
@@ -0,0 +1,432 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.1.10"
+    }
+  ],
+  "database_name": "default",
+  "collection_name": "default",
+  "data": [
+    {
+      "_id": 1,
+      "encrypted_string": {
+        "$binary": {
+          "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==",
+          "subType": "06"
+        }
+      }
+    },
+    {
+      "_id": 2,
+      "encrypted_string": {
+        "$binary": {
+          "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==",
+          "subType": "06"
+        }
+      },
+      "random": {
+        "$binary": {
+          "base64": "AgAAAAAAAAAAAAAAAAAAAAACyfp+lXvKOi7f5vh6ZsCijLEaXFKq1X06RmyS98ZvmMQGixTw8HM1f/bGxZjGwvYwjXOkIEb7Exgb8p2KCDI5TQ==",
+          "subType": "06"
+        }
+      }
+    }
+  ],
+  "json_schema": {
+    "properties": {
+      "encrypted_w_altname": {
+        "encrypt": {
+          "keyId": "/altname",
+          "bsonType": "string",
+          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random"
+        }
+      },
+      "encrypted_string": {
+        "encrypt": {
+          "keyId": [
+            {
+              "$binary": {
+                "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                "subType": "04"
+              }
+            }
+          ],
+          "bsonType": "string",
+          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+        }
+      },
+      "random": {
+        "encrypt": {
+          "keyId": [
+            {
+              "$binary": {
+                "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                "subType": "04"
+              }
+            }
+          ],
+          "bsonType": "string",
+          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random"
+        }
+      },
+      "encrypted_string_equivalent": {
+        "encrypt": {
+          "keyId": [
+            {
+              "$binary": {
+                "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                "subType": "04"
+              }
+            }
+          ],
+          "bsonType": "string",
+          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+        }
+      }
+    },
+    "bsonType": "object"
+  },
+  "key_vault_data": [
+    {
+      "status": 1,
+      "_id": {
+        "$binary": {
+          "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+          "subType": "04"
+        }
+      },
+      "masterKey": {
+        "provider": "aws",
+        "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0",
+        "region": "us-east-1"
+      },
+      "updateDate": {
+        "$date": {
+          "$numberLong": "1552949630483"
+        }
+      },
+      "keyMaterial": {
+        "$binary": {
+          "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO",
+          "subType": "00"
+        }
+      },
+      "creationDate": {
+        "$date": {
+          "$numberLong": "1552949630483"
+        }
+      },
+      "keyAltNames": [
+        "altname",
+        "another_altname"
+      ]
+    }
+  ],
+  "tests": [
+    {
+      "description": "Find with deterministic encryption",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "kmsProviders": {
+            "aws": {}
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "find",
+          "arguments": {
+            "filter": {
+              "encrypted_string": "string0"
+            }
+          },
+          "result": [
+            {
+              "_id": 1,
+              "encrypted_string": "string0"
+            }
+          ]
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1,
+              "filter": {
+                "name": "default"
+              }
+            },
+            "command_name": "listCollections"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1,
+              "filter": {
+                "name": "datakeys"
+              },
+              "$db": "keyvault"
+            },
+            "command_name": "listCollections"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "datakeys",
+              "filter": {
+                "$or": [
+                  {
+                    "_id": {
+                      "$in": [
+                        {
+                          "$binary": {
+                            "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                          }
+                        }
+                      ]
+                    }
+                  },
+                  {
+                    "keyAltNames": {
+                      "$in": []
+                    }
+                  }
+                ]
+              },
+              "$db": "keyvault",
+              "readConcern": {
+                "level": "majority"
+              }
+            },
+            "command_name": "find"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "default",
+              "filter": {
+                "encrypted_string": {
+                  "$eq": {
+                    "$binary": {
+                      "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==",
+                      "subType": "06"
+                    }
+                  }
+                }
+              }
+            },
+            "command_name": "find"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "encrypted_string": {
+                "$binary": {
+                  "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==",
+                  "subType": "06"
+                }
+              }
+            },
+            {
+              "_id": 2,
+              "encrypted_string": {
+                "$binary": {
+                  "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==",
+                  "subType": "06"
+                }
+              },
+              "random": {
+                "$binary": {
+                  "base64": "AgAAAAAAAAAAAAAAAAAAAAACyfp+lXvKOi7f5vh6ZsCijLEaXFKq1X06RmyS98ZvmMQGixTw8HM1f/bGxZjGwvYwjXOkIEb7Exgb8p2KCDI5TQ==",
+                  "subType": "06"
+                }
+              }
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "Find with $in with deterministic encryption",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "kmsProviders": {
+            "aws": {}
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "find",
+          "arguments": {
+            "filter": {
+              "encrypted_string": {
+                "$in": [
+                  "string0",
+                  "string1"
+                ]
+              }
+            }
+          },
+          "result": [
+            {
+              "_id": 1,
+              "encrypted_string": "string0"
+            },
+            {
+              "_id": 2,
+              "encrypted_string": "string1",
+              "random": "abc"
+            }
+          ]
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1,
+              "filter": {
+                "name": "default"
+              }
+            },
+            "command_name": "listCollections"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1,
+              "filter": {
+                "name": "datakeys"
+              },
+              "$db": "keyvault"
+            },
+            "command_name": "listCollections"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "datakeys",
+              "filter": {
+                "$or": [
+                  {
+                    "_id": {
+                      "$in": [
+                        {
+                          "$binary": {
+                            "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                          }
+                        }
+                      ]
+                    }
+                  },
+                  {
+                    "keyAltNames": {
+                      "$in": []
+                    }
+                  }
+                ]
+              },
+              "$db": "keyvault",
+              "readConcern": {
+                "level": "majority"
+              }
+            },
+            "command_name": "find"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "default",
+              "filter": {
+                "encrypted_string": {
+                  "$in": [
+                    {
+                      "$binary": {
+                        "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==",
+                        "subType": "06"
+                      }
+                    },
+                    {
+                      "$binary": {
+                        "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==",
+                        "subType": "06"
+                      }
+                    }
+                  ]
+                }
+              }
+            },
+            "command_name": "find"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "encrypted_string": {
+                "$binary": {
+                  "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==",
+                  "subType": "06"
+                }
+              }
+            },
+            {
+              "_id": 2,
+              "encrypted_string": {
+                "$binary": {
+                  "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==",
+                  "subType": "06"
+                }
+              },
+              "random": {
+                "$binary": {
+                  "base64": "AgAAAAAAAAAAAAAAAAAAAAACyfp+lXvKOi7f5vh6ZsCijLEaXFKq1X06RmyS98ZvmMQGixTw8HM1f/bGxZjGwvYwjXOkIEb7Exgb8p2KCDI5TQ==",
+                  "subType": "06"
+                }
+              }
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "Find fails when filtering on a random encrypted field",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "kmsProviders": {
+            "aws": {}
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "find",
+          "arguments": {
+            "filter": {
+              "random": "abc"
+            }
+          },
+          "result": {
+            "errorContains": "Cannot query on fields encrypted with the randomized encryption"
+          }
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/tests/findOneAndDelete.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/tests/findOneAndDelete.json
new file mode 100644
index 0000000000000000000000000000000000000000..6261d8601bafe1344af9c2f0d2777b9e46d8d9f4
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/tests/findOneAndDelete.json	
@@ -0,0 +1,233 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.1.10"
+    }
+  ],
+  "database_name": "default",
+  "collection_name": "default",
+  "data": [
+    {
+      "_id": 1,
+      "encrypted_string": {
+        "$binary": {
+          "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==",
+          "subType": "06"
+        }
+      }
+    },
+    {
+      "_id": 2,
+      "encrypted_string": {
+        "$binary": {
+          "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==",
+          "subType": "06"
+        }
+      }
+    }
+  ],
+  "json_schema": {
+    "properties": {
+      "encrypted_w_altname": {
+        "encrypt": {
+          "keyId": "/altname",
+          "bsonType": "string",
+          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random"
+        }
+      },
+      "encrypted_string": {
+        "encrypt": {
+          "keyId": [
+            {
+              "$binary": {
+                "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                "subType": "04"
+              }
+            }
+          ],
+          "bsonType": "string",
+          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+        }
+      },
+      "random": {
+        "encrypt": {
+          "keyId": [
+            {
+              "$binary": {
+                "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                "subType": "04"
+              }
+            }
+          ],
+          "bsonType": "string",
+          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random"
+        }
+      },
+      "encrypted_string_equivalent": {
+        "encrypt": {
+          "keyId": [
+            {
+              "$binary": {
+                "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                "subType": "04"
+              }
+            }
+          ],
+          "bsonType": "string",
+          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+        }
+      }
+    },
+    "bsonType": "object"
+  },
+  "key_vault_data": [
+    {
+      "status": 1,
+      "_id": {
+        "$binary": {
+          "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+          "subType": "04"
+        }
+      },
+      "masterKey": {
+        "provider": "aws",
+        "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0",
+        "region": "us-east-1"
+      },
+      "updateDate": {
+        "$date": {
+          "$numberLong": "1552949630483"
+        }
+      },
+      "keyMaterial": {
+        "$binary": {
+          "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO",
+          "subType": "00"
+        }
+      },
+      "creationDate": {
+        "$date": {
+          "$numberLong": "1552949630483"
+        }
+      },
+      "keyAltNames": [
+        "altname",
+        "another_altname"
+      ]
+    }
+  ],
+  "tests": [
+    {
+      "description": "findOneAndDelete with deterministic encryption",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "kmsProviders": {
+            "aws": {}
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "findOneAndDelete",
+          "arguments": {
+            "filter": {
+              "encrypted_string": "string0"
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1,
+              "filter": {
+                "name": "default"
+              }
+            },
+            "command_name": "listCollections"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1,
+              "filter": {
+                "name": "datakeys"
+              },
+              "$db": "keyvault"
+            },
+            "command_name": "listCollections"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "datakeys",
+              "filter": {
+                "$or": [
+                  {
+                    "_id": {
+                      "$in": [
+                        {
+                          "$binary": {
+                            "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                          }
+                        }
+                      ]
+                    }
+                  },
+                  {
+                    "keyAltNames": {
+                      "$in": []
+                    }
+                  }
+                ]
+              },
+              "$db": "keyvault",
+              "readConcern": {
+                "level": "majority"
+              }
+            },
+            "command_name": "find"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "findAndModify": "default",
+              "query": {
+                "encrypted_string": {
+                  "$eq": {
+                    "$binary": {
+                      "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==",
+                      "subType": "06"
+                    }
+                  }
+                }
+              },
+              "remove": true
+            },
+            "command_name": "findAndModify"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 2,
+              "encrypted_string": {
+                "$binary": {
+                  "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==",
+                  "subType": "06"
+                }
+              }
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/tests/findOneAndReplace.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/tests/findOneAndReplace.json
new file mode 100644
index 0000000000000000000000000000000000000000..d91bc059980782054b0bde568246978694e8f997
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/tests/findOneAndReplace.json	
@@ -0,0 +1,239 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.1.10"
+    }
+  ],
+  "database_name": "default",
+  "collection_name": "default",
+  "data": [
+    {
+      "_id": 1,
+      "encrypted_string": {
+        "$binary": {
+          "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==",
+          "subType": "06"
+        }
+      }
+    }
+  ],
+  "json_schema": {
+    "properties": {
+      "encrypted_w_altname": {
+        "encrypt": {
+          "keyId": "/altname",
+          "bsonType": "string",
+          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random"
+        }
+      },
+      "encrypted_string": {
+        "encrypt": {
+          "keyId": [
+            {
+              "$binary": {
+                "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                "subType": "04"
+              }
+            }
+          ],
+          "bsonType": "string",
+          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+        }
+      },
+      "random": {
+        "encrypt": {
+          "keyId": [
+            {
+              "$binary": {
+                "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                "subType": "04"
+              }
+            }
+          ],
+          "bsonType": "string",
+          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random"
+        }
+      },
+      "encrypted_string_equivalent": {
+        "encrypt": {
+          "keyId": [
+            {
+              "$binary": {
+                "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                "subType": "04"
+              }
+            }
+          ],
+          "bsonType": "string",
+          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+        }
+      }
+    },
+    "bsonType": "object"
+  },
+  "key_vault_data": [
+    {
+      "status": 1,
+      "_id": {
+        "$binary": {
+          "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+          "subType": "04"
+        }
+      },
+      "masterKey": {
+        "provider": "aws",
+        "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0",
+        "region": "us-east-1"
+      },
+      "updateDate": {
+        "$date": {
+          "$numberLong": "1552949630483"
+        }
+      },
+      "keyMaterial": {
+        "$binary": {
+          "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO",
+          "subType": "00"
+        }
+      },
+      "creationDate": {
+        "$date": {
+          "$numberLong": "1552949630483"
+        }
+      },
+      "keyAltNames": [
+        "altname",
+        "another_altname"
+      ]
+    }
+  ],
+  "tests": [
+    {
+      "description": "findOneAndReplace with deterministic encryption",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "kmsProviders": {
+            "aws": {}
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "findOneAndReplace",
+          "arguments": {
+            "filter": {
+              "encrypted_string": "string0"
+            },
+            "replacement": {
+              "encrypted_string": "string1"
+            },
+            "returnDocument": "Before"
+          },
+          "result": {
+            "_id": 1,
+            "encrypted_string": "string0"
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1,
+              "filter": {
+                "name": "default"
+              }
+            },
+            "command_name": "listCollections"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1,
+              "filter": {
+                "name": "datakeys"
+              },
+              "$db": "keyvault"
+            },
+            "command_name": "listCollections"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "datakeys",
+              "filter": {
+                "$or": [
+                  {
+                    "_id": {
+                      "$in": [
+                        {
+                          "$binary": {
+                            "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                          }
+                        }
+                      ]
+                    }
+                  },
+                  {
+                    "keyAltNames": {
+                      "$in": []
+                    }
+                  }
+                ]
+              },
+              "$db": "keyvault",
+              "readConcern": {
+                "level": "majority"
+              }
+            },
+            "command_name": "find"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "findAndModify": "default",
+              "query": {
+                "encrypted_string": {
+                  "$eq": {
+                    "$binary": {
+                      "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==",
+                      "subType": "06"
+                    }
+                  }
+                }
+              },
+              "update": {
+                "encrypted_string": {
+                  "$binary": {
+                    "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==",
+                    "subType": "06"
+                  }
+                }
+              }
+            },
+            "command_name": "findAndModify"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "encrypted_string": {
+                "$binary": {
+                  "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==",
+                  "subType": "06"
+                }
+              }
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/tests/findOneAndUpdate.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/tests/findOneAndUpdate.json
new file mode 100644
index 0000000000000000000000000000000000000000..fad70609ad7d8faf140ac505deb4068b9a70f0e8
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/tests/findOneAndUpdate.json	
@@ -0,0 +1,243 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.1.10"
+    }
+  ],
+  "database_name": "default",
+  "collection_name": "default",
+  "data": [
+    {
+      "_id": 1,
+      "encrypted_string": {
+        "$binary": {
+          "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==",
+          "subType": "06"
+        }
+      }
+    }
+  ],
+  "json_schema": {
+    "properties": {
+      "encrypted_w_altname": {
+        "encrypt": {
+          "keyId": "/altname",
+          "bsonType": "string",
+          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random"
+        }
+      },
+      "encrypted_string": {
+        "encrypt": {
+          "keyId": [
+            {
+              "$binary": {
+                "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                "subType": "04"
+              }
+            }
+          ],
+          "bsonType": "string",
+          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+        }
+      },
+      "random": {
+        "encrypt": {
+          "keyId": [
+            {
+              "$binary": {
+                "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                "subType": "04"
+              }
+            }
+          ],
+          "bsonType": "string",
+          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random"
+        }
+      },
+      "encrypted_string_equivalent": {
+        "encrypt": {
+          "keyId": [
+            {
+              "$binary": {
+                "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                "subType": "04"
+              }
+            }
+          ],
+          "bsonType": "string",
+          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+        }
+      }
+    },
+    "bsonType": "object"
+  },
+  "key_vault_data": [
+    {
+      "status": 1,
+      "_id": {
+        "$binary": {
+          "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+          "subType": "04"
+        }
+      },
+      "masterKey": {
+        "provider": "aws",
+        "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0",
+        "region": "us-east-1"
+      },
+      "updateDate": {
+        "$date": {
+          "$numberLong": "1552949630483"
+        }
+      },
+      "keyMaterial": {
+        "$binary": {
+          "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO",
+          "subType": "00"
+        }
+      },
+      "creationDate": {
+        "$date": {
+          "$numberLong": "1552949630483"
+        }
+      },
+      "keyAltNames": [
+        "altname",
+        "another_altname"
+      ]
+    }
+  ],
+  "tests": [
+    {
+      "description": "findOneAndUpdate with deterministic encryption",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "kmsProviders": {
+            "aws": {}
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "findOneAndUpdate",
+          "arguments": {
+            "filter": {
+              "encrypted_string": "string0"
+            },
+            "update": {
+              "$set": {
+                "encrypted_string": "string1"
+              }
+            },
+            "returnDocument": "Before"
+          },
+          "result": {
+            "_id": 1,
+            "encrypted_string": "string0"
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1,
+              "filter": {
+                "name": "default"
+              }
+            },
+            "command_name": "listCollections"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1,
+              "filter": {
+                "name": "datakeys"
+              },
+              "$db": "keyvault"
+            },
+            "command_name": "listCollections"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "datakeys",
+              "filter": {
+                "$or": [
+                  {
+                    "_id": {
+                      "$in": [
+                        {
+                          "$binary": {
+                            "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                          }
+                        }
+                      ]
+                    }
+                  },
+                  {
+                    "keyAltNames": {
+                      "$in": []
+                    }
+                  }
+                ]
+              },
+              "$db": "keyvault",
+              "readConcern": {
+                "level": "majority"
+              }
+            },
+            "command_name": "find"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "findAndModify": "default",
+              "query": {
+                "encrypted_string": {
+                  "$eq": {
+                    "$binary": {
+                      "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==",
+                      "subType": "06"
+                    }
+                  }
+                }
+              },
+              "update": {
+                "$set": {
+                  "encrypted_string": {
+                    "$binary": {
+                      "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==",
+                      "subType": "06"
+                    }
+                  }
+                }
+              }
+            },
+            "command_name": "findAndModify"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "encrypted_string": {
+                "$binary": {
+                  "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==",
+                  "subType": "06"
+                }
+              }
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/tests/getMore.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/tests/getMore.json
new file mode 100644
index 0000000000000000000000000000000000000000..cf2344222640e21440bc87b5a0e0752ce08f1984
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/tests/getMore.json	
@@ -0,0 +1,275 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.1.10"
+    }
+  ],
+  "database_name": "default",
+  "collection_name": "default",
+  "data": [
+    {
+      "_id": 1,
+      "encrypted_string": {
+        "$binary": {
+          "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==",
+          "subType": "06"
+        }
+      }
+    },
+    {
+      "_id": 2,
+      "encrypted_string": {
+        "$binary": {
+          "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==",
+          "subType": "06"
+        }
+      }
+    },
+    {
+      "_id": 3,
+      "encrypted_string": {
+        "$binary": {
+          "base64": "AQAAAAAAAAAAAAAAAAAAAAACQ76HWOut3DZtQuV90hp1aaCpZn95vZIaWmn+wrBehcEtcFwyJlBdlyzDzZTWPZCPgiFq72Wvh6Y7VbpU9NAp3A==",
+          "subType": "06"
+        }
+      }
+    }
+  ],
+  "json_schema": {
+    "properties": {
+      "encrypted_w_altname": {
+        "encrypt": {
+          "keyId": "/altname",
+          "bsonType": "string",
+          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random"
+        }
+      },
+      "encrypted_string": {
+        "encrypt": {
+          "keyId": [
+            {
+              "$binary": {
+                "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                "subType": "04"
+              }
+            }
+          ],
+          "bsonType": "string",
+          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+        }
+      },
+      "random": {
+        "encrypt": {
+          "keyId": [
+            {
+              "$binary": {
+                "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                "subType": "04"
+              }
+            }
+          ],
+          "bsonType": "string",
+          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random"
+        }
+      },
+      "encrypted_string_equivalent": {
+        "encrypt": {
+          "keyId": [
+            {
+              "$binary": {
+                "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                "subType": "04"
+              }
+            }
+          ],
+          "bsonType": "string",
+          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+        }
+      }
+    },
+    "bsonType": "object"
+  },
+  "key_vault_data": [
+    {
+      "status": 1,
+      "_id": {
+        "$binary": {
+          "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+          "subType": "04"
+        }
+      },
+      "masterKey": {
+        "provider": "aws",
+        "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0",
+        "region": "us-east-1"
+      },
+      "updateDate": {
+        "$date": {
+          "$numberLong": "1552949630483"
+        }
+      },
+      "keyMaterial": {
+        "$binary": {
+          "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO",
+          "subType": "00"
+        }
+      },
+      "creationDate": {
+        "$date": {
+          "$numberLong": "1552949630483"
+        }
+      },
+      "keyAltNames": [
+        "altname",
+        "another_altname"
+      ]
+    }
+  ],
+  "tests": [
+    {
+      "description": "getMore with encryption",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "kmsProviders": {
+            "aws": {}
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "find",
+          "arguments": {
+            "batchSize": 2,
+            "filter": {}
+          },
+          "result": [
+            {
+              "_id": 1,
+              "encrypted_string": "string0"
+            },
+            {
+              "_id": 2,
+              "encrypted_string": "string1"
+            },
+            {
+              "_id": 3,
+              "encrypted_string": "string2"
+            }
+          ]
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1,
+              "filter": {
+                "name": "default"
+              }
+            },
+            "command_name": "listCollections"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "default",
+              "batchSize": 2
+            },
+            "command_name": "find"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1,
+              "filter": {
+                "name": "datakeys"
+              },
+              "$db": "keyvault"
+            },
+            "command_name": "listCollections"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "datakeys",
+              "filter": {
+                "$or": [
+                  {
+                    "_id": {
+                      "$in": [
+                        {
+                          "$binary": {
+                            "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                          }
+                        }
+                      ]
+                    }
+                  },
+                  {
+                    "keyAltNames": {
+                      "$in": []
+                    }
+                  }
+                ]
+              },
+              "$db": "keyvault",
+              "readConcern": {
+                "level": "majority"
+              }
+            },
+            "command_name": "find"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "getMore": {
+                "$$type": "long"
+              },
+              "collection": "default",
+              "batchSize": 2
+            },
+            "command_name": "getMore"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "encrypted_string": {
+                "$binary": {
+                  "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==",
+                  "subType": "06"
+                }
+              }
+            },
+            {
+              "_id": 2,
+              "encrypted_string": {
+                "$binary": {
+                  "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==",
+                  "subType": "06"
+                }
+              }
+            },
+            {
+              "_id": 3,
+              "encrypted_string": {
+                "$binary": {
+                  "base64": "AQAAAAAAAAAAAAAAAAAAAAACQ76HWOut3DZtQuV90hp1aaCpZn95vZIaWmn+wrBehcEtcFwyJlBdlyzDzZTWPZCPgiFq72Wvh6Y7VbpU9NAp3A==",
+                  "subType": "06"
+                }
+              }
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/tests/insert.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/tests/insert.json
new file mode 100644
index 0000000000000000000000000000000000000000..78fa8feba0e40c0ce174b8f19bdcb867db9d1b9a
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/tests/insert.json	
@@ -0,0 +1,368 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.1.10"
+    }
+  ],
+  "database_name": "default",
+  "collection_name": "default",
+  "data": [],
+  "json_schema": {
+    "properties": {
+      "encrypted_w_altname": {
+        "encrypt": {
+          "keyId": "/altname",
+          "bsonType": "string",
+          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random"
+        }
+      },
+      "encrypted_string": {
+        "encrypt": {
+          "keyId": [
+            {
+              "$binary": {
+                "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                "subType": "04"
+              }
+            }
+          ],
+          "bsonType": "string",
+          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+        }
+      },
+      "random": {
+        "encrypt": {
+          "keyId": [
+            {
+              "$binary": {
+                "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                "subType": "04"
+              }
+            }
+          ],
+          "bsonType": "string",
+          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random"
+        }
+      },
+      "encrypted_string_equivalent": {
+        "encrypt": {
+          "keyId": [
+            {
+              "$binary": {
+                "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                "subType": "04"
+              }
+            }
+          ],
+          "bsonType": "string",
+          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+        }
+      }
+    },
+    "bsonType": "object"
+  },
+  "key_vault_data": [
+    {
+      "status": 1,
+      "_id": {
+        "$binary": {
+          "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+          "subType": "04"
+        }
+      },
+      "masterKey": {
+        "provider": "aws",
+        "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0",
+        "region": "us-east-1"
+      },
+      "updateDate": {
+        "$date": {
+          "$numberLong": "1552949630483"
+        }
+      },
+      "keyMaterial": {
+        "$binary": {
+          "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO",
+          "subType": "00"
+        }
+      },
+      "creationDate": {
+        "$date": {
+          "$numberLong": "1552949630483"
+        }
+      },
+      "keyAltNames": [
+        "altname",
+        "another_altname"
+      ]
+    }
+  ],
+  "tests": [
+    {
+      "description": "insertOne with encryption",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "kmsProviders": {
+            "aws": {}
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "insertOne",
+          "arguments": {
+            "document": {
+              "_id": 1,
+              "encrypted_string": "string0",
+              "random": "abc"
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1,
+              "filter": {
+                "name": "default"
+              }
+            },
+            "command_name": "listCollections"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1,
+              "filter": {
+                "name": "datakeys"
+              },
+              "$db": "keyvault"
+            },
+            "command_name": "listCollections"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "datakeys",
+              "filter": {
+                "$or": [
+                  {
+                    "_id": {
+                      "$in": [
+                        {
+                          "$binary": {
+                            "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                          }
+                        }
+                      ]
+                    }
+                  },
+                  {
+                    "keyAltNames": {
+                      "$in": []
+                    }
+                  }
+                ]
+              },
+              "$db": "keyvault",
+              "readConcern": {
+                "level": "majority"
+              }
+            },
+            "command_name": "find"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "default",
+              "documents": [
+                {
+                  "_id": 1,
+                  "encrypted_string": {
+                    "$binary": {
+                      "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==",
+                      "subType": "06"
+                    }
+                  },
+                  "random": {
+                    "$$type": "binData"
+                  }
+                }
+              ],
+              "ordered": true
+            },
+            "command_name": "insert"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "encrypted_string": {
+                "$binary": {
+                  "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==",
+                  "subType": "06"
+                }
+              },
+              "random": {
+                "$$type": "binData"
+              }
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "insertMany with encryption",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "kmsProviders": {
+            "aws": {}
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "insertMany",
+          "arguments": {
+            "documents": [
+              {
+                "_id": 1,
+                "encrypted_string": "string0",
+                "random": "abc"
+              },
+              {
+                "_id": 2,
+                "encrypted_string": "string1"
+              }
+            ]
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1,
+              "filter": {
+                "name": "default"
+              }
+            },
+            "command_name": "listCollections"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1,
+              "filter": {
+                "name": "datakeys"
+              },
+              "$db": "keyvault"
+            },
+            "command_name": "listCollections"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "datakeys",
+              "filter": {
+                "$or": [
+                  {
+                    "_id": {
+                      "$in": [
+                        {
+                          "$binary": {
+                            "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                          }
+                        }
+                      ]
+                    }
+                  },
+                  {
+                    "keyAltNames": {
+                      "$in": []
+                    }
+                  }
+                ]
+              },
+              "$db": "keyvault",
+              "readConcern": {
+                "level": "majority"
+              }
+            },
+            "command_name": "find"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "default",
+              "documents": [
+                {
+                  "_id": 1,
+                  "encrypted_string": {
+                    "$binary": {
+                      "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==",
+                      "subType": "06"
+                    }
+                  },
+                  "random": {
+                    "$$type": "binData"
+                  }
+                },
+                {
+                  "_id": 2,
+                  "encrypted_string": {
+                    "$binary": {
+                      "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==",
+                      "subType": "06"
+                    }
+                  }
+                }
+              ],
+              "ordered": true
+            },
+            "command_name": "insert"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "encrypted_string": {
+                "$binary": {
+                  "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==",
+                  "subType": "06"
+                }
+              },
+              "random": {
+                "$$type": "binData"
+              }
+            },
+            {
+              "_id": 2,
+              "encrypted_string": {
+                "$binary": {
+                  "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==",
+                  "subType": "06"
+                }
+              }
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/tests/keyAltName.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/tests/keyAltName.json
new file mode 100644
index 0000000000000000000000000000000000000000..d062bed4537f24b68f07738a71e89a6c3447e8dd
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/tests/keyAltName.json	
@@ -0,0 +1,240 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.1.10"
+    }
+  ],
+  "database_name": "default",
+  "collection_name": "default",
+  "data": [],
+  "json_schema": {
+    "properties": {
+      "encrypted_w_altname": {
+        "encrypt": {
+          "keyId": "/altname",
+          "bsonType": "string",
+          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random"
+        }
+      },
+      "encrypted_string": {
+        "encrypt": {
+          "keyId": [
+            {
+              "$binary": {
+                "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                "subType": "04"
+              }
+            }
+          ],
+          "bsonType": "string",
+          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+        }
+      },
+      "random": {
+        "encrypt": {
+          "keyId": [
+            {
+              "$binary": {
+                "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                "subType": "04"
+              }
+            }
+          ],
+          "bsonType": "string",
+          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random"
+        }
+      },
+      "encrypted_string_equivalent": {
+        "encrypt": {
+          "keyId": [
+            {
+              "$binary": {
+                "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                "subType": "04"
+              }
+            }
+          ],
+          "bsonType": "string",
+          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+        }
+      }
+    },
+    "bsonType": "object"
+  },
+  "key_vault_data": [
+    {
+      "status": 1,
+      "_id": {
+        "$binary": {
+          "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+          "subType": "04"
+        }
+      },
+      "masterKey": {
+        "provider": "aws",
+        "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0",
+        "region": "us-east-1"
+      },
+      "updateDate": {
+        "$date": {
+          "$numberLong": "1552949630483"
+        }
+      },
+      "keyMaterial": {
+        "$binary": {
+          "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO",
+          "subType": "00"
+        }
+      },
+      "creationDate": {
+        "$date": {
+          "$numberLong": "1552949630483"
+        }
+      },
+      "keyAltNames": [
+        "altname",
+        "another_altname"
+      ]
+    }
+  ],
+  "tests": [
+    {
+      "description": "Insert with encryption using key alt name",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "kmsProviders": {
+            "aws": {}
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "insertOne",
+          "arguments": {
+            "document": {
+              "_id": 1,
+              "encrypted_w_altname": "string0",
+              "altname": "altname"
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1,
+              "filter": {
+                "name": "default"
+              }
+            },
+            "command_name": "listCollections"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1,
+              "filter": {
+                "name": "datakeys"
+              },
+              "$db": "keyvault"
+            },
+            "command_name": "listCollections"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "datakeys",
+              "filter": {
+                "$or": [
+                  {
+                    "_id": {
+                      "$in": []
+                    }
+                  },
+                  {
+                    "keyAltNames": {
+                      "$in": [
+                        "altname"
+                      ]
+                    }
+                  }
+                ]
+              },
+              "$db": "keyvault",
+              "readConcern": {
+                "level": "majority"
+              }
+            },
+            "command_name": "find"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "default",
+              "documents": [
+                {
+                  "_id": 1,
+                  "encrypted_w_altname": {
+                    "$$type": "binData"
+                  },
+                  "altname": "altname"
+                }
+              ],
+              "ordered": true
+            },
+            "command_name": "insert"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "encrypted_w_altname": {
+                "$$type": "binData"
+              },
+              "altname": "altname"
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "Replace with key alt name fails",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "kmsProviders": {
+            "aws": {}
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "updateOne",
+          "arguments": {
+            "filter": {},
+            "update": {
+              "$set": {
+                "encrypted_w_altname": "string0"
+              }
+            },
+            "upsert": true
+          },
+          "result": {
+            "errorContains": "A non-static (JSONPointer) keyId is not supported"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": []
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/tests/localKMS.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/tests/localKMS.json
new file mode 100644
index 0000000000000000000000000000000000000000..e4d25309c44a99762947f29f4dca4499bf5b00d7
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/tests/localKMS.json	
@@ -0,0 +1,203 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.1.10"
+    }
+  ],
+  "database_name": "default",
+  "collection_name": "default",
+  "data": [],
+  "json_schema": {
+    "properties": {
+      "encrypted_string": {
+        "encrypt": {
+          "keyId": [
+            {
+              "$binary": {
+                "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                "subType": "04"
+              }
+            }
+          ],
+          "bsonType": "string",
+          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+        }
+      },
+      "random": {
+        "encrypt": {
+          "keyId": [
+            {
+              "$binary": {
+                "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                "subType": "04"
+              }
+            }
+          ],
+          "bsonType": "string",
+          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random"
+        }
+      }
+    },
+    "bsonType": "object"
+  },
+  "key_vault_data": [
+    {
+      "_id": {
+        "$binary": {
+          "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+          "subType": "04"
+        }
+      },
+      "keyMaterial": {
+        "$binary": {
+          "base64": "Ce9HSz/HKKGkIt4uyy+jDuKGA+rLC2cycykMo6vc8jXxqa1UVDYHWq1r+vZKbnnSRBfB981akzRKZCFpC05CTyFqDhXv6OnMjpG97OZEREGIsHEYiJkBW0jJJvfLLgeLsEpBzsro9FztGGXASxyxFRZFhXvHxyiLOKrdWfs7X1O/iK3pEoHMx6uSNSfUOgbebLfIqW7TO++iQS5g1xovXA==",
+          "subType": "00"
+        }
+      },
+      "creationDate": {
+        "$date": {
+          "$numberLong": "1552949630483"
+        }
+      },
+      "updateDate": {
+        "$date": {
+          "$numberLong": "1552949630483"
+        }
+      },
+      "status": {
+        "$numberInt": "0"
+      },
+      "masterKey": {
+        "provider": "local"
+      }
+    }
+  ],
+  "tests": [
+    {
+      "description": "Insert a document with auto encryption using local KMS provider",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "kmsProviders": {
+            "aws": {},
+            "local": {
+              "key": {
+                "$binary": {
+                  "base64": "Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk",
+                  "subType": "00"
+                }
+              }
+            }
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "insertOne",
+          "arguments": {
+            "document": {
+              "_id": 1,
+              "encrypted_string": "string0",
+              "random": "abc"
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1,
+              "filter": {
+                "name": "default"
+              }
+            },
+            "command_name": "listCollections"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1,
+              "filter": {
+                "name": "datakeys"
+              },
+              "$db": "keyvault"
+            },
+            "command_name": "listCollections"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "datakeys",
+              "filter": {
+                "$or": [
+                  {
+                    "_id": {
+                      "$in": [
+                        {
+                          "$binary": {
+                            "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                          }
+                        }
+                      ]
+                    }
+                  },
+                  {
+                    "keyAltNames": {
+                      "$in": []
+                    }
+                  }
+                ]
+              },
+              "$db": "keyvault"
+            },
+            "command_name": "find"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "default",
+              "documents": [
+                {
+                  "_id": 1,
+                  "encrypted_string": {
+                    "$binary": {
+                      "base64": "AQAAAAAAAAAAAAAAAAAAAAACV/+zJmpqMU47yxS/xIVAviGi7wHDuFwaULAixEAoIh0xHz73UYOM3D8D44gcJn67EROjbz4ITpYzzlCJovDL0Q==",
+                      "subType": "06"
+                    }
+                  },
+                  "random": {
+                    "$$type": "binData"
+                  }
+                }
+              ],
+              "ordered": true
+            },
+            "command_name": "insert"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "encrypted_string": {
+                "$binary": {
+                  "base64": "AQAAAAAAAAAAAAAAAAAAAAACV/+zJmpqMU47yxS/xIVAviGi7wHDuFwaULAixEAoIh0xHz73UYOM3D8D44gcJn67EROjbz4ITpYzzlCJovDL0Q==",
+                  "subType": "06"
+                }
+              },
+              "random": {
+                "$$type": "binData"
+              }
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/tests/localSchema.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/tests/localSchema.json
new file mode 100644
index 0000000000000000000000000000000000000000..7071d6fefd19bc854c005c26db34576cdba1ecfe
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/tests/localSchema.json	
@@ -0,0 +1,270 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.1.10"
+    }
+  ],
+  "database_name": "default",
+  "collection_name": "default",
+  "data": [],
+  "json_schema": {},
+  "key_vault_data": [
+    {
+      "status": 1,
+      "_id": {
+        "$binary": {
+          "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+          "subType": "04"
+        }
+      },
+      "masterKey": {
+        "provider": "aws",
+        "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0",
+        "region": "us-east-1"
+      },
+      "updateDate": {
+        "$date": {
+          "$numberLong": "1552949630483"
+        }
+      },
+      "keyMaterial": {
+        "$binary": {
+          "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO",
+          "subType": "00"
+        }
+      },
+      "creationDate": {
+        "$date": {
+          "$numberLong": "1552949630483"
+        }
+      },
+      "keyAltNames": [
+        "altname",
+        "another_altname"
+      ]
+    }
+  ],
+  "tests": [
+    {
+      "description": "A local schema should override",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "schemaMap": {
+            "default.default": {
+              "properties": {
+                "encrypted_w_altname": {
+                  "encrypt": {
+                    "keyId": "/altname",
+                    "bsonType": "string",
+                    "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random"
+                  }
+                },
+                "encrypted_string": {
+                  "encrypt": {
+                    "keyId": [
+                      {
+                        "$binary": {
+                          "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                          "subType": "04"
+                        }
+                      }
+                    ],
+                    "bsonType": "string",
+                    "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+                  }
+                },
+                "random": {
+                  "encrypt": {
+                    "keyId": [
+                      {
+                        "$binary": {
+                          "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                          "subType": "04"
+                        }
+                      }
+                    ],
+                    "bsonType": "string",
+                    "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random"
+                  }
+                },
+                "encrypted_string_equivalent": {
+                  "encrypt": {
+                    "keyId": [
+                      {
+                        "$binary": {
+                          "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                          "subType": "04"
+                        }
+                      }
+                    ],
+                    "bsonType": "string",
+                    "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+                  }
+                }
+              },
+              "bsonType": "object"
+            }
+          },
+          "kmsProviders": {
+            "aws": {}
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "insertOne",
+          "arguments": {
+            "document": {
+              "_id": 1,
+              "encrypted_string": "string0"
+            }
+          }
+        },
+        {
+          "name": "find",
+          "arguments": {
+            "filter": {
+              "_id": 1
+            }
+          },
+          "result": [
+            {
+              "_id": 1,
+              "encrypted_string": "string0"
+            }
+          ]
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1,
+              "filter": {
+                "name": "datakeys"
+              },
+              "$db": "keyvault"
+            },
+            "command_name": "listCollections"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "datakeys",
+              "filter": {
+                "$or": [
+                  {
+                    "_id": {
+                      "$in": [
+                        {
+                          "$binary": {
+                            "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                          }
+                        }
+                      ]
+                    }
+                  },
+                  {
+                    "keyAltNames": {
+                      "$in": []
+                    }
+                  }
+                ]
+              },
+              "$db": "keyvault",
+              "readConcern": {
+                "level": "majority"
+              }
+            },
+            "command_name": "find"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "default",
+              "documents": [
+                {
+                  "_id": 1,
+                  "encrypted_string": {
+                    "$binary": {
+                      "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==",
+                      "subType": "06"
+                    }
+                  }
+                }
+              ],
+              "ordered": true
+            },
+            "command_name": "insert"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "default",
+              "filter": {
+                "_id": 1
+              }
+            },
+            "command_name": "find"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "encrypted_string": {
+                "$binary": {
+                  "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==",
+                  "subType": "06"
+                }
+              }
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "A local schema with no encryption is an error",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "schemaMap": {
+            "default.default": {
+              "properties": {
+                "test": {
+                  "bsonType": "string"
+                }
+              },
+              "bsonType": "object",
+              "required": [
+                "test"
+              ]
+            }
+          },
+          "kmsProviders": {
+            "aws": {}
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "insertOne",
+          "arguments": {
+            "document": {
+              "_id": 1,
+              "encrypted_string": "string0"
+            }
+          },
+          "result": {
+            "errorContains": "JSON schema keyword 'required' is only allowed with a remote schema"
+          }
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/tests/malformedCiphertext.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/tests/malformedCiphertext.json
new file mode 100644
index 0000000000000000000000000000000000000000..c81330ce83338150cf4c96725e5430fc68e7334e
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/tests/malformedCiphertext.json	
@@ -0,0 +1,321 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.1.10"
+    }
+  ],
+  "database_name": "default",
+  "collection_name": "default",
+  "data": [
+    {
+      "_id": 1,
+      "encrypted_string": {
+        "$binary": {
+          "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==",
+          "subType": "00"
+        }
+      }
+    },
+    {
+      "_id": 2,
+      "encrypted_string": {
+        "$binary": {
+          "base64": "AQ==",
+          "subType": "06"
+        }
+      }
+    },
+    {
+      "_id": 3,
+      "encrypted_string": {
+        "$binary": {
+          "base64": "AQAAa2V2aW4gYWxiZXJ0c29uCg==",
+          "subType": "06"
+        }
+      }
+    }
+  ],
+  "key_vault_data": [
+    {
+      "status": 1,
+      "_id": {
+        "$binary": {
+          "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+          "subType": "04"
+        }
+      },
+      "masterKey": {
+        "provider": "aws",
+        "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0",
+        "region": "us-east-1"
+      },
+      "updateDate": {
+        "$date": {
+          "$numberLong": "1552949630483"
+        }
+      },
+      "keyMaterial": {
+        "$binary": {
+          "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO",
+          "subType": "00"
+        }
+      },
+      "creationDate": {
+        "$date": {
+          "$numberLong": "1552949630483"
+        }
+      },
+      "keyAltNames": [
+        "altname",
+        "another_altname"
+      ]
+    }
+  ],
+  "tests": [
+    {
+      "description": "Wrong subtype",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "schemaMap": {
+            "default.default": {
+              "properties": {
+                "encrypted_w_altname": {
+                  "encrypt": {
+                    "keyId": "/altname",
+                    "bsonType": "string",
+                    "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random"
+                  }
+                },
+                "encrypted_string": {
+                  "encrypt": {
+                    "keyId": [
+                      {
+                        "$binary": {
+                          "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                          "subType": "04"
+                        }
+                      }
+                    ],
+                    "bsonType": "string",
+                    "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+                  }
+                },
+                "random": {
+                  "encrypt": {
+                    "keyId": [
+                      {
+                        "$binary": {
+                          "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                          "subType": "04"
+                        }
+                      }
+                    ],
+                    "bsonType": "string",
+                    "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random"
+                  }
+                },
+                "encrypted_string_equivalent": {
+                  "encrypt": {
+                    "keyId": [
+                      {
+                        "$binary": {
+                          "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                          "subType": "04"
+                        }
+                      }
+                    ],
+                    "bsonType": "string",
+                    "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+                  }
+                }
+              },
+              "bsonType": "object"
+            }
+          },
+          "kmsProviders": {
+            "aws": {}
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "find",
+          "arguments": {
+            "filter": {
+              "_id": 1
+            }
+          },
+          "result": [
+            {
+              "_id": 1,
+              "encrypted_string": {
+                "$binary": {
+                  "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==",
+                  "subType": "00"
+                }
+              }
+            }
+          ]
+        }
+      ]
+    },
+    {
+      "description": "Empty data",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "schemaMap": {
+            "default.default": {
+              "properties": {
+                "encrypted_w_altname": {
+                  "encrypt": {
+                    "keyId": "/altname",
+                    "bsonType": "string",
+                    "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random"
+                  }
+                },
+                "encrypted_string": {
+                  "encrypt": {
+                    "keyId": [
+                      {
+                        "$binary": {
+                          "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                          "subType": "04"
+                        }
+                      }
+                    ],
+                    "bsonType": "string",
+                    "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+                  }
+                },
+                "random": {
+                  "encrypt": {
+                    "keyId": [
+                      {
+                        "$binary": {
+                          "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                          "subType": "04"
+                        }
+                      }
+                    ],
+                    "bsonType": "string",
+                    "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random"
+                  }
+                },
+                "encrypted_string_equivalent": {
+                  "encrypt": {
+                    "keyId": [
+                      {
+                        "$binary": {
+                          "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                          "subType": "04"
+                        }
+                      }
+                    ],
+                    "bsonType": "string",
+                    "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+                  }
+                }
+              },
+              "bsonType": "object"
+            }
+          },
+          "kmsProviders": {
+            "aws": {}
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "find",
+          "arguments": {
+            "filter": {
+              "_id": 2
+            }
+          },
+          "result": {
+            "errorContains": "malformed ciphertext"
+          }
+        }
+      ]
+    },
+    {
+      "description": "Malformed data",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "schemaMap": {
+            "default.default": {
+              "properties": {
+                "encrypted_w_altname": {
+                  "encrypt": {
+                    "keyId": "/altname",
+                    "bsonType": "string",
+                    "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random"
+                  }
+                },
+                "encrypted_string": {
+                  "encrypt": {
+                    "keyId": [
+                      {
+                        "$binary": {
+                          "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                          "subType": "04"
+                        }
+                      }
+                    ],
+                    "bsonType": "string",
+                    "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+                  }
+                },
+                "random": {
+                  "encrypt": {
+                    "keyId": [
+                      {
+                        "$binary": {
+                          "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                          "subType": "04"
+                        }
+                      }
+                    ],
+                    "bsonType": "string",
+                    "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random"
+                  }
+                },
+                "encrypted_string_equivalent": {
+                  "encrypt": {
+                    "keyId": [
+                      {
+                        "$binary": {
+                          "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                          "subType": "04"
+                        }
+                      }
+                    ],
+                    "bsonType": "string",
+                    "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+                  }
+                }
+              },
+              "bsonType": "object"
+            }
+          },
+          "kmsProviders": {
+            "aws": {}
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "find",
+          "arguments": {
+            "filter": {
+              "_id": 3
+            }
+          },
+          "result": {
+            "errorContains": "not all keys requested were satisfied"
+          }
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/tests/maxWireVersion.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/tests/maxWireVersion.json
new file mode 100644
index 0000000000000000000000000000000000000000..144786290dcd94e91bd3c3150e7b12ba585ffe22
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/tests/maxWireVersion.json	
@@ -0,0 +1,71 @@
+{
+  "runOn": [
+    {
+      "maxServerVersion": "4.0"
+    }
+  ],
+  "database_name": "default",
+  "collection_name": "default",
+  "data": [],
+  "key_vault_data": [
+    {
+      "status": 1,
+      "_id": {
+        "$binary": {
+          "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+          "subType": "04"
+        }
+      },
+      "masterKey": {
+        "provider": "aws",
+        "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0",
+        "region": "us-east-1"
+      },
+      "updateDate": {
+        "$date": {
+          "$numberLong": "1552949630483"
+        }
+      },
+      "keyMaterial": {
+        "$binary": {
+          "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO",
+          "subType": "00"
+        }
+      },
+      "creationDate": {
+        "$date": {
+          "$numberLong": "1552949630483"
+        }
+      },
+      "keyAltNames": [
+        "altname",
+        "another_altname"
+      ]
+    }
+  ],
+  "tests": [
+    {
+      "description": "operation fails with maxWireVersion < 8",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "kmsProviders": {
+            "aws": {}
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "insertOne",
+          "arguments": {
+            "document": {
+              "encrypted_string": "string0"
+            }
+          },
+          "result": {
+            "errorContains": "Auto-encryption requires a minimum MongoDB version of 4.2"
+          }
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/tests/missingKey.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/tests/missingKey.json
new file mode 100644
index 0000000000000000000000000000000000000000..ac8e8320b0e20f1054684dc0dfcd32a846f5b36b
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/tests/missingKey.json	
@@ -0,0 +1,191 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.1.10"
+    }
+  ],
+  "database_name": "default",
+  "collection_name": "default",
+  "data": [],
+  "json_schema": {
+    "properties": {
+      "encrypted_w_altname": {
+        "encrypt": {
+          "keyId": "/altname",
+          "bsonType": "string",
+          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random"
+        }
+      },
+      "encrypted_string": {
+        "encrypt": {
+          "keyId": [
+            {
+              "$binary": {
+                "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                "subType": "04"
+              }
+            }
+          ],
+          "bsonType": "string",
+          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+        }
+      },
+      "random": {
+        "encrypt": {
+          "keyId": [
+            {
+              "$binary": {
+                "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                "subType": "04"
+              }
+            }
+          ],
+          "bsonType": "string",
+          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random"
+        }
+      },
+      "encrypted_string_equivalent": {
+        "encrypt": {
+          "keyId": [
+            {
+              "$binary": {
+                "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                "subType": "04"
+              }
+            }
+          ],
+          "bsonType": "string",
+          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+        }
+      }
+    },
+    "bsonType": "object"
+  },
+  "key_vault_data": [
+    {
+      "status": 1,
+      "_id": {
+        "$binary": {
+          "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+          "subType": "04"
+        }
+      },
+      "masterKey": {
+        "provider": "aws",
+        "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0",
+        "region": "us-east-1"
+      },
+      "updateDate": {
+        "$date": {
+          "$numberLong": "1552949630483"
+        }
+      },
+      "keyMaterial": {
+        "$binary": {
+          "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO",
+          "subType": "00"
+        }
+      },
+      "creationDate": {
+        "$date": {
+          "$numberLong": "1552949630483"
+        }
+      },
+      "keyAltNames": [
+        "altname",
+        "another_altname"
+      ]
+    }
+  ],
+  "tests": [
+    {
+      "description": "Insert with encryption on a missing key",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "keyVaultNamespace": "keyvault.different",
+          "kmsProviders": {
+            "aws": {}
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "insertOne",
+          "arguments": {
+            "document": {
+              "_id": 1,
+              "encrypted_string": "string0",
+              "random": "abc"
+            }
+          },
+          "result": {
+            "errorContains": "not all keys requested were satisfied"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": []
+        }
+      },
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1,
+              "filter": {
+                "name": "default"
+              }
+            },
+            "command_name": "listCollections"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1,
+              "filter": {
+                "name": "different"
+              },
+              "$db": "keyvault"
+            },
+            "command_name": "listCollections"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "different",
+              "filter": {
+                "$or": [
+                  {
+                    "_id": {
+                      "$in": [
+                        {
+                          "$binary": {
+                            "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                          }
+                        }
+                      ]
+                    }
+                  },
+                  {
+                    "keyAltNames": {
+                      "$in": []
+                    }
+                  }
+                ]
+              },
+              "$db": "keyvault",
+              "readConcern": {
+                "level": "majority"
+              }
+            },
+            "command_name": "find"
+          }
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/tests/replaceOne.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/tests/replaceOne.json
new file mode 100644
index 0000000000000000000000000000000000000000..5cdb3d40f0d2925045e82b633c91a5071b1d76d6
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/tests/replaceOne.json	
@@ -0,0 +1,251 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.1.10"
+    }
+  ],
+  "database_name": "default",
+  "collection_name": "default",
+  "data": [
+    {
+      "_id": 1,
+      "encrypted_string": {
+        "$binary": {
+          "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==",
+          "subType": "06"
+        }
+      }
+    }
+  ],
+  "json_schema": {
+    "properties": {
+      "encrypted_w_altname": {
+        "encrypt": {
+          "keyId": "/altname",
+          "bsonType": "string",
+          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random"
+        }
+      },
+      "encrypted_string": {
+        "encrypt": {
+          "keyId": [
+            {
+              "$binary": {
+                "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                "subType": "04"
+              }
+            }
+          ],
+          "bsonType": "string",
+          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+        }
+      },
+      "random": {
+        "encrypt": {
+          "keyId": [
+            {
+              "$binary": {
+                "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                "subType": "04"
+              }
+            }
+          ],
+          "bsonType": "string",
+          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random"
+        }
+      },
+      "encrypted_string_equivalent": {
+        "encrypt": {
+          "keyId": [
+            {
+              "$binary": {
+                "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                "subType": "04"
+              }
+            }
+          ],
+          "bsonType": "string",
+          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+        }
+      }
+    },
+    "bsonType": "object"
+  },
+  "key_vault_data": [
+    {
+      "status": 1,
+      "_id": {
+        "$binary": {
+          "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+          "subType": "04"
+        }
+      },
+      "masterKey": {
+        "provider": "aws",
+        "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0",
+        "region": "us-east-1"
+      },
+      "updateDate": {
+        "$date": {
+          "$numberLong": "1552949630483"
+        }
+      },
+      "keyMaterial": {
+        "$binary": {
+          "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO",
+          "subType": "00"
+        }
+      },
+      "creationDate": {
+        "$date": {
+          "$numberLong": "1552949630483"
+        }
+      },
+      "keyAltNames": [
+        "altname",
+        "another_altname"
+      ]
+    }
+  ],
+  "tests": [
+    {
+      "description": "replaceOne with encryption",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "kmsProviders": {
+            "aws": {}
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "replaceOne",
+          "arguments": {
+            "filter": {
+              "encrypted_string": "string0"
+            },
+            "replacement": {
+              "encrypted_string": "string1",
+              "random": "abc"
+            }
+          },
+          "result": {
+            "matchedCount": 1,
+            "modifiedCount": 1,
+            "upsertedCount": 0
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1,
+              "filter": {
+                "name": "default"
+              }
+            },
+            "command_name": "listCollections"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1,
+              "filter": {
+                "name": "datakeys"
+              },
+              "$db": "keyvault"
+            },
+            "command_name": "listCollections"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "datakeys",
+              "filter": {
+                "$or": [
+                  {
+                    "_id": {
+                      "$in": [
+                        {
+                          "$binary": {
+                            "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                          }
+                        }
+                      ]
+                    }
+                  },
+                  {
+                    "keyAltNames": {
+                      "$in": []
+                    }
+                  }
+                ]
+              },
+              "$db": "keyvault",
+              "readConcern": {
+                "level": "majority"
+              }
+            },
+            "command_name": "find"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "update": "default",
+              "updates": [
+                {
+                  "q": {
+                    "encrypted_string": {
+                      "$eq": {
+                        "$binary": {
+                          "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==",
+                          "subType": "06"
+                        }
+                      }
+                    }
+                  },
+                  "u": {
+                    "encrypted_string": {
+                      "$binary": {
+                        "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==",
+                        "subType": "06"
+                      }
+                    },
+                    "random": {
+                      "$$type": "binData"
+                    }
+                  }
+                }
+              ],
+              "ordered": true
+            },
+            "command_name": "update"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "encrypted_string": {
+                "$binary": {
+                  "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==",
+                  "subType": "06"
+                }
+              },
+              "random": {
+                "$$type": "binData"
+              }
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/tests/types.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/tests/types.json
new file mode 100644
index 0000000000000000000000000000000000000000..47e4c27a2e2ccf8abaf7dc44e79740c2215d4d28
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/tests/types.json	
@@ -0,0 +1,1742 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.1.10"
+    }
+  ],
+  "database_name": "default",
+  "collection_name": "default",
+  "data": [],
+  "json_schema": {},
+  "key_vault_data": [
+    {
+      "status": 1,
+      "_id": {
+        "$binary": {
+          "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+          "subType": "04"
+        }
+      },
+      "masterKey": {
+        "provider": "aws",
+        "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0",
+        "region": "us-east-1"
+      },
+      "updateDate": {
+        "$date": {
+          "$numberLong": "1552949630483"
+        }
+      },
+      "keyMaterial": {
+        "$binary": {
+          "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO",
+          "subType": "00"
+        }
+      },
+      "creationDate": {
+        "$date": {
+          "$numberLong": "1552949630483"
+        }
+      },
+      "keyAltNames": [
+        "altname",
+        "another_altname"
+      ]
+    }
+  ],
+  "tests": [
+    {
+      "description": "type=objectId",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "schemaMap": {
+            "default.default": {
+              "properties": {
+                "encrypted_objectId": {
+                  "encrypt": {
+                    "keyId": [
+                      {
+                        "$binary": {
+                          "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                          "subType": "04"
+                        }
+                      }
+                    ],
+                    "bsonType": "objectId",
+                    "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+                  }
+                }
+              },
+              "bsonType": "object"
+            }
+          },
+          "kmsProviders": {
+            "aws": {}
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "insertOne",
+          "arguments": {
+            "document": {
+              "_id": 1,
+              "encrypted_objectId": {
+                "$oid": "AAAAAAAAAAAAAAAAAAAAAAAA"
+              }
+            }
+          }
+        },
+        {
+          "name": "findOne",
+          "arguments": {
+            "filter": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "_id": 1,
+            "encrypted_objectId": {
+              "$oid": "AAAAAAAAAAAAAAAAAAAAAAAA"
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1,
+              "filter": {
+                "name": "datakeys"
+              },
+              "$db": "keyvault"
+            },
+            "command_name": "listCollections"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "datakeys",
+              "filter": {
+                "$or": [
+                  {
+                    "_id": {
+                      "$in": [
+                        {
+                          "$binary": {
+                            "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                          }
+                        }
+                      ]
+                    }
+                  },
+                  {
+                    "keyAltNames": {
+                      "$in": []
+                    }
+                  }
+                ]
+              },
+              "$db": "keyvault",
+              "readConcern": {
+                "level": "majority"
+              }
+            },
+            "command_name": "find"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "default",
+              "documents": [
+                {
+                  "_id": 1,
+                  "encrypted_objectId": {
+                    "$binary": {
+                      "base64": "AQAAAAAAAAAAAAAAAAAAAAAHmkTPqvzfHMWpvS1mEsrjOxVQ2dyihEgIFWD5E0eNEsiMBQsC0GuvjdqYRL5DHLFI1vKuGek7EYYp0Qyii/tHqA==",
+                      "subType": "06"
+                    }
+                  }
+                }
+              ],
+              "ordered": true
+            },
+            "command_name": "insert"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "default",
+              "filter": {
+                "_id": 1
+              }
+            },
+            "command_name": "find"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "encrypted_objectId": {
+                "$binary": {
+                  "base64": "AQAAAAAAAAAAAAAAAAAAAAAHmkTPqvzfHMWpvS1mEsrjOxVQ2dyihEgIFWD5E0eNEsiMBQsC0GuvjdqYRL5DHLFI1vKuGek7EYYp0Qyii/tHqA==",
+                  "subType": "06"
+                }
+              }
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "type=symbol",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "schemaMap": {
+            "default.default": {
+              "properties": {
+                "encrypted_symbol": {
+                  "encrypt": {
+                    "keyId": [
+                      {
+                        "$binary": {
+                          "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                          "subType": "04"
+                        }
+                      }
+                    ],
+                    "bsonType": "symbol",
+                    "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+                  }
+                }
+              },
+              "bsonType": "object"
+            }
+          },
+          "kmsProviders": {
+            "aws": {}
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "insertOne",
+          "arguments": {
+            "document": {
+              "_id": 1,
+              "encrypted_symbol": {
+                "$symbol": "test"
+              }
+            }
+          }
+        },
+        {
+          "name": "findOne",
+          "arguments": {
+            "filter": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "_id": 1,
+            "encrypted_symbol": {
+              "$symbol": "test"
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1,
+              "filter": {
+                "name": "datakeys"
+              },
+              "$db": "keyvault"
+            },
+            "command_name": "listCollections"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "datakeys",
+              "filter": {
+                "$or": [
+                  {
+                    "_id": {
+                      "$in": [
+                        {
+                          "$binary": {
+                            "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                          }
+                        }
+                      ]
+                    }
+                  },
+                  {
+                    "keyAltNames": {
+                      "$in": []
+                    }
+                  }
+                ]
+              },
+              "$db": "keyvault",
+              "readConcern": {
+                "level": "majority"
+              }
+            },
+            "command_name": "find"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "default",
+              "documents": [
+                {
+                  "_id": 1,
+                  "encrypted_symbol": {
+                    "$binary": {
+                      "base64": "AQAAAAAAAAAAAAAAAAAAAAAOOmvDmWjcuKsSCO7U/7t9HJ8eI73B6wduyMbdkvn7n7V4uTJes/j+BTtneSdyG2JHKHGkevWAJSIU2XoO66BSXw==",
+                      "subType": "06"
+                    }
+                  }
+                }
+              ],
+              "ordered": true
+            },
+            "command_name": "insert"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "default",
+              "filter": {
+                "_id": 1
+              }
+            },
+            "command_name": "find"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "encrypted_symbol": {
+                "$binary": {
+                  "base64": "AQAAAAAAAAAAAAAAAAAAAAAOOmvDmWjcuKsSCO7U/7t9HJ8eI73B6wduyMbdkvn7n7V4uTJes/j+BTtneSdyG2JHKHGkevWAJSIU2XoO66BSXw==",
+                  "subType": "06"
+                }
+              }
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "type=int",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "schemaMap": {
+            "default.default": {
+              "properties": {
+                "encrypted_int": {
+                  "encrypt": {
+                    "keyId": [
+                      {
+                        "$binary": {
+                          "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                          "subType": "04"
+                        }
+                      }
+                    ],
+                    "bsonType": "int",
+                    "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+                  }
+                }
+              },
+              "bsonType": "object"
+            }
+          },
+          "kmsProviders": {
+            "aws": {}
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "insertOne",
+          "arguments": {
+            "document": {
+              "_id": 1,
+              "encrypted_int": {
+                "$numberInt": "123"
+              }
+            }
+          }
+        },
+        {
+          "name": "findOne",
+          "arguments": {
+            "filter": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "_id": 1,
+            "encrypted_int": {
+              "$numberInt": "123"
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1,
+              "filter": {
+                "name": "datakeys"
+              },
+              "$db": "keyvault"
+            },
+            "command_name": "listCollections"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "datakeys",
+              "filter": {
+                "$or": [
+                  {
+                    "_id": {
+                      "$in": [
+                        {
+                          "$binary": {
+                            "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                          }
+                        }
+                      ]
+                    }
+                  },
+                  {
+                    "keyAltNames": {
+                      "$in": []
+                    }
+                  }
+                ]
+              },
+              "$db": "keyvault",
+              "readConcern": {
+                "level": "majority"
+              }
+            },
+            "command_name": "find"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "default",
+              "documents": [
+                {
+                  "_id": 1,
+                  "encrypted_int": {
+                    "$binary": {
+                      "base64": "AQAAAAAAAAAAAAAAAAAAAAAQPNXJVXMEjGZnftMuf2INKufXCtQIRHdw5wTgn6QYt3ejcoAXyiwI4XIUizkpsob494qpt2in4tWeiO7b9zkA8Q==",
+                      "subType": "06"
+                    }
+                  }
+                }
+              ],
+              "ordered": true
+            },
+            "command_name": "insert"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "default",
+              "filter": {
+                "_id": 1
+              }
+            },
+            "command_name": "find"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "encrypted_int": {
+                "$binary": {
+                  "base64": "AQAAAAAAAAAAAAAAAAAAAAAQPNXJVXMEjGZnftMuf2INKufXCtQIRHdw5wTgn6QYt3ejcoAXyiwI4XIUizkpsob494qpt2in4tWeiO7b9zkA8Q==",
+                  "subType": "06"
+                }
+              }
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "type=double",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "schemaMap": {
+            "default.default": {
+              "properties": {
+                "encrypted_double": {
+                  "encrypt": {
+                    "keyId": [
+                      {
+                        "$binary": {
+                          "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                          "subType": "04"
+                        }
+                      }
+                    ],
+                    "bsonType": "double",
+                    "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+                  }
+                }
+              },
+              "bsonType": "object"
+            }
+          },
+          "kmsProviders": {
+            "aws": {}
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "insertOne",
+          "arguments": {
+            "document": {
+              "_id": 1,
+              "encrypted_double": {
+                "$numberDouble": "1.23"
+              }
+            }
+          },
+          "result": {
+            "errorContains": "Cannot use deterministic encryption for element of type: double"
+          }
+        }
+      ]
+    },
+    {
+      "description": "type=decimal",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "schemaMap": {
+            "default.default": {
+              "properties": {
+                "encrypted_decimal": {
+                  "encrypt": {
+                    "keyId": [
+                      {
+                        "$binary": {
+                          "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                          "subType": "04"
+                        }
+                      }
+                    ],
+                    "bsonType": "decimal",
+                    "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+                  }
+                }
+              },
+              "bsonType": "object"
+            }
+          },
+          "kmsProviders": {
+            "aws": {}
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "insertOne",
+          "arguments": {
+            "document": {
+              "_id": 1,
+              "encrypted_decimal": {
+                "$numberDecimal": "1.23"
+              }
+            }
+          },
+          "result": {
+            "errorContains": "Cannot use deterministic encryption for element of type: decimal"
+          }
+        }
+      ]
+    },
+    {
+      "description": "type=binData",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "schemaMap": {
+            "default.default": {
+              "properties": {
+                "encrypted_binData": {
+                  "encrypt": {
+                    "keyId": [
+                      {
+                        "$binary": {
+                          "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                          "subType": "04"
+                        }
+                      }
+                    ],
+                    "bsonType": "binData",
+                    "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+                  }
+                }
+              },
+              "bsonType": "object"
+            }
+          },
+          "kmsProviders": {
+            "aws": {}
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "insertOne",
+          "arguments": {
+            "document": {
+              "_id": 1,
+              "encrypted_binData": {
+                "$binary": {
+                  "base64": "AAAA",
+                  "subType": "00"
+                }
+              }
+            }
+          }
+        },
+        {
+          "name": "findOne",
+          "arguments": {
+            "filter": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "_id": 1,
+            "encrypted_binData": {
+              "$binary": {
+                "base64": "AAAA",
+                "subType": "00"
+              }
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1,
+              "filter": {
+                "name": "datakeys"
+              },
+              "$db": "keyvault"
+            },
+            "command_name": "listCollections"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "datakeys",
+              "filter": {
+                "$or": [
+                  {
+                    "_id": {
+                      "$in": [
+                        {
+                          "$binary": {
+                            "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                          }
+                        }
+                      ]
+                    }
+                  },
+                  {
+                    "keyAltNames": {
+                      "$in": []
+                    }
+                  }
+                ]
+              },
+              "$db": "keyvault",
+              "readConcern": {
+                "level": "majority"
+              }
+            },
+            "command_name": "find"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "default",
+              "documents": [
+                {
+                  "_id": 1,
+                  "encrypted_binData": {
+                    "$binary": {
+                      "base64": "AQAAAAAAAAAAAAAAAAAAAAAFB/KHZQHaHHo8fctcl7v6kR+sLkJoTRx2cPSSck9ya+nbGROSeFhdhDRHaCzhV78fDEqnMDSVPNi+ZkbaIh46GQ==",
+                      "subType": "06"
+                    }
+                  }
+                }
+              ],
+              "ordered": true
+            },
+            "command_name": "insert"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "default",
+              "filter": {
+                "_id": 1
+              }
+            },
+            "command_name": "find"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "encrypted_binData": {
+                "$binary": {
+                  "base64": "AQAAAAAAAAAAAAAAAAAAAAAFB/KHZQHaHHo8fctcl7v6kR+sLkJoTRx2cPSSck9ya+nbGROSeFhdhDRHaCzhV78fDEqnMDSVPNi+ZkbaIh46GQ==",
+                  "subType": "06"
+                }
+              }
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "type=javascript",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "schemaMap": {
+            "default.default": {
+              "properties": {
+                "encrypted_javascript": {
+                  "encrypt": {
+                    "keyId": [
+                      {
+                        "$binary": {
+                          "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                          "subType": "04"
+                        }
+                      }
+                    ],
+                    "bsonType": "javascript",
+                    "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+                  }
+                }
+              },
+              "bsonType": "object"
+            }
+          },
+          "kmsProviders": {
+            "aws": {}
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "insertOne",
+          "arguments": {
+            "document": {
+              "_id": 1,
+              "encrypted_javascript": {
+                "$code": "var x = 1;"
+              }
+            }
+          }
+        },
+        {
+          "name": "findOne",
+          "arguments": {
+            "filter": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "_id": 1,
+            "encrypted_javascript": {
+              "$code": "var x = 1;"
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1,
+              "filter": {
+                "name": "datakeys"
+              },
+              "$db": "keyvault"
+            },
+            "command_name": "listCollections"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "datakeys",
+              "filter": {
+                "$or": [
+                  {
+                    "_id": {
+                      "$in": [
+                        {
+                          "$binary": {
+                            "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                          }
+                        }
+                      ]
+                    }
+                  },
+                  {
+                    "keyAltNames": {
+                      "$in": []
+                    }
+                  }
+                ]
+              },
+              "$db": "keyvault",
+              "readConcern": {
+                "level": "majority"
+              }
+            },
+            "command_name": "find"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "default",
+              "documents": [
+                {
+                  "_id": 1,
+                  "encrypted_javascript": {
+                    "$binary": {
+                      "base64": "AQAAAAAAAAAAAAAAAAAAAAANrvMgJkTKWGMc9wt3E2RBR2Hu5gL9p+vIIdHe9FcOm99t1W480/oX1Gnd87ON3B399DuFaxi/aaIiQSo7gTX6Lw==",
+                      "subType": "06"
+                    }
+                  }
+                }
+              ],
+              "ordered": true
+            },
+            "command_name": "insert"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "default",
+              "filter": {
+                "_id": 1
+              }
+            },
+            "command_name": "find"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "encrypted_javascript": {
+                "$binary": {
+                  "base64": "AQAAAAAAAAAAAAAAAAAAAAANrvMgJkTKWGMc9wt3E2RBR2Hu5gL9p+vIIdHe9FcOm99t1W480/oX1Gnd87ON3B399DuFaxi/aaIiQSo7gTX6Lw==",
+                  "subType": "06"
+                }
+              }
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "type=javascriptWithScope",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "schemaMap": {
+            "default.default": {
+              "properties": {
+                "encrypted_javascriptWithScope": {
+                  "encrypt": {
+                    "keyId": [
+                      {
+                        "$binary": {
+                          "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                          "subType": "04"
+                        }
+                      }
+                    ],
+                    "bsonType": "javascriptWithScope",
+                    "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+                  }
+                }
+              },
+              "bsonType": "object"
+            }
+          },
+          "kmsProviders": {
+            "aws": {}
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "insertOne",
+          "arguments": {
+            "document": {
+              "_id": 1,
+              "encrypted_javascriptWithScope": {
+                "$code": "var x = 1;",
+                "$scope": {}
+              }
+            }
+          },
+          "result": {
+            "errorContains": "Cannot use deterministic encryption for element of type: javascriptWithScope"
+          }
+        }
+      ]
+    },
+    {
+      "description": "type=object",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "schemaMap": {
+            "default.default": {
+              "properties": {
+                "encrypted_object": {
+                  "encrypt": {
+                    "keyId": [
+                      {
+                        "$binary": {
+                          "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                          "subType": "04"
+                        }
+                      }
+                    ],
+                    "bsonType": "object",
+                    "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+                  }
+                }
+              },
+              "bsonType": "object"
+            }
+          },
+          "kmsProviders": {
+            "aws": {}
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "insertOne",
+          "arguments": {
+            "document": {
+              "_id": 1,
+              "encrypted_object": {}
+            }
+          },
+          "result": {
+            "errorContains": "Cannot use deterministic encryption for element of type: object"
+          }
+        }
+      ]
+    },
+    {
+      "description": "type=timestamp",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "schemaMap": {
+            "default.default": {
+              "properties": {
+                "encrypted_timestamp": {
+                  "encrypt": {
+                    "keyId": [
+                      {
+                        "$binary": {
+                          "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                          "subType": "04"
+                        }
+                      }
+                    ],
+                    "bsonType": "timestamp",
+                    "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+                  }
+                }
+              },
+              "bsonType": "object"
+            }
+          },
+          "kmsProviders": {
+            "aws": {}
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "insertOne",
+          "arguments": {
+            "document": {
+              "_id": 1,
+              "encrypted_timestamp": {
+                "$timestamp": {
+                  "t": 123,
+                  "i": 456
+                }
+              }
+            }
+          }
+        },
+        {
+          "name": "findOne",
+          "arguments": {
+            "filter": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "_id": 1,
+            "encrypted_timestamp": {
+              "$timestamp": {
+                "t": 123,
+                "i": 456
+              }
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1,
+              "filter": {
+                "name": "datakeys"
+              },
+              "$db": "keyvault"
+            },
+            "command_name": "listCollections"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "datakeys",
+              "filter": {
+                "$or": [
+                  {
+                    "_id": {
+                      "$in": [
+                        {
+                          "$binary": {
+                            "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                          }
+                        }
+                      ]
+                    }
+                  },
+                  {
+                    "keyAltNames": {
+                      "$in": []
+                    }
+                  }
+                ]
+              },
+              "$db": "keyvault",
+              "readConcern": {
+                "level": "majority"
+              }
+            },
+            "command_name": "find"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "default",
+              "documents": [
+                {
+                  "_id": 1,
+                  "encrypted_timestamp": {
+                    "$binary": {
+                      "base64": "AQAAAAAAAAAAAAAAAAAAAAARJHaM4Gq3MpDTdBasBsEolQaOmxJQU1wsZVaSFAOLpEh1QihDglXI95xemePFMKhg+KNpFg7lw1ChCs2Wn/c26Q==",
+                      "subType": "06"
+                    }
+                  }
+                }
+              ],
+              "ordered": true
+            },
+            "command_name": "insert"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "default",
+              "filter": {
+                "_id": 1
+              }
+            },
+            "command_name": "find"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "encrypted_timestamp": {
+                "$binary": {
+                  "base64": "AQAAAAAAAAAAAAAAAAAAAAARJHaM4Gq3MpDTdBasBsEolQaOmxJQU1wsZVaSFAOLpEh1QihDglXI95xemePFMKhg+KNpFg7lw1ChCs2Wn/c26Q==",
+                  "subType": "06"
+                }
+              }
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "type=regex",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "schemaMap": {
+            "default.default": {
+              "properties": {
+                "encrypted_regex": {
+                  "encrypt": {
+                    "keyId": [
+                      {
+                        "$binary": {
+                          "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                          "subType": "04"
+                        }
+                      }
+                    ],
+                    "bsonType": "regex",
+                    "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+                  }
+                }
+              },
+              "bsonType": "object"
+            }
+          },
+          "kmsProviders": {
+            "aws": {}
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "insertOne",
+          "arguments": {
+            "document": {
+              "_id": 1,
+              "encrypted_regex": {
+                "$regularExpression": {
+                  "pattern": "test",
+                  "options": ""
+                }
+              }
+            }
+          }
+        },
+        {
+          "name": "findOne",
+          "arguments": {
+            "filter": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "_id": 1,
+            "encrypted_regex": {
+              "$regularExpression": {
+                "pattern": "test",
+                "options": ""
+              }
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1,
+              "filter": {
+                "name": "datakeys"
+              },
+              "$db": "keyvault"
+            },
+            "command_name": "listCollections"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "datakeys",
+              "filter": {
+                "$or": [
+                  {
+                    "_id": {
+                      "$in": [
+                        {
+                          "$binary": {
+                            "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                          }
+                        }
+                      ]
+                    }
+                  },
+                  {
+                    "keyAltNames": {
+                      "$in": []
+                    }
+                  }
+                ]
+              },
+              "$db": "keyvault",
+              "readConcern": {
+                "level": "majority"
+              }
+            },
+            "command_name": "find"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "default",
+              "documents": [
+                {
+                  "_id": 1,
+                  "encrypted_regex": {
+                    "$binary": {
+                      "base64": "AQAAAAAAAAAAAAAAAAAAAAALVnxM4UqGhqf5eXw6nsS08am3YJrTf1EvjKitT8tyyMAbHsICIU3GUjuC7EBofCHbusvgo7pDyaClGostFz44nA==",
+                      "subType": "06"
+                    }
+                  }
+                }
+              ],
+              "ordered": true
+            },
+            "command_name": "insert"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "default",
+              "filter": {
+                "_id": 1
+              }
+            },
+            "command_name": "find"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "encrypted_regex": {
+                "$binary": {
+                  "base64": "AQAAAAAAAAAAAAAAAAAAAAALVnxM4UqGhqf5eXw6nsS08am3YJrTf1EvjKitT8tyyMAbHsICIU3GUjuC7EBofCHbusvgo7pDyaClGostFz44nA==",
+                  "subType": "06"
+                }
+              }
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "type=date",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "schemaMap": {
+            "default.default": {
+              "properties": {
+                "encrypted_date": {
+                  "encrypt": {
+                    "keyId": [
+                      {
+                        "$binary": {
+                          "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                          "subType": "04"
+                        }
+                      }
+                    ],
+                    "bsonType": "date",
+                    "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+                  }
+                }
+              },
+              "bsonType": "object"
+            }
+          },
+          "kmsProviders": {
+            "aws": {}
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "insertOne",
+          "arguments": {
+            "document": {
+              "_id": 1,
+              "encrypted_date": {
+                "$date": {
+                  "$numberLong": "123"
+                }
+              }
+            }
+          }
+        },
+        {
+          "name": "findOne",
+          "arguments": {
+            "filter": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "_id": 1,
+            "encrypted_date": {
+              "$date": {
+                "$numberLong": "123"
+              }
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1,
+              "filter": {
+                "name": "datakeys"
+              },
+              "$db": "keyvault"
+            },
+            "command_name": "listCollections"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "datakeys",
+              "filter": {
+                "$or": [
+                  {
+                    "_id": {
+                      "$in": [
+                        {
+                          "$binary": {
+                            "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                          }
+                        }
+                      ]
+                    }
+                  },
+                  {
+                    "keyAltNames": {
+                      "$in": []
+                    }
+                  }
+                ]
+              },
+              "$db": "keyvault",
+              "readConcern": {
+                "level": "majority"
+              }
+            },
+            "command_name": "find"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "default",
+              "documents": [
+                {
+                  "_id": 1,
+                  "encrypted_date": {
+                    "$binary": {
+                      "base64": "AQAAAAAAAAAAAAAAAAAAAAAJ5sN7u6l97+DswfKTqZAijSTSOo5htinGKQKUD7pHNJYlLXGOkB4glrCu7ibu0g3344RHQ5yUp4YxMEa8GD+Snw==",
+                      "subType": "06"
+                    }
+                  }
+                }
+              ],
+              "ordered": true
+            },
+            "command_name": "insert"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "default",
+              "filter": {
+                "_id": 1
+              }
+            },
+            "command_name": "find"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "encrypted_date": {
+                "$binary": {
+                  "base64": "AQAAAAAAAAAAAAAAAAAAAAAJ5sN7u6l97+DswfKTqZAijSTSOo5htinGKQKUD7pHNJYlLXGOkB4glrCu7ibu0g3344RHQ5yUp4YxMEa8GD+Snw==",
+                  "subType": "06"
+                }
+              }
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "type=minKey",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "schemaMap": {
+            "default.default": {
+              "properties": {
+                "encrypted_minKey": {
+                  "encrypt": {
+                    "keyId": [
+                      {
+                        "$binary": {
+                          "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                          "subType": "04"
+                        }
+                      }
+                    ],
+                    "bsonType": "minKey",
+                    "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+                  }
+                }
+              },
+              "bsonType": "object"
+            }
+          },
+          "kmsProviders": {
+            "aws": {}
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "insertOne",
+          "arguments": {
+            "document": {
+              "_id": 1,
+              "encrypted_minKey": {
+                "$minKey": 1
+              }
+            }
+          },
+          "result": {
+            "errorContains": "Cannot encrypt element of type: minKey"
+          }
+        }
+      ]
+    },
+    {
+      "description": "type=maxKey",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "schemaMap": {
+            "default.default": {
+              "properties": {
+                "encrypted_maxKey": {
+                  "encrypt": {
+                    "keyId": [
+                      {
+                        "$binary": {
+                          "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                          "subType": "04"
+                        }
+                      }
+                    ],
+                    "bsonType": "maxKey",
+                    "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+                  }
+                }
+              },
+              "bsonType": "object"
+            }
+          },
+          "kmsProviders": {
+            "aws": {}
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "insertOne",
+          "arguments": {
+            "document": {
+              "_id": 1,
+              "encrypted_maxKey": {
+                "$maxKey": 1
+              }
+            }
+          },
+          "result": {
+            "errorContains": "Cannot encrypt element of type: maxKey"
+          }
+        }
+      ]
+    },
+    {
+      "description": "type=undefined",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "schemaMap": {
+            "default.default": {
+              "properties": {
+                "encrypted_undefined": {
+                  "encrypt": {
+                    "keyId": [
+                      {
+                        "$binary": {
+                          "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                          "subType": "04"
+                        }
+                      }
+                    ],
+                    "bsonType": "undefined",
+                    "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+                  }
+                }
+              },
+              "bsonType": "object"
+            }
+          },
+          "kmsProviders": {
+            "aws": {}
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "insertOne",
+          "arguments": {
+            "document": {
+              "_id": 1,
+              "encrypted_undefined": {
+                "$undefined": true
+              }
+            }
+          },
+          "result": {
+            "errorContains": "Cannot encrypt element of type: undefined"
+          }
+        }
+      ]
+    },
+    {
+      "description": "type=array",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "schemaMap": {
+            "default.default": {
+              "properties": {
+                "encrypted_array": {
+                  "encrypt": {
+                    "keyId": [
+                      {
+                        "$binary": {
+                          "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                          "subType": "04"
+                        }
+                      }
+                    ],
+                    "bsonType": "array",
+                    "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+                  }
+                }
+              },
+              "bsonType": "object"
+            }
+          },
+          "kmsProviders": {
+            "aws": {}
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "insertOne",
+          "arguments": {
+            "document": {
+              "_id": 1,
+              "encrypted_array": []
+            }
+          },
+          "result": {
+            "errorContains": "Cannot use deterministic encryption for element of type: array"
+          }
+        }
+      ]
+    },
+    {
+      "description": "type=bool",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "schemaMap": {
+            "default.default": {
+              "properties": {
+                "encrypted_bool": {
+                  "encrypt": {
+                    "keyId": [
+                      {
+                        "$binary": {
+                          "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                          "subType": "04"
+                        }
+                      }
+                    ],
+                    "bsonType": "bool",
+                    "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+                  }
+                }
+              },
+              "bsonType": "object"
+            }
+          },
+          "kmsProviders": {
+            "aws": {}
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "insertOne",
+          "arguments": {
+            "document": {
+              "_id": 1,
+              "encrypted_bool": true
+            }
+          },
+          "result": {
+            "errorContains": "Cannot use deterministic encryption for element of type: bool"
+          }
+        }
+      ]
+    },
+    {
+      "description": "type=null",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "schemaMap": {
+            "default.default": {
+              "properties": {
+                "encrypted_null": {
+                  "encrypt": {
+                    "keyId": [
+                      {
+                        "$binary": {
+                          "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                          "subType": "04"
+                        }
+                      }
+                    ],
+                    "bsonType": "null",
+                    "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+                  }
+                }
+              },
+              "bsonType": "object"
+            }
+          },
+          "kmsProviders": {
+            "aws": {}
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "insertOne",
+          "arguments": {
+            "document": {
+              "_id": 1,
+              "encrypted_null": true
+            }
+          },
+          "result": {
+            "errorContains": "Cannot encrypt element of type: null"
+          }
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/tests/unsupportedCommand.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/tests/unsupportedCommand.json
new file mode 100644
index 0000000000000000000000000000000000000000..31887151150c8f27bb734416f6b145397885ee65
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/tests/unsupportedCommand.json	
@@ -0,0 +1,152 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.1.10"
+    }
+  ],
+  "database_name": "default",
+  "collection_name": "default",
+  "data": [
+    {
+      "_id": 1,
+      "x": 1,
+      "encrypted_string": {
+        "$binary": {
+          "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==",
+          "subType": "06"
+        }
+      }
+    },
+    {
+      "_id": 2,
+      "x": 2,
+      "encrypted_string": {
+        "$binary": {
+          "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==",
+          "subType": "06"
+        }
+      }
+    }
+  ],
+  "json_schema": {
+    "properties": {
+      "encrypted_w_altname": {
+        "encrypt": {
+          "keyId": "/altname",
+          "bsonType": "string",
+          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random"
+        }
+      },
+      "encrypted_string": {
+        "encrypt": {
+          "keyId": [
+            {
+              "$binary": {
+                "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                "subType": "04"
+              }
+            }
+          ],
+          "bsonType": "string",
+          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+        }
+      },
+      "random": {
+        "encrypt": {
+          "keyId": [
+            {
+              "$binary": {
+                "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                "subType": "04"
+              }
+            }
+          ],
+          "bsonType": "string",
+          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random"
+        }
+      },
+      "encrypted_string_equivalent": {
+        "encrypt": {
+          "keyId": [
+            {
+              "$binary": {
+                "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                "subType": "04"
+              }
+            }
+          ],
+          "bsonType": "string",
+          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+        }
+      }
+    },
+    "bsonType": "object"
+  },
+  "key_vault_data": [
+    {
+      "status": 1,
+      "_id": {
+        "$binary": {
+          "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+          "subType": "04"
+        }
+      },
+      "masterKey": {
+        "provider": "aws",
+        "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0",
+        "region": "us-east-1"
+      },
+      "updateDate": {
+        "$date": {
+          "$numberLong": "1552949630483"
+        }
+      },
+      "keyMaterial": {
+        "$binary": {
+          "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO",
+          "subType": "00"
+        }
+      },
+      "creationDate": {
+        "$date": {
+          "$numberLong": "1552949630483"
+        }
+      },
+      "keyAltNames": [
+        "altname",
+        "another_altname"
+      ]
+    }
+  ],
+  "tests": [
+    {
+      "description": "mapReduce deterministic encryption (unsupported)",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "kmsProviders": {
+            "aws": {}
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "mapReduce",
+          "arguments": {
+            "map": {
+              "$code": "function inc() { return emit(0, this.x + 1) }"
+            },
+            "reduce": {
+              "$code": "function sum(key, values) { return values.reduce((acc, x) => acc + x); }"
+            },
+            "out": {
+              "inline": 1
+            }
+          },
+          "result": {
+            "errorContains": "command not supported for auto encryption: mapreduce"
+          }
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/tests/updateMany.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/tests/updateMany.json
new file mode 100644
index 0000000000000000000000000000000000000000..fd1f4d12bdf828e5cd878624a308473e00d2f0e3
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/tests/updateMany.json	
@@ -0,0 +1,319 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.1.10"
+    }
+  ],
+  "database_name": "default",
+  "collection_name": "default",
+  "data": [
+    {
+      "_id": 1,
+      "encrypted_string": {
+        "$binary": {
+          "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==",
+          "subType": "06"
+        }
+      }
+    },
+    {
+      "_id": 2,
+      "encrypted_string": {
+        "$binary": {
+          "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==",
+          "subType": "06"
+        }
+      }
+    }
+  ],
+  "json_schema": {
+    "properties": {
+      "encrypted_w_altname": {
+        "encrypt": {
+          "keyId": "/altname",
+          "bsonType": "string",
+          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random"
+        }
+      },
+      "encrypted_string": {
+        "encrypt": {
+          "keyId": [
+            {
+              "$binary": {
+                "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                "subType": "04"
+              }
+            }
+          ],
+          "bsonType": "string",
+          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+        }
+      },
+      "random": {
+        "encrypt": {
+          "keyId": [
+            {
+              "$binary": {
+                "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                "subType": "04"
+              }
+            }
+          ],
+          "bsonType": "string",
+          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random"
+        }
+      },
+      "encrypted_string_equivalent": {
+        "encrypt": {
+          "keyId": [
+            {
+              "$binary": {
+                "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                "subType": "04"
+              }
+            }
+          ],
+          "bsonType": "string",
+          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+        }
+      }
+    },
+    "bsonType": "object"
+  },
+  "key_vault_data": [
+    {
+      "status": 1,
+      "_id": {
+        "$binary": {
+          "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+          "subType": "04"
+        }
+      },
+      "masterKey": {
+        "provider": "aws",
+        "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0",
+        "region": "us-east-1"
+      },
+      "updateDate": {
+        "$date": {
+          "$numberLong": "1552949630483"
+        }
+      },
+      "keyMaterial": {
+        "$binary": {
+          "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO",
+          "subType": "00"
+        }
+      },
+      "creationDate": {
+        "$date": {
+          "$numberLong": "1552949630483"
+        }
+      },
+      "keyAltNames": [
+        "altname",
+        "another_altname"
+      ]
+    }
+  ],
+  "tests": [
+    {
+      "description": "updateMany with deterministic encryption",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "kmsProviders": {
+            "aws": {}
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "updateMany",
+          "arguments": {
+            "filter": {
+              "encrypted_string": {
+                "$in": [
+                  "string0",
+                  "string1"
+                ]
+              }
+            },
+            "update": {
+              "$set": {
+                "encrypted_string": "string2",
+                "random": "abc"
+              }
+            }
+          },
+          "result": {
+            "matchedCount": 2,
+            "modifiedCount": 2,
+            "upsertedCount": 0
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1,
+              "filter": {
+                "name": "default"
+              }
+            },
+            "command_name": "listCollections"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1,
+              "filter": {
+                "name": "datakeys"
+              },
+              "$db": "keyvault"
+            },
+            "command_name": "listCollections"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "datakeys",
+              "filter": {
+                "$or": [
+                  {
+                    "_id": {
+                      "$in": [
+                        {
+                          "$binary": {
+                            "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                          }
+                        }
+                      ]
+                    }
+                  },
+                  {
+                    "keyAltNames": {
+                      "$in": []
+                    }
+                  }
+                ]
+              },
+              "$db": "keyvault",
+              "readConcern": {
+                "level": "majority"
+              }
+            },
+            "command_name": "find"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "update": "default",
+              "updates": [
+                {
+                  "q": {
+                    "encrypted_string": {
+                      "$in": [
+                        {
+                          "$binary": {
+                            "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==",
+                            "subType": "06"
+                          }
+                        },
+                        {
+                          "$binary": {
+                            "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==",
+                            "subType": "06"
+                          }
+                        }
+                      ]
+                    }
+                  },
+                  "u": {
+                    "$set": {
+                      "encrypted_string": {
+                        "$binary": {
+                          "base64": "AQAAAAAAAAAAAAAAAAAAAAACQ76HWOut3DZtQuV90hp1aaCpZn95vZIaWmn+wrBehcEtcFwyJlBdlyzDzZTWPZCPgiFq72Wvh6Y7VbpU9NAp3A==",
+                          "subType": "06"
+                        }
+                      },
+                      "random": {
+                        "$$type": "binData"
+                      }
+                    }
+                  },
+                  "multi": true,
+                  "upsert": false
+                }
+              ],
+              "ordered": true
+            },
+            "command_name": "update"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "encrypted_string": {
+                "$binary": {
+                  "base64": "AQAAAAAAAAAAAAAAAAAAAAACQ76HWOut3DZtQuV90hp1aaCpZn95vZIaWmn+wrBehcEtcFwyJlBdlyzDzZTWPZCPgiFq72Wvh6Y7VbpU9NAp3A==",
+                  "subType": "06"
+                }
+              },
+              "random": {
+                "$$type": "binData"
+              }
+            },
+            {
+              "_id": 2,
+              "encrypted_string": {
+                "$binary": {
+                  "base64": "AQAAAAAAAAAAAAAAAAAAAAACQ76HWOut3DZtQuV90hp1aaCpZn95vZIaWmn+wrBehcEtcFwyJlBdlyzDzZTWPZCPgiFq72Wvh6Y7VbpU9NAp3A==",
+                  "subType": "06"
+                }
+              },
+              "random": {
+                "$$type": "binData"
+              }
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "updateMany fails when filtering on a random field",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "kmsProviders": {
+            "aws": {}
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "updateMany",
+          "arguments": {
+            "filter": {
+              "random": "abc"
+            },
+            "update": {
+              "$set": {
+                "encrypted_string": "string1"
+              }
+            }
+          },
+          "result": {
+            "errorContains": "Cannot query on fields encrypted with the randomized encryption"
+          }
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/tests/updateOne.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/tests/updateOne.json
new file mode 100644
index 0000000000000000000000000000000000000000..bed763d720589bb7739051e307c0ce68f72d1dea
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/client-side-encryption/tests/updateOne.json	
@@ -0,0 +1,477 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.1.10"
+    }
+  ],
+  "database_name": "default",
+  "collection_name": "default",
+  "data": [
+    {
+      "_id": 1,
+      "encrypted_string": {
+        "$binary": {
+          "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==",
+          "subType": "06"
+        }
+      }
+    }
+  ],
+  "json_schema": {
+    "properties": {
+      "encrypted_w_altname": {
+        "encrypt": {
+          "keyId": "/altname",
+          "bsonType": "string",
+          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random"
+        }
+      },
+      "encrypted_string": {
+        "encrypt": {
+          "keyId": [
+            {
+              "$binary": {
+                "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                "subType": "04"
+              }
+            }
+          ],
+          "bsonType": "string",
+          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+        }
+      },
+      "random": {
+        "encrypt": {
+          "keyId": [
+            {
+              "$binary": {
+                "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                "subType": "04"
+              }
+            }
+          ],
+          "bsonType": "string",
+          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random"
+        }
+      },
+      "encrypted_string_equivalent": {
+        "encrypt": {
+          "keyId": [
+            {
+              "$binary": {
+                "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                "subType": "04"
+              }
+            }
+          ],
+          "bsonType": "string",
+          "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
+        }
+      }
+    },
+    "bsonType": "object"
+  },
+  "key_vault_data": [
+    {
+      "status": 1,
+      "_id": {
+        "$binary": {
+          "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+          "subType": "04"
+        }
+      },
+      "masterKey": {
+        "provider": "aws",
+        "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0",
+        "region": "us-east-1"
+      },
+      "updateDate": {
+        "$date": {
+          "$numberLong": "1552949630483"
+        }
+      },
+      "keyMaterial": {
+        "$binary": {
+          "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO",
+          "subType": "00"
+        }
+      },
+      "creationDate": {
+        "$date": {
+          "$numberLong": "1552949630483"
+        }
+      },
+      "keyAltNames": [
+        "altname",
+        "another_altname"
+      ]
+    }
+  ],
+  "tests": [
+    {
+      "description": "updateOne with deterministic encryption",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "kmsProviders": {
+            "aws": {}
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "updateOne",
+          "arguments": {
+            "filter": {
+              "encrypted_string": "string0"
+            },
+            "update": {
+              "$set": {
+                "encrypted_string": "string1",
+                "random": "abc"
+              }
+            }
+          },
+          "result": {
+            "matchedCount": 1,
+            "modifiedCount": 1,
+            "upsertedCount": 0
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1,
+              "filter": {
+                "name": "default"
+              }
+            },
+            "command_name": "listCollections"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1,
+              "filter": {
+                "name": "datakeys"
+              },
+              "$db": "keyvault"
+            },
+            "command_name": "listCollections"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "datakeys",
+              "filter": {
+                "$or": [
+                  {
+                    "_id": {
+                      "$in": [
+                        {
+                          "$binary": {
+                            "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
+                            "subType": "04"
+                          }
+                        }
+                      ]
+                    }
+                  },
+                  {
+                    "keyAltNames": {
+                      "$in": []
+                    }
+                  }
+                ]
+              },
+              "$db": "keyvault",
+              "readConcern": {
+                "level": "majority"
+              }
+            },
+            "command_name": "find"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "update": "default",
+              "updates": [
+                {
+                  "q": {
+                    "encrypted_string": {
+                      "$eq": {
+                        "$binary": {
+                          "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==",
+                          "subType": "06"
+                        }
+                      }
+                    }
+                  },
+                  "u": {
+                    "$set": {
+                      "encrypted_string": {
+                        "$binary": {
+                          "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==",
+                          "subType": "06"
+                        }
+                      },
+                      "random": {
+                        "$$type": "binData"
+                      }
+                    }
+                  }
+                }
+              ],
+              "ordered": true
+            },
+            "command_name": "update"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "encrypted_string": {
+                "$binary": {
+                  "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==",
+                  "subType": "06"
+                }
+              },
+              "random": {
+                "$$type": "binData"
+              }
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "updateOne fails when filtering on a random field",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "kmsProviders": {
+            "aws": {}
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "updateOne",
+          "arguments": {
+            "filter": {
+              "random": "abc"
+            },
+            "update": {
+              "$set": {
+                "encrypted_string": "string1"
+              }
+            }
+          },
+          "result": {
+            "errorContains": "Cannot query on fields encrypted with the randomized encryption"
+          }
+        }
+      ]
+    },
+    {
+      "description": "$unset works with an encrypted field",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "kmsProviders": {
+            "aws": {}
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "updateOne",
+          "arguments": {
+            "filter": {},
+            "update": {
+              "$unset": {
+                "encrypted_string": ""
+              }
+            }
+          },
+          "result": {
+            "matchedCount": 1,
+            "modifiedCount": 1,
+            "upsertedCount": 0
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1,
+              "filter": {
+                "name": "default"
+              }
+            },
+            "command_name": "listCollections"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "update": "default",
+              "updates": [
+                {
+                  "q": {},
+                  "u": {
+                    "$unset": {
+                      "encrypted_string": ""
+                    }
+                  }
+                }
+              ],
+              "ordered": true
+            },
+            "command_name": "update"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "$rename works if target value has same encryption options",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "kmsProviders": {
+            "aws": {}
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "updateOne",
+          "arguments": {
+            "filter": {},
+            "update": {
+              "$rename": {
+                "encrypted_string": "encrypted_string_equivalent"
+              }
+            }
+          },
+          "result": {
+            "matchedCount": 1,
+            "modifiedCount": 1,
+            "upsertedCount": 0
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1,
+              "filter": {
+                "name": "default"
+              }
+            },
+            "command_name": "listCollections"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "update": "default",
+              "updates": [
+                {
+                  "q": {},
+                  "u": {
+                    "$rename": {
+                      "encrypted_string": "encrypted_string_equivalent"
+                    }
+                  }
+                }
+              ],
+              "ordered": true
+            },
+            "command_name": "update"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "encrypted_string_equivalent": {
+                "$binary": {
+                  "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==",
+                  "subType": "06"
+                }
+              }
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "$rename fails if target value has different encryption options",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "kmsProviders": {
+            "aws": {}
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "updateOne",
+          "arguments": {
+            "filter": {},
+            "update": {
+              "$rename": {
+                "encrypted_string": "random"
+              }
+            }
+          },
+          "result": {
+            "errorContains": "$rename between two encrypted fields must have the same metadata or both be unencrypted"
+          }
+        }
+      ]
+    },
+    {
+      "description": "an invalid update (no $ operators) is validated and errors",
+      "clientOptions": {
+        "autoEncryptOpts": {
+          "kmsProviders": {
+            "aws": {}
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "updateOne",
+          "arguments": {
+            "filter": {},
+            "update": {
+              "encrypted_string": "random"
+            }
+          },
+          "result": {
+            "errorContains": ""
+          }
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/command-monitoring/bulkWrite.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/command-monitoring/bulkWrite.json
new file mode 100644
index 0000000000000000000000000000000000000000..ca5a9a105cd860b21b79ab4461e816df34578c2a
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/command-monitoring/bulkWrite.json	
@@ -0,0 +1,110 @@
+{
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    },
+    {
+      "_id": 3,
+      "x": 33
+    }
+  ],
+  "collection_name": "test",
+  "database_name": "command-monitoring-tests",
+  "tests": [
+    {
+      "description": "A successful mixed bulk write",
+      "operation": {
+        "name": "bulkWrite",
+        "arguments": {
+          "requests": [
+            {
+              "name": "insertOne",
+              "arguments": {
+                "document": {
+                  "_id": 4,
+                  "x": 44
+                }
+              }
+            },
+            {
+              "name": "updateOne",
+              "arguments": {
+                "filter": {
+                  "_id": 3
+                },
+                "update": {
+                  "$set": {
+                    "x": 333
+                  }
+                }
+              }
+            }
+          ]
+        }
+      },
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 4,
+                  "x": 44
+                }
+              ],
+              "ordered": true
+            },
+            "command_name": "insert",
+            "database_name": "command-monitoring-tests"
+          }
+        },
+        {
+          "command_succeeded_event": {
+            "reply": {
+              "ok": 1,
+              "n": 1
+            },
+            "command_name": "insert"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "update": "test",
+              "updates": [
+                {
+                  "q": {
+                    "_id": 3
+                  },
+                  "u": {
+                    "$set": {
+                      "x": 333
+                    }
+                  }
+                }
+              ],
+              "ordered": true
+            },
+            "command_name": "update",
+            "database_name": "command-monitoring-tests"
+          }
+        },
+        {
+          "command_succeeded_event": {
+            "reply": {
+              "ok": 1,
+              "n": 1
+            },
+            "command_name": "update"
+          }
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/command-monitoring/command.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/command-monitoring/command.json
new file mode 100644
index 0000000000000000000000000000000000000000..7e1e347be0739cac1944a093dfd9c473390a4c44
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/command-monitoring/command.json	
@@ -0,0 +1,113 @@
+{
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    }
+  ],
+  "collection_name": "test",
+  "database_name": "command-monitoring-tests",
+  "tests": [
+    {
+      "description": "A successful command",
+      "operation": {
+        "name": "count",
+        "arguments": {
+          "filter": {
+            "_id": 1
+          }
+        }
+      },
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "count": "test",
+              "query": {
+                "_id": 1
+              }
+            },
+            "command_name": "count",
+            "database_name": "command-monitoring-tests"
+          }
+        },
+        {
+          "command_succeeded_event": {
+            "reply": {
+              "ok": 1,
+              "n": 1
+            },
+            "command_name": "count"
+          }
+        }
+      ]
+    },
+    {
+      "description": "A failed command event",
+      "operation": {
+        "name": "count",
+        "arguments": {
+          "filter": {
+            "$or": true
+          }
+        }
+      },
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "count": "test",
+              "query": {
+                "$or": true
+              }
+            },
+            "command_name": "count",
+            "database_name": "command-monitoring-tests"
+          }
+        },
+        {
+          "command_failed_event": {
+            "command_name": "count"
+          }
+        }
+      ]
+    },
+    {
+      "description": "A successful command with a non-primary read preference",
+      "operation": {
+        "name": "count",
+        "arguments": {
+          "filter": {
+            "_id": 1
+          }
+        },
+        "read_preference": {
+          "mode": "primaryPreferred"
+        }
+      },
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "count": "test",
+              "query": {
+                "_id": 1
+              }
+            },
+            "command_name": "count",
+            "database_name": "command-monitoring-tests"
+          }
+        },
+        {
+          "command_succeeded_event": {
+            "reply": {
+              "ok": 1,
+              "n": 1
+            },
+            "command_name": "count"
+          }
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/command-monitoring/deleteMany.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/command-monitoring/deleteMany.json
new file mode 100644
index 0000000000000000000000000000000000000000..7cd396806cc06a47d7f0dae0b413fcdb3deef4b1
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/command-monitoring/deleteMany.json	
@@ -0,0 +1,115 @@
+{
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    },
+    {
+      "_id": 3,
+      "x": 33
+    }
+  ],
+  "collection_name": "test",
+  "database_name": "command-monitoring-tests",
+  "tests": [
+    {
+      "description": "A successful delete many",
+      "operation": {
+        "name": "deleteMany",
+        "arguments": {
+          "filter": {
+            "_id": {
+              "$gt": 1
+            }
+          }
+        }
+      },
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "delete": "test",
+              "deletes": [
+                {
+                  "q": {
+                    "_id": {
+                      "$gt": 1
+                    }
+                  },
+                  "limit": 0
+                }
+              ],
+              "ordered": true
+            },
+            "command_name": "delete",
+            "database_name": "command-monitoring-tests"
+          }
+        },
+        {
+          "command_succeeded_event": {
+            "reply": {
+              "ok": 1,
+              "n": 2
+            },
+            "command_name": "delete"
+          }
+        }
+      ]
+    },
+    {
+      "description": "A successful delete many command with write errors",
+      "operation": {
+        "name": "deleteMany",
+        "arguments": {
+          "filter": {
+            "_id": {
+              "$nothing": 1
+            }
+          }
+        }
+      },
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "delete": "test",
+              "deletes": [
+                {
+                  "q": {
+                    "_id": {
+                      "$nothing": 1
+                    }
+                  },
+                  "limit": 0
+                }
+              ],
+              "ordered": true
+            },
+            "command_name": "delete",
+            "database_name": "command-monitoring-tests"
+          }
+        },
+        {
+          "command_succeeded_event": {
+            "reply": {
+              "ok": 1,
+              "n": 0,
+              "writeErrors": [
+                {
+                  "index": 0,
+                  "code": 42,
+                  "errmsg": ""
+                }
+              ]
+            },
+            "command_name": "delete"
+          }
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/command-monitoring/deleteOne.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/command-monitoring/deleteOne.json
new file mode 100644
index 0000000000000000000000000000000000000000..0971dfcf2cdae5aa9ce2af951fd5224819cdaa2e
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/command-monitoring/deleteOne.json	
@@ -0,0 +1,115 @@
+{
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    },
+    {
+      "_id": 3,
+      "x": 33
+    }
+  ],
+  "collection_name": "test",
+  "database_name": "command-monitoring-tests",
+  "tests": [
+    {
+      "description": "A successful delete one",
+      "operation": {
+        "name": "deleteOne",
+        "arguments": {
+          "filter": {
+            "_id": {
+              "$gt": 1
+            }
+          }
+        }
+      },
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "delete": "test",
+              "deletes": [
+                {
+                  "q": {
+                    "_id": {
+                      "$gt": 1
+                    }
+                  },
+                  "limit": 1
+                }
+              ],
+              "ordered": true
+            },
+            "command_name": "delete",
+            "database_name": "command-monitoring-tests"
+          }
+        },
+        {
+          "command_succeeded_event": {
+            "reply": {
+              "ok": 1,
+              "n": 1
+            },
+            "command_name": "delete"
+          }
+        }
+      ]
+    },
+    {
+      "description": "A successful delete one command with write errors",
+      "operation": {
+        "name": "deleteOne",
+        "arguments": {
+          "filter": {
+            "_id": {
+              "$nothing": 1
+            }
+          }
+        }
+      },
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "delete": "test",
+              "deletes": [
+                {
+                  "q": {
+                    "_id": {
+                      "$nothing": 1
+                    }
+                  },
+                  "limit": 1
+                }
+              ],
+              "ordered": true
+            },
+            "command_name": "delete",
+            "database_name": "command-monitoring-tests"
+          }
+        },
+        {
+          "command_succeeded_event": {
+            "reply": {
+              "ok": 1,
+              "n": 0,
+              "writeErrors": [
+                {
+                  "index": 0,
+                  "code": 42,
+                  "errmsg": ""
+                }
+              ]
+            },
+            "command_name": "delete"
+          }
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/command-monitoring/find.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/command-monitoring/find.json
new file mode 100644
index 0000000000000000000000000000000000000000..039c5fead1a27f5e056d1d353562b53828a8ed57
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/command-monitoring/find.json	
@@ -0,0 +1,560 @@
+{
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    },
+    {
+      "_id": 3,
+      "x": 33
+    },
+    {
+      "_id": 4,
+      "x": 44
+    },
+    {
+      "_id": 5,
+      "x": 55
+    }
+  ],
+  "collection_name": "test",
+  "database_name": "command-monitoring-tests",
+  "namespace": "command-monitoring-tests.test",
+  "tests": [
+    {
+      "description": "A successful find event with no options",
+      "operation": {
+        "name": "find",
+        "arguments": {
+          "filter": {
+            "_id": 1
+          }
+        }
+      },
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "find": "test",
+              "filter": {
+                "_id": 1
+              }
+            },
+            "command_name": "find",
+            "database_name": "command-monitoring-tests"
+          }
+        },
+        {
+          "command_succeeded_event": {
+            "reply": {
+              "ok": 1,
+              "cursor": {
+                "id": {
+                  "$numberLong": "0"
+                },
+                "ns": "command-monitoring-tests.test",
+                "firstBatch": [
+                  {
+                    "_id": 1,
+                    "x": 11
+                  }
+                ]
+              }
+            },
+            "command_name": "find"
+          }
+        }
+      ]
+    },
+    {
+      "description": "A successful find event with options",
+      "operation": {
+        "name": "find",
+        "read_preference": {
+          "mode": "primaryPreferred"
+        },
+        "arguments": {
+          "filter": {
+            "_id": {
+              "$gt": 1
+            }
+          },
+          "sort": {
+            "_id": 1
+          },
+          "skip": {
+            "$numberLong": "2"
+          },
+          "modifiers": {
+            "$comment": "test",
+            "$hint": {
+              "_id": 1
+            },
+            "$max": {
+              "_id": 6
+            },
+            "$maxTimeMS": 6000,
+            "$min": {
+              "_id": 0
+            },
+            "$returnKey": false,
+            "$showDiskLoc": false
+          }
+        }
+      },
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "find": "test",
+              "filter": {
+                "_id": {
+                  "$gt": 1
+                }
+              },
+              "sort": {
+                "_id": 1
+              },
+              "skip": {
+                "$numberLong": "2"
+              },
+              "comment": "test",
+              "hint": {
+                "_id": 1
+              },
+              "max": {
+                "_id": 6
+              },
+              "maxTimeMS": 6000,
+              "min": {
+                "_id": 0
+              },
+              "returnKey": false,
+              "showRecordId": false
+            },
+            "command_name": "find",
+            "database_name": "command-monitoring-tests"
+          }
+        },
+        {
+          "command_succeeded_event": {
+            "reply": {
+              "ok": 1,
+              "cursor": {
+                "id": {
+                  "$numberLong": "0"
+                },
+                "ns": "command-monitoring-tests.test",
+                "firstBatch": [
+                  {
+                    "_id": 4,
+                    "x": 44
+                  },
+                  {
+                    "_id": 5,
+                    "x": 55
+                  }
+                ]
+              }
+            },
+            "command_name": "find"
+          }
+        }
+      ]
+    },
+    {
+      "description": "A successful find event with a getmore",
+      "operation": {
+        "name": "find",
+        "arguments": {
+          "filter": {
+            "_id": {
+              "$gte": 1
+            }
+          },
+          "sort": {
+            "_id": 1
+          },
+          "batchSize": {
+            "$numberLong": "3"
+          }
+        }
+      },
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "find": "test",
+              "filter": {
+                "_id": {
+                  "$gte": 1
+                }
+              },
+              "sort": {
+                "_id": 1
+              },
+              "batchSize": {
+                "$numberLong": "3"
+              }
+            },
+            "command_name": "find",
+            "database_name": "command-monitoring-tests"
+          }
+        },
+        {
+          "command_succeeded_event": {
+            "reply": {
+              "ok": 1,
+              "cursor": {
+                "id": {
+                  "$numberLong": "42"
+                },
+                "ns": "command-monitoring-tests.test",
+                "firstBatch": [
+                  {
+                    "_id": 1,
+                    "x": 11
+                  },
+                  {
+                    "_id": 2,
+                    "x": 22
+                  },
+                  {
+                    "_id": 3,
+                    "x": 33
+                  }
+                ]
+              }
+            },
+            "command_name": "find"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "getMore": {
+                "$numberLong": "42"
+              },
+              "collection": "test",
+              "batchSize": {
+                "$numberLong": "3"
+              }
+            },
+            "command_name": "getMore",
+            "database_name": "command-monitoring-tests"
+          }
+        },
+        {
+          "command_succeeded_event": {
+            "reply": {
+              "ok": 1,
+              "cursor": {
+                "id": {
+                  "$numberLong": "0"
+                },
+                "ns": "command-monitoring-tests.test",
+                "nextBatch": [
+                  {
+                    "_id": 4,
+                    "x": 44
+                  },
+                  {
+                    "_id": 5,
+                    "x": 55
+                  }
+                ]
+              }
+            },
+            "command_name": "getMore"
+          }
+        }
+      ]
+    },
+    {
+      "description": "A successful find event with a getmore and killcursors",
+      "ignore_if_server_version_greater_than": "3.0",
+      "operation": {
+        "name": "find",
+        "arguments": {
+          "filter": {
+            "_id": {
+              "$gte": 1
+            }
+          },
+          "sort": {
+            "_id": 1
+          },
+          "batchSize": {
+            "$numberLong": "3"
+          },
+          "limit": {
+            "$numberLong": "4"
+          }
+        }
+      },
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "find": "test",
+              "filter": {
+                "_id": {
+                  "$gte": 1
+                }
+              },
+              "sort": {
+                "_id": 1
+              },
+              "batchSize": {
+                "$numberLong": "3"
+              },
+              "limit": {
+                "$numberLong": "4"
+              }
+            },
+            "command_name": "find",
+            "database_name": "command-monitoring-tests"
+          }
+        },
+        {
+          "command_succeeded_event": {
+            "reply": {
+              "ok": 1,
+              "cursor": {
+                "id": {
+                  "$numberLong": "42"
+                },
+                "ns": "command-monitoring-tests.test",
+                "firstBatch": [
+                  {
+                    "_id": 1,
+                    "x": 11
+                  },
+                  {
+                    "_id": 2,
+                    "x": 22
+                  },
+                  {
+                    "_id": 3,
+                    "x": 33
+                  }
+                ]
+              }
+            },
+            "command_name": "find"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "getMore": {
+                "$numberLong": "42"
+              },
+              "collection": "test",
+              "batchSize": {
+                "$numberLong": "1"
+              }
+            },
+            "command_name": "getMore",
+            "database_name": "command-monitoring-tests"
+          }
+        },
+        {
+          "command_succeeded_event": {
+            "reply": {
+              "ok": 1,
+              "cursor": {
+                "id": {
+                  "$numberLong": "42"
+                },
+                "ns": "command-monitoring-tests.test",
+                "nextBatch": [
+                  {
+                    "_id": 4,
+                    "x": 44
+                  }
+                ]
+              }
+            },
+            "command_name": "getMore"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "killCursors": "test",
+              "cursors": [
+                {
+                  "$numberLong": "42"
+                }
+              ]
+            },
+            "command_name": "killCursors",
+            "database_name": "command-monitoring-tests"
+          }
+        },
+        {
+          "command_succeeded_event": {
+            "reply": {
+              "ok": 1,
+              "cursorsUnknown": [
+                {
+                  "$numberLong": "42"
+                }
+              ]
+            },
+            "command_name": "killCursors"
+          }
+        }
+      ]
+    },
+    {
+      "description": "A successful find event with a getmore and the server kills the cursor",
+      "ignore_if_server_version_less_than": "3.1",
+      "ignore_if_topology_type": [
+        "sharded"
+      ],
+      "operation": {
+        "name": "find",
+        "arguments": {
+          "filter": {
+            "_id": {
+              "$gte": 1
+            }
+          },
+          "sort": {
+            "_id": 1
+          },
+          "batchSize": {
+            "$numberLong": "3"
+          },
+          "limit": {
+            "$numberLong": "4"
+          }
+        }
+      },
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "find": "test",
+              "filter": {
+                "_id": {
+                  "$gte": 1
+                }
+              },
+              "sort": {
+                "_id": 1
+              },
+              "batchSize": {
+                "$numberLong": "3"
+              },
+              "limit": {
+                "$numberLong": "4"
+              }
+            },
+            "command_name": "find",
+            "database_name": "command-monitoring-tests"
+          }
+        },
+        {
+          "command_succeeded_event": {
+            "reply": {
+              "ok": 1,
+              "cursor": {
+                "id": {
+                  "$numberLong": "42"
+                },
+                "ns": "command-monitoring-tests.test",
+                "firstBatch": [
+                  {
+                    "_id": 1,
+                    "x": 11
+                  },
+                  {
+                    "_id": 2,
+                    "x": 22
+                  },
+                  {
+                    "_id": 3,
+                    "x": 33
+                  }
+                ]
+              }
+            },
+            "command_name": "find"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "getMore": {
+                "$numberLong": "42"
+              },
+              "collection": "test",
+              "batchSize": {
+                "$numberLong": "1"
+              }
+            },
+            "command_name": "getMore",
+            "database_name": "command-monitoring-tests"
+          }
+        },
+        {
+          "command_succeeded_event": {
+            "reply": {
+              "ok": 1,
+              "cursor": {
+                "id": {
+                  "$numberLong": "0"
+                },
+                "ns": "command-monitoring-tests.test",
+                "nextBatch": [
+                  {
+                    "_id": 4,
+                    "x": 44
+                  }
+                ]
+              }
+            },
+            "command_name": "getMore"
+          }
+        }
+      ]
+    },
+    {
+      "description": "A failed find event",
+      "operation": {
+        "name": "find",
+        "arguments": {
+          "filter": {
+            "$or": true
+          }
+        }
+      },
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "find": "test",
+              "filter": {
+                "$or": true
+              }
+            },
+            "command_name": "find",
+            "database_name": "command-monitoring-tests"
+          }
+        },
+        {
+          "command_failed_event": {
+            "command_name": "find"
+          }
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/command-monitoring/insertMany.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/command-monitoring/insertMany.json
new file mode 100644
index 0000000000000000000000000000000000000000..0becf928e4dd24649c4039c6fddb3c8c8e27513a
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/command-monitoring/insertMany.json	
@@ -0,0 +1,145 @@
+{
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    }
+  ],
+  "collection_name": "test",
+  "database_name": "command-monitoring-tests",
+  "tests": [
+    {
+      "description": "A successful insert many",
+      "operation": {
+        "name": "insertMany",
+        "arguments": {
+          "documents": [
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      },
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 2,
+                  "x": 22
+                }
+              ],
+              "ordered": true
+            },
+            "command_name": "insert",
+            "database_name": "command-monitoring-tests"
+          }
+        },
+        {
+          "command_succeeded_event": {
+            "reply": {
+              "ok": 1,
+              "n": 1
+            },
+            "command_name": "insert"
+          }
+        }
+      ]
+    },
+    {
+      "description": "A successful insert many command with write errors",
+      "operation": {
+        "name": "insertMany",
+        "arguments": {
+          "documents": [
+            {
+              "_id": 1,
+              "x": 11
+            }
+          ]
+        }
+      },
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1,
+                  "x": 11
+                }
+              ],
+              "ordered": true
+            },
+            "command_name": "insert",
+            "database_name": "command-monitoring-tests"
+          }
+        },
+        {
+          "command_succeeded_event": {
+            "reply": {
+              "ok": 1,
+              "n": 0,
+              "writeErrors": [
+                {
+                  "index": 0,
+                  "code": 42,
+                  "errmsg": ""
+                }
+              ]
+            },
+            "command_name": "insert"
+          }
+        }
+      ]
+    },
+    {
+      "description": "A successful unordered insert many",
+      "operation": {
+        "name": "insertMany",
+        "arguments": {
+          "documents": [
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ],
+          "options": {
+            "ordered": false
+          }
+        }
+      },
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 2,
+                  "x": 22
+                }
+              ],
+              "ordered": false
+            },
+            "command_name": "insert",
+            "database_name": "command-monitoring-tests"
+          }
+        },
+        {
+          "command_succeeded_event": {
+            "reply": {
+              "ok": 1,
+              "n": 1
+            },
+            "command_name": "insert"
+          }
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/command-monitoring/insertOne.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/command-monitoring/insertOne.json
new file mode 100644
index 0000000000000000000000000000000000000000..877bca1a615dc15efa337699619cda4866d9f0e4
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/command-monitoring/insertOne.json	
@@ -0,0 +1,97 @@
+{
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    }
+  ],
+  "collection_name": "test",
+  "database_name": "command-monitoring-tests",
+  "tests": [
+    {
+      "description": "A successful insert one",
+      "operation": {
+        "name": "insertOne",
+        "arguments": {
+          "document": {
+            "_id": 2,
+            "x": 22
+          }
+        }
+      },
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 2,
+                  "x": 22
+                }
+              ],
+              "ordered": true
+            },
+            "command_name": "insert",
+            "database_name": "command-monitoring-tests"
+          }
+        },
+        {
+          "command_succeeded_event": {
+            "reply": {
+              "ok": 1,
+              "n": 1
+            },
+            "command_name": "insert"
+          }
+        }
+      ]
+    },
+    {
+      "description": "A successful insert one command with write errors",
+      "operation": {
+        "name": "insertOne",
+        "arguments": {
+          "document": {
+            "_id": 1,
+            "x": 11
+          }
+        }
+      },
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1,
+                  "x": 11
+                }
+              ],
+              "ordered": true
+            },
+            "command_name": "insert",
+            "database_name": "command-monitoring-tests"
+          }
+        },
+        {
+          "command_succeeded_event": {
+            "reply": {
+              "ok": 1,
+              "n": 0,
+              "writeErrors": [
+                {
+                  "index": 0,
+                  "code": 42,
+                  "errmsg": ""
+                }
+              ]
+            },
+            "command_name": "insert"
+          }
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/command-monitoring/unacknowledgedBulkWrite.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/command-monitoring/unacknowledgedBulkWrite.json
new file mode 100644
index 0000000000000000000000000000000000000000..ae116289eba62b12853c95fd4b7b89e7817c3f37
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/command-monitoring/unacknowledgedBulkWrite.json	
@@ -0,0 +1,69 @@
+{
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    }
+  ],
+  "collection_name": "test-unacknowledged-bulk-write",
+  "database_name": "command-monitoring-tests",
+  "tests": [
+    {
+      "description": "A successful unordered bulk write with an unacknowledged write concern",
+      "comment": "On a 2.4 server, no GLE is sent and requires a client-side manufactured reply",
+      "operation": {
+        "name": "bulkWrite",
+        "collectionOptions": {
+          "writeConcern": {
+            "w": 0
+          }
+        },
+        "arguments": {
+          "requests": [
+            {
+              "name": "insertOne",
+              "arguments": {
+                "document": {
+                  "_id": "unorderedBulkWriteInsertW0",
+                  "x": 44
+                }
+              }
+            }
+          ],
+          "options": {
+            "ordered": false
+          }
+        }
+      },
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test-unacknowledged-bulk-write",
+              "documents": [
+                {
+                  "_id": "unorderedBulkWriteInsertW0",
+                  "x": 44
+                }
+              ],
+              "ordered": false,
+              "writeConcern": {
+                "w": 0
+              }
+            },
+            "command_name": "insert",
+            "database_name": "command-monitoring-tests"
+          }
+        },
+        {
+          "command_succeeded_event": {
+            "reply": {
+              "ok": 1
+            },
+            "command_name": "insert"
+          }
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/command-monitoring/updateMany.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/command-monitoring/updateMany.json
new file mode 100644
index 0000000000000000000000000000000000000000..d82792fc4e4074d8863ecb745026e5e9990bf450
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/command-monitoring/updateMany.json	
@@ -0,0 +1,135 @@
+{
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    },
+    {
+      "_id": 3,
+      "x": 33
+    }
+  ],
+  "collection_name": "test",
+  "database_name": "command-monitoring-tests",
+  "tests": [
+    {
+      "description": "A successful update many",
+      "operation": {
+        "name": "updateMany",
+        "arguments": {
+          "filter": {
+            "_id": {
+              "$gt": 1
+            }
+          },
+          "update": {
+            "$inc": {
+              "x": 1
+            }
+          }
+        }
+      },
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "update": "test",
+              "ordered": true,
+              "updates": [
+                {
+                  "q": {
+                    "_id": {
+                      "$gt": 1
+                    }
+                  },
+                  "u": {
+                    "$inc": {
+                      "x": 1
+                    }
+                  },
+                  "multi": true
+                }
+              ]
+            },
+            "command_name": "update",
+            "database_name": "command-monitoring-tests"
+          }
+        },
+        {
+          "command_succeeded_event": {
+            "reply": {
+              "ok": 1,
+              "n": 2
+            },
+            "command_name": "update"
+          }
+        }
+      ]
+    },
+    {
+      "description": "A successful update many command with write errors",
+      "operation": {
+        "name": "updateMany",
+        "arguments": {
+          "filter": {
+            "_id": {
+              "$gt": 1
+            }
+          },
+          "update": {
+            "$nothing": {
+              "x": 1
+            }
+          }
+        }
+      },
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "update": "test",
+              "ordered": true,
+              "updates": [
+                {
+                  "q": {
+                    "_id": {
+                      "$gt": 1
+                    }
+                  },
+                  "u": {
+                    "$nothing": {
+                      "x": 1
+                    }
+                  },
+                  "multi": true
+                }
+              ]
+            },
+            "command_name": "update",
+            "database_name": "command-monitoring-tests"
+          }
+        },
+        {
+          "command_succeeded_event": {
+            "reply": {
+              "ok": 1,
+              "n": 0,
+              "writeErrors": [
+                {
+                  "index": 0,
+                  "code": 42,
+                  "errmsg": ""
+                }
+              ]
+            },
+            "command_name": "update"
+          }
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/command-monitoring/updateOne.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/command-monitoring/updateOne.json
new file mode 100644
index 0000000000000000000000000000000000000000..ba41dbb0c0afd80922ebd7cd00129268059f09ae
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/command-monitoring/updateOne.json	
@@ -0,0 +1,190 @@
+{
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    },
+    {
+      "_id": 3,
+      "x": 33
+    }
+  ],
+  "collection_name": "test",
+  "database_name": "command-monitoring-tests",
+  "tests": [
+    {
+      "description": "A successful update one",
+      "operation": {
+        "name": "updateOne",
+        "arguments": {
+          "filter": {
+            "_id": {
+              "$gt": 1
+            }
+          },
+          "update": {
+            "$inc": {
+              "x": 1
+            }
+          }
+        }
+      },
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "update": "test",
+              "ordered": true,
+              "updates": [
+                {
+                  "q": {
+                    "_id": {
+                      "$gt": 1
+                    }
+                  },
+                  "u": {
+                    "$inc": {
+                      "x": 1
+                    }
+                  }
+                }
+              ]
+            },
+            "command_name": "update",
+            "database_name": "command-monitoring-tests"
+          }
+        },
+        {
+          "command_succeeded_event": {
+            "reply": {
+              "ok": 1,
+              "n": 1
+            },
+            "command_name": "update"
+          }
+        }
+      ]
+    },
+    {
+      "description": "A successful update one with upsert when the upserted id is not an object id",
+      "operation": {
+        "name": "updateOne",
+        "arguments": {
+          "filter": {
+            "_id": 4
+          },
+          "update": {
+            "$inc": {
+              "x": 1
+            }
+          },
+          "upsert": true
+        }
+      },
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "update": "test",
+              "ordered": true,
+              "updates": [
+                {
+                  "q": {
+                    "_id": 4
+                  },
+                  "u": {
+                    "$inc": {
+                      "x": 1
+                    }
+                  },
+                  "upsert": true
+                }
+              ]
+            },
+            "command_name": "update",
+            "database_name": "command-monitoring-tests"
+          }
+        },
+        {
+          "command_succeeded_event": {
+            "reply": {
+              "ok": 1,
+              "n": 1,
+              "upserted": [
+                {
+                  "index": 0,
+                  "_id": 4
+                }
+              ]
+            },
+            "command_name": "update"
+          }
+        }
+      ]
+    },
+    {
+      "description": "A successful update one command with write errors",
+      "operation": {
+        "name": "updateOne",
+        "arguments": {
+          "filter": {
+            "_id": {
+              "$gt": 1
+            }
+          },
+          "update": {
+            "$nothing": {
+              "x": 1
+            }
+          }
+        }
+      },
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "update": "test",
+              "ordered": true,
+              "updates": [
+                {
+                  "q": {
+                    "_id": {
+                      "$gt": 1
+                    }
+                  },
+                  "u": {
+                    "$nothing": {
+                      "x": 1
+                    }
+                  }
+                }
+              ]
+            },
+            "command_name": "update",
+            "database_name": "command-monitoring-tests"
+          }
+        },
+        {
+          "command_succeeded_event": {
+            "reply": {
+              "ok": 1,
+              "n": 0,
+              "writeErrors": [
+                {
+                  "index": 0,
+                  "code": 42,
+                  "errmsg": ""
+                }
+              ]
+            },
+            "command_name": "update"
+          }
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/aggregate-merge.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/aggregate-merge.json
new file mode 100644
index 0000000000000000000000000000000000000000..c61736a0bbfe62e3ffbd1751b3d353d9be8b91c8
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/aggregate-merge.json	
@@ -0,0 +1,415 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.1.11"
+    }
+  ],
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    },
+    {
+      "_id": 3,
+      "x": 33
+    }
+  ],
+  "collection_name": "test_aggregate_merge",
+  "tests": [
+    {
+      "description": "Aggregate with $merge",
+      "operations": [
+        {
+          "object": "collection",
+          "name": "aggregate",
+          "arguments": {
+            "pipeline": [
+              {
+                "$sort": {
+                  "x": 1
+                }
+              },
+              {
+                "$match": {
+                  "_id": {
+                    "$gt": 1
+                  }
+                }
+              },
+              {
+                "$merge": {
+                  "into": "other_test_collection"
+                }
+              }
+            ]
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test_aggregate_merge",
+              "pipeline": [
+                {
+                  "$sort": {
+                    "x": 1
+                  }
+                },
+                {
+                  "$match": {
+                    "_id": {
+                      "$gt": 1
+                    }
+                  }
+                },
+                {
+                  "$merge": {
+                    "into": "other_test_collection"
+                  }
+                }
+              ]
+            }
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "name": "other_test_collection",
+          "data": [
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "Aggregate with $merge and batch size of 0",
+      "operations": [
+        {
+          "object": "collection",
+          "name": "aggregate",
+          "arguments": {
+            "pipeline": [
+              {
+                "$sort": {
+                  "x": 1
+                }
+              },
+              {
+                "$match": {
+                  "_id": {
+                    "$gt": 1
+                  }
+                }
+              },
+              {
+                "$merge": {
+                  "into": "other_test_collection"
+                }
+              }
+            ],
+            "batchSize": 0
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test_aggregate_merge",
+              "pipeline": [
+                {
+                  "$sort": {
+                    "x": 1
+                  }
+                },
+                {
+                  "$match": {
+                    "_id": {
+                      "$gt": 1
+                    }
+                  }
+                },
+                {
+                  "$merge": {
+                    "into": "other_test_collection"
+                  }
+                }
+              ],
+              "cursor": {}
+            }
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "name": "other_test_collection",
+          "data": [
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "Aggregate with $merge and majority readConcern",
+      "operations": [
+        {
+          "object": "collection",
+          "name": "aggregate",
+          "collectionOptions": {
+            "readConcern": {
+              "level": "majority"
+            }
+          },
+          "arguments": {
+            "pipeline": [
+              {
+                "$sort": {
+                  "x": 1
+                }
+              },
+              {
+                "$match": {
+                  "_id": {
+                    "$gt": 1
+                  }
+                }
+              },
+              {
+                "$merge": {
+                  "into": "other_test_collection"
+                }
+              }
+            ]
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test_aggregate_merge",
+              "pipeline": [
+                {
+                  "$sort": {
+                    "x": 1
+                  }
+                },
+                {
+                  "$match": {
+                    "_id": {
+                      "$gt": 1
+                    }
+                  }
+                },
+                {
+                  "$merge": {
+                    "into": "other_test_collection"
+                  }
+                }
+              ],
+              "readConcern": {
+                "level": "majority"
+              }
+            }
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "name": "other_test_collection",
+          "data": [
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "Aggregate with $merge and local readConcern",
+      "operations": [
+        {
+          "object": "collection",
+          "name": "aggregate",
+          "collectionOptions": {
+            "readConcern": {
+              "level": "local"
+            }
+          },
+          "arguments": {
+            "pipeline": [
+              {
+                "$sort": {
+                  "x": 1
+                }
+              },
+              {
+                "$match": {
+                  "_id": {
+                    "$gt": 1
+                  }
+                }
+              },
+              {
+                "$merge": {
+                  "into": "other_test_collection"
+                }
+              }
+            ]
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test_aggregate_merge",
+              "pipeline": [
+                {
+                  "$sort": {
+                    "x": 1
+                  }
+                },
+                {
+                  "$match": {
+                    "_id": {
+                      "$gt": 1
+                    }
+                  }
+                },
+                {
+                  "$merge": {
+                    "into": "other_test_collection"
+                  }
+                }
+              ],
+              "readConcern": {
+                "level": "local"
+              }
+            }
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "name": "other_test_collection",
+          "data": [
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "Aggregate with $merge and available readConcern",
+      "operations": [
+        {
+          "object": "collection",
+          "name": "aggregate",
+          "collectionOptions": {
+            "readConcern": {
+              "level": "available"
+            }
+          },
+          "arguments": {
+            "pipeline": [
+              {
+                "$sort": {
+                  "x": 1
+                }
+              },
+              {
+                "$match": {
+                  "_id": {
+                    "$gt": 1
+                  }
+                }
+              },
+              {
+                "$merge": {
+                  "into": "other_test_collection"
+                }
+              }
+            ]
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test_aggregate_merge",
+              "pipeline": [
+                {
+                  "$sort": {
+                    "x": 1
+                  }
+                },
+                {
+                  "$match": {
+                    "_id": {
+                      "$gt": 1
+                    }
+                  }
+                },
+                {
+                  "$merge": {
+                    "into": "other_test_collection"
+                  }
+                }
+              ],
+              "readConcern": {
+                "level": "available"
+              }
+            }
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "name": "other_test_collection",
+          "data": [
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/aggregate-out-readConcern.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/aggregate-out-readConcern.json
new file mode 100644
index 0000000000000000000000000000000000000000..c39ee0e2815e8218f24df8b17f62f0dea9338b37
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/aggregate-out-readConcern.json	
@@ -0,0 +1,385 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.1.0",
+      "topology": [
+        "replicaset",
+        "sharded"
+      ]
+    }
+  ],
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    },
+    {
+      "_id": 3,
+      "x": 33
+    }
+  ],
+  "collection_name": "test_aggregate_out_readconcern",
+  "tests": [
+    {
+      "description": "readConcern majority with out stage",
+      "operations": [
+        {
+          "object": "collection",
+          "name": "aggregate",
+          "collectionOptions": {
+            "readConcern": {
+              "level": "majority"
+            }
+          },
+          "arguments": {
+            "pipeline": [
+              {
+                "$sort": {
+                  "x": 1
+                }
+              },
+              {
+                "$match": {
+                  "_id": {
+                    "$gt": 1
+                  }
+                }
+              },
+              {
+                "$out": "other_test_collection"
+              }
+            ]
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test_aggregate_out_readconcern",
+              "pipeline": [
+                {
+                  "$sort": {
+                    "x": 1
+                  }
+                },
+                {
+                  "$match": {
+                    "_id": {
+                      "$gt": 1
+                    }
+                  }
+                },
+                {
+                  "$out": "other_test_collection"
+                }
+              ],
+              "readConcern": {
+                "level": "majority"
+              }
+            }
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "name": "other_test_collection",
+          "data": [
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "readConcern local with out stage",
+      "operations": [
+        {
+          "object": "collection",
+          "name": "aggregate",
+          "collectionOptions": {
+            "readConcern": {
+              "level": "local"
+            }
+          },
+          "arguments": {
+            "pipeline": [
+              {
+                "$sort": {
+                  "x": 1
+                }
+              },
+              {
+                "$match": {
+                  "_id": {
+                    "$gt": 1
+                  }
+                }
+              },
+              {
+                "$out": "other_test_collection"
+              }
+            ]
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test_aggregate_out_readconcern",
+              "pipeline": [
+                {
+                  "$sort": {
+                    "x": 1
+                  }
+                },
+                {
+                  "$match": {
+                    "_id": {
+                      "$gt": 1
+                    }
+                  }
+                },
+                {
+                  "$out": "other_test_collection"
+                }
+              ],
+              "readConcern": {
+                "level": "local"
+              }
+            }
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "name": "other_test_collection",
+          "data": [
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "readConcern available with out stage",
+      "operations": [
+        {
+          "object": "collection",
+          "name": "aggregate",
+          "collectionOptions": {
+            "readConcern": {
+              "level": "available"
+            }
+          },
+          "arguments": {
+            "pipeline": [
+              {
+                "$sort": {
+                  "x": 1
+                }
+              },
+              {
+                "$match": {
+                  "_id": {
+                    "$gt": 1
+                  }
+                }
+              },
+              {
+                "$out": "other_test_collection"
+              }
+            ]
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test_aggregate_out_readconcern",
+              "pipeline": [
+                {
+                  "$sort": {
+                    "x": 1
+                  }
+                },
+                {
+                  "$match": {
+                    "_id": {
+                      "$gt": 1
+                    }
+                  }
+                },
+                {
+                  "$out": "other_test_collection"
+                }
+              ],
+              "readConcern": {
+                "level": "available"
+              }
+            }
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "name": "other_test_collection",
+          "data": [
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "readConcern linearizable with out stage",
+      "operations": [
+        {
+          "object": "collection",
+          "name": "aggregate",
+          "collectionOptions": {
+            "readConcern": {
+              "level": "linearizable"
+            }
+          },
+          "arguments": {
+            "pipeline": [
+              {
+                "$sort": {
+                  "x": 1
+                }
+              },
+              {
+                "$match": {
+                  "_id": {
+                    "$gt": 1
+                  }
+                }
+              },
+              {
+                "$out": "other_test_collection"
+              }
+            ]
+          },
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test_aggregate_out_readconcern",
+              "pipeline": [
+                {
+                  "$sort": {
+                    "x": 1
+                  }
+                },
+                {
+                  "$match": {
+                    "_id": {
+                      "$gt": 1
+                    }
+                  }
+                },
+                {
+                  "$out": "other_test_collection"
+                }
+              ],
+              "readConcern": {
+                "level": "linearizable"
+              }
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "invalid readConcern with out stage",
+      "operations": [
+        {
+          "object": "collection",
+          "name": "aggregate",
+          "collectionOptions": {
+            "readConcern": {
+              "level": "!invalid123"
+            }
+          },
+          "arguments": {
+            "pipeline": [
+              {
+                "$sort": {
+                  "x": 1
+                }
+              },
+              {
+                "$match": {
+                  "_id": {
+                    "$gt": 1
+                  }
+                }
+              },
+              {
+                "$out": "other_test_collection"
+              }
+            ]
+          },
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test_aggregate_out_readconcern",
+              "pipeline": [
+                {
+                  "$sort": {
+                    "x": 1
+                  }
+                },
+                {
+                  "$match": {
+                    "_id": {
+                      "$gt": 1
+                    }
+                  }
+                },
+                {
+                  "$out": "other_test_collection"
+                }
+              ],
+              "readConcern": {
+                "level": "!invalid123"
+              }
+            }
+          }
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/bulkWrite-arrayFilters-clientError.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/bulkWrite-arrayFilters-clientError.json
new file mode 100644
index 0000000000000000000000000000000000000000..22e22f0efb1b737837a63edddd5563e6f75328e6
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/bulkWrite-arrayFilters-clientError.json	
@@ -0,0 +1,110 @@
+{
+  "runOn": [
+    {
+      "maxServerVersion": "3.5.5"
+    }
+  ],
+  "data": [
+    {
+      "_id": 1,
+      "y": [
+        {
+          "b": 3
+        },
+        {
+          "b": 1
+        }
+      ]
+    },
+    {
+      "_id": 2,
+      "y": [
+        {
+          "b": 0
+        },
+        {
+          "b": 1
+        }
+      ]
+    }
+  ],
+  "tests": [
+    {
+      "description": "BulkWrite on server that doesn't support arrayFilters",
+      "operations": [
+        {
+          "name": "bulkWrite",
+          "arguments": {
+            "requests": [
+              {
+                "name": "updateOne",
+                "arguments": {
+                  "filter": {},
+                  "update": {
+                    "$set": {
+                      "y.0.b": 2
+                    }
+                  },
+                  "arrayFilters": [
+                    {
+                      "i.b": 1
+                    }
+                  ]
+                }
+              }
+            ],
+            "options": {
+              "ordered": true
+            }
+          },
+          "error": true
+        }
+      ],
+      "expectations": []
+    },
+    {
+      "description": "BulkWrite on server that doesn't support arrayFilters with arrayFilters on second op",
+      "operations": [
+        {
+          "name": "bulkWrite",
+          "arguments": {
+            "requests": [
+              {
+                "name": "updateOne",
+                "arguments": {
+                  "filter": {},
+                  "update": {
+                    "$set": {
+                      "y.0.b": 2
+                    }
+                  }
+                }
+              },
+              {
+                "name": "updateMany",
+                "arguments": {
+                  "filter": {},
+                  "update": {
+                    "$set": {
+                      "y.$[i].b": 2
+                    }
+                  },
+                  "arrayFilters": [
+                    {
+                      "i.b": 1
+                    }
+                  ]
+                }
+              }
+            ],
+            "options": {
+              "ordered": true
+            }
+          },
+          "error": true
+        }
+      ],
+      "expectations": []
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/bulkWrite-arrayFilters.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/bulkWrite-arrayFilters.json
new file mode 100644
index 0000000000000000000000000000000000000000..2d3ce96de17b77874903a6fe23b77e33b6ad4fb3
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/bulkWrite-arrayFilters.json	
@@ -0,0 +1,226 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "3.5.6"
+    }
+  ],
+  "data": [
+    {
+      "_id": 1,
+      "y": [
+        {
+          "b": 3
+        },
+        {
+          "b": 1
+        }
+      ]
+    },
+    {
+      "_id": 2,
+      "y": [
+        {
+          "b": 0
+        },
+        {
+          "b": 1
+        }
+      ]
+    }
+  ],
+  "collection_name": "test",
+  "database_name": "crud-tests",
+  "tests": [
+    {
+      "description": "BulkWrite updateOne with arrayFilters",
+      "operations": [
+        {
+          "name": "bulkWrite",
+          "arguments": {
+            "requests": [
+              {
+                "name": "updateOne",
+                "arguments": {
+                  "filter": {},
+                  "update": {
+                    "$set": {
+                      "y.$[i].b": 2
+                    }
+                  },
+                  "arrayFilters": [
+                    {
+                      "i.b": 3
+                    }
+                  ]
+                }
+              }
+            ],
+            "options": {
+              "ordered": true
+            }
+          },
+          "result": {
+            "deletedCount": 0,
+            "insertedCount": 0,
+            "insertedIds": {},
+            "matchedCount": 1,
+            "modifiedCount": 1,
+            "upsertedCount": 0,
+            "upsertedIds": {}
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "update": "test",
+              "updates": [
+                {
+                  "q": {},
+                  "u": {
+                    "$set": {
+                      "y.$[i].b": 2
+                    }
+                  },
+                  "arrayFilters": [
+                    {
+                      "i.b": 3
+                    }
+                  ]
+                }
+              ],
+              "ordered": true
+            },
+            "command_name": "update",
+            "database_name": "crud-tests"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "y": [
+                {
+                  "b": 2
+                },
+                {
+                  "b": 1
+                }
+              ]
+            },
+            {
+              "_id": 2,
+              "y": [
+                {
+                  "b": 0
+                },
+                {
+                  "b": 1
+                }
+              ]
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "BulkWrite updateMany with arrayFilters",
+      "operations": [
+        {
+          "name": "bulkWrite",
+          "arguments": {
+            "requests": [
+              {
+                "name": "updateMany",
+                "arguments": {
+                  "filter": {},
+                  "update": {
+                    "$set": {
+                      "y.$[i].b": 2
+                    }
+                  },
+                  "arrayFilters": [
+                    {
+                      "i.b": 1
+                    }
+                  ]
+                }
+              }
+            ],
+            "options": {
+              "ordered": true
+            }
+          },
+          "result": {
+            "deletedCount": 0,
+            "insertedCount": 0,
+            "insertedIds": {},
+            "matchedCount": 2,
+            "modifiedCount": 2,
+            "upsertedCount": 0,
+            "upsertedIds": {}
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "update": "test",
+              "updates": [
+                {
+                  "q": {},
+                  "u": {
+                    "$set": {
+                      "y.$[i].b": 2
+                    }
+                  },
+                  "multi": true,
+                  "arrayFilters": [
+                    {
+                      "i.b": 1
+                    }
+                  ]
+                }
+              ],
+              "ordered": true
+            },
+            "command_name": "update",
+            "database_name": "crud-tests"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "y": [
+                {
+                  "b": 3
+                },
+                {
+                  "b": 2
+                }
+              ]
+            },
+            {
+              "_id": 2,
+              "y": [
+                {
+                  "b": 0
+                },
+                {
+                  "b": 2
+                }
+              ]
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/bulkWrite-delete-hint-clientError.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/bulkWrite-delete-hint-clientError.json
new file mode 100644
index 0000000000000000000000000000000000000000..cfeac904ca17708f2d0849ccba0ccd4c3ce8c285
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/bulkWrite-delete-hint-clientError.json	
@@ -0,0 +1,150 @@
+{
+  "runOn": [
+    {
+      "maxServerVersion": "3.3.99"
+    }
+  ],
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    },
+    {
+      "_id": 3,
+      "x": 33
+    },
+    {
+      "_id": 4,
+      "x": 44
+    }
+  ],
+  "collection_name": "BulkWrite_delete_hint",
+  "tests": [
+    {
+      "description": "BulkWrite deleteOne with hints unsupported (client-side error)",
+      "operations": [
+        {
+          "name": "bulkWrite",
+          "arguments": {
+            "requests": [
+              {
+                "name": "deleteOne",
+                "arguments": {
+                  "filter": {
+                    "_id": 1
+                  },
+                  "hint": "_id_"
+                }
+              },
+              {
+                "name": "deleteOne",
+                "arguments": {
+                  "filter": {
+                    "_id": 2
+                  },
+                  "hint": {
+                    "_id": 1
+                  }
+                }
+              }
+            ],
+            "options": {
+              "ordered": true
+            }
+          },
+          "error": true
+        }
+      ],
+      "expectations": [],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            },
+            {
+              "_id": 4,
+              "x": 44
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "BulkWrite deleteMany with hints unsupported (client-side error)",
+      "operations": [
+        {
+          "name": "bulkWrite",
+          "arguments": {
+            "requests": [
+              {
+                "name": "deleteMany",
+                "arguments": {
+                  "filter": {
+                    "_id": {
+                      "$lt": 3
+                    }
+                  },
+                  "hint": "_id_"
+                }
+              },
+              {
+                "name": "deleteMany",
+                "arguments": {
+                  "filter": {
+                    "_id": {
+                      "$gte": 4
+                    }
+                  },
+                  "hint": {
+                    "_id": 1
+                  }
+                }
+              }
+            ],
+            "options": {
+              "ordered": true
+            }
+          },
+          "error": true
+        }
+      ],
+      "expectations": [],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            },
+            {
+              "_id": 4,
+              "x": 44
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/bulkWrite-delete-hint-serverError.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/bulkWrite-delete-hint-serverError.json
new file mode 100644
index 0000000000000000000000000000000000000000..c68973b0f68e28b19d5ea33894d626e429f2a732
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/bulkWrite-delete-hint-serverError.json	
@@ -0,0 +1,209 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "3.4.0",
+      "maxServerVersion": "4.3.3"
+    }
+  ],
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    },
+    {
+      "_id": 3,
+      "x": 33
+    },
+    {
+      "_id": 4,
+      "x": 44
+    }
+  ],
+  "collection_name": "BulkWrite_delete_hint",
+  "tests": [
+    {
+      "description": "BulkWrite deleteOne with hints unsupported (server-side error)",
+      "operations": [
+        {
+          "name": "bulkWrite",
+          "arguments": {
+            "requests": [
+              {
+                "name": "deleteOne",
+                "arguments": {
+                  "filter": {
+                    "_id": 1
+                  },
+                  "hint": "_id_"
+                }
+              },
+              {
+                "name": "deleteOne",
+                "arguments": {
+                  "filter": {
+                    "_id": 2
+                  },
+                  "hint": {
+                    "_id": 1
+                  }
+                }
+              }
+            ],
+            "options": {
+              "ordered": true
+            }
+          },
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "delete": "BulkWrite_delete_hint",
+              "deletes": [
+                {
+                  "q": {
+                    "_id": 1
+                  },
+                  "hint": "_id_",
+                  "limit": 1
+                },
+                {
+                  "q": {
+                    "_id": 2
+                  },
+                  "hint": {
+                    "_id": 1
+                  },
+                  "limit": 1
+                }
+              ],
+              "ordered": true
+            }
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            },
+            {
+              "_id": 4,
+              "x": 44
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "BulkWrite deleteMany with hints unsupported (server-side error)",
+      "operations": [
+        {
+          "name": "bulkWrite",
+          "arguments": {
+            "requests": [
+              {
+                "name": "deleteMany",
+                "arguments": {
+                  "filter": {
+                    "_id": {
+                      "$lt": 3
+                    }
+                  },
+                  "hint": "_id_"
+                }
+              },
+              {
+                "name": "deleteMany",
+                "arguments": {
+                  "filter": {
+                    "_id": {
+                      "$gte": 4
+                    }
+                  },
+                  "hint": {
+                    "_id": 1
+                  }
+                }
+              }
+            ],
+            "options": {
+              "ordered": true
+            }
+          },
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "delete": "BulkWrite_delete_hint",
+              "deletes": [
+                {
+                  "q": {
+                    "_id": {
+                      "$lt": 3
+                    }
+                  },
+                  "hint": "_id_",
+                  "limit": 0
+                },
+                {
+                  "q": {
+                    "_id": {
+                      "$gte": 4
+                    }
+                  },
+                  "hint": {
+                    "_id": 1
+                  },
+                  "limit": 0
+                }
+              ],
+              "ordered": true
+            }
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            },
+            {
+              "_id": 4,
+              "x": 44
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/bulkWrite-delete-hint.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/bulkWrite-delete-hint.json
new file mode 100644
index 0000000000000000000000000000000000000000..ece3238fc3cf824a2091656450d1c2c3feb54068
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/bulkWrite-delete-hint.json	
@@ -0,0 +1,204 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.3.4"
+    }
+  ],
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    },
+    {
+      "_id": 3,
+      "x": 33
+    },
+    {
+      "_id": 4,
+      "x": 44
+    }
+  ],
+  "collection_name": "BulkWrite_delete_hint",
+  "tests": [
+    {
+      "description": "BulkWrite deleteOne with hints",
+      "operations": [
+        {
+          "name": "bulkWrite",
+          "arguments": {
+            "requests": [
+              {
+                "name": "deleteOne",
+                "arguments": {
+                  "filter": {
+                    "_id": 1
+                  },
+                  "hint": "_id_"
+                }
+              },
+              {
+                "name": "deleteOne",
+                "arguments": {
+                  "filter": {
+                    "_id": 2
+                  },
+                  "hint": {
+                    "_id": 1
+                  }
+                }
+              }
+            ],
+            "options": {
+              "ordered": true
+            }
+          },
+          "result": {
+            "deletedCount": 2,
+            "insertedCount": 0,
+            "insertedIds": {},
+            "matchedCount": 0,
+            "modifiedCount": 0,
+            "upsertedCount": 0,
+            "upsertedIds": {}
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "delete": "BulkWrite_delete_hint",
+              "deletes": [
+                {
+                  "q": {
+                    "_id": 1
+                  },
+                  "hint": "_id_",
+                  "limit": 1
+                },
+                {
+                  "q": {
+                    "_id": 2
+                  },
+                  "hint": {
+                    "_id": 1
+                  },
+                  "limit": 1
+                }
+              ],
+              "ordered": true
+            }
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 3,
+              "x": 33
+            },
+            {
+              "_id": 4,
+              "x": 44
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "BulkWrite deleteMany with hints",
+      "operations": [
+        {
+          "name": "bulkWrite",
+          "arguments": {
+            "requests": [
+              {
+                "name": "deleteMany",
+                "arguments": {
+                  "filter": {
+                    "_id": {
+                      "$lt": 3
+                    }
+                  },
+                  "hint": "_id_"
+                }
+              },
+              {
+                "name": "deleteMany",
+                "arguments": {
+                  "filter": {
+                    "_id": {
+                      "$gte": 4
+                    }
+                  },
+                  "hint": {
+                    "_id": 1
+                  }
+                }
+              }
+            ],
+            "options": {
+              "ordered": true
+            }
+          },
+          "result": {
+            "deletedCount": 3,
+            "insertedCount": 0,
+            "insertedIds": {},
+            "matchedCount": 0,
+            "modifiedCount": 0,
+            "upsertedCount": 0,
+            "upsertedIds": {}
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "delete": "BulkWrite_delete_hint",
+              "deletes": [
+                {
+                  "q": {
+                    "_id": {
+                      "$lt": 3
+                    }
+                  },
+                  "hint": "_id_",
+                  "limit": 0
+                },
+                {
+                  "q": {
+                    "_id": {
+                      "$gte": 4
+                    }
+                  },
+                  "hint": {
+                    "_id": 1
+                  },
+                  "limit": 0
+                }
+              ],
+              "ordered": true
+            }
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/bulkWrite-update-hint-clientError.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/bulkWrite-update-hint-clientError.json
new file mode 100644
index 0000000000000000000000000000000000000000..fa919ec51502aa1ccf71c10ad345246ad68787a1
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/bulkWrite-update-hint-clientError.json	
@@ -0,0 +1,235 @@
+{
+  "runOn": [
+    {
+      "maxServerVersion": "3.3.99"
+    }
+  ],
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    },
+    {
+      "_id": 3,
+      "x": 33
+    },
+    {
+      "_id": 4,
+      "x": 44
+    }
+  ],
+  "collection_name": "test_bulkwrite_update_hint",
+  "tests": [
+    {
+      "description": "BulkWrite updateOne with update hints unsupported (client-side error)",
+      "operations": [
+        {
+          "name": "bulkWrite",
+          "arguments": {
+            "requests": [
+              {
+                "name": "updateOne",
+                "arguments": {
+                  "filter": {
+                    "_id": 1
+                  },
+                  "update": {
+                    "$inc": {
+                      "x": 1
+                    }
+                  },
+                  "hint": "_id_"
+                }
+              },
+              {
+                "name": "updateOne",
+                "arguments": {
+                  "filter": {
+                    "_id": 1
+                  },
+                  "update": {
+                    "$inc": {
+                      "x": 1
+                    }
+                  },
+                  "hint": {
+                    "_id": 1
+                  }
+                }
+              }
+            ],
+            "options": {
+              "ordered": true
+            }
+          },
+          "error": true
+        }
+      ],
+      "expectations": [],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            },
+            {
+              "_id": 4,
+              "x": 44
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "BulkWrite updateMany with update hints unsupported (client-side error)",
+      "operations": [
+        {
+          "name": "bulkWrite",
+          "arguments": {
+            "requests": [
+              {
+                "name": "updateMany",
+                "arguments": {
+                  "filter": {
+                    "_id": {
+                      "$lt": 3
+                    }
+                  },
+                  "update": {
+                    "$inc": {
+                      "x": 1
+                    }
+                  },
+                  "hint": "_id_"
+                }
+              },
+              {
+                "name": "updateMany",
+                "arguments": {
+                  "filter": {
+                    "_id": {
+                      "$lt": 3
+                    }
+                  },
+                  "update": {
+                    "$inc": {
+                      "x": 1
+                    }
+                  },
+                  "hint": {
+                    "_id": 1
+                  }
+                }
+              }
+            ],
+            "options": {
+              "ordered": true
+            }
+          },
+          "error": true
+        }
+      ],
+      "expectations": [],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            },
+            {
+              "_id": 4,
+              "x": 44
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "BulkWrite replaceOne with update hints unsupported (client-side error)",
+      "operations": [
+        {
+          "name": "bulkWrite",
+          "arguments": {
+            "requests": [
+              {
+                "name": "replaceOne",
+                "arguments": {
+                  "filter": {
+                    "_id": 3
+                  },
+                  "replacement": {
+                    "x": 333
+                  },
+                  "hint": "_id_"
+                }
+              },
+              {
+                "name": "replaceOne",
+                "arguments": {
+                  "filter": {
+                    "_id": 4
+                  },
+                  "replacement": {
+                    "x": 444
+                  },
+                  "hint": {
+                    "_id": 1
+                  }
+                }
+              }
+            ],
+            "options": {
+              "ordered": true
+            }
+          },
+          "error": true
+        }
+      ],
+      "expectations": [],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            },
+            {
+              "_id": 4,
+              "x": 44
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/bulkWrite-update-hint-serverError.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/bulkWrite-update-hint-serverError.json
new file mode 100644
index 0000000000000000000000000000000000000000..e8b96fffebf26bcc76a7a60180acb75d29dbf63b
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/bulkWrite-update-hint-serverError.json	
@@ -0,0 +1,343 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "3.4.0",
+      "maxServerVersion": "4.1.9"
+    }
+  ],
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    },
+    {
+      "_id": 3,
+      "x": 33
+    },
+    {
+      "_id": 4,
+      "x": 44
+    }
+  ],
+  "collection_name": "test_bulkwrite_update_hint",
+  "tests": [
+    {
+      "description": "BulkWrite updateOne with update hints unsupported (server-side error)",
+      "operations": [
+        {
+          "name": "bulkWrite",
+          "arguments": {
+            "requests": [
+              {
+                "name": "updateOne",
+                "arguments": {
+                  "filter": {
+                    "_id": 1
+                  },
+                  "update": {
+                    "$inc": {
+                      "x": 1
+                    }
+                  },
+                  "hint": "_id_"
+                }
+              },
+              {
+                "name": "updateOne",
+                "arguments": {
+                  "filter": {
+                    "_id": 1
+                  },
+                  "update": {
+                    "$inc": {
+                      "x": 1
+                    }
+                  },
+                  "hint": {
+                    "_id": 1
+                  }
+                }
+              }
+            ],
+            "options": {
+              "ordered": true
+            }
+          },
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "update": "test_bulkwrite_update_hint",
+              "updates": [
+                {
+                  "q": {
+                    "_id": 1
+                  },
+                  "u": {
+                    "$inc": {
+                      "x": 1
+                    }
+                  },
+                  "hint": "_id_"
+                },
+                {
+                  "q": {
+                    "_id": 1
+                  },
+                  "u": {
+                    "$inc": {
+                      "x": 1
+                    }
+                  },
+                  "hint": {
+                    "_id": 1
+                  }
+                }
+              ],
+              "ordered": true
+            }
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            },
+            {
+              "_id": 4,
+              "x": 44
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "BulkWrite updateMany with update hints unsupported (server-side error)",
+      "operations": [
+        {
+          "name": "bulkWrite",
+          "arguments": {
+            "requests": [
+              {
+                "name": "updateMany",
+                "arguments": {
+                  "filter": {
+                    "_id": {
+                      "$lt": 3
+                    }
+                  },
+                  "update": {
+                    "$inc": {
+                      "x": 1
+                    }
+                  },
+                  "hint": "_id_"
+                }
+              },
+              {
+                "name": "updateMany",
+                "arguments": {
+                  "filter": {
+                    "_id": {
+                      "$lt": 3
+                    }
+                  },
+                  "update": {
+                    "$inc": {
+                      "x": 1
+                    }
+                  },
+                  "hint": {
+                    "_id": 1
+                  }
+                }
+              }
+            ],
+            "options": {
+              "ordered": true
+            }
+          },
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "update": "test_bulkwrite_update_hint",
+              "updates": [
+                {
+                  "q": {
+                    "_id": {
+                      "$lt": 3
+                    }
+                  },
+                  "u": {
+                    "$inc": {
+                      "x": 1
+                    }
+                  },
+                  "multi": true,
+                  "hint": "_id_"
+                },
+                {
+                  "q": {
+                    "_id": {
+                      "$lt": 3
+                    }
+                  },
+                  "u": {
+                    "$inc": {
+                      "x": 1
+                    }
+                  },
+                  "multi": true,
+                  "hint": {
+                    "_id": 1
+                  }
+                }
+              ],
+              "ordered": true
+            }
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            },
+            {
+              "_id": 4,
+              "x": 44
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "BulkWrite replaceOne with update hints unsupported (server-side error)",
+      "operations": [
+        {
+          "name": "bulkWrite",
+          "arguments": {
+            "requests": [
+              {
+                "name": "replaceOne",
+                "arguments": {
+                  "filter": {
+                    "_id": 3
+                  },
+                  "replacement": {
+                    "x": 333
+                  },
+                  "hint": "_id_"
+                }
+              },
+              {
+                "name": "replaceOne",
+                "arguments": {
+                  "filter": {
+                    "_id": 4
+                  },
+                  "replacement": {
+                    "x": 444
+                  },
+                  "hint": {
+                    "_id": 1
+                  }
+                }
+              }
+            ],
+            "options": {
+              "ordered": true
+            }
+          },
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "update": "test_bulkwrite_update_hint",
+              "updates": [
+                {
+                  "q": {
+                    "_id": 3
+                  },
+                  "u": {
+                    "x": 333
+                  },
+                  "hint": "_id_"
+                },
+                {
+                  "q": {
+                    "_id": 4
+                  },
+                  "u": {
+                    "x": 444
+                  },
+                  "hint": {
+                    "_id": 1
+                  }
+                }
+              ],
+              "ordered": true
+            }
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            },
+            {
+              "_id": 4,
+              "x": 44
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/bulkWrite-update-hint.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/bulkWrite-update-hint.json
new file mode 100644
index 0000000000000000000000000000000000000000..15e169f76c9956b481213532f5f42a9ca13d4fb4
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/bulkWrite-update-hint.json	
@@ -0,0 +1,366 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.2.0"
+    }
+  ],
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    },
+    {
+      "_id": 3,
+      "x": 33
+    },
+    {
+      "_id": 4,
+      "x": 44
+    }
+  ],
+  "collection_name": "test_bulkwrite_update_hint",
+  "tests": [
+    {
+      "description": "BulkWrite updateOne with update hints",
+      "operations": [
+        {
+          "name": "bulkWrite",
+          "arguments": {
+            "requests": [
+              {
+                "name": "updateOne",
+                "arguments": {
+                  "filter": {
+                    "_id": 1
+                  },
+                  "update": {
+                    "$inc": {
+                      "x": 1
+                    }
+                  },
+                  "hint": "_id_"
+                }
+              },
+              {
+                "name": "updateOne",
+                "arguments": {
+                  "filter": {
+                    "_id": 1
+                  },
+                  "update": {
+                    "$inc": {
+                      "x": 1
+                    }
+                  },
+                  "hint": {
+                    "_id": 1
+                  }
+                }
+              }
+            ],
+            "options": {
+              "ordered": true
+            }
+          },
+          "result": {
+            "deletedCount": 0,
+            "insertedCount": 0,
+            "insertedIds": {},
+            "matchedCount": 2,
+            "modifiedCount": 2,
+            "upsertedCount": 0,
+            "upsertedIds": {}
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "update": "test_bulkwrite_update_hint",
+              "updates": [
+                {
+                  "q": {
+                    "_id": 1
+                  },
+                  "u": {
+                    "$inc": {
+                      "x": 1
+                    }
+                  },
+                  "hint": "_id_"
+                },
+                {
+                  "q": {
+                    "_id": 1
+                  },
+                  "u": {
+                    "$inc": {
+                      "x": 1
+                    }
+                  },
+                  "hint": {
+                    "_id": 1
+                  }
+                }
+              ],
+              "ordered": true
+            }
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 13
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            },
+            {
+              "_id": 4,
+              "x": 44
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "BulkWrite updateMany with update hints",
+      "operations": [
+        {
+          "name": "bulkWrite",
+          "arguments": {
+            "requests": [
+              {
+                "name": "updateMany",
+                "arguments": {
+                  "filter": {
+                    "_id": {
+                      "$lt": 3
+                    }
+                  },
+                  "update": {
+                    "$inc": {
+                      "x": 1
+                    }
+                  },
+                  "hint": "_id_"
+                }
+              },
+              {
+                "name": "updateMany",
+                "arguments": {
+                  "filter": {
+                    "_id": {
+                      "$lt": 3
+                    }
+                  },
+                  "update": {
+                    "$inc": {
+                      "x": 1
+                    }
+                  },
+                  "hint": {
+                    "_id": 1
+                  }
+                }
+              }
+            ],
+            "options": {
+              "ordered": true
+            }
+          },
+          "result": {
+            "deletedCount": 0,
+            "insertedCount": 0,
+            "insertedIds": {},
+            "matchedCount": 4,
+            "modifiedCount": 4,
+            "upsertedCount": 0,
+            "upsertedIds": {}
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "update": "test_bulkwrite_update_hint",
+              "updates": [
+                {
+                  "q": {
+                    "_id": {
+                      "$lt": 3
+                    }
+                  },
+                  "u": {
+                    "$inc": {
+                      "x": 1
+                    }
+                  },
+                  "multi": true,
+                  "hint": "_id_"
+                },
+                {
+                  "q": {
+                    "_id": {
+                      "$lt": 3
+                    }
+                  },
+                  "u": {
+                    "$inc": {
+                      "x": 1
+                    }
+                  },
+                  "multi": true,
+                  "hint": {
+                    "_id": 1
+                  }
+                }
+              ],
+              "ordered": true
+            }
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 13
+            },
+            {
+              "_id": 2,
+              "x": 24
+            },
+            {
+              "_id": 3,
+              "x": 33
+            },
+            {
+              "_id": 4,
+              "x": 44
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "BulkWrite replaceOne with update hints",
+      "operations": [
+        {
+          "name": "bulkWrite",
+          "arguments": {
+            "requests": [
+              {
+                "name": "replaceOne",
+                "arguments": {
+                  "filter": {
+                    "_id": 3
+                  },
+                  "replacement": {
+                    "x": 333
+                  },
+                  "hint": "_id_"
+                }
+              },
+              {
+                "name": "replaceOne",
+                "arguments": {
+                  "filter": {
+                    "_id": 4
+                  },
+                  "replacement": {
+                    "x": 444
+                  },
+                  "hint": {
+                    "_id": 1
+                  }
+                }
+              }
+            ],
+            "options": {
+              "ordered": true
+            }
+          },
+          "result": {
+            "deletedCount": 0,
+            "insertedCount": 0,
+            "insertedIds": {},
+            "matchedCount": 2,
+            "modifiedCount": 2,
+            "upsertedCount": 0,
+            "upsertedIds": {}
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "update": "test_bulkwrite_update_hint",
+              "updates": [
+                {
+                  "q": {
+                    "_id": 3
+                  },
+                  "u": {
+                    "x": 333
+                  },
+                  "hint": "_id_"
+                },
+                {
+                  "q": {
+                    "_id": 4
+                  },
+                  "u": {
+                    "x": 444
+                  },
+                  "hint": {
+                    "_id": 1
+                  }
+                }
+              ],
+              "ordered": true
+            }
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 333
+            },
+            {
+              "_id": 4,
+              "x": 444
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/bulkWrite-update-validation.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/bulkWrite-update-validation.json
new file mode 100644
index 0000000000000000000000000000000000000000..481e13c45cc5e32adb38e5784cb857b92dfdde98
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/bulkWrite-update-validation.json	
@@ -0,0 +1,151 @@
+{
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    },
+    {
+      "_id": 3,
+      "x": 33
+    }
+  ],
+  "tests": [
+    {
+      "description": "BulkWrite replaceOne prohibits atomic modifiers",
+      "operations": [
+        {
+          "name": "bulkWrite",
+          "arguments": {
+            "requests": [
+              {
+                "name": "replaceOne",
+                "arguments": {
+                  "filter": {
+                    "_id": 1
+                  },
+                  "replacement": {
+                    "$set": {
+                      "x": 22
+                    }
+                  }
+                }
+              }
+            ]
+          },
+          "error": true
+        }
+      ],
+      "expectations": [],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "BulkWrite updateOne requires atomic modifiers",
+      "operations": [
+        {
+          "name": "bulkWrite",
+          "arguments": {
+            "requests": [
+              {
+                "name": "updateOne",
+                "arguments": {
+                  "filter": {
+                    "_id": 1
+                  },
+                  "update": {
+                    "x": 22
+                  }
+                }
+              }
+            ]
+          },
+          "error": true
+        }
+      ],
+      "expectations": [],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "BulkWrite updateMany requires atomic modifiers",
+      "operations": [
+        {
+          "name": "bulkWrite",
+          "arguments": {
+            "requests": [
+              {
+                "name": "updateMany",
+                "arguments": {
+                  "filter": {
+                    "_id": {
+                      "$gt": 1
+                    }
+                  },
+                  "update": {
+                    "x": 44
+                  }
+                }
+              }
+            ]
+          },
+          "error": true
+        }
+      ],
+      "expectations": [],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/db-aggregate.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/db-aggregate.json
new file mode 100644
index 0000000000000000000000000000000000000000..d88b9e18197cca88dac6265efb76947ebf8b4dcc
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/db-aggregate.json	
@@ -0,0 +1,81 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "3.6.0"
+    }
+  ],
+  "database_name": "admin",
+  "tests": [
+    {
+      "description": "Aggregate with $listLocalSessions",
+      "operations": [
+        {
+          "name": "aggregate",
+          "object": "database",
+          "arguments": {
+            "pipeline": [
+              {
+                "$listLocalSessions": {}
+              },
+              {
+                "$limit": 1
+              },
+              {
+                "$addFields": {
+                  "dummy": "dummy field"
+                }
+              },
+              {
+                "$project": {
+                  "_id": 0,
+                  "dummy": 1
+                }
+              }
+            ]
+          },
+          "result": [
+            {
+              "dummy": "dummy field"
+            }
+          ]
+        }
+      ]
+    },
+    {
+      "description": "Aggregate with $listLocalSessions and allowDiskUse",
+      "operations": [
+        {
+          "name": "aggregate",
+          "object": "database",
+          "arguments": {
+            "pipeline": [
+              {
+                "$listLocalSessions": {}
+              },
+              {
+                "$limit": 1
+              },
+              {
+                "$addFields": {
+                  "dummy": "dummy field"
+                }
+              },
+              {
+                "$project": {
+                  "_id": 0,
+                  "dummy": 1
+                }
+              }
+            ],
+            "allowDiskUse": true
+          },
+          "result": [
+            {
+              "dummy": "dummy field"
+            }
+          ]
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/deleteMany-hint-clientError.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/deleteMany-hint-clientError.json
new file mode 100644
index 0000000000000000000000000000000000000000..3a0d02566b6ca400b2019f53e3916ea9e271a87b
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/deleteMany-hint-clientError.json	
@@ -0,0 +1,100 @@
+{
+  "runOn": [
+    {
+      "maxServerVersion": "3.3.99"
+    }
+  ],
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    },
+    {
+      "_id": 3,
+      "x": 33
+    }
+  ],
+  "collection_name": "DeleteMany_hint",
+  "tests": [
+    {
+      "description": "DeleteMany with hint string unsupported (client-side error)",
+      "operations": [
+        {
+          "object": "collection",
+          "name": "deleteMany",
+          "arguments": {
+            "filter": {
+              "_id": {
+                "$gt": 1
+              }
+            },
+            "hint": "_id_"
+          },
+          "error": true
+        }
+      ],
+      "expectations": [],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "DeleteMany with hint document unsupported (client-side error)",
+      "operations": [
+        {
+          "object": "collection",
+          "name": "deleteMany",
+          "arguments": {
+            "filter": {
+              "_id": {
+                "$gt": 1
+              }
+            },
+            "hint": {
+              "_id": 1
+            }
+          },
+          "error": true
+        }
+      ],
+      "expectations": [],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/deleteMany-hint-serverError.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/deleteMany-hint-serverError.json
new file mode 100644
index 0000000000000000000000000000000000000000..5829e86df892ec7bb9cd08c7426787746a1c19b6
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/deleteMany-hint-serverError.json	
@@ -0,0 +1,141 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "3.4.0",
+      "maxServerVersion": "4.3.3"
+    }
+  ],
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    },
+    {
+      "_id": 3,
+      "x": 33
+    }
+  ],
+  "collection_name": "DeleteMany_hint",
+  "tests": [
+    {
+      "description": "DeleteMany with hint string unsupported (server-side error)",
+      "operations": [
+        {
+          "object": "collection",
+          "name": "deleteMany",
+          "arguments": {
+            "filter": {
+              "_id": {
+                "$gt": 1
+              }
+            },
+            "hint": "_id_"
+          },
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "delete": "DeleteMany_hint",
+              "deletes": [
+                {
+                  "q": {
+                    "_id": {
+                      "$gt": 1
+                    }
+                  },
+                  "hint": "_id_",
+                  "limit": 0
+                }
+              ]
+            }
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "DeleteMany with hint document unsupported (server-side error)",
+      "operations": [
+        {
+          "object": "collection",
+          "name": "deleteMany",
+          "arguments": {
+            "filter": {
+              "_id": {
+                "$gt": 1
+              }
+            },
+            "hint": {
+              "_id": 1
+            }
+          },
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "delete": "DeleteMany_hint",
+              "deletes": [
+                {
+                  "q": {
+                    "_id": {
+                      "$gt": 1
+                    }
+                  },
+                  "hint": {
+                    "_id": 1
+                  },
+                  "limit": 0
+                }
+              ]
+            }
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/deleteMany-hint.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/deleteMany-hint.json
new file mode 100644
index 0000000000000000000000000000000000000000..51ee38606643f78ddcb847444111cd3757b53bb3
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/deleteMany-hint.json	
@@ -0,0 +1,128 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.3.4"
+    }
+  ],
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    },
+    {
+      "_id": 3,
+      "x": 33
+    }
+  ],
+  "collection_name": "DeleteMany_hint",
+  "tests": [
+    {
+      "description": "DeleteMany with hint string",
+      "operations": [
+        {
+          "object": "collection",
+          "name": "deleteMany",
+          "arguments": {
+            "filter": {
+              "_id": {
+                "$gt": 1
+              }
+            },
+            "hint": "_id_"
+          },
+          "result": {
+            "deletedCount": 2
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "delete": "DeleteMany_hint",
+              "deletes": [
+                {
+                  "q": {
+                    "_id": {
+                      "$gt": 1
+                    }
+                  },
+                  "hint": "_id_",
+                  "limit": 0
+                }
+              ]
+            }
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "DeleteMany with hint document",
+      "operations": [
+        {
+          "object": "collection",
+          "name": "deleteMany",
+          "arguments": {
+            "filter": {
+              "_id": {
+                "$gt": 1
+              }
+            },
+            "hint": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "deletedCount": 2
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "delete": "DeleteMany_hint",
+              "deletes": [
+                {
+                  "q": {
+                    "_id": {
+                      "$gt": 1
+                    }
+                  },
+                  "hint": {
+                    "_id": 1
+                  },
+                  "limit": 0
+                }
+              ]
+            }
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/deleteOne-hint-clientError.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/deleteOne-hint-clientError.json
new file mode 100644
index 0000000000000000000000000000000000000000..97f8ec4924ac819e1870adc59db31e989a8be6c6
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/deleteOne-hint-clientError.json	
@@ -0,0 +1,84 @@
+{
+  "runOn": [
+    {
+      "maxServerVersion": "3.3.99"
+    }
+  ],
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    }
+  ],
+  "collection_name": "DeleteOne_hint",
+  "tests": [
+    {
+      "description": "DeleteOne with hint string unsupported (client-side error)",
+      "operations": [
+        {
+          "object": "collection",
+          "name": "deleteOne",
+          "arguments": {
+            "filter": {
+              "_id": 1
+            },
+            "hint": "_id_"
+          },
+          "error": true
+        }
+      ],
+      "expectations": [],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "DeleteOne with hint document unsupported (client-side error)",
+      "operations": [
+        {
+          "object": "collection",
+          "name": "deleteOne",
+          "arguments": {
+            "filter": {
+              "_id": 1
+            },
+            "hint": {
+              "_id": 1
+            }
+          },
+          "error": true
+        }
+      ],
+      "expectations": [],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/deleteOne-hint-serverError.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/deleteOne-hint-serverError.json
new file mode 100644
index 0000000000000000000000000000000000000000..3cf9400a88daa425ce02020a1dfaa3bf5d536ef2
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/deleteOne-hint-serverError.json	
@@ -0,0 +1,121 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "3.4.0",
+      "maxServerVersion": "4.3.3"
+    }
+  ],
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    }
+  ],
+  "collection_name": "DeleteOne_hint",
+  "tests": [
+    {
+      "description": "DeleteOne with hint string unsupported (server-side error)",
+      "operations": [
+        {
+          "object": "collection",
+          "name": "deleteOne",
+          "arguments": {
+            "filter": {
+              "_id": 1
+            },
+            "hint": "_id_"
+          },
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "delete": "DeleteOne_hint",
+              "deletes": [
+                {
+                  "q": {
+                    "_id": 1
+                  },
+                  "hint": "_id_",
+                  "limit": 1
+                }
+              ]
+            }
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "DeleteOne with hint document unsupported (server-side error)",
+      "operations": [
+        {
+          "object": "collection",
+          "name": "deleteOne",
+          "arguments": {
+            "filter": {
+              "_id": 1
+            },
+            "hint": {
+              "_id": 1
+            }
+          },
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "delete": "DeleteOne_hint",
+              "deletes": [
+                {
+                  "q": {
+                    "_id": 1
+                  },
+                  "hint": {
+                    "_id": 1
+                  },
+                  "limit": 1
+                }
+              ]
+            }
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/deleteOne-hint.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/deleteOne-hint.json
new file mode 100644
index 0000000000000000000000000000000000000000..ec8e7715a294e78b4a53ac63b5b56d6841a90c73
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/deleteOne-hint.json	
@@ -0,0 +1,116 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.3.4"
+    }
+  ],
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    }
+  ],
+  "collection_name": "DeleteOne_hint",
+  "tests": [
+    {
+      "description": "DeleteOne with hint string",
+      "operations": [
+        {
+          "object": "collection",
+          "name": "deleteOne",
+          "arguments": {
+            "filter": {
+              "_id": 1
+            },
+            "hint": "_id_"
+          },
+          "result": {
+            "deletedCount": 1
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "delete": "DeleteOne_hint",
+              "deletes": [
+                {
+                  "q": {
+                    "_id": 1
+                  },
+                  "hint": "_id_",
+                  "limit": 1
+                }
+              ]
+            }
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "deleteOne with hint document",
+      "operations": [
+        {
+          "object": "collection",
+          "name": "deleteOne",
+          "arguments": {
+            "filter": {
+              "_id": 1
+            },
+            "hint": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "deletedCount": 1
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "delete": "DeleteOne_hint",
+              "deletes": [
+                {
+                  "q": {
+                    "_id": 1
+                  },
+                  "hint": {
+                    "_id": 1
+                  },
+                  "limit": 1
+                }
+              ]
+            }
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/find-allowdiskuse-clientError.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/find-allowdiskuse-clientError.json
new file mode 100644
index 0000000000000000000000000000000000000000..5ea013966a11aa3151cfbbdfebcf447ca68ba717
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/find-allowdiskuse-clientError.json	
@@ -0,0 +1,40 @@
+{
+  "runOn": [
+    {
+      "maxServerVersion": "3.0.99"
+    }
+  ],
+  "collection_name": "test_find_allowdiskuse_clienterror",
+  "tests": [
+    {
+      "description": "Find fails when allowDiskUse true is specified against pre 3.2 server",
+      "operations": [
+        {
+          "object": "collection",
+          "name": "find",
+          "arguments": {
+            "filter": {},
+            "allowDiskUse": true
+          },
+          "error": true
+        }
+      ],
+      "expectations": []
+    },
+    {
+      "description": "Find fails when allowDiskUse false is specified against pre 3.2 server",
+      "operations": [
+        {
+          "object": "collection",
+          "name": "find",
+          "arguments": {
+            "filter": {},
+            "allowDiskUse": false
+          },
+          "error": true
+        }
+      ],
+      "expectations": []
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/find-allowdiskuse-serverError.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/find-allowdiskuse-serverError.json
new file mode 100644
index 0000000000000000000000000000000000000000..31aa50e9514f37422b537e579e0d72116f1bcdc8
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/find-allowdiskuse-serverError.json	
@@ -0,0 +1,61 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "3.2",
+      "maxServerVersion": "4.3.0"
+    }
+  ],
+  "collection_name": "test_find_allowdiskuse_servererror",
+  "tests": [
+    {
+      "description": "Find fails when allowDiskUse true is specified against pre 4.4 server (server-side error)",
+      "operations": [
+        {
+          "object": "collection",
+          "name": "find",
+          "arguments": {
+            "filter": {},
+            "allowDiskUse": true
+          },
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "find": "test_find_allowdiskuse_servererror",
+              "filter": {},
+              "allowDiskUse": true
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "Find fails when allowDiskUse false is specified against pre 4.4 server (server-side error)",
+      "operations": [
+        {
+          "object": "collection",
+          "name": "find",
+          "arguments": {
+            "filter": {},
+            "allowDiskUse": false
+          },
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "find": "test_find_allowdiskuse_servererror",
+              "filter": {},
+              "allowDiskUse": false
+            }
+          }
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/find-allowdiskuse.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/find-allowdiskuse.json
new file mode 100644
index 0000000000000000000000000000000000000000..2df4dbc98ea193a07ed60489af1951f04e9d2638
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/find-allowdiskuse.json	
@@ -0,0 +1,78 @@
+{
+    "runOn": [
+        {
+            "minServerVersion": "4.3.1"
+        }
+    ],
+    "collection_name": "test_find_allowdiskuse",
+    "tests": [
+        {
+            "description": "Find does not send allowDiskuse when value is not specified",
+            "operations": [
+                {
+                    "object": "collection",
+                    "name": "find",
+                    "arguments": {
+                        "filter": {}
+                    }
+                }
+            ],
+            "expectations": [
+                {
+                    "command_started_event": {
+                        "command": {
+                            "find": "test_find_allowdiskuse",
+                            "allowDiskUse": null
+                        }
+                    }
+                }
+            ]
+        },
+        {
+            "description": "Find sends allowDiskuse false when false is specified",
+            "operations": [
+                {
+                    "object": "collection",
+                    "name": "find",
+                    "arguments": {
+                        "filter": {},
+                        "allowDiskUse": false
+                    }
+                }
+            ],
+            "expectations": [
+                {
+                    "command_started_event": {
+                        "command": {
+                            "find": "test_find_allowdiskuse",
+                            "allowDiskUse": false
+                        }
+                    }
+                }
+            ]
+        },
+        {
+            "description": "Find sends allowDiskUse true when true is specified",
+            "operations": [
+                {
+                    "object": "collection",
+                    "name": "find",
+                    "arguments": {
+                        "filter": {},
+                        "allowDiskUse": true
+                    }
+                }
+            ],
+            "expectations": [
+                {
+                    "command_started_event": {
+                        "command": {
+                            "find": "test_find_allowdiskuse",
+                            "allowDiskUse": true
+                        }
+                    }
+                }
+            ]
+        }
+    ]
+}
\ No newline at end of file
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/findOneAndDelete-hint-clientError.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/findOneAndDelete-hint-clientError.json
new file mode 100644
index 0000000000000000000000000000000000000000..262e78ce75089fe81d2d658fd836d71b1e2f7ee2
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/findOneAndDelete-hint-clientError.json	
@@ -0,0 +1,84 @@
+{
+  "runOn": [
+    {
+      "maxServerVersion": "4.0.99"
+    }
+  ],
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    }
+  ],
+  "collection_name": "findOneAndDelete_hint",
+  "tests": [
+    {
+      "description": "FindOneAndDelete with hint string unsupported (client-side error)",
+      "operations": [
+        {
+          "object": "collection",
+          "name": "findOneAndDelete",
+          "arguments": {
+            "filter": {
+              "_id": 1
+            },
+            "hint": "_id_"
+          },
+          "error": true
+        }
+      ],
+      "expectations": [],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "FindOneAndDelete with hint document",
+      "operations": [
+        {
+          "object": "collection",
+          "name": "findOneAndDelete",
+          "arguments": {
+            "filter": {
+              "_id": 1
+            },
+            "hint": {
+              "_id": 1
+            }
+          },
+          "error": true
+        }
+      ],
+      "expectations": [],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/findOneAndDelete-hint-serverError.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/findOneAndDelete-hint-serverError.json
new file mode 100644
index 0000000000000000000000000000000000000000..9412b36f238244642d33f288ef4fbed808c2df9f
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/findOneAndDelete-hint-serverError.json	
@@ -0,0 +1,113 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.2.0",
+      "maxServerVersion": "4.3.3"
+    }
+  ],
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    }
+  ],
+  "collection_name": "findOneAndDelete_hint",
+  "tests": [
+    {
+      "description": "FindOneAndDelete with hint string unsupported (server-side error)",
+      "operations": [
+        {
+          "object": "collection",
+          "name": "findOneAndDelete",
+          "arguments": {
+            "filter": {
+              "_id": 1
+            },
+            "hint": "_id_"
+          },
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "findAndModify": "findOneAndDelete_hint",
+              "query": {
+                "_id": 1
+              },
+              "hint": "_id_",
+              "remove": true
+            }
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "FindOneAndDelete with hint document unsupported (server-side error)",
+      "operations": [
+        {
+          "object": "collection",
+          "name": "findOneAndDelete",
+          "arguments": {
+            "filter": {
+              "_id": 1
+            },
+            "hint": {
+              "_id": 1
+            }
+          },
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "findAndModify": "findOneAndDelete_hint",
+              "query": {
+                "_id": 1
+              },
+              "hint": {
+                "_id": 1
+              },
+              "remove": true
+            }
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/findOneAndDelete-hint.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/findOneAndDelete-hint.json
new file mode 100644
index 0000000000000000000000000000000000000000..fe8dcfa4c55fc2c603510b5c3e2035f0903265ea
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/findOneAndDelete-hint.json	
@@ -0,0 +1,110 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.3.4"
+    }
+  ],
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    }
+  ],
+  "collection_name": "findOneAndDelete_hint",
+  "tests": [
+    {
+      "description": "FindOneAndDelete with hint string",
+      "operations": [
+        {
+          "object": "collection",
+          "name": "findOneAndDelete",
+          "arguments": {
+            "filter": {
+              "_id": 1
+            },
+            "hint": "_id_"
+          },
+          "result": {
+            "_id": 1,
+            "x": 11
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "findAndModify": "findOneAndDelete_hint",
+              "query": {
+                "_id": 1
+              },
+              "hint": "_id_",
+              "remove": true
+            }
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "FindOneAndDelete with hint document",
+      "operations": [
+        {
+          "object": "collection",
+          "name": "findOneAndDelete",
+          "arguments": {
+            "filter": {
+              "_id": 1
+            },
+            "hint": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "_id": 1,
+            "x": 11
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "findAndModify": "findOneAndDelete_hint",
+              "query": {
+                "_id": 1
+              },
+              "hint": {
+                "_id": 1
+              },
+              "remove": true
+            }
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/findOneAndReplace-hint-clientError.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/findOneAndReplace-hint-clientError.json
new file mode 100644
index 0000000000000000000000000000000000000000..08fd4b3ecc0c7a07a768dce332a6726aef2b2690
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/findOneAndReplace-hint-clientError.json	
@@ -0,0 +1,90 @@
+{
+  "runOn": [
+    {
+      "maxServerVersion": "4.0.99"
+    }
+  ],
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    }
+  ],
+  "collection_name": "findOneAndReplace_hint",
+  "tests": [
+    {
+      "description": "FindOneAndReplace with hint string unsupported (client-side error)",
+      "operations": [
+        {
+          "object": "collection",
+          "name": "findOneAndReplace",
+          "arguments": {
+            "filter": {
+              "_id": 1
+            },
+            "replacement": {
+              "x": 33
+            },
+            "hint": "_id_"
+          },
+          "error": true
+        }
+      ],
+      "expectations": [],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "FindOneAndReplace with hint document unsupported (client-side error)",
+      "operations": [
+        {
+          "object": "collection",
+          "name": "findOneAndReplace",
+          "arguments": {
+            "filter": {
+              "_id": 1
+            },
+            "replacement": {
+              "x": 33
+            },
+            "hint": {
+              "_id": 1
+            }
+          },
+          "error": true
+        }
+      ],
+      "expectations": [],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/findOneAndReplace-hint-serverError.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/findOneAndReplace-hint-serverError.json
new file mode 100644
index 0000000000000000000000000000000000000000..6710e6a70e883bbd7f840a6c18d356637d0151b3
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/findOneAndReplace-hint-serverError.json	
@@ -0,0 +1,123 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.2.0",
+      "maxServerVersion": "4.3.0"
+    }
+  ],
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    }
+  ],
+  "collection_name": "findOneAndReplace_hint",
+  "tests": [
+    {
+      "description": "FindOneAndReplace with hint string unsupported (server-side error)",
+      "operations": [
+        {
+          "object": "collection",
+          "name": "findOneAndReplace",
+          "arguments": {
+            "filter": {
+              "_id": 1
+            },
+            "replacement": {
+              "x": 33
+            },
+            "hint": "_id_"
+          },
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "findAndModify": "findOneAndReplace_hint",
+              "query": {
+                "_id": 1
+              },
+              "update": {
+                "x": 33
+              },
+              "hint": "_id_"
+            }
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "FindOneAndReplace with hint document unsupported (server-side error)",
+      "operations": [
+        {
+          "object": "collection",
+          "name": "findOneAndReplace",
+          "arguments": {
+            "filter": {
+              "_id": 1
+            },
+            "replacement": {
+              "x": 33
+            },
+            "hint": {
+              "_id": 1
+            }
+          },
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "findAndModify": "findOneAndReplace_hint",
+              "query": {
+                "_id": 1
+              },
+              "update": {
+                "x": 33
+              },
+              "hint": {
+                "_id": 1
+              }
+            }
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/findOneAndReplace-hint.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/findOneAndReplace-hint.json
new file mode 100644
index 0000000000000000000000000000000000000000..263fdf9623937353744a98701662d823f7fc697c
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/findOneAndReplace-hint.json	
@@ -0,0 +1,128 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.3.1"
+    }
+  ],
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    }
+  ],
+  "collection_name": "findOneAndReplace_hint",
+  "tests": [
+    {
+      "description": "FindOneAndReplace with hint string",
+      "operations": [
+        {
+          "object": "collection",
+          "name": "findOneAndReplace",
+          "arguments": {
+            "filter": {
+              "_id": 1
+            },
+            "replacement": {
+              "x": 33
+            },
+            "hint": "_id_"
+          },
+          "result": {
+            "_id": 1,
+            "x": 11
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "findAndModify": "findOneAndReplace_hint",
+              "query": {
+                "_id": 1
+              },
+              "update": {
+                "x": 33
+              },
+              "hint": "_id_"
+            }
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 33
+            },
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "FindOneAndReplace with hint document",
+      "operations": [
+        {
+          "object": "collection",
+          "name": "findOneAndReplace",
+          "arguments": {
+            "filter": {
+              "_id": 1
+            },
+            "replacement": {
+              "x": 33
+            },
+            "hint": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "_id": 1,
+            "x": 11
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "findAndModify": "findOneAndReplace_hint",
+              "query": {
+                "_id": 1
+              },
+              "update": {
+                "x": 33
+              },
+              "hint": {
+                "_id": 1
+              }
+            }
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 33
+            },
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/findOneAndUpdate-hint-clientError.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/findOneAndUpdate-hint-clientError.json
new file mode 100644
index 0000000000000000000000000000000000000000..8cd5cddb51ea5c2022e766dabd1d2e2b8e1cf7ee
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/findOneAndUpdate-hint-clientError.json	
@@ -0,0 +1,94 @@
+{
+  "runOn": [
+    {
+      "maxServerVersion": "4.0.99"
+    }
+  ],
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    }
+  ],
+  "collection_name": "findOneAndUpdate_hint",
+  "tests": [
+    {
+      "description": "FindOneAndUpdate with hint string unsupported (client-side error)",
+      "operations": [
+        {
+          "object": "collection",
+          "name": "findOneAndUpdate",
+          "arguments": {
+            "filter": {
+              "_id": 1
+            },
+            "update": {
+              "$inc": {
+                "x": 1
+              }
+            },
+            "hint": "_id_"
+          },
+          "error": true
+        }
+      ],
+      "expectations": [],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "FindOneAndUpdate with hint document unsupported (client-side error)",
+      "operations": [
+        {
+          "object": "collection",
+          "name": "findOneAndUpdate",
+          "arguments": {
+            "filter": {
+              "_id": 1
+            },
+            "update": {
+              "$inc": {
+                "x": 1
+              }
+            },
+            "hint": {
+              "_id": 1
+            }
+          },
+          "error": true
+        }
+      ],
+      "expectations": [],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/findOneAndUpdate-hint-serverError.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/findOneAndUpdate-hint-serverError.json
new file mode 100644
index 0000000000000000000000000000000000000000..1f4b2bda8b6d9fdea44fd721dd56aef0953a6790
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/findOneAndUpdate-hint-serverError.json	
@@ -0,0 +1,131 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.2.0",
+      "maxServerVersion": "4.3.0"
+    }
+  ],
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    }
+  ],
+  "collection_name": "findOneAndUpdate_hint",
+  "tests": [
+    {
+      "description": "FindOneAndUpdate with hint string unsupported (server-side error)",
+      "operations": [
+        {
+          "object": "collection",
+          "name": "findOneAndUpdate",
+          "arguments": {
+            "filter": {
+              "_id": 1
+            },
+            "update": {
+              "$inc": {
+                "x": 1
+              }
+            },
+            "hint": "_id_"
+          },
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "findAndModify": "findOneAndUpdate_hint",
+              "query": {
+                "_id": 1
+              },
+              "update": {
+                "$inc": {
+                  "x": 1
+                }
+              },
+              "hint": "_id_"
+            }
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "FindOneAndUpdate with hint document unsupported (server-side error)",
+      "operations": [
+        {
+          "object": "collection",
+          "name": "findOneAndUpdate",
+          "arguments": {
+            "filter": {
+              "_id": 1
+            },
+            "update": {
+              "$inc": {
+                "x": 1
+              }
+            },
+            "hint": {
+              "_id": 1
+            }
+          },
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "findAndModify": "findOneAndUpdate_hint",
+              "query": {
+                "_id": 1
+              },
+              "update": {
+                "$inc": {
+                  "x": 1
+                }
+              },
+              "hint": {
+                "_id": 1
+              }
+            }
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/findOneAndUpdate-hint.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/findOneAndUpdate-hint.json
new file mode 100644
index 0000000000000000000000000000000000000000..451eecc013820759bd12f5d6b1f7a6e049a47686
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/findOneAndUpdate-hint.json	
@@ -0,0 +1,136 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.3.1"
+    }
+  ],
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    }
+  ],
+  "collection_name": "findOneAndUpdate_hint",
+  "tests": [
+    {
+      "description": "FindOneAndUpdate with hint string",
+      "operations": [
+        {
+          "object": "collection",
+          "name": "findOneAndUpdate",
+          "arguments": {
+            "filter": {
+              "_id": 1
+            },
+            "update": {
+              "$inc": {
+                "x": 1
+              }
+            },
+            "hint": "_id_"
+          },
+          "result": {
+            "_id": 1,
+            "x": 11
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "findAndModify": "findOneAndUpdate_hint",
+              "query": {
+                "_id": 1
+              },
+              "update": {
+                "$inc": {
+                  "x": 1
+                }
+              },
+              "hint": "_id_"
+            }
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 12
+            },
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "FindOneAndUpdate with hint document",
+      "operations": [
+        {
+          "object": "collection",
+          "name": "findOneAndUpdate",
+          "arguments": {
+            "filter": {
+              "_id": 1
+            },
+            "update": {
+              "$inc": {
+                "x": 1
+              }
+            },
+            "hint": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "_id": 1,
+            "x": 11
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "findAndModify": "findOneAndUpdate_hint",
+              "query": {
+                "_id": 1
+              },
+              "update": {
+                "$inc": {
+                  "x": 1
+                }
+              },
+              "hint": {
+                "_id": 1
+              }
+            }
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 12
+            },
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/replaceOne-hint.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/replaceOne-hint.json
new file mode 100644
index 0000000000000000000000000000000000000000..de4aa4d02f6277b1458ef03ac39fb1455f8d5524
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/replaceOne-hint.json	
@@ -0,0 +1,146 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.2.0"
+    }
+  ],
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    }
+  ],
+  "collection_name": "test_replaceone_hint",
+  "tests": [
+    {
+      "description": "ReplaceOne with hint string",
+      "operations": [
+        {
+          "object": "collection",
+          "name": "replaceOne",
+          "arguments": {
+            "filter": {
+              "_id": {
+                "$gt": 1
+              }
+            },
+            "replacement": {
+              "x": 111
+            },
+            "hint": "_id_"
+          },
+          "result": {
+            "matchedCount": 1,
+            "modifiedCount": 1,
+            "upsertedCount": 0
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "update": "test_replaceone_hint",
+              "updates": [
+                {
+                  "q": {
+                    "_id": {
+                      "$gt": 1
+                    }
+                  },
+                  "u": {
+                    "x": 111
+                  },
+                  "hint": "_id_"
+                }
+              ]
+            }
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 111
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "ReplaceOne with hint document",
+      "operations": [
+        {
+          "object": "collection",
+          "name": "replaceOne",
+          "arguments": {
+            "filter": {
+              "_id": {
+                "$gt": 1
+              }
+            },
+            "replacement": {
+              "x": 111
+            },
+            "hint": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "matchedCount": 1,
+            "modifiedCount": 1,
+            "upsertedCount": 0
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "update": "test_replaceone_hint",
+              "updates": [
+                {
+                  "q": {
+                    "_id": {
+                      "$gt": 1
+                    }
+                  },
+                  "u": {
+                    "x": 111
+                  },
+                  "hint": {
+                    "_id": 1
+                  }
+                }
+              ]
+            }
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 111
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/replaceOne-validation.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/replaceOne-validation.json
new file mode 100644
index 0000000000000000000000000000000000000000..2de4a6728bdbfbdd7798c4017c4355e05dd20b01
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/replaceOne-validation.json	
@@ -0,0 +1,41 @@
+{
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    }
+  ],
+  "tests": [
+    {
+      "description": "ReplaceOne prohibits atomic modifiers",
+      "operations": [
+        {
+          "object": "collection",
+          "name": "replaceOne",
+          "arguments": {
+            "filter": {
+              "_id": 1
+            },
+            "replacement": {
+              "$set": {
+                "x": 22
+              }
+            }
+          },
+          "error": true
+        }
+      ],
+      "expectations": [],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/unacknowledged-bulkWrite-delete-hint-clientError.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/unacknowledged-bulkWrite-delete-hint-clientError.json
new file mode 100644
index 0000000000000000000000000000000000000000..a92c5dfb8865c1321db206c2fc977a8edd3ecf99
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/unacknowledged-bulkWrite-delete-hint-clientError.json	
@@ -0,0 +1,160 @@
+{
+  "runOn": [
+    {
+      "maxServerVersion": "4.3.3"
+    }
+  ],
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    },
+    {
+      "_id": 3,
+      "x": 33
+    },
+    {
+      "_id": 4,
+      "x": 44
+    }
+  ],
+  "collection_name": "BulkWrite_delete_hint",
+  "tests": [
+    {
+      "description": "Unacknowledged bulkWrite deleteOne with hints fails with client-side error on server < 4.4",
+      "operations": [
+        {
+          "name": "bulkWrite",
+          "collectionOptions": {
+            "writeConcern": {
+              "w": 0
+            }
+          },
+          "arguments": {
+            "requests": [
+              {
+                "name": "deleteOne",
+                "arguments": {
+                  "filter": {
+                    "_id": 1
+                  },
+                  "hint": "_id_"
+                }
+              },
+              {
+                "name": "deleteOne",
+                "arguments": {
+                  "filter": {
+                    "_id": 2
+                  },
+                  "hint": {
+                    "_id": 1
+                  }
+                }
+              }
+            ],
+            "options": {
+              "ordered": true
+            }
+          },
+          "error": true
+        }
+      ],
+      "expectations": {},
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            },
+            {
+              "_id": 4,
+              "x": 44
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "Unacknowledged bulkWrite deleteMany with hints fails with client-side error on server < 4.4",
+      "operations": [
+        {
+          "name": "bulkWrite",
+          "collectionOptions": {
+            "writeConcern": {
+              "w": 0
+            }
+          },
+          "arguments": {
+            "requests": [
+              {
+                "name": "deleteMany",
+                "arguments": {
+                  "filter": {
+                    "_id": {
+                      "$lt": 3
+                    }
+                  },
+                  "hint": "_id_"
+                }
+              },
+              {
+                "name": "deleteMany",
+                "arguments": {
+                  "filter": {
+                    "_id": {
+                      "$gte": 4
+                    }
+                  },
+                  "hint": {
+                    "_id": 1
+                  }
+                }
+              }
+            ],
+            "options": {
+              "ordered": true
+            }
+          },
+          "error": true
+        }
+      ],
+      "expectations": {},
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            },
+            {
+              "_id": 4,
+              "x": 44
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/unacknowledged-bulkWrite-delete-hint.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/unacknowledged-bulkWrite-delete-hint.json
new file mode 100644
index 0000000000000000000000000000000000000000..b2147a27f9e462334d474a33bf21cd1256d9393d
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/unacknowledged-bulkWrite-delete-hint.json	
@@ -0,0 +1,174 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.3.4"
+    }
+  ],
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    },
+    {
+      "_id": 3,
+      "x": 33
+    },
+    {
+      "_id": 4,
+      "x": 44
+    }
+  ],
+  "collection_name": "BulkWrite_delete_hint",
+  "tests": [
+    {
+      "description": "Unacknowledged bulkWrite deleteOne with hints succeeds on server >= 4.4",
+      "operations": [
+        {
+          "name": "bulkWrite",
+          "collectionOptions": {
+            "writeConcern": {
+              "w": 0
+            }
+          },
+          "arguments": {
+            "requests": [
+              {
+                "name": "deleteOne",
+                "arguments": {
+                  "filter": {
+                    "_id": 1
+                  },
+                  "hint": "_id_"
+                }
+              },
+              {
+                "name": "deleteOne",
+                "arguments": {
+                  "filter": {
+                    "_id": 2
+                  },
+                  "hint": {
+                    "_id": 1
+                  }
+                }
+              }
+            ],
+            "options": {
+              "ordered": true
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "delete": "BulkWrite_delete_hint",
+              "deletes": [
+                {
+                  "q": {
+                    "_id": 1
+                  },
+                  "hint": "_id_",
+                  "limit": 1
+                },
+                {
+                  "q": {
+                    "_id": 2
+                  },
+                  "hint": {
+                    "_id": 1
+                  },
+                  "limit": 1
+                }
+              ],
+              "ordered": true
+            }
+          }
+        }
+      ],
+      "outcome": {}
+    },
+    {
+      "description": "Unacknowledged bulkWrite deleteMany with hints succeeds on server >= 4.4",
+      "operations": [
+        {
+          "name": "bulkWrite",
+          "collectionOptions": {
+            "writeConcern": {
+              "w": 0
+            }
+          },
+          "arguments": {
+            "requests": [
+              {
+                "name": "deleteMany",
+                "arguments": {
+                  "filter": {
+                    "_id": {
+                      "$lt": 3
+                    }
+                  },
+                  "hint": "_id_"
+                }
+              },
+              {
+                "name": "deleteMany",
+                "arguments": {
+                  "filter": {
+                    "_id": {
+                      "$gte": 4
+                    }
+                  },
+                  "hint": {
+                    "_id": 1
+                  }
+                }
+              }
+            ],
+            "options": {
+              "ordered": true
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "delete": "BulkWrite_delete_hint",
+              "deletes": [
+                {
+                  "q": {
+                    "_id": {
+                      "$lt": 3
+                    }
+                  },
+                  "hint": "_id_",
+                  "limit": 0
+                },
+                {
+                  "q": {
+                    "_id": {
+                      "$gte": 4
+                    }
+                  },
+                  "hint": {
+                    "_id": 1
+                  },
+                  "limit": 0
+                }
+              ],
+              "ordered": true
+            }
+          }
+        }
+      ],
+      "outcome": {}
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/unacknowledged-bulkWrite-update-hint-clientError.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/unacknowledged-bulkWrite-update-hint-clientError.json
new file mode 100644
index 0000000000000000000000000000000000000000..93c46f82ea377a84499a1de4bf0d69f2ca8ff792
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/unacknowledged-bulkWrite-update-hint-clientError.json	
@@ -0,0 +1,250 @@
+{
+  "runOn": [
+    {
+      "maxServerVersion": "4.1.9"
+    }
+  ],
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    },
+    {
+      "_id": 3,
+      "x": 33
+    },
+    {
+      "_id": 4,
+      "x": 44
+    }
+  ],
+  "collection_name": "Bulkwrite_update_hint",
+  "tests": [
+    {
+      "description": "Unacknowledged bulkWrite updateOne with hints fails with client-side error on server < 4.2",
+      "operations": [
+        {
+          "name": "bulkWrite",
+          "collectionOptions": {
+            "writeConcern": {
+              "w": 0
+            }
+          },
+          "arguments": {
+            "requests": [
+              {
+                "name": "updateOne",
+                "arguments": {
+                  "filter": {
+                    "_id": 1
+                  },
+                  "update": {
+                    "$inc": {
+                      "x": 1
+                    }
+                  },
+                  "hint": "_id_"
+                }
+              },
+              {
+                "name": "updateOne",
+                "arguments": {
+                  "filter": {
+                    "_id": 1
+                  },
+                  "update": {
+                    "$inc": {
+                      "x": 1
+                    }
+                  },
+                  "hint": {
+                    "_id": 1
+                  }
+                }
+              }
+            ],
+            "options": {
+              "ordered": true
+            }
+          },
+          "error": true
+        }
+      ],
+      "expectations": {},
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            },
+            {
+              "_id": 4,
+              "x": 44
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "Unacknowledged bulkWrite updateMany with hints fails with client-side error on server < 4.2",
+      "operations": [
+        {
+          "name": "bulkWrite",
+          "collectionOptions": {
+            "writeConcern": {
+              "w": 0
+            }
+          },
+          "arguments": {
+            "requests": [
+              {
+                "name": "updateMany",
+                "arguments": {
+                  "filter": {
+                    "_id": {
+                      "$lt": 3
+                    }
+                  },
+                  "update": {
+                    "$inc": {
+                      "x": 1
+                    }
+                  },
+                  "hint": "_id_"
+                }
+              },
+              {
+                "name": "updateMany",
+                "arguments": {
+                  "filter": {
+                    "_id": {
+                      "$lt": 3
+                    }
+                  },
+                  "update": {
+                    "$inc": {
+                      "x": 1
+                    }
+                  },
+                  "hint": {
+                    "_id": 1
+                  }
+                }
+              }
+            ],
+            "options": {
+              "ordered": true
+            }
+          },
+          "error": true
+        }
+      ],
+      "expectations": {},
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            },
+            {
+              "_id": 4,
+              "x": 44
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "Unacknowledged bulkWrite replaceOne with hints unsupported (client-side error)",
+      "operations": [
+        {
+          "name": "bulkWrite",
+          "collectionOptions": {
+            "writeConcern": {
+              "w": 0
+            }
+          },
+          "arguments": {
+            "requests": [
+              {
+                "name": "replaceOne",
+                "arguments": {
+                  "filter": {
+                    "_id": 3
+                  },
+                  "replacement": {
+                    "x": 333
+                  },
+                  "hint": "_id_"
+                }
+              },
+              {
+                "name": "replaceOne",
+                "arguments": {
+                  "filter": {
+                    "_id": 4
+                  },
+                  "replacement": {
+                    "x": 444
+                  },
+                  "hint": {
+                    "_id": 1
+                  }
+                }
+              }
+            ],
+            "options": {
+              "ordered": true
+            }
+          },
+          "error": true
+        }
+      ],
+      "expectations": {},
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            },
+            {
+              "_id": 4,
+              "x": 44
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/unacknowledged-bulkWrite-update-hint.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/unacknowledged-bulkWrite-update-hint.json
new file mode 100644
index 0000000000000000000000000000000000000000..eaba364e9580bbf2f83bbb39e6a9b75f7e37797b
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/unacknowledged-bulkWrite-update-hint.json	
@@ -0,0 +1,291 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.2.0"
+    }
+  ],
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    },
+    {
+      "_id": 3,
+      "x": 33
+    },
+    {
+      "_id": 4,
+      "x": 44
+    }
+  ],
+  "collection_name": "BulkWrite_update_hint",
+  "tests": [
+    {
+      "description": "Unacknowledged bulkWrite updateOne with update hint succeeds on server >= 4.2",
+      "operations": [
+        {
+          "name": "bulkWrite",
+          "collectionOptions": {
+            "writeConcern": {
+              "w": 0
+            }
+          },
+          "arguments": {
+            "requests": [
+              {
+                "name": "updateOne",
+                "arguments": {
+                  "filter": {
+                    "_id": 1
+                  },
+                  "update": {
+                    "$inc": {
+                      "x": 1
+                    }
+                  },
+                  "hint": "_id_"
+                }
+              },
+              {
+                "name": "updateOne",
+                "arguments": {
+                  "filter": {
+                    "_id": 1
+                  },
+                  "update": {
+                    "$inc": {
+                      "x": 1
+                    }
+                  },
+                  "hint": {
+                    "_id": 1
+                  }
+                }
+              }
+            ],
+            "options": {
+              "ordered": true
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "update": "BulkWrite_update_hint",
+              "updates": [
+                {
+                  "q": {
+                    "_id": 1
+                  },
+                  "u": {
+                    "$inc": {
+                      "x": 1
+                    }
+                  },
+                  "hint": "_id_"
+                },
+                {
+                  "q": {
+                    "_id": 1
+                  },
+                  "u": {
+                    "$inc": {
+                      "x": 1
+                    }
+                  },
+                  "hint": {
+                    "_id": 1
+                  }
+                }
+              ],
+              "ordered": true
+            }
+          }
+        }
+      ],
+      "outcome": {}
+    },
+    {
+      "description": "Unacknowledged bulkWrite updateMany with update hint succeeds on server >= 4.2",
+      "operations": [
+        {
+          "name": "bulkWrite",
+          "collectionOptions": {
+            "writeConcern": {
+              "w": 0
+            }
+          },
+          "arguments": {
+            "requests": [
+              {
+                "name": "updateMany",
+                "arguments": {
+                  "filter": {
+                    "_id": {
+                      "$lt": 3
+                    }
+                  },
+                  "update": {
+                    "$inc": {
+                      "x": 1
+                    }
+                  },
+                  "hint": "_id_"
+                }
+              },
+              {
+                "name": "updateMany",
+                "arguments": {
+                  "filter": {
+                    "_id": {
+                      "$lt": 3
+                    }
+                  },
+                  "update": {
+                    "$inc": {
+                      "x": 1
+                    }
+                  },
+                  "hint": {
+                    "_id": 1
+                  }
+                }
+              }
+            ],
+            "options": {
+              "ordered": true
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "update": "BulkWrite_update_hint",
+              "updates": [
+                {
+                  "q": {
+                    "_id": {
+                      "$lt": 3
+                    }
+                  },
+                  "u": {
+                    "$inc": {
+                      "x": 1
+                    }
+                  },
+                  "multi": true,
+                  "hint": "_id_"
+                },
+                {
+                  "q": {
+                    "_id": {
+                      "$lt": 3
+                    }
+                  },
+                  "u": {
+                    "$inc": {
+                      "x": 1
+                    }
+                  },
+                  "multi": true,
+                  "hint": {
+                    "_id": 1
+                  }
+                }
+              ],
+              "ordered": true
+            }
+          }
+        }
+      ],
+      "outcome": {}
+    },
+    {
+      "description": "Unacknowledged bulkWrite replaceOne with update hints",
+      "operations": [
+        {
+          "name": "bulkWrite",
+          "collectionOptions": {
+            "writeConcern": {
+              "w": 0
+            }
+          },
+          "arguments": {
+            "requests": [
+              {
+                "name": "replaceOne",
+                "arguments": {
+                  "filter": {
+                    "_id": 3
+                  },
+                  "replacement": {
+                    "x": 333
+                  },
+                  "hint": "_id_"
+                }
+              },
+              {
+                "name": "replaceOne",
+                "arguments": {
+                  "filter": {
+                    "_id": 4
+                  },
+                  "replacement": {
+                    "x": 444
+                  },
+                  "hint": {
+                    "_id": 1
+                  }
+                }
+              }
+            ],
+            "options": {
+              "ordered": true
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "update": "BulkWrite_update_hint",
+              "updates": [
+                {
+                  "q": {
+                    "_id": 3
+                  },
+                  "u": {
+                    "x": 333
+                  },
+                  "hint": "_id_"
+                },
+                {
+                  "q": {
+                    "_id": 4
+                  },
+                  "u": {
+                    "x": 444
+                  },
+                  "hint": {
+                    "_id": 1
+                  }
+                }
+              ],
+              "ordered": true
+            }
+          }
+        }
+      ],
+      "outcome": {}
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/unacknowledged-deleteMany-hint-clientError.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/unacknowledged-deleteMany-hint-clientError.json
new file mode 100644
index 0000000000000000000000000000000000000000..903340bf015e8b15490a8ab01e1a55193d35eeac
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/unacknowledged-deleteMany-hint-clientError.json	
@@ -0,0 +1,110 @@
+{
+  "runOn": [
+    {
+      "maxServerVersion": "4.3.3"
+    }
+  ],
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    },
+    {
+      "_id": 3,
+      "x": 33
+    }
+  ],
+  "collection_name": "DeleteMany_hint",
+  "tests": [
+    {
+      "description": "Unacknowledged deleteMany with hint string fails with client-side error on server < 4.4",
+      "operations": [
+        {
+          "object": "collection",
+          "collectionOptions": {
+            "writeConcern": {
+              "w": 0
+            }
+          },
+          "name": "deleteMany",
+          "arguments": {
+            "filter": {
+              "_id": {
+                "$gt": 1
+              }
+            },
+            "hint": "_id_"
+          },
+          "error": true
+        }
+      ],
+      "expectations": {},
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "Unacknowledged deleteMany with hint document fails with client-side error on server < 4.4",
+      "operations": [
+        {
+          "object": "collection",
+          "collectionOptions": {
+            "writeConcern": {
+              "w": 0
+            }
+          },
+          "name": "deleteMany",
+          "arguments": {
+            "filter": {
+              "_id": {
+                "$gt": 1
+              }
+            },
+            "hint": {
+              "_id": 1
+            }
+          },
+          "error": true
+        }
+      ],
+      "expectations": {},
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/unacknowledged-deleteMany-hint.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/unacknowledged-deleteMany-hint.json
new file mode 100644
index 0000000000000000000000000000000000000000..485fd619857c0d0185d2975773b0a2295f48e826
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/unacknowledged-deleteMany-hint.json	
@@ -0,0 +1,114 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.3.4"
+    }
+  ],
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    },
+    {
+      "_id": 3,
+      "x": 33
+    }
+  ],
+  "collection_name": "DeleteMany_hint",
+  "tests": [
+    {
+      "description": "Unacknowledged deleteMany with hint string succeeds on server >= 4.4",
+      "operations": [
+        {
+          "object": "collection",
+          "collectionOptions": {
+            "writeConcern": {
+              "w": 0
+            }
+          },
+          "name": "deleteMany",
+          "arguments": {
+            "filter": {
+              "_id": {
+                "$gt": 1
+              }
+            },
+            "hint": "_id_"
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "delete": "DeleteMany_hint",
+              "deletes": [
+                {
+                  "q": {
+                    "_id": {
+                      "$gt": 1
+                    }
+                  },
+                  "hint": "_id_",
+                  "limit": 0
+                }
+              ]
+            }
+          }
+        }
+      ],
+      "outcome": {}
+    },
+    {
+      "description": "Unacknowledged deleteMany with hint document succeeds on server >= 4.4",
+      "operations": [
+        {
+          "object": "collection",
+          "collectionOptions": {
+            "writeConcern": {
+              "w": 0
+            }
+          },
+          "name": "deleteMany",
+          "arguments": {
+            "filter": {
+              "_id": {
+                "$gt": 1
+              }
+            },
+            "hint": {
+              "_id": 1
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "delete": "DeleteMany_hint",
+              "deletes": [
+                {
+                  "q": {
+                    "_id": {
+                      "$gt": 1
+                    }
+                  },
+                  "hint": {
+                    "_id": 1
+                  },
+                  "limit": 0
+                }
+              ]
+            }
+          }
+        }
+      ],
+      "outcome": {}
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/unacknowledged-deleteOne-hint-clientError.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/unacknowledged-deleteOne-hint-clientError.json
new file mode 100644
index 0000000000000000000000000000000000000000..11e0b883cb031c3cc7a0479d332074380b85dcdd
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/unacknowledged-deleteOne-hint-clientError.json	
@@ -0,0 +1,94 @@
+{
+  "runOn": [
+    {
+      "maxServerVersion": "4.3.3"
+    }
+  ],
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    }
+  ],
+  "collection_name": "DeleteOne_hint",
+  "tests": [
+    {
+      "description": "Unacknowledged deleteOne with hint string fails with client-side error on server < 4.4",
+      "operations": [
+        {
+          "object": "collection",
+          "collectionOptions": {
+            "writeConcern": {
+              "w": 0
+            }
+          },
+          "name": "deleteOne",
+          "arguments": {
+            "filter": {
+              "_id": 1
+            },
+            "hint": "_id_"
+          },
+          "error": true
+        }
+      ],
+      "expectations": {},
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "Unacknowledged deleteOne with hint document fails with client-side error on server < 4.4",
+      "operations": [
+        {
+          "object": "collection",
+          "collectionOptions": {
+            "writeConcern": {
+              "w": 0
+            }
+          },
+          "name": "deleteOne",
+          "arguments": {
+            "filter": {
+              "_id": 1
+            },
+            "hint": {
+              "_id": 1
+            }
+          },
+          "error": true
+        }
+      ],
+      "expectations": {},
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/unacknowledged-deleteOne-hint.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/unacknowledged-deleteOne-hint.json
new file mode 100644
index 0000000000000000000000000000000000000000..bd9443d4f7327cd20ee6f3a56114d9fd8ea805e6
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/unacknowledged-deleteOne-hint.json	
@@ -0,0 +1,102 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.3.4"
+    }
+  ],
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    }
+  ],
+  "collection_name": "DeleteOne_hint",
+  "tests": [
+    {
+      "description": "Unacknowledged deleteOne with hint string succeeds on server >= 4.4",
+      "operations": [
+        {
+          "object": "collection",
+          "collectionOptions": {
+            "writeConcern": {
+              "w": 0
+            }
+          },
+          "name": "deleteOne",
+          "arguments": {
+            "filter": {
+              "_id": 1
+            },
+            "hint": "_id_"
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "delete": "DeleteOne_hint",
+              "deletes": [
+                {
+                  "q": {
+                    "_id": 1
+                  },
+                  "hint": "_id_",
+                  "limit": 1
+                }
+              ]
+            }
+          }
+        }
+      ],
+      "outcome": {}
+    },
+    {
+      "description": "Unacknowledged deleteOne with hint document succeeds on server >= 4.4",
+      "operations": [
+        {
+          "object": "collection",
+          "collectionOptions": {
+            "writeConcern": {
+              "w": 0
+            }
+          },
+          "name": "deleteOne",
+          "arguments": {
+            "filter": {
+              "_id": 1
+            },
+            "hint": {
+              "_id": 1
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "delete": "DeleteOne_hint",
+              "deletes": [
+                {
+                  "q": {
+                    "_id": 1
+                  },
+                  "hint": {
+                    "_id": 1
+                  },
+                  "limit": 1
+                }
+              ]
+            }
+          }
+        }
+      ],
+      "outcome": {}
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/unacknowledged-findOneAndDelete-hint-clientError.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/unacknowledged-findOneAndDelete-hint-clientError.json
new file mode 100644
index 0000000000000000000000000000000000000000..1c4423d3c3eea24cfe930237e99e2abc8f450571
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/unacknowledged-findOneAndDelete-hint-clientError.json	
@@ -0,0 +1,94 @@
+{
+  "runOn": [
+    {
+      "maxServerVersion": "4.3.3"
+    }
+  ],
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    }
+  ],
+  "collection_name": "findOneAndDelete_hint",
+  "tests": [
+    {
+      "description": "Unacknowledged findOneAndDelete with hint string fails with client-side error on server < 4.4",
+      "operations": [
+        {
+          "object": "collection",
+          "collectionOptions": {
+            "writeConcern": {
+              "w": 0
+            }
+          },
+          "name": "findOneAndDelete",
+          "arguments": {
+            "filter": {
+              "_id": 1
+            },
+            "hint": "_id_"
+          },
+          "error": true
+        }
+      ],
+      "expectations": {},
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "Unacknowledged findOneAndDelete with hint document fails with client-side error on server < 4.4",
+      "operations": [
+        {
+          "object": "collection",
+          "collectionOptions": {
+            "writeConcern": {
+              "w": 0
+            }
+          },
+          "name": "findOneAndDelete",
+          "arguments": {
+            "filter": {
+              "_id": 1
+            },
+            "hint": {
+              "_id": 1
+            }
+          },
+          "error": true
+        }
+      ],
+      "expectations": {},
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/unacknowledged-findOneAndDelete-hint.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/unacknowledged-findOneAndDelete-hint.json
new file mode 100644
index 0000000000000000000000000000000000000000..9dce1ae9d82aadc50ce6bdd04e5af618c411fa07
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/unacknowledged-findOneAndDelete-hint.json	
@@ -0,0 +1,94 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.3.4"
+    }
+  ],
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    }
+  ],
+  "collection_name": "findOneAndDelete_hint",
+  "tests": [
+    {
+      "description": "Unacknowledged findOneAndDelete with hint string succeeds on server >= 4.4",
+      "operations": [
+        {
+          "object": "collection",
+          "collectionOptions": {
+            "writeConcern": {
+              "w": 0
+            }
+          },
+          "name": "findOneAndDelete",
+          "arguments": {
+            "filter": {
+              "_id": 1
+            },
+            "hint": "_id_"
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "findAndModify": "findOneAndDelete_hint",
+              "query": {
+                "_id": 1
+              },
+              "hint": "_id_",
+              "remove": true
+            }
+          }
+        }
+      ],
+      "outcome": {}
+    },
+    {
+      "description": "Unacknowledged findOneAndDelete with hint document succeeds on server >= 4.4",
+      "operations": [
+        {
+          "object": "collection",
+          "collectionOptions": {
+            "writeConcern": {
+              "w": 0
+            }
+          },
+          "name": "findOneAndDelete",
+          "arguments": {
+            "filter": {
+              "_id": 1
+            },
+            "hint": {
+              "_id": 1
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "findAndModify": "findOneAndDelete_hint",
+              "query": {
+                "_id": 1
+              },
+              "hint": {
+                "_id": 1
+              },
+              "remove": true
+            }
+          }
+        }
+      ],
+      "outcome": {}
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/unacknowledged-findOneAndReplace-hint-clientError.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/unacknowledged-findOneAndReplace-hint-clientError.json
new file mode 100644
index 0000000000000000000000000000000000000000..0379e7946e11ba74b56327520cdf81a12c7e89a4
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/unacknowledged-findOneAndReplace-hint-clientError.json	
@@ -0,0 +1,100 @@
+{
+  "runOn": [
+    {
+      "maxServerVersion": "4.3.3"
+    }
+  ],
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    }
+  ],
+  "collection_name": "FindOneAndReplace_hint",
+  "tests": [
+    {
+      "description": "Unacknowledged findOneAndReplace with hint string fails with client-side error on server < 4.4",
+      "operations": [
+        {
+          "object": "collection",
+          "collectionOptions": {
+            "writeConcern": {
+              "w": 0
+            }
+          },
+          "name": "findOneAndReplace",
+          "arguments": {
+            "filter": {
+              "_id": 1
+            },
+            "replacement": {
+              "x": 33
+            },
+            "hint": "_id_"
+          },
+          "error": true
+        }
+      ],
+      "expectations": {},
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "Unacknowledged findOneAndReplace with hint document fails with client-side error on server < 4.4",
+      "operations": [
+        {
+          "object": "collection",
+          "collectionOptions": {
+            "writeConcern": {
+              "w": 0
+            }
+          },
+          "name": "findOneAndReplace",
+          "arguments": {
+            "filter": {
+              "_id": 1
+            },
+            "replacement": {
+              "x": 33
+            },
+            "hint": {
+              "_id": 1
+            }
+          },
+          "error": true
+        }
+      ],
+      "expectations": {},
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/unacknowledged-findOneAndReplace-hint.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/unacknowledged-findOneAndReplace-hint.json
new file mode 100644
index 0000000000000000000000000000000000000000..7c3e55e046c1be01e2a988299fee0afed72e3f41
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/unacknowledged-findOneAndReplace-hint.json	
@@ -0,0 +1,101 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.3.4"
+    }
+  ],
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    }
+  ],
+  "collection_name": "FindOneAndReplace_hint",
+  "tests": [
+    {
+      "description": "Unacknowledged findOneAndReplace with hint string succeeds on server >= 4.4",
+      "operations": [
+        {
+          "object": "collection",
+          "collectionOptions": {
+            "writeConcern": {
+              "w": 0
+            }
+          },
+          "name": "findOneAndReplace",
+          "arguments": {
+            "filter": {
+              "_id": 1
+            },
+            "replacement": {
+              "x": 33
+            },
+            "hint": "_id_"
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "findAndModify": "FindOneAndReplace_hint",
+              "query": {
+                "_id": 1
+              },
+              "update": {
+                "x": 33
+              },
+              "hint": "_id_"
+            }
+          }
+        }
+      ],
+      "outcome": {}
+    },
+    {
+      "description": "Unacknowledged findOneAndReplace with hint document succeeds on server >= 4.4",
+      "operations": [
+        {
+          "object": "collection",
+          "collectionOptions": {
+            "writeConcern": {
+              "w": 0
+            }
+          },
+          "name": "findOneAndReplace",
+          "arguments": {
+            "filter": {
+              "_id": 1
+            },
+            "replacement": {
+              "x": 33
+            },
+            "hint": {
+              "_id": 1
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "findAndModify": "FindOneAndReplace_hint",
+              "query": {
+                "_id": 1
+              },
+              "update": {
+                "x": 33
+              }
+            }
+          }
+        }
+      ],
+      "outcome": {}
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/unacknowledged-findOneAndUpdate-hint-clientError.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/unacknowledged-findOneAndUpdate-hint-clientError.json
new file mode 100644
index 0000000000000000000000000000000000000000..14e1fb6da46f4fe0d9936cd38f3142f39b318acc
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/unacknowledged-findOneAndUpdate-hint-clientError.json	
@@ -0,0 +1,104 @@
+{
+  "runOn": [
+    {
+      "maxServerVersion": "4.3.3"
+    }
+  ],
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    }
+  ],
+  "collection_name": "FindOneAndUpdate_hint",
+  "tests": [
+    {
+      "description": "Unacknowledged findOneAndUpdate with hint string fails with client-side error on server < 4.4",
+      "operations": [
+        {
+          "object": "collection",
+          "collectionOptions": {
+            "writeConcern": {
+              "w": 0
+            }
+          },
+          "name": "findOneAndUpdate",
+          "arguments": {
+            "filter": {
+              "_id": 1
+            },
+            "update": {
+              "$inc": {
+                "x": 1
+              }
+            },
+            "hint": "_id_"
+          },
+          "error": true
+        }
+      ],
+      "expectations": {},
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "Unacknowledged findOneAndUpdate with hint document fails with client-side error on server < 4.4",
+      "operations": [
+        {
+          "object": "collection",
+          "collectionOptions": {
+            "writeConcern": {
+              "w": 0
+            }
+          },
+          "name": "findOneAndUpdate",
+          "arguments": {
+            "filter": {
+              "_id": 1
+            },
+            "update": {
+              "$inc": {
+                "x": 1
+              }
+            },
+            "hint": {
+              "_id": 1
+            }
+          },
+          "error": true
+        }
+      ],
+      "expectations": {},
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/unacknowledged-findOneAndUpdate-hint.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/unacknowledged-findOneAndUpdate-hint.json
new file mode 100644
index 0000000000000000000000000000000000000000..383ca6ad6d4e3bd677e5c4020a3d5a36cd99b015
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/unacknowledged-findOneAndUpdate-hint.json	
@@ -0,0 +1,112 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.3.4"
+    }
+  ],
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    }
+  ],
+  "collection_name": "FindOneAndUpdate_hint",
+  "tests": [
+    {
+      "description": "Unacknowledged findOneAndUpdate with hint string succeeds on server >= 4.4",
+      "operations": [
+        {
+          "object": "collection",
+          "collectionOptions": {
+            "writeConcern": {
+              "w": 0
+            }
+          },
+          "name": "findOneAndUpdate",
+          "arguments": {
+            "filter": {
+              "_id": 1
+            },
+            "update": {
+              "$inc": {
+                "x": 1
+              }
+            },
+            "hint": "_id_"
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "findAndModify": "FindOneAndUpdate_hint",
+              "query": {
+                "_id": 1
+              },
+              "update": {
+                "$inc": {
+                  "x": 1
+                }
+              },
+              "hint": "_id_"
+            }
+          }
+        }
+      ],
+      "outcome": {}
+    },
+    {
+      "description": "Unacknowledged findOneAndUpdate with hint document succeeds on server >= 4.4",
+      "operations": [
+        {
+          "object": "collection",
+          "collectionOptions": {
+            "writeConcern": {
+              "w": 0
+            }
+          },
+          "name": "findOneAndUpdate",
+          "arguments": {
+            "filter": {
+              "_id": 1
+            },
+            "update": {
+              "$inc": {
+                "x": 1
+              }
+            },
+            "hint": {
+              "_id": 1
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "findAndModify": "FindOneAndUpdate_hint",
+              "query": {
+                "_id": 1
+              },
+              "update": {
+                "$inc": {
+                  "x": 1
+                }
+              },
+              "hint": {
+                "_id": 1
+              }
+            }
+          }
+        }
+      ],
+      "outcome": {}
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/unacknowledged-replaceOne-hint-clientError.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/unacknowledged-replaceOne-hint-clientError.json
new file mode 100644
index 0000000000000000000000000000000000000000..f442953f2de65a225be1bf35410cdb85c35877fa
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/unacknowledged-replaceOne-hint-clientError.json	
@@ -0,0 +1,104 @@
+{
+  "runOn": [
+    {
+      "maxServerVersion": "4.1.9"
+    }
+  ],
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    }
+  ],
+  "collection_name": "ReplaceOne_hint",
+  "tests": [
+    {
+      "description": "Unacknowledged ReplaceOne with hint string fails with client-side error on server < 4.2",
+      "operations": [
+        {
+          "object": "collection",
+          "collectionOptions": {
+            "writeConcern": {
+              "w": 0
+            }
+          },
+          "name": "replaceOne",
+          "arguments": {
+            "filter": {
+              "_id": {
+                "$gt": 1
+              }
+            },
+            "replacement": {
+              "x": 111
+            },
+            "hint": "_id_"
+          },
+          "error": true
+        }
+      ],
+      "expectations": {},
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "Unacknowledged ReplaceOne with hint document fails with client-side error on server < 4.2",
+      "operations": [
+        {
+          "object": "collection",
+          "collectionOptions": {
+            "writeConcern": {
+              "w": 0
+            }
+          },
+          "name": "replaceOne",
+          "arguments": {
+            "filter": {
+              "_id": {
+                "$gt": 1
+              }
+            },
+            "replacement": {
+              "x": 111
+            },
+            "hint": {
+              "_id": 1
+            }
+          },
+          "error": true
+        }
+      ],
+      "expectations": {},
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/unacknowledged-replaceOne-hint.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/unacknowledged-replaceOne-hint.json
new file mode 100644
index 0000000000000000000000000000000000000000..1d896bfb57464da88a8c53e6924f87487750fbbb
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/unacknowledged-replaceOne-hint.json	
@@ -0,0 +1,120 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.2.0"
+    }
+  ],
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    }
+  ],
+  "collection_name": "Replaceone_hint",
+  "tests": [
+    {
+      "description": "Unacknowledged replaceOne with hint string succeeds on server >= 4.2",
+      "operations": [
+        {
+          "object": "collection",
+          "collectionOptions": {
+            "writeConcern": {
+              "w": 0
+            }
+          },
+          "name": "replaceOne",
+          "arguments": {
+            "filter": {
+              "_id": {
+                "$gt": 1
+              }
+            },
+            "replacement": {
+              "x": 111
+            },
+            "hint": "_id_"
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "update": "Replaceone_hint",
+              "updates": [
+                {
+                  "q": {
+                    "_id": {
+                      "$gt": 1
+                    }
+                  },
+                  "u": {
+                    "x": 111
+                  },
+                  "hint": "_id_"
+                }
+              ]
+            }
+          }
+        }
+      ],
+      "outcome": {}
+    },
+    {
+      "description": "Unacknowledged replaceOne with hint document succeeds on server >= 4.2",
+      "operations": [
+        {
+          "object": "collection",
+          "collectionOptions": {
+            "writeConcern": {
+              "w": 0
+            }
+          },
+          "name": "replaceOne",
+          "arguments": {
+            "filter": {
+              "_id": {
+                "$gt": 1
+              }
+            },
+            "replacement": {
+              "x": 111
+            },
+            "hint": {
+              "_id": 1
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "update": "Replaceone_hint",
+              "updates": [
+                {
+                  "q": {
+                    "_id": {
+                      "$gt": 1
+                    }
+                  },
+                  "u": {
+                    "x": 111
+                  },
+                  "hint": {
+                    "_id": 1
+                  }
+                }
+              ]
+            }
+          }
+        }
+      ],
+      "outcome": {}
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/unacknowledged-updateMany-hint-clientError.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/unacknowledged-updateMany-hint-clientError.json
new file mode 100644
index 0000000000000000000000000000000000000000..9425d542ebfbf1539fbb964d68d80b6697b40c7b
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/unacknowledged-updateMany-hint-clientError.json	
@@ -0,0 +1,120 @@
+{
+  "runOn": [
+    {
+      "maxServerVersion": "4.1.9"
+    }
+  ],
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    },
+    {
+      "_id": 3,
+      "x": 33
+    }
+  ],
+  "collection_name": "Updatemany_hint",
+  "tests": [
+    {
+      "description": "Unacknowledged updateMany with hint string fails with client-side error on server < 4.2",
+      "operations": [
+        {
+          "object": "collection",
+          "collectionOptions": {
+            "writeConcern": {
+              "w": 0
+            }
+          },
+          "name": "updateMany",
+          "arguments": {
+            "filter": {
+              "_id": {
+                "$gt": 1
+              }
+            },
+            "update": {
+              "$inc": {
+                "x": 1
+              }
+            },
+            "hint": "_id_"
+          },
+          "error": true
+        }
+      ],
+      "expectations": {},
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "Unacknowledged updateMany with hint document fails with client-side error on server < 4.2",
+      "operations": [
+        {
+          "object": "collection",
+          "collectionOptions": {
+            "writeConcern": {
+              "w": 0
+            }
+          },
+          "name": "updateMany",
+          "arguments": {
+            "filter": {
+              "_id": {
+                "$gt": 1
+              }
+            },
+            "update": {
+              "$inc": {
+                "x": 1
+              }
+            },
+            "hint": {
+              "_id": 1
+            }
+          },
+          "error": true
+        }
+      ],
+      "expectations": {},
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/unacknowledged-updateMany-hint.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/unacknowledged-updateMany-hint.json
new file mode 100644
index 0000000000000000000000000000000000000000..d601a1b709aa77724c1a786f090ea59b721c2938
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/unacknowledged-updateMany-hint.json	
@@ -0,0 +1,134 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.2.0"
+    }
+  ],
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    },
+    {
+      "_id": 3,
+      "x": 33
+    }
+  ],
+  "collection_name": "UpdateMany_hint",
+  "tests": [
+    {
+      "description": "Unacknowledged updateMany with hint string succeeds on server >= 4.2",
+      "operations": [
+        {
+          "object": "collection",
+          "collectionOptions": {
+            "writeConcern": {
+              "w": 0
+            }
+          },
+          "name": "updateMany",
+          "arguments": {
+            "filter": {
+              "_id": {
+                "$gt": 1
+              }
+            },
+            "update": {
+              "$inc": {
+                "x": 1
+              }
+            },
+            "hint": "_id_"
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "update": "UpdateMany_hint",
+              "updates": [
+                {
+                  "q": {
+                    "_id": {
+                      "$gt": 1
+                    }
+                  },
+                  "u": {
+                    "$inc": {
+                      "x": 1
+                    }
+                  },
+                  "multi": true,
+                  "hint": "_id_"
+                }
+              ]
+            }
+          }
+        }
+      ],
+      "outcome": {}
+    },
+    {
+      "description": "Unacknowledged updateMany with hint document succeeds on server >= 4.2",
+      "operations": [
+        {
+          "object": "collection",
+          "collectionOptions": {
+            "writeConcern": {
+              "w": 0
+            }
+          },
+          "name": "updateMany",
+          "arguments": {
+            "filter": {
+              "_id": {
+                "$gt": 1
+              }
+            },
+            "update": {
+              "$inc": {
+                "x": 1
+              }
+            },
+            "hint": {
+              "_id": 1
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "update": "UpdateMany_hint",
+              "updates": [
+                {
+                  "q": {
+                    "_id": {
+                      "$gt": 1
+                    }
+                  },
+                  "u": {
+                    "$inc": {
+                      "x": 1
+                    }
+                  },
+                  "multi": true,
+                  "hint": {
+                    "_id": 1
+                  }
+                }
+              ]
+            }
+          }
+        }
+      ],
+      "outcome": {}
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/unacknowledged-updateOne-hint-clientError.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/unacknowledged-updateOne-hint-clientError.json
new file mode 100644
index 0000000000000000000000000000000000000000..bce3add675123f48e04b8f5c24edbb8de88ff294
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/unacknowledged-updateOne-hint-clientError.json	
@@ -0,0 +1,108 @@
+{
+  "runOn": [
+    {
+      "maxServerVersion": "4.1.9"
+    }
+  ],
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    }
+  ],
+  "collection_name": "Updateone_hint",
+  "tests": [
+    {
+      "description": "Unacknowledged updateOne with hint string fails with client-side error on server < 4.2",
+      "operations": [
+        {
+          "object": "collection",
+          "collectionOptions": {
+            "writeConcern": {
+              "w": 0
+            }
+          },
+          "name": "updateOne",
+          "arguments": {
+            "filter": {
+              "_id": {
+                "$gt": 1
+              }
+            },
+            "update": {
+              "$inc": {
+                "x": 1
+              }
+            },
+            "hint": "_id_"
+          },
+          "error": true
+        }
+      ],
+      "expectations": {},
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "Unacknowledged updateOne with hint document fails with client-side error on server < 4.2",
+      "operations": [
+        {
+          "object": "collection",
+          "collectionOptions": {
+            "writeConcern": {
+              "w": 0
+            }
+          },
+          "name": "updateOne",
+          "arguments": {
+            "filter": {
+              "_id": {
+                "$gt": 1
+              }
+            },
+            "update": {
+              "$inc": {
+                "x": 1
+              }
+            },
+            "hint": {
+              "_id": 1
+            }
+          },
+          "error": true
+        }
+      ],
+      "expectations": {},
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/unacknowledged-updateOne-hint.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/unacknowledged-updateOne-hint.json
new file mode 100644
index 0000000000000000000000000000000000000000..ca2f57f621ff9e8388b3b32836aef90007b3c44c
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/unacknowledged-updateOne-hint.json	
@@ -0,0 +1,128 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.2.0"
+    }
+  ],
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    }
+  ],
+  "collection_name": "updateone_hint",
+  "tests": [
+    {
+      "description": "Unacknowledged updateOne with hint string succeeds on server >= 4.2",
+      "operations": [
+        {
+          "object": "collection",
+          "collectionOptions": {
+            "writeConcern": {
+              "w": 0
+            }
+          },
+          "name": "updateOne",
+          "arguments": {
+            "filter": {
+              "_id": {
+                "$gt": 1
+              }
+            },
+            "update": {
+              "$inc": {
+                "x": 1
+              }
+            },
+            "hint": "_id_"
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "update": "updateone_hint",
+              "updates": [
+                {
+                  "q": {
+                    "_id": {
+                      "$gt": 1
+                    }
+                  },
+                  "u": {
+                    "$inc": {
+                      "x": 1
+                    }
+                  },
+                  "hint": "_id_"
+                }
+              ]
+            }
+          }
+        }
+      ],
+      "outcome": {}
+    },
+    {
+      "description": "Unacknowledged updateOne with hint document succeeds on server >= 4.2",
+      "operations": [
+        {
+          "object": "collection",
+          "collectionOptions": {
+            "writeConcern": {
+              "w": 0
+            }
+          },
+          "name": "updateOne",
+          "arguments": {
+            "filter": {
+              "_id": {
+                "$gt": 1
+              }
+            },
+            "update": {
+              "$inc": {
+                "x": 1
+              }
+            },
+            "hint": {
+              "_id": 1
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "update": "updateone_hint",
+              "updates": [
+                {
+                  "q": {
+                    "_id": {
+                      "$gt": 1
+                    }
+                  },
+                  "u": {
+                    "$inc": {
+                      "x": 1
+                    }
+                  },
+                  "hint": {
+                    "_id": 1
+                  }
+                }
+              ]
+            }
+          }
+        }
+      ],
+      "outcome": {}
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/updateMany-hint-clientError.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/updateMany-hint-clientError.json
new file mode 100644
index 0000000000000000000000000000000000000000..44ebddc53daf0f47fc10963e863f0d68fb5d1fda
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/updateMany-hint-clientError.json	
@@ -0,0 +1,110 @@
+{
+  "runOn": [
+    {
+      "maxServerVersion": "3.3.99"
+    }
+  ],
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    },
+    {
+      "_id": 3,
+      "x": 33
+    }
+  ],
+  "collection_name": "test_updatemany_hint",
+  "tests": [
+    {
+      "description": "UpdateMany with hint string unsupported (client-side error)",
+      "operations": [
+        {
+          "object": "collection",
+          "name": "updateMany",
+          "arguments": {
+            "filter": {
+              "_id": {
+                "$gt": 1
+              }
+            },
+            "update": {
+              "$inc": {
+                "x": 1
+              }
+            },
+            "hint": "_id_"
+          },
+          "error": true
+        }
+      ],
+      "expectations": [],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "UpdateMany with hint document unsupported (client-side error)",
+      "operations": [
+        {
+          "object": "collection",
+          "name": "updateMany",
+          "arguments": {
+            "filter": {
+              "_id": {
+                "$gt": 1
+              }
+            },
+            "update": {
+              "$inc": {
+                "x": 1
+              }
+            },
+            "hint": {
+              "_id": 1
+            }
+          },
+          "error": true
+        }
+      ],
+      "expectations": [],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/updateMany-hint-serverError.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/updateMany-hint-serverError.json
new file mode 100644
index 0000000000000000000000000000000000000000..86f21246e90726ff44414ba1815c3b2a459bb493
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/updateMany-hint-serverError.json	
@@ -0,0 +1,161 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "3.4.0",
+      "maxServerVersion": "4.1.9"
+    }
+  ],
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    },
+    {
+      "_id": 3,
+      "x": 33
+    }
+  ],
+  "collection_name": "test_updatemany_hint",
+  "tests": [
+    {
+      "description": "UpdateMany with hint string unsupported (server-side error)",
+      "operations": [
+        {
+          "object": "collection",
+          "name": "updateMany",
+          "arguments": {
+            "filter": {
+              "_id": {
+                "$gt": 1
+              }
+            },
+            "update": {
+              "$inc": {
+                "x": 1
+              }
+            },
+            "hint": "_id_"
+          },
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "update": "test_updatemany_hint",
+              "updates": [
+                {
+                  "q": {
+                    "_id": {
+                      "$gt": 1
+                    }
+                  },
+                  "u": {
+                    "$inc": {
+                      "x": 1
+                    }
+                  },
+                  "multi": true,
+                  "hint": "_id_"
+                }
+              ]
+            }
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "UpdateMany with hint document unsupported (server-side error)",
+      "operations": [
+        {
+          "object": "collection",
+          "name": "updateMany",
+          "arguments": {
+            "filter": {
+              "_id": {
+                "$gt": 1
+              }
+            },
+            "update": {
+              "$inc": {
+                "x": 1
+              }
+            },
+            "hint": {
+              "_id": 1
+            }
+          },
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "update": "test_updatemany_hint",
+              "updates": [
+                {
+                  "q": {
+                    "_id": {
+                      "$gt": 1
+                    }
+                  },
+                  "u": {
+                    "$inc": {
+                      "x": 1
+                    }
+                  },
+                  "multi": true,
+                  "hint": {
+                    "_id": 1
+                  }
+                }
+              ]
+            }
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/updateMany-hint.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/updateMany-hint.json
new file mode 100644
index 0000000000000000000000000000000000000000..489348917f913b20876f1970de8cb56f715e9f78
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/updateMany-hint.json	
@@ -0,0 +1,168 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.2.0"
+    }
+  ],
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    },
+    {
+      "_id": 3,
+      "x": 33
+    }
+  ],
+  "collection_name": "test_updatemany_hint",
+  "tests": [
+    {
+      "description": "UpdateMany with hint string",
+      "operations": [
+        {
+          "object": "collection",
+          "name": "updateMany",
+          "arguments": {
+            "filter": {
+              "_id": {
+                "$gt": 1
+              }
+            },
+            "update": {
+              "$inc": {
+                "x": 1
+              }
+            },
+            "hint": "_id_"
+          },
+          "result": {
+            "matchedCount": 2,
+            "modifiedCount": 2,
+            "upsertedCount": 0
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "update": "test_updatemany_hint",
+              "updates": [
+                {
+                  "q": {
+                    "_id": {
+                      "$gt": 1
+                    }
+                  },
+                  "u": {
+                    "$inc": {
+                      "x": 1
+                    }
+                  },
+                  "multi": true,
+                  "hint": "_id_"
+                }
+              ]
+            }
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 23
+            },
+            {
+              "_id": 3,
+              "x": 34
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "UpdateMany with hint document",
+      "operations": [
+        {
+          "object": "collection",
+          "name": "updateMany",
+          "arguments": {
+            "filter": {
+              "_id": {
+                "$gt": 1
+              }
+            },
+            "update": {
+              "$inc": {
+                "x": 1
+              }
+            },
+            "hint": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "matchedCount": 2,
+            "modifiedCount": 2,
+            "upsertedCount": 0
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "update": "test_updatemany_hint",
+              "updates": [
+                {
+                  "q": {
+                    "_id": {
+                      "$gt": 1
+                    }
+                  },
+                  "u": {
+                    "$inc": {
+                      "x": 1
+                    }
+                  },
+                  "multi": true,
+                  "hint": {
+                    "_id": 1
+                  }
+                }
+              ]
+            }
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 23
+            },
+            {
+              "_id": 3,
+              "x": 34
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/updateMany-validation.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/updateMany-validation.json
new file mode 100644
index 0000000000000000000000000000000000000000..a85ccfa86ea38a907f958bd1d3d1305fa21a8393
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/updateMany-validation.json	
@@ -0,0 +1,57 @@
+{
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    },
+    {
+      "_id": 3,
+      "x": 33
+    }
+  ],
+  "tests": [
+    {
+      "description": "UpdateOne requires atomic modifiers",
+      "operations": [
+        {
+          "object": "collection",
+          "name": "updateMany",
+          "arguments": {
+            "filter": {
+              "_id": {
+                "$gt": 1
+              }
+            },
+            "update": {
+              "x": 44
+            }
+          },
+          "error": true
+        }
+      ],
+      "expectations": [],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/updateOne-hint-clientError.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/updateOne-hint-clientError.json
new file mode 100644
index 0000000000000000000000000000000000000000..82bfe368c7a30d7251d0aae3a42edb37e1dc2dea
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/updateOne-hint-clientError.json	
@@ -0,0 +1,98 @@
+{
+  "runOn": [
+    {
+      "maxServerVersion": "3.3.99"
+    }
+  ],
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    }
+  ],
+  "collection_name": "test_updateone_hint",
+  "tests": [
+    {
+      "description": "UpdateOne with hint string unsupported (client-side error)",
+      "operations": [
+        {
+          "object": "collection",
+          "name": "updateOne",
+          "arguments": {
+            "filter": {
+              "_id": {
+                "$gt": 1
+              }
+            },
+            "update": {
+              "$inc": {
+                "x": 1
+              }
+            },
+            "hint": "_id_"
+          },
+          "error": true
+        }
+      ],
+      "expectations": [],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "UpdateOne with hint document unsupported (client-side error)",
+      "operations": [
+        {
+          "object": "collection",
+          "name": "updateOne",
+          "arguments": {
+            "filter": {
+              "_id": {
+                "$gt": 1
+              }
+            },
+            "update": {
+              "$inc": {
+                "x": 1
+              }
+            },
+            "hint": {
+              "_id": 1
+            }
+          },
+          "error": true
+        }
+      ],
+      "expectations": [],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/updateOne-hint-serverError.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/updateOne-hint-serverError.json
new file mode 100644
index 0000000000000000000000000000000000000000..8e8037eb8c37c6671ca3ea247a33a8d99667e39b
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/updateOne-hint-serverError.json	
@@ -0,0 +1,147 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "3.4.0",
+      "maxServerVersion": "4.1.9"
+    }
+  ],
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    }
+  ],
+  "collection_name": "test_updateone_hint",
+  "tests": [
+    {
+      "description": "UpdateOne with hint string unsupported (server-side error)",
+      "operations": [
+        {
+          "object": "collection",
+          "name": "updateOne",
+          "arguments": {
+            "filter": {
+              "_id": {
+                "$gt": 1
+              }
+            },
+            "update": {
+              "$inc": {
+                "x": 1
+              }
+            },
+            "hint": "_id_"
+          },
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "update": "test_updateone_hint",
+              "updates": [
+                {
+                  "q": {
+                    "_id": {
+                      "$gt": 1
+                    }
+                  },
+                  "u": {
+                    "$inc": {
+                      "x": 1
+                    }
+                  },
+                  "hint": "_id_"
+                }
+              ]
+            }
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "UpdateOne with hint document unsupported (server-side error)",
+      "operations": [
+        {
+          "object": "collection",
+          "name": "updateOne",
+          "arguments": {
+            "filter": {
+              "_id": {
+                "$gt": 1
+              }
+            },
+            "update": {
+              "$inc": {
+                "x": 1
+              }
+            },
+            "hint": {
+              "_id": 1
+            }
+          },
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "update": "test_updateone_hint",
+              "updates": [
+                {
+                  "q": {
+                    "_id": {
+                      "$gt": 1
+                    }
+                  },
+                  "u": {
+                    "$inc": {
+                      "x": 1
+                    }
+                  },
+                  "hint": {
+                    "_id": 1
+                  }
+                }
+              ]
+            }
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/updateOne-hint.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/updateOne-hint.json
new file mode 100644
index 0000000000000000000000000000000000000000..43f76da4988346e3a37b333030173484ba0be9a4
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/updateOne-hint.json	
@@ -0,0 +1,154 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.2.0"
+    }
+  ],
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    }
+  ],
+  "collection_name": "test_updateone_hint",
+  "tests": [
+    {
+      "description": "UpdateOne with hint string",
+      "operations": [
+        {
+          "object": "collection",
+          "name": "updateOne",
+          "arguments": {
+            "filter": {
+              "_id": {
+                "$gt": 1
+              }
+            },
+            "update": {
+              "$inc": {
+                "x": 1
+              }
+            },
+            "hint": "_id_"
+          },
+          "result": {
+            "matchedCount": 1,
+            "modifiedCount": 1,
+            "upsertedCount": 0
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "update": "test_updateone_hint",
+              "updates": [
+                {
+                  "q": {
+                    "_id": {
+                      "$gt": 1
+                    }
+                  },
+                  "u": {
+                    "$inc": {
+                      "x": 1
+                    }
+                  },
+                  "hint": "_id_"
+                }
+              ]
+            }
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 23
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "UpdateOne with hint document",
+      "operations": [
+        {
+          "object": "collection",
+          "name": "updateOne",
+          "arguments": {
+            "filter": {
+              "_id": {
+                "$gt": 1
+              }
+            },
+            "update": {
+              "$inc": {
+                "x": 1
+              }
+            },
+            "hint": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "matchedCount": 1,
+            "modifiedCount": 1,
+            "upsertedCount": 0
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "update": "test_updateone_hint",
+              "updates": [
+                {
+                  "q": {
+                    "_id": {
+                      "$gt": 1
+                    }
+                  },
+                  "u": {
+                    "$inc": {
+                      "x": 1
+                    }
+                  },
+                  "hint": {
+                    "_id": 1
+                  }
+                }
+              ]
+            }
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 23
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/updateOne-validation.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/updateOne-validation.json
new file mode 100644
index 0000000000000000000000000000000000000000..6c919f5ea04b22c4478f47cdc9bf613a9ec9d107
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/updateOne-validation.json	
@@ -0,0 +1,39 @@
+{
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    }
+  ],
+  "tests": [
+    {
+      "description": "UpdateOne requires atomic modifiers",
+      "operations": [
+        {
+          "object": "collection",
+          "name": "updateOne",
+          "arguments": {
+            "filter": {
+              "_id": 1
+            },
+            "update": {
+              "x": 22
+            }
+          },
+          "error": true
+        }
+      ],
+      "expectations": [],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/updateWithPipelines.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/updateWithPipelines.json
new file mode 100644
index 0000000000000000000000000000000000000000..a310f2825f25c1476f787b84a7914f6079cbf58f
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/crud/updateWithPipelines.json	
@@ -0,0 +1,408 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.1.11"
+    }
+  ],
+  "data": [
+    {
+      "_id": 1,
+      "x": 1,
+      "y": 1,
+      "t": {
+        "u": {
+          "v": 1
+        }
+      }
+    },
+    {
+      "_id": 2,
+      "x": 2,
+      "y": 1
+    }
+  ],
+  "collection_name": "test",
+  "database_name": "crud-tests",
+  "tests": [
+    {
+      "description": "UpdateOne using pipelines",
+      "operations": [
+        {
+          "name": "updateOne",
+          "arguments": {
+            "filter": {
+              "_id": 1
+            },
+            "update": [
+              {
+                "$replaceRoot": {
+                  "newRoot": "$t"
+                }
+              },
+              {
+                "$addFields": {
+                  "foo": 1
+                }
+              }
+            ]
+          },
+          "result": {
+            "matchedCount": 1,
+            "modifiedCount": 1,
+            "upsertedCount": 0
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "update": "test",
+              "updates": [
+                {
+                  "q": {
+                    "_id": 1
+                  },
+                  "u": [
+                    {
+                      "$replaceRoot": {
+                        "newRoot": "$t"
+                      }
+                    },
+                    {
+                      "$addFields": {
+                        "foo": 1
+                      }
+                    }
+                  ]
+                }
+              ]
+            },
+            "command_name": "update",
+            "database_name": "crud-tests"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "u": {
+                "v": 1
+              },
+              "foo": 1
+            },
+            {
+              "_id": 2,
+              "x": 2,
+              "y": 1
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "UpdateMany using pipelines",
+      "operations": [
+        {
+          "name": "updateMany",
+          "arguments": {
+            "filter": {},
+            "update": [
+              {
+                "$project": {
+                  "x": 1
+                }
+              },
+              {
+                "$addFields": {
+                  "foo": 1
+                }
+              }
+            ]
+          },
+          "result": {
+            "matchedCount": 2,
+            "modifiedCount": 2,
+            "upsertedCount": 0
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "update": "test",
+              "updates": [
+                {
+                  "q": {},
+                  "u": [
+                    {
+                      "$project": {
+                        "x": 1
+                      }
+                    },
+                    {
+                      "$addFields": {
+                        "foo": 1
+                      }
+                    }
+                  ],
+                  "multi": true
+                }
+              ]
+            },
+            "command_name": "update",
+            "database_name": "crud-tests"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 1,
+              "foo": 1
+            },
+            {
+              "_id": 2,
+              "x": 2,
+              "foo": 1
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "FindOneAndUpdate using pipelines",
+      "operations": [
+        {
+          "name": "findOneAndUpdate",
+          "arguments": {
+            "filter": {
+              "_id": 1
+            },
+            "update": [
+              {
+                "$project": {
+                  "x": 1
+                }
+              },
+              {
+                "$addFields": {
+                  "foo": 1
+                }
+              }
+            ]
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "findAndModify": "test",
+              "update": [
+                {
+                  "$project": {
+                    "x": 1
+                  }
+                },
+                {
+                  "$addFields": {
+                    "foo": 1
+                  }
+                }
+              ]
+            },
+            "command_name": "findAndModify",
+            "database_name": "crud-tests"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 1,
+              "foo": 1
+            },
+            {
+              "_id": 2,
+              "x": 2,
+              "y": 1
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "UpdateOne in bulk write using pipelines",
+      "operations": [
+        {
+          "name": "bulkWrite",
+          "arguments": {
+            "requests": [
+              {
+                "name": "updateOne",
+                "arguments": {
+                  "filter": {
+                    "_id": 1
+                  },
+                  "update": [
+                    {
+                      "$replaceRoot": {
+                        "newRoot": "$t"
+                      }
+                    },
+                    {
+                      "$addFields": {
+                        "foo": 1
+                      }
+                    }
+                  ]
+                }
+              }
+            ]
+          },
+          "result": {
+            "matchedCount": 1,
+            "modifiedCount": 1,
+            "upsertedCount": 0
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "update": "test",
+              "updates": [
+                {
+                  "q": {
+                    "_id": 1
+                  },
+                  "u": [
+                    {
+                      "$replaceRoot": {
+                        "newRoot": "$t"
+                      }
+                    },
+                    {
+                      "$addFields": {
+                        "foo": 1
+                      }
+                    }
+                  ]
+                }
+              ]
+            },
+            "command_name": "update",
+            "database_name": "crud-tests"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "u": {
+                "v": 1
+              },
+              "foo": 1
+            },
+            {
+              "_id": 2,
+              "x": 2,
+              "y": 1
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "UpdateMany in bulk write using pipelines",
+      "operations": [
+        {
+          "name": "bulkWrite",
+          "arguments": {
+            "requests": [
+              {
+                "name": "updateMany",
+                "arguments": {
+                  "filter": {},
+                  "update": [
+                    {
+                      "$project": {
+                        "x": 1
+                      }
+                    },
+                    {
+                      "$addFields": {
+                        "foo": 1
+                      }
+                    }
+                  ]
+                }
+              }
+            ]
+          },
+          "result": {
+            "matchedCount": 2,
+            "modifiedCount": 2,
+            "upsertedCount": 0
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "update": "test",
+              "updates": [
+                {
+                  "q": {},
+                  "u": [
+                    {
+                      "$project": {
+                        "x": 1
+                      }
+                    },
+                    {
+                      "$addFields": {
+                        "foo": 1
+                      }
+                    }
+                  ],
+                  "multi": true
+                }
+              ]
+            },
+            "command_name": "update",
+            "database_name": "crud-tests"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 1,
+              "foo": 1
+            },
+            {
+              "_id": 2,
+              "x": 2,
+              "foo": 1
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/read-write-concern/operation/default-write-concern-2.6.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/read-write-concern/operation/default-write-concern-2.6.json
new file mode 100644
index 0000000000000000000000000000000000000000..c623298cd781867eebf5f6228fe13800a603e468
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/read-write-concern/operation/default-write-concern-2.6.json	
@@ -0,0 +1,544 @@
+{
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    }
+  ],
+  "collection_name": "default_write_concern_coll",
+  "database_name": "default_write_concern_db",
+  "runOn": [
+    {
+      "minServerVersion": "2.6"
+    }
+  ],
+  "tests": [
+    {
+      "description": "DeleteOne omits default write concern",
+      "operations": [
+        {
+          "name": "deleteOne",
+          "object": "collection",
+          "collectionOptions": {
+            "writeConcern": {}
+          },
+          "arguments": {
+            "filter": {}
+          },
+          "result": {
+            "deletedCount": 1
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "delete": "default_write_concern_coll",
+              "deletes": [
+                {
+                  "q": {},
+                  "limit": 1
+                }
+              ],
+              "writeConcern": null
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "DeleteMany omits default write concern",
+      "operations": [
+        {
+          "name": "deleteMany",
+          "object": "collection",
+          "collectionOptions": {
+            "writeConcern": {}
+          },
+          "arguments": {
+            "filter": {}
+          },
+          "result": {
+            "deletedCount": 2
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "delete": "default_write_concern_coll",
+              "deletes": [
+                {
+                  "q": {},
+                  "limit": 0
+                }
+              ],
+              "writeConcern": null
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "BulkWrite with all models omits default write concern",
+      "operations": [
+        {
+          "name": "bulkWrite",
+          "object": "collection",
+          "collectionOptions": {
+            "writeConcern": {}
+          },
+          "arguments": {
+            "ordered": true,
+            "requests": [
+              {
+                "name": "deleteMany",
+                "arguments": {
+                  "filter": {}
+                }
+              },
+              {
+                "name": "insertOne",
+                "arguments": {
+                  "document": {
+                    "_id": 1
+                  }
+                }
+              },
+              {
+                "name": "updateOne",
+                "arguments": {
+                  "filter": {
+                    "_id": 1
+                  },
+                  "update": {
+                    "$set": {
+                      "x": 1
+                    }
+                  }
+                }
+              },
+              {
+                "name": "insertOne",
+                "arguments": {
+                  "document": {
+                    "_id": 2
+                  }
+                }
+              },
+              {
+                "name": "replaceOne",
+                "arguments": {
+                  "filter": {
+                    "_id": 1
+                  },
+                  "replacement": {
+                    "x": 2
+                  }
+                }
+              },
+              {
+                "name": "insertOne",
+                "arguments": {
+                  "document": {
+                    "_id": 3
+                  }
+                }
+              },
+              {
+                "name": "updateMany",
+                "arguments": {
+                  "filter": {
+                    "_id": 1
+                  },
+                  "update": {
+                    "$set": {
+                      "x": 3
+                    }
+                  }
+                }
+              },
+              {
+                "name": "deleteOne",
+                "arguments": {
+                  "filter": {
+                    "_id": 3
+                  }
+                }
+              }
+            ]
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "name": "default_write_concern_coll",
+          "data": [
+            {
+              "_id": 1,
+              "x": 3
+            },
+            {
+              "_id": 2
+            }
+          ]
+        }
+      },
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "delete": "default_write_concern_coll",
+              "deletes": [
+                {
+                  "q": {},
+                  "limit": 0
+                }
+              ],
+              "writeConcern": null
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "default_write_concern_coll",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "writeConcern": null
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "update": "default_write_concern_coll",
+              "updates": [
+                {
+                  "q": {
+                    "_id": 1
+                  },
+                  "u": {
+                    "$set": {
+                      "x": 1
+                    }
+                  }
+                }
+              ],
+              "writeConcern": null
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "default_write_concern_coll",
+              "documents": [
+                {
+                  "_id": 2
+                }
+              ],
+              "writeConcern": null
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "update": "default_write_concern_coll",
+              "updates": [
+                {
+                  "q": {
+                    "_id": 1
+                  },
+                  "u": {
+                    "x": 2
+                  }
+                }
+              ],
+              "writeConcern": null
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "default_write_concern_coll",
+              "documents": [
+                {
+                  "_id": 3
+                }
+              ],
+              "writeConcern": null
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "update": "default_write_concern_coll",
+              "updates": [
+                {
+                  "q": {
+                    "_id": 1
+                  },
+                  "u": {
+                    "$set": {
+                      "x": 3
+                    }
+                  },
+                  "multi": true
+                }
+              ],
+              "writeConcern": null
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "delete": "default_write_concern_coll",
+              "deletes": [
+                {
+                  "q": {
+                    "_id": 3
+                  },
+                  "limit": 1
+                }
+              ],
+              "writeConcern": null
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "InsertOne and InsertMany omit default write concern",
+      "operations": [
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "collectionOptions": {
+            "writeConcern": {}
+          },
+          "arguments": {
+            "document": {
+              "_id": 3
+            }
+          }
+        },
+        {
+          "name": "insertMany",
+          "object": "collection",
+          "collectionOptions": {
+            "writeConcern": {}
+          },
+          "arguments": {
+            "documents": [
+              {
+                "_id": 4
+              },
+              {
+                "_id": 5
+              }
+            ]
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "name": "default_write_concern_coll",
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3
+            },
+            {
+              "_id": 4
+            },
+            {
+              "_id": 5
+            }
+          ]
+        }
+      },
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "default_write_concern_coll",
+              "documents": [
+                {
+                  "_id": 3
+                }
+              ],
+              "writeConcern": null
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "default_write_concern_coll",
+              "documents": [
+                {
+                  "_id": 4
+                },
+                {
+                  "_id": 5
+                }
+              ],
+              "writeConcern": null
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "UpdateOne, UpdateMany, and ReplaceOne omit default write concern",
+      "operations": [
+        {
+          "name": "updateOne",
+          "object": "collection",
+          "collectionOptions": {
+            "writeConcern": {}
+          },
+          "arguments": {
+            "filter": {
+              "_id": 1
+            },
+            "update": {
+              "$set": {
+                "x": 1
+              }
+            }
+          }
+        },
+        {
+          "name": "updateMany",
+          "object": "collection",
+          "collectionOptions": {
+            "writeConcern": {}
+          },
+          "arguments": {
+            "filter": {
+              "_id": 2
+            },
+            "update": {
+              "$set": {
+                "x": 2
+              }
+            }
+          }
+        },
+        {
+          "name": "replaceOne",
+          "object": "collection",
+          "collectionOptions": {
+            "writeConcern": {}
+          },
+          "arguments": {
+            "filter": {
+              "_id": 2
+            },
+            "replacement": {
+              "x": 3
+            }
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "name": "default_write_concern_coll",
+          "data": [
+            {
+              "_id": 1,
+              "x": 1
+            },
+            {
+              "_id": 2,
+              "x": 3
+            }
+          ]
+        }
+      },
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "update": "default_write_concern_coll",
+              "updates": [
+                {
+                  "q": {
+                    "_id": 1
+                  },
+                  "u": {
+                    "$set": {
+                      "x": 1
+                    }
+                  }
+                }
+              ],
+              "writeConcern": null
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "update": "default_write_concern_coll",
+              "updates": [
+                {
+                  "q": {
+                    "_id": 2
+                  },
+                  "u": {
+                    "$set": {
+                      "x": 2
+                    }
+                  },
+                  "multi": true
+                }
+              ],
+              "writeConcern": null
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "update": "default_write_concern_coll",
+              "updates": [
+                {
+                  "q": {
+                    "_id": 2
+                  },
+                  "u": {
+                    "x": 3
+                  }
+                }
+              ],
+              "writeConcern": null
+            }
+          }
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/read-write-concern/operation/default-write-concern-3.2.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/read-write-concern/operation/default-write-concern-3.2.json
new file mode 100644
index 0000000000000000000000000000000000000000..04dd231f040cd0e57beefd93b64691c52e07e310
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/read-write-concern/operation/default-write-concern-3.2.json	
@@ -0,0 +1,125 @@
+{
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    }
+  ],
+  "collection_name": "default_write_concern_coll",
+  "database_name": "default_write_concern_db",
+  "runOn": [
+    {
+      "minServerVersion": "3.2"
+    }
+  ],
+  "tests": [
+    {
+      "description": "findAndModify operations omit default write concern",
+      "operations": [
+        {
+          "name": "findOneAndUpdate",
+          "object": "collection",
+          "collectionOptions": {
+            "writeConcern": {}
+          },
+          "arguments": {
+            "filter": {
+              "_id": 1
+            },
+            "update": {
+              "$set": {
+                "x": 1
+              }
+            }
+          }
+        },
+        {
+          "name": "findOneAndReplace",
+          "object": "collection",
+          "collectionOptions": {
+            "writeConcern": {}
+          },
+          "arguments": {
+            "filter": {
+              "_id": 2
+            },
+            "replacement": {
+              "x": 2
+            }
+          }
+        },
+        {
+          "name": "findOneAndDelete",
+          "object": "collection",
+          "collectionOptions": {
+            "writeConcern": {}
+          },
+          "arguments": {
+            "filter": {
+              "_id": 2
+            }
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "name": "default_write_concern_coll",
+          "data": [
+            {
+              "_id": 1,
+              "x": 1
+            }
+          ]
+        }
+      },
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "findAndModify": "default_write_concern_coll",
+              "query": {
+                "_id": 1
+              },
+              "update": {
+                "$set": {
+                  "x": 1
+                }
+              },
+              "writeConcern": null
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "findAndModify": "default_write_concern_coll",
+              "query": {
+                "_id": 2
+              },
+              "update": {
+                "x": 2
+              },
+              "writeConcern": null
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "findAndModify": "default_write_concern_coll",
+              "query": {
+                "_id": 2
+              },
+              "remove": true,
+              "writeConcern": null
+            }
+          }
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/read-write-concern/operation/default-write-concern-3.4.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/read-write-concern/operation/default-write-concern-3.4.json
new file mode 100644
index 0000000000000000000000000000000000000000..6519f6f089eaf3bf653777ea3dd657912dc5fde8
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/read-write-concern/operation/default-write-concern-3.4.json	
@@ -0,0 +1,216 @@
+{
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    }
+  ],
+  "collection_name": "default_write_concern_coll",
+  "database_name": "default_write_concern_db",
+  "runOn": [
+    {
+      "minServerVersion": "3.4"
+    }
+  ],
+  "tests": [
+    {
+      "description": "Aggregate with $out omits default write concern",
+      "operations": [
+        {
+          "object": "collection",
+          "collectionOptions": {
+            "writeConcern": {}
+          },
+          "name": "aggregate",
+          "arguments": {
+            "pipeline": [
+              {
+                "$match": {
+                  "_id": {
+                    "$gt": 1
+                  }
+                }
+              },
+              {
+                "$out": "other_collection_name"
+              }
+            ]
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "name": "other_collection_name",
+          "data": [
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      },
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "default_write_concern_coll",
+              "pipeline": [
+                {
+                  "$match": {
+                    "_id": {
+                      "$gt": 1
+                    }
+                  }
+                },
+                {
+                  "$out": "other_collection_name"
+                }
+              ],
+              "writeConcern": null
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "RunCommand with a write command omits default write concern (runCommand should never inherit write concern)",
+      "operations": [
+        {
+          "object": "database",
+          "databaseOptions": {
+            "writeConcern": {}
+          },
+          "name": "runCommand",
+          "command_name": "delete",
+          "arguments": {
+            "command": {
+              "delete": "default_write_concern_coll",
+              "deletes": [
+                {
+                  "q": {},
+                  "limit": 1
+                }
+              ]
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "delete": "default_write_concern_coll",
+              "deletes": [
+                {
+                  "q": {},
+                  "limit": 1
+                }
+              ],
+              "writeConcern": null
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "CreateIndex and dropIndex omits default write concern",
+      "operations": [
+        {
+          "object": "collection",
+          "collectionOptions": {
+            "writeConcern": {}
+          },
+          "name": "createIndex",
+          "arguments": {
+            "keys": {
+              "x": 1
+            }
+          }
+        },
+        {
+          "object": "collection",
+          "collectionOptions": {
+            "writeConcern": {}
+          },
+          "name": "dropIndex",
+          "arguments": {
+            "name": "x_1"
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "createIndexes": "default_write_concern_coll",
+              "indexes": [
+                {
+                  "name": "x_1",
+                  "key": {
+                    "x": 1
+                  }
+                }
+              ],
+              "writeConcern": null
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "dropIndexes": "default_write_concern_coll",
+              "index": "x_1",
+              "writeConcern": null
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "MapReduce omits default write concern",
+      "operations": [
+        {
+          "name": "mapReduce",
+          "object": "collection",
+          "collectionOptions": {
+            "writeConcern": {}
+          },
+          "arguments": {
+            "map": {
+              "$code": "function inc() { return emit(0, this.x + 1) }"
+            },
+            "reduce": {
+              "$code": "function sum(key, values) { return values.reduce((acc, x) => acc + x); }"
+            },
+            "out": {
+              "inline": 1
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "mapReduce": "default_write_concern_coll",
+              "map": {
+                "$code": "function inc() { return emit(0, this.x + 1) }"
+              },
+              "reduce": {
+                "$code": "function sum(key, values) { return values.reduce((acc, x) => acc + x); }"
+              },
+              "out": {
+                "inline": 1
+              },
+              "writeConcern": null
+            }
+          }
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/read-write-concern/operation/default-write-concern-4.2.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/read-write-concern/operation/default-write-concern-4.2.json
new file mode 100644
index 0000000000000000000000000000000000000000..fef192d1a3956f3ae90c69960aceff3777d2bdf6
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/read-write-concern/operation/default-write-concern-4.2.json	
@@ -0,0 +1,87 @@
+{
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    }
+  ],
+  "collection_name": "default_write_concern_coll",
+  "database_name": "default_write_concern_db",
+  "runOn": [
+    {
+      "minServerVersion": "4.2"
+    }
+  ],
+  "tests": [
+    {
+      "description": "Aggregate with $merge omits default write concern",
+      "operations": [
+        {
+          "object": "collection",
+          "databaseOptions": {
+            "writeConcern": {}
+          },
+          "collectionOptions": {
+            "writeConcern": {}
+          },
+          "name": "aggregate",
+          "arguments": {
+            "pipeline": [
+              {
+                "$match": {
+                  "_id": {
+                    "$gt": 1
+                  }
+                }
+              },
+              {
+                "$merge": {
+                  "into": "other_collection_name"
+                }
+              }
+            ]
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "default_write_concern_coll",
+              "pipeline": [
+                {
+                  "$match": {
+                    "_id": {
+                      "$gt": 1
+                    }
+                  }
+                },
+                {
+                  "$merge": {
+                    "into": "other_collection_name"
+                  }
+                }
+              ],
+              "writeConcern": null
+            }
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "name": "other_collection_name",
+          "data": [
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/aggregate-merge.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/aggregate-merge.json
new file mode 100644
index 0000000000000000000000000000000000000000..b401d741ba551b334d56469c4631fe8fc304bb3e
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/aggregate-merge.json	
@@ -0,0 +1,98 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.1.11"
+    }
+  ],
+  "database_name": "retryable-reads-tests",
+  "collection_name": "coll",
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    },
+    {
+      "_id": 3,
+      "x": 33
+    }
+  ],
+  "tests": [
+    {
+      "description": "Aggregate with $merge does not retry",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "aggregate"
+          ],
+          "closeConnection": true
+        }
+      },
+      "operations": [
+        {
+          "object": "collection",
+          "name": "aggregate",
+          "arguments": {
+            "pipeline": [
+              {
+                "$match": {
+                  "_id": {
+                    "$gt": 1
+                  }
+                }
+              },
+              {
+                "$sort": {
+                  "x": 1
+                }
+              },
+              {
+                "$merge": {
+                  "into": "output-collection"
+                }
+              }
+            ]
+          },
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "pipeline": [
+                {
+                  "$match": {
+                    "_id": {
+                      "$gt": 1
+                    }
+                  }
+                },
+                {
+                  "$sort": {
+                    "x": 1
+                  }
+                },
+                {
+                  "$merge": {
+                    "into": "output-collection"
+                  }
+                }
+              ]
+            },
+            "command_name": "aggregate",
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/aggregate-serverErrors.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/aggregate-serverErrors.json
new file mode 100644
index 0000000000000000000000000000000000000000..04208bc95b8d3695e1e1f75b0f04d6cc5b013038
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/aggregate-serverErrors.json	
@@ -0,0 +1,1207 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.0",
+      "topology": [
+        "single",
+        "replicaset"
+      ]
+    },
+    {
+      "minServerVersion": "4.1.7",
+      "topology": [
+        "sharded"
+      ]
+    }
+  ],
+  "database_name": "retryable-reads-tests",
+  "collection_name": "coll",
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    },
+    {
+      "_id": 3,
+      "x": 33
+    }
+  ],
+  "tests": [
+    {
+      "description": "Aggregate succeeds after InterruptedAtShutdown",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "aggregate"
+          ],
+          "errorCode": 11600
+        }
+      },
+      "operations": [
+        {
+          "name": "aggregate",
+          "object": "collection",
+          "arguments": {
+            "pipeline": [
+              {
+                "$match": {
+                  "_id": {
+                    "$gt": 1
+                  }
+                }
+              },
+              {
+                "$sort": {
+                  "x": 1
+                }
+              }
+            ]
+          },
+          "result": [
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "pipeline": [
+                {
+                  "$match": {
+                    "_id": {
+                      "$gt": 1
+                    }
+                  }
+                },
+                {
+                  "$sort": {
+                    "x": 1
+                  }
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "pipeline": [
+                {
+                  "$match": {
+                    "_id": {
+                      "$gt": 1
+                    }
+                  }
+                },
+                {
+                  "$sort": {
+                    "x": 1
+                  }
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "Aggregate succeeds after InterruptedDueToReplStateChange",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "aggregate"
+          ],
+          "errorCode": 11602
+        }
+      },
+      "operations": [
+        {
+          "name": "aggregate",
+          "object": "collection",
+          "arguments": {
+            "pipeline": [
+              {
+                "$match": {
+                  "_id": {
+                    "$gt": 1
+                  }
+                }
+              },
+              {
+                "$sort": {
+                  "x": 1
+                }
+              }
+            ]
+          },
+          "result": [
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "pipeline": [
+                {
+                  "$match": {
+                    "_id": {
+                      "$gt": 1
+                    }
+                  }
+                },
+                {
+                  "$sort": {
+                    "x": 1
+                  }
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "pipeline": [
+                {
+                  "$match": {
+                    "_id": {
+                      "$gt": 1
+                    }
+                  }
+                },
+                {
+                  "$sort": {
+                    "x": 1
+                  }
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "Aggregate succeeds after NotMaster",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "aggregate"
+          ],
+          "errorCode": 10107
+        }
+      },
+      "operations": [
+        {
+          "name": "aggregate",
+          "object": "collection",
+          "arguments": {
+            "pipeline": [
+              {
+                "$match": {
+                  "_id": {
+                    "$gt": 1
+                  }
+                }
+              },
+              {
+                "$sort": {
+                  "x": 1
+                }
+              }
+            ]
+          },
+          "result": [
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "pipeline": [
+                {
+                  "$match": {
+                    "_id": {
+                      "$gt": 1
+                    }
+                  }
+                },
+                {
+                  "$sort": {
+                    "x": 1
+                  }
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "pipeline": [
+                {
+                  "$match": {
+                    "_id": {
+                      "$gt": 1
+                    }
+                  }
+                },
+                {
+                  "$sort": {
+                    "x": 1
+                  }
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "Aggregate succeeds after NotMasterNoSlaveOk",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "aggregate"
+          ],
+          "errorCode": 13435
+        }
+      },
+      "operations": [
+        {
+          "name": "aggregate",
+          "object": "collection",
+          "arguments": {
+            "pipeline": [
+              {
+                "$match": {
+                  "_id": {
+                    "$gt": 1
+                  }
+                }
+              },
+              {
+                "$sort": {
+                  "x": 1
+                }
+              }
+            ]
+          },
+          "result": [
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "pipeline": [
+                {
+                  "$match": {
+                    "_id": {
+                      "$gt": 1
+                    }
+                  }
+                },
+                {
+                  "$sort": {
+                    "x": 1
+                  }
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "pipeline": [
+                {
+                  "$match": {
+                    "_id": {
+                      "$gt": 1
+                    }
+                  }
+                },
+                {
+                  "$sort": {
+                    "x": 1
+                  }
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "Aggregate succeeds after NotMasterOrSecondary",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "aggregate"
+          ],
+          "errorCode": 13436
+        }
+      },
+      "operations": [
+        {
+          "name": "aggregate",
+          "object": "collection",
+          "arguments": {
+            "pipeline": [
+              {
+                "$match": {
+                  "_id": {
+                    "$gt": 1
+                  }
+                }
+              },
+              {
+                "$sort": {
+                  "x": 1
+                }
+              }
+            ]
+          },
+          "result": [
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "pipeline": [
+                {
+                  "$match": {
+                    "_id": {
+                      "$gt": 1
+                    }
+                  }
+                },
+                {
+                  "$sort": {
+                    "x": 1
+                  }
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "pipeline": [
+                {
+                  "$match": {
+                    "_id": {
+                      "$gt": 1
+                    }
+                  }
+                },
+                {
+                  "$sort": {
+                    "x": 1
+                  }
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "Aggregate succeeds after PrimarySteppedDown",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "aggregate"
+          ],
+          "errorCode": 189
+        }
+      },
+      "operations": [
+        {
+          "name": "aggregate",
+          "object": "collection",
+          "arguments": {
+            "pipeline": [
+              {
+                "$match": {
+                  "_id": {
+                    "$gt": 1
+                  }
+                }
+              },
+              {
+                "$sort": {
+                  "x": 1
+                }
+              }
+            ]
+          },
+          "result": [
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "pipeline": [
+                {
+                  "$match": {
+                    "_id": {
+                      "$gt": 1
+                    }
+                  }
+                },
+                {
+                  "$sort": {
+                    "x": 1
+                  }
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "pipeline": [
+                {
+                  "$match": {
+                    "_id": {
+                      "$gt": 1
+                    }
+                  }
+                },
+                {
+                  "$sort": {
+                    "x": 1
+                  }
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "Aggregate succeeds after ShutdownInProgress",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "aggregate"
+          ],
+          "errorCode": 91
+        }
+      },
+      "operations": [
+        {
+          "name": "aggregate",
+          "object": "collection",
+          "arguments": {
+            "pipeline": [
+              {
+                "$match": {
+                  "_id": {
+                    "$gt": 1
+                  }
+                }
+              },
+              {
+                "$sort": {
+                  "x": 1
+                }
+              }
+            ]
+          },
+          "result": [
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "pipeline": [
+                {
+                  "$match": {
+                    "_id": {
+                      "$gt": 1
+                    }
+                  }
+                },
+                {
+                  "$sort": {
+                    "x": 1
+                  }
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "pipeline": [
+                {
+                  "$match": {
+                    "_id": {
+                      "$gt": 1
+                    }
+                  }
+                },
+                {
+                  "$sort": {
+                    "x": 1
+                  }
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "Aggregate succeeds after HostNotFound",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "aggregate"
+          ],
+          "errorCode": 7
+        }
+      },
+      "operations": [
+        {
+          "name": "aggregate",
+          "object": "collection",
+          "arguments": {
+            "pipeline": [
+              {
+                "$match": {
+                  "_id": {
+                    "$gt": 1
+                  }
+                }
+              },
+              {
+                "$sort": {
+                  "x": 1
+                }
+              }
+            ]
+          },
+          "result": [
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "pipeline": [
+                {
+                  "$match": {
+                    "_id": {
+                      "$gt": 1
+                    }
+                  }
+                },
+                {
+                  "$sort": {
+                    "x": 1
+                  }
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "pipeline": [
+                {
+                  "$match": {
+                    "_id": {
+                      "$gt": 1
+                    }
+                  }
+                },
+                {
+                  "$sort": {
+                    "x": 1
+                  }
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "Aggregate succeeds after HostUnreachable",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "aggregate"
+          ],
+          "errorCode": 6
+        }
+      },
+      "operations": [
+        {
+          "name": "aggregate",
+          "object": "collection",
+          "arguments": {
+            "pipeline": [
+              {
+                "$match": {
+                  "_id": {
+                    "$gt": 1
+                  }
+                }
+              },
+              {
+                "$sort": {
+                  "x": 1
+                }
+              }
+            ]
+          },
+          "result": [
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "pipeline": [
+                {
+                  "$match": {
+                    "_id": {
+                      "$gt": 1
+                    }
+                  }
+                },
+                {
+                  "$sort": {
+                    "x": 1
+                  }
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "pipeline": [
+                {
+                  "$match": {
+                    "_id": {
+                      "$gt": 1
+                    }
+                  }
+                },
+                {
+                  "$sort": {
+                    "x": 1
+                  }
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "Aggregate succeeds after NetworkTimeout",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "aggregate"
+          ],
+          "errorCode": 89
+        }
+      },
+      "operations": [
+        {
+          "name": "aggregate",
+          "object": "collection",
+          "arguments": {
+            "pipeline": [
+              {
+                "$match": {
+                  "_id": {
+                    "$gt": 1
+                  }
+                }
+              },
+              {
+                "$sort": {
+                  "x": 1
+                }
+              }
+            ]
+          },
+          "result": [
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "pipeline": [
+                {
+                  "$match": {
+                    "_id": {
+                      "$gt": 1
+                    }
+                  }
+                },
+                {
+                  "$sort": {
+                    "x": 1
+                  }
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "pipeline": [
+                {
+                  "$match": {
+                    "_id": {
+                      "$gt": 1
+                    }
+                  }
+                },
+                {
+                  "$sort": {
+                    "x": 1
+                  }
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "Aggregate succeeds after SocketException",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "aggregate"
+          ],
+          "errorCode": 9001
+        }
+      },
+      "operations": [
+        {
+          "name": "aggregate",
+          "object": "collection",
+          "arguments": {
+            "pipeline": [
+              {
+                "$match": {
+                  "_id": {
+                    "$gt": 1
+                  }
+                }
+              },
+              {
+                "$sort": {
+                  "x": 1
+                }
+              }
+            ]
+          },
+          "result": [
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "pipeline": [
+                {
+                  "$match": {
+                    "_id": {
+                      "$gt": 1
+                    }
+                  }
+                },
+                {
+                  "$sort": {
+                    "x": 1
+                  }
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "pipeline": [
+                {
+                  "$match": {
+                    "_id": {
+                      "$gt": 1
+                    }
+                  }
+                },
+                {
+                  "$sort": {
+                    "x": 1
+                  }
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "Aggregate fails after two NotMaster errors",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 2
+        },
+        "data": {
+          "failCommands": [
+            "aggregate"
+          ],
+          "errorCode": 10107
+        }
+      },
+      "operations": [
+        {
+          "name": "aggregate",
+          "object": "collection",
+          "arguments": {
+            "pipeline": [
+              {
+                "$match": {
+                  "_id": {
+                    "$gt": 1
+                  }
+                }
+              },
+              {
+                "$sort": {
+                  "x": 1
+                }
+              }
+            ]
+          },
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "pipeline": [
+                {
+                  "$match": {
+                    "_id": {
+                      "$gt": 1
+                    }
+                  }
+                },
+                {
+                  "$sort": {
+                    "x": 1
+                  }
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "pipeline": [
+                {
+                  "$match": {
+                    "_id": {
+                      "$gt": 1
+                    }
+                  }
+                },
+                {
+                  "$sort": {
+                    "x": 1
+                  }
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "Aggregate fails after NotMaster when retryReads is false",
+      "clientOptions": {
+        "retryReads": false
+      },
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "aggregate"
+          ],
+          "errorCode": 10107
+        }
+      },
+      "operations": [
+        {
+          "name": "aggregate",
+          "object": "collection",
+          "arguments": {
+            "pipeline": [
+              {
+                "$match": {
+                  "_id": {
+                    "$gt": 1
+                  }
+                }
+              },
+              {
+                "$sort": {
+                  "x": 1
+                }
+              }
+            ]
+          },
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "pipeline": [
+                {
+                  "$match": {
+                    "_id": {
+                      "$gt": 1
+                    }
+                  }
+                },
+                {
+                  "$sort": {
+                    "x": 1
+                  }
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/aggregate.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/aggregate.json
new file mode 100644
index 0000000000000000000000000000000000000000..30a6e05e69538cece0ac34913450f3cce1900b38
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/aggregate.json	
@@ -0,0 +1,405 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.0",
+      "topology": [
+        "single",
+        "replicaset"
+      ]
+    },
+    {
+      "minServerVersion": "4.1.7",
+      "topology": [
+        "sharded"
+      ]
+    }
+  ],
+  "database_name": "retryable-reads-tests",
+  "collection_name": "coll",
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    },
+    {
+      "_id": 3,
+      "x": 33
+    }
+  ],
+  "tests": [
+    {
+      "description": "Aggregate succeeds on first attempt",
+      "operations": [
+        {
+          "name": "aggregate",
+          "object": "collection",
+          "arguments": {
+            "pipeline": [
+              {
+                "$match": {
+                  "_id": {
+                    "$gt": 1
+                  }
+                }
+              },
+              {
+                "$sort": {
+                  "x": 1
+                }
+              }
+            ]
+          },
+          "result": [
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "pipeline": [
+                {
+                  "$match": {
+                    "_id": {
+                      "$gt": 1
+                    }
+                  }
+                },
+                {
+                  "$sort": {
+                    "x": 1
+                  }
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "Aggregate succeeds on second attempt",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "aggregate"
+          ],
+          "closeConnection": true
+        }
+      },
+      "operations": [
+        {
+          "name": "aggregate",
+          "object": "collection",
+          "arguments": {
+            "pipeline": [
+              {
+                "$match": {
+                  "_id": {
+                    "$gt": 1
+                  }
+                }
+              },
+              {
+                "$sort": {
+                  "x": 1
+                }
+              }
+            ]
+          },
+          "result": [
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "pipeline": [
+                {
+                  "$match": {
+                    "_id": {
+                      "$gt": 1
+                    }
+                  }
+                },
+                {
+                  "$sort": {
+                    "x": 1
+                  }
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "pipeline": [
+                {
+                  "$match": {
+                    "_id": {
+                      "$gt": 1
+                    }
+                  }
+                },
+                {
+                  "$sort": {
+                    "x": 1
+                  }
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "Aggregate fails on first attempt",
+      "clientOptions": {
+        "retryReads": false
+      },
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "aggregate"
+          ],
+          "closeConnection": true
+        }
+      },
+      "operations": [
+        {
+          "name": "aggregate",
+          "object": "collection",
+          "arguments": {
+            "pipeline": [
+              {
+                "$match": {
+                  "_id": {
+                    "$gt": 1
+                  }
+                }
+              },
+              {
+                "$sort": {
+                  "x": 1
+                }
+              }
+            ]
+          },
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "pipeline": [
+                {
+                  "$match": {
+                    "_id": {
+                      "$gt": 1
+                    }
+                  }
+                },
+                {
+                  "$sort": {
+                    "x": 1
+                  }
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "Aggregate fails on second attempt",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 2
+        },
+        "data": {
+          "failCommands": [
+            "aggregate"
+          ],
+          "closeConnection": true
+        }
+      },
+      "operations": [
+        {
+          "name": "aggregate",
+          "object": "collection",
+          "arguments": {
+            "pipeline": [
+              {
+                "$match": {
+                  "_id": {
+                    "$gt": 1
+                  }
+                }
+              },
+              {
+                "$sort": {
+                  "x": 1
+                }
+              }
+            ]
+          },
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "pipeline": [
+                {
+                  "$match": {
+                    "_id": {
+                      "$gt": 1
+                    }
+                  }
+                },
+                {
+                  "$sort": {
+                    "x": 1
+                  }
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "pipeline": [
+                {
+                  "$match": {
+                    "_id": {
+                      "$gt": 1
+                    }
+                  }
+                },
+                {
+                  "$sort": {
+                    "x": 1
+                  }
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "Aggregate with $out does not retry",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "aggregate"
+          ],
+          "closeConnection": true
+        }
+      },
+      "operations": [
+        {
+          "name": "aggregate",
+          "object": "collection",
+          "arguments": {
+            "pipeline": [
+              {
+                "$match": {
+                  "_id": {
+                    "$gt": 1
+                  }
+                }
+              },
+              {
+                "$sort": {
+                  "x": 1
+                }
+              },
+              {
+                "$out": "output-collection"
+              }
+            ]
+          },
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "pipeline": [
+                {
+                  "$match": {
+                    "_id": {
+                      "$gt": 1
+                    }
+                  }
+                },
+                {
+                  "$sort": {
+                    "x": 1
+                  }
+                },
+                {
+                  "$out": "output-collection"
+                }
+              ]
+            },
+            "command_name": "aggregate",
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/changeStreams-client.watch-serverErrors.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/changeStreams-client.watch-serverErrors.json
new file mode 100644
index 0000000000000000000000000000000000000000..cf6c230ec8f2a4ccc51012d8f547583175f44db8
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/changeStreams-client.watch-serverErrors.json	
@@ -0,0 +1,738 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.0",
+      "topology": [
+        "replicaset"
+      ]
+    },
+    {
+      "minServerVersion": "4.1.7",
+      "topology": [
+        "sharded"
+      ]
+    }
+  ],
+  "database_name": "retryable-reads-tests",
+  "collection_name": "coll",
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    },
+    {
+      "_id": 3,
+      "x": 33
+    }
+  ],
+  "tests": [
+    {
+      "description": "client.watch succeeds after InterruptedAtShutdown",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "aggregate"
+          ],
+          "errorCode": 11600
+        }
+      },
+      "operations": [
+        {
+          "name": "watch",
+          "object": "client"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": 1,
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {
+                    "allChangesForCluster": true
+                  }
+                }
+              ]
+            },
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": 1,
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {
+                    "allChangesForCluster": true
+                  }
+                }
+              ]
+            },
+            "database_name": "admin"
+          }
+        }
+      ]
+    },
+    {
+      "description": "client.watch succeeds after InterruptedDueToReplStateChange",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "aggregate"
+          ],
+          "errorCode": 11602
+        }
+      },
+      "operations": [
+        {
+          "name": "watch",
+          "object": "client"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": 1,
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {
+                    "allChangesForCluster": true
+                  }
+                }
+              ]
+            },
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": 1,
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {
+                    "allChangesForCluster": true
+                  }
+                }
+              ]
+            },
+            "database_name": "admin"
+          }
+        }
+      ]
+    },
+    {
+      "description": "client.watch succeeds after NotMaster",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "aggregate"
+          ],
+          "errorCode": 10107
+        }
+      },
+      "operations": [
+        {
+          "name": "watch",
+          "object": "client"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": 1,
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {
+                    "allChangesForCluster": true
+                  }
+                }
+              ]
+            },
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": 1,
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {
+                    "allChangesForCluster": true
+                  }
+                }
+              ]
+            },
+            "database_name": "admin"
+          }
+        }
+      ]
+    },
+    {
+      "description": "client.watch succeeds after NotMasterNoSlaveOk",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "aggregate"
+          ],
+          "errorCode": 13435
+        }
+      },
+      "operations": [
+        {
+          "name": "watch",
+          "object": "client"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": 1,
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {
+                    "allChangesForCluster": true
+                  }
+                }
+              ]
+            },
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": 1,
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {
+                    "allChangesForCluster": true
+                  }
+                }
+              ]
+            },
+            "database_name": "admin"
+          }
+        }
+      ]
+    },
+    {
+      "description": "client.watch succeeds after NotMasterOrSecondary",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "aggregate"
+          ],
+          "errorCode": 13436
+        }
+      },
+      "operations": [
+        {
+          "name": "watch",
+          "object": "client"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": 1,
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {
+                    "allChangesForCluster": true
+                  }
+                }
+              ]
+            },
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": 1,
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {
+                    "allChangesForCluster": true
+                  }
+                }
+              ]
+            },
+            "database_name": "admin"
+          }
+        }
+      ]
+    },
+    {
+      "description": "client.watch succeeds after PrimarySteppedDown",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "aggregate"
+          ],
+          "errorCode": 189
+        }
+      },
+      "operations": [
+        {
+          "name": "watch",
+          "object": "client"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": 1,
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {
+                    "allChangesForCluster": true
+                  }
+                }
+              ]
+            },
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": 1,
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {
+                    "allChangesForCluster": true
+                  }
+                }
+              ]
+            },
+            "database_name": "admin"
+          }
+        }
+      ]
+    },
+    {
+      "description": "client.watch succeeds after ShutdownInProgress",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "aggregate"
+          ],
+          "errorCode": 91
+        }
+      },
+      "operations": [
+        {
+          "name": "watch",
+          "object": "client"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": 1,
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {
+                    "allChangesForCluster": true
+                  }
+                }
+              ]
+            },
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": 1,
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {
+                    "allChangesForCluster": true
+                  }
+                }
+              ]
+            },
+            "database_name": "admin"
+          }
+        }
+      ]
+    },
+    {
+      "description": "client.watch succeeds after HostNotFound",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "aggregate"
+          ],
+          "errorCode": 7
+        }
+      },
+      "operations": [
+        {
+          "name": "watch",
+          "object": "client"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": 1,
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {
+                    "allChangesForCluster": true
+                  }
+                }
+              ]
+            },
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": 1,
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {
+                    "allChangesForCluster": true
+                  }
+                }
+              ]
+            },
+            "database_name": "admin"
+          }
+        }
+      ]
+    },
+    {
+      "description": "client.watch succeeds after HostUnreachable",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "aggregate"
+          ],
+          "errorCode": 6
+        }
+      },
+      "operations": [
+        {
+          "name": "watch",
+          "object": "client"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": 1,
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {
+                    "allChangesForCluster": true
+                  }
+                }
+              ]
+            },
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": 1,
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {
+                    "allChangesForCluster": true
+                  }
+                }
+              ]
+            },
+            "database_name": "admin"
+          }
+        }
+      ]
+    },
+    {
+      "description": "client.watch succeeds after NetworkTimeout",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "aggregate"
+          ],
+          "errorCode": 89
+        }
+      },
+      "operations": [
+        {
+          "name": "watch",
+          "object": "client"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": 1,
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {
+                    "allChangesForCluster": true
+                  }
+                }
+              ]
+            },
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": 1,
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {
+                    "allChangesForCluster": true
+                  }
+                }
+              ]
+            },
+            "database_name": "admin"
+          }
+        }
+      ]
+    },
+    {
+      "description": "client.watch succeeds after SocketException",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "aggregate"
+          ],
+          "errorCode": 9001
+        }
+      },
+      "operations": [
+        {
+          "name": "watch",
+          "object": "client"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": 1,
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {
+                    "allChangesForCluster": true
+                  }
+                }
+              ]
+            },
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": 1,
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {
+                    "allChangesForCluster": true
+                  }
+                }
+              ]
+            },
+            "database_name": "admin"
+          }
+        }
+      ]
+    },
+    {
+      "description": "client.watch fails after two NotMaster errors",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 2
+        },
+        "data": {
+          "failCommands": [
+            "aggregate"
+          ],
+          "errorCode": 10107
+        }
+      },
+      "operations": [
+        {
+          "name": "watch",
+          "object": "client",
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": 1,
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {
+                    "allChangesForCluster": true
+                  }
+                }
+              ]
+            },
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": 1,
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {
+                    "allChangesForCluster": true
+                  }
+                }
+              ]
+            },
+            "database_name": "admin"
+          }
+        }
+      ]
+    },
+    {
+      "description": "client.watch fails after NotMaster when retryReads is false",
+      "clientOptions": {
+        "retryReads": false
+      },
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "aggregate"
+          ],
+          "errorCode": 10107
+        }
+      },
+      "operations": [
+        {
+          "name": "watch",
+          "object": "client",
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": 1,
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {
+                    "allChangesForCluster": true
+                  }
+                }
+              ]
+            },
+            "database_name": "admin"
+          }
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/changeStreams-client.watch.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/changeStreams-client.watch.json
new file mode 100644
index 0000000000000000000000000000000000000000..9a2ccad095038ea5bb08a4114665320a99b3d961
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/changeStreams-client.watch.json	
@@ -0,0 +1,207 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.0",
+      "topology": [
+        "replicaset"
+      ]
+    },
+    {
+      "minServerVersion": "4.1.7",
+      "topology": [
+        "sharded"
+      ]
+    }
+  ],
+  "database_name": "retryable-reads-tests",
+  "collection_name": "coll",
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    }
+  ],
+  "tests": [
+    {
+      "description": "client.watch succeeds on first attempt",
+      "operations": [
+        {
+          "name": "watch",
+          "object": "client"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": 1,
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {
+                    "allChangesForCluster": true
+                  }
+                }
+              ]
+            },
+            "database_name": "admin"
+          }
+        }
+      ]
+    },
+    {
+      "description": "client.watch succeeds on second attempt",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "aggregate"
+          ],
+          "closeConnection": true
+        }
+      },
+      "operations": [
+        {
+          "name": "watch",
+          "object": "client"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": 1,
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {
+                    "allChangesForCluster": true
+                  }
+                }
+              ]
+            },
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": 1,
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {
+                    "allChangesForCluster": true
+                  }
+                }
+              ]
+            },
+            "database_name": "admin"
+          }
+        }
+      ]
+    },
+    {
+      "description": "client.watch fails on first attempt",
+      "clientOptions": {
+        "retryReads": false
+      },
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "aggregate"
+          ],
+          "closeConnection": true
+        }
+      },
+      "operations": [
+        {
+          "name": "watch",
+          "object": "client",
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": 1,
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {
+                    "allChangesForCluster": true
+                  }
+                }
+              ]
+            },
+            "database_name": "admin"
+          }
+        }
+      ]
+    },
+    {
+      "description": "client.watch fails on second attempt",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 2
+        },
+        "data": {
+          "failCommands": [
+            "aggregate"
+          ],
+          "closeConnection": true
+        }
+      },
+      "operations": [
+        {
+          "name": "watch",
+          "object": "client",
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": 1,
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {
+                    "allChangesForCluster": true
+                  }
+                }
+              ]
+            },
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": 1,
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {
+                    "allChangesForCluster": true
+                  }
+                }
+              ]
+            },
+            "database_name": "admin"
+          }
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/changeStreams-db.coll.watch-serverErrors.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/changeStreams-db.coll.watch-serverErrors.json
new file mode 100644
index 0000000000000000000000000000000000000000..eb7df1e2643d7e23d64abf9b4f30f41d38f23a7d
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/changeStreams-db.coll.watch-serverErrors.json	
@@ -0,0 +1,688 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.0",
+      "topology": [
+        "replicaset"
+      ]
+    },
+    {
+      "minServerVersion": "4.1.7",
+      "topology": [
+        "sharded"
+      ]
+    }
+  ],
+  "database_name": "retryable-reads-tests",
+  "collection_name": "coll",
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    },
+    {
+      "_id": 3,
+      "x": 33
+    }
+  ],
+  "tests": [
+    {
+      "description": "db.coll.watch succeeds after InterruptedAtShutdown",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "aggregate"
+          ],
+          "errorCode": 11600
+        }
+      },
+      "operations": [
+        {
+          "name": "watch",
+          "object": "collection"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "db.coll.watch succeeds after InterruptedDueToReplStateChange",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "aggregate"
+          ],
+          "errorCode": 11602
+        }
+      },
+      "operations": [
+        {
+          "name": "watch",
+          "object": "collection"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "db.coll.watch succeeds after NotMaster",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "aggregate"
+          ],
+          "errorCode": 10107
+        }
+      },
+      "operations": [
+        {
+          "name": "watch",
+          "object": "collection"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "db.coll.watch succeeds after NotMasterNoSlaveOk",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "aggregate"
+          ],
+          "errorCode": 13435
+        }
+      },
+      "operations": [
+        {
+          "name": "watch",
+          "object": "collection"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "db.coll.watch succeeds after NotMasterOrSecondary",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "aggregate"
+          ],
+          "errorCode": 13436
+        }
+      },
+      "operations": [
+        {
+          "name": "watch",
+          "object": "collection"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "db.coll.watch succeeds after PrimarySteppedDown",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "aggregate"
+          ],
+          "errorCode": 189
+        }
+      },
+      "operations": [
+        {
+          "name": "watch",
+          "object": "collection"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "db.coll.watch succeeds after ShutdownInProgress",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "aggregate"
+          ],
+          "errorCode": 91
+        }
+      },
+      "operations": [
+        {
+          "name": "watch",
+          "object": "collection"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "db.coll.watch succeeds after HostNotFound",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "aggregate"
+          ],
+          "errorCode": 7
+        }
+      },
+      "operations": [
+        {
+          "name": "watch",
+          "object": "collection"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "db.coll.watch succeeds after HostUnreachable",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "aggregate"
+          ],
+          "errorCode": 6
+        }
+      },
+      "operations": [
+        {
+          "name": "watch",
+          "object": "collection"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "db.coll.watch succeeds after NetworkTimeout",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "aggregate"
+          ],
+          "errorCode": 89
+        }
+      },
+      "operations": [
+        {
+          "name": "watch",
+          "object": "collection"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "db.coll.watch succeeds after SocketException",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "aggregate"
+          ],
+          "errorCode": 9001
+        }
+      },
+      "operations": [
+        {
+          "name": "watch",
+          "object": "collection"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "db.coll.watch fails after two NotMaster errors",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 2
+        },
+        "data": {
+          "failCommands": [
+            "aggregate"
+          ],
+          "errorCode": 10107
+        }
+      },
+      "operations": [
+        {
+          "name": "watch",
+          "object": "collection",
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "db.coll.watch fails after NotMaster when retryReads is false",
+      "clientOptions": {
+        "retryReads": false
+      },
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "aggregate"
+          ],
+          "errorCode": 10107
+        }
+      },
+      "operations": [
+        {
+          "name": "watch",
+          "object": "collection",
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/changeStreams-db.coll.watch.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/changeStreams-db.coll.watch.json
new file mode 100644
index 0000000000000000000000000000000000000000..3408c842362ac962a9c514bc233c1963781eef2d
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/changeStreams-db.coll.watch.json	
@@ -0,0 +1,195 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.0",
+      "topology": [
+        "replicaset"
+      ]
+    },
+    {
+      "minServerVersion": "4.1.7",
+      "topology": [
+        "sharded"
+      ]
+    }
+  ],
+  "database_name": "retryable-reads-tests",
+  "collection_name": "coll",
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    }
+  ],
+  "tests": [
+    {
+      "description": "db.coll.watch succeeds on first attempt",
+      "operations": [
+        {
+          "name": "watch",
+          "object": "collection"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "db.coll.watch succeeds on second attempt",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "aggregate"
+          ],
+          "closeConnection": true
+        }
+      },
+      "operations": [
+        {
+          "name": "watch",
+          "object": "collection"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "db.coll.watch fails on first attempt",
+      "clientOptions": {
+        "retryReads": false
+      },
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "aggregate"
+          ],
+          "closeConnection": true
+        }
+      },
+      "operations": [
+        {
+          "name": "watch",
+          "object": "collection",
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "db.coll.watch fails on second attempt",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 2
+        },
+        "data": {
+          "failCommands": [
+            "aggregate"
+          ],
+          "closeConnection": true
+        }
+      },
+      "operations": [
+        {
+          "name": "watch",
+          "object": "collection",
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/changeStreams-db.watch-serverErrors.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/changeStreams-db.watch-serverErrors.json
new file mode 100644
index 0000000000000000000000000000000000000000..e070f56a01b98209fc52fb1ca2f72bc5285bc230
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/changeStreams-db.watch-serverErrors.json	
@@ -0,0 +1,688 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.0",
+      "topology": [
+        "replicaset"
+      ]
+    },
+    {
+      "minServerVersion": "4.1.7",
+      "topology": [
+        "sharded"
+      ]
+    }
+  ],
+  "database_name": "retryable-reads-tests",
+  "collection_name": "coll",
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    },
+    {
+      "_id": 3,
+      "x": 33
+    }
+  ],
+  "tests": [
+    {
+      "description": "db.watch succeeds after InterruptedAtShutdown",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "aggregate"
+          ],
+          "errorCode": 11600
+        }
+      },
+      "operations": [
+        {
+          "name": "watch",
+          "object": "database"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": 1,
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": 1,
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "db.watch succeeds after InterruptedDueToReplStateChange",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "aggregate"
+          ],
+          "errorCode": 11602
+        }
+      },
+      "operations": [
+        {
+          "name": "watch",
+          "object": "database"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": 1,
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": 1,
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "db.watch succeeds after NotMaster",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "aggregate"
+          ],
+          "errorCode": 10107
+        }
+      },
+      "operations": [
+        {
+          "name": "watch",
+          "object": "database"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": 1,
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": 1,
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "db.watch succeeds after NotMasterNoSlaveOk",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "aggregate"
+          ],
+          "errorCode": 13435
+        }
+      },
+      "operations": [
+        {
+          "name": "watch",
+          "object": "database"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": 1,
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": 1,
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "db.watch succeeds after NotMasterOrSecondary",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "aggregate"
+          ],
+          "errorCode": 13436
+        }
+      },
+      "operations": [
+        {
+          "name": "watch",
+          "object": "database"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": 1,
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": 1,
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "db.watch succeeds after PrimarySteppedDown",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "aggregate"
+          ],
+          "errorCode": 189
+        }
+      },
+      "operations": [
+        {
+          "name": "watch",
+          "object": "database"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": 1,
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": 1,
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "db.watch succeeds after ShutdownInProgress",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "aggregate"
+          ],
+          "errorCode": 91
+        }
+      },
+      "operations": [
+        {
+          "name": "watch",
+          "object": "database"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": 1,
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": 1,
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "db.watch succeeds after HostNotFound",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "aggregate"
+          ],
+          "errorCode": 7
+        }
+      },
+      "operations": [
+        {
+          "name": "watch",
+          "object": "database"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": 1,
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": 1,
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "db.watch succeeds after HostUnreachable",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "aggregate"
+          ],
+          "errorCode": 6
+        }
+      },
+      "operations": [
+        {
+          "name": "watch",
+          "object": "database"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": 1,
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": 1,
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "db.watch succeeds after NetworkTimeout",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "aggregate"
+          ],
+          "errorCode": 89
+        }
+      },
+      "operations": [
+        {
+          "name": "watch",
+          "object": "database"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": 1,
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": 1,
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "db.watch succeeds after SocketException",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "aggregate"
+          ],
+          "errorCode": 9001
+        }
+      },
+      "operations": [
+        {
+          "name": "watch",
+          "object": "database"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": 1,
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": 1,
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "db.watch fails after two NotMaster errors",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 2
+        },
+        "data": {
+          "failCommands": [
+            "aggregate"
+          ],
+          "errorCode": 10107
+        }
+      },
+      "operations": [
+        {
+          "name": "watch",
+          "object": "database",
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": 1,
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": 1,
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "db.watch fails after NotMaster when retryReads is false",
+      "clientOptions": {
+        "retryReads": false
+      },
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "aggregate"
+          ],
+          "errorCode": 10107
+        }
+      },
+      "operations": [
+        {
+          "name": "watch",
+          "object": "database",
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": 1,
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/changeStreams-db.watch.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/changeStreams-db.watch.json
new file mode 100644
index 0000000000000000000000000000000000000000..bec09c49b76a9db01af029b701e35d8daf0a7c71
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/changeStreams-db.watch.json	
@@ -0,0 +1,195 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.0",
+      "topology": [
+        "replicaset"
+      ]
+    },
+    {
+      "minServerVersion": "4.1.7",
+      "topology": [
+        "sharded"
+      ]
+    }
+  ],
+  "database_name": "retryable-reads-tests",
+  "collection_name": "coll",
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    }
+  ],
+  "tests": [
+    {
+      "description": "db.watch succeeds on first attempt",
+      "operations": [
+        {
+          "name": "watch",
+          "object": "database"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": 1,
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "db.watch succeeds on second attempt",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "aggregate"
+          ],
+          "closeConnection": true
+        }
+      },
+      "operations": [
+        {
+          "name": "watch",
+          "object": "database"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": 1,
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": 1,
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "db.watch fails on first attempt",
+      "clientOptions": {
+        "retryReads": false
+      },
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "aggregate"
+          ],
+          "closeConnection": true
+        }
+      },
+      "operations": [
+        {
+          "name": "watch",
+          "object": "database",
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": 1,
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "db.watch fails on second attempt",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 2
+        },
+        "data": {
+          "failCommands": [
+            "aggregate"
+          ],
+          "closeConnection": true
+        }
+      },
+      "operations": [
+        {
+          "name": "watch",
+          "object": "database",
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": 1,
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": 1,
+              "cursor": {},
+              "pipeline": [
+                {
+                  "$changeStream": {}
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/count-serverErrors.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/count-serverErrors.json
new file mode 100644
index 0000000000000000000000000000000000000000..839680fe59f8694f9ae0e504545608e2ec2bdd96
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/count-serverErrors.json	
@@ -0,0 +1,585 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.0",
+      "topology": [
+        "single",
+        "replicaset"
+      ]
+    },
+    {
+      "minServerVersion": "4.1.7",
+      "topology": [
+        "sharded"
+      ]
+    }
+  ],
+  "database_name": "retryable-reads-tests",
+  "collection_name": "coll",
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    }
+  ],
+  "tests": [
+    {
+      "description": "Count succeeds after InterruptedAtShutdown",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "count"
+          ],
+          "errorCode": 11600
+        }
+      },
+      "operations": [
+        {
+          "name": "count",
+          "object": "collection",
+          "arguments": {
+            "filter": {}
+          },
+          "result": 2
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "count": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "count": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "Count succeeds after InterruptedDueToReplStateChange",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "count"
+          ],
+          "errorCode": 11602
+        }
+      },
+      "operations": [
+        {
+          "name": "count",
+          "object": "collection",
+          "arguments": {
+            "filter": {}
+          },
+          "result": 2
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "count": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "count": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "Count succeeds after NotMaster",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "count"
+          ],
+          "errorCode": 10107
+        }
+      },
+      "operations": [
+        {
+          "name": "count",
+          "object": "collection",
+          "arguments": {
+            "filter": {}
+          },
+          "result": 2
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "count": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "count": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "Count succeeds after NotMasterNoSlaveOk",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "count"
+          ],
+          "errorCode": 13435
+        }
+      },
+      "operations": [
+        {
+          "name": "count",
+          "object": "collection",
+          "arguments": {
+            "filter": {}
+          },
+          "result": 2
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "count": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "count": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "Count succeeds after NotMasterOrSecondary",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "count"
+          ],
+          "errorCode": 13436
+        }
+      },
+      "operations": [
+        {
+          "name": "count",
+          "object": "collection",
+          "arguments": {
+            "filter": {}
+          },
+          "result": 2
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "count": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "count": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "Count succeeds after PrimarySteppedDown",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "count"
+          ],
+          "errorCode": 189
+        }
+      },
+      "operations": [
+        {
+          "name": "count",
+          "object": "collection",
+          "arguments": {
+            "filter": {}
+          },
+          "result": 2
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "count": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "count": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "Count succeeds after ShutdownInProgress",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "count"
+          ],
+          "errorCode": 91
+        }
+      },
+      "operations": [
+        {
+          "name": "count",
+          "object": "collection",
+          "arguments": {
+            "filter": {}
+          },
+          "result": 2
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "count": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "count": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "Count succeeds after HostNotFound",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "count"
+          ],
+          "errorCode": 7
+        }
+      },
+      "operations": [
+        {
+          "name": "count",
+          "object": "collection",
+          "arguments": {
+            "filter": {}
+          },
+          "result": 2
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "count": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "count": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "Count succeeds after HostUnreachable",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "count"
+          ],
+          "errorCode": 6
+        }
+      },
+      "operations": [
+        {
+          "name": "count",
+          "object": "collection",
+          "arguments": {
+            "filter": {}
+          },
+          "result": 2
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "count": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "count": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "Count succeeds after NetworkTimeout",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "count"
+          ],
+          "errorCode": 89
+        }
+      },
+      "operations": [
+        {
+          "name": "count",
+          "object": "collection",
+          "arguments": {
+            "filter": {}
+          },
+          "result": 2
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "count": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "count": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "Count succeeds after SocketException",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "count"
+          ],
+          "errorCode": 9001
+        }
+      },
+      "operations": [
+        {
+          "name": "count",
+          "object": "collection",
+          "arguments": {
+            "filter": {}
+          },
+          "result": 2
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "count": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "count": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "Count fails after two NotMaster errors",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 2
+        },
+        "data": {
+          "failCommands": [
+            "count"
+          ],
+          "errorCode": 10107
+        }
+      },
+      "operations": [
+        {
+          "name": "count",
+          "object": "collection",
+          "arguments": {
+            "filter": {}
+          },
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "count": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "count": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "Count fails after NotMaster when retryReads is false",
+      "clientOptions": {
+        "retryReads": false
+      },
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "count"
+          ],
+          "errorCode": 10107
+        }
+      },
+      "operations": [
+        {
+          "name": "count",
+          "object": "collection",
+          "arguments": {
+            "filter": {}
+          },
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "count": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/count.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/count.json
new file mode 100644
index 0000000000000000000000000000000000000000..0ccf4982ba6299d96ba64c28bb9490a1e7a40b49
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/count.json	
@@ -0,0 +1,178 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.0",
+      "topology": [
+        "single",
+        "replicaset"
+      ]
+    },
+    {
+      "minServerVersion": "4.1.7",
+      "topology": [
+        "sharded"
+      ]
+    }
+  ],
+  "database_name": "retryable-reads-tests",
+  "collection_name": "coll",
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    }
+  ],
+  "tests": [
+    {
+      "description": "Count succeeds on first attempt",
+      "operations": [
+        {
+          "name": "count",
+          "object": "collection",
+          "arguments": {
+            "filter": {}
+          },
+          "result": 2
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "count": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "Count succeeds on second attempt",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "count"
+          ],
+          "closeConnection": true
+        }
+      },
+      "operations": [
+        {
+          "name": "count",
+          "object": "collection",
+          "arguments": {
+            "filter": {}
+          },
+          "result": 2
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "count": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "count": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "Count fails on first attempt",
+      "clientOptions": {
+        "retryReads": false
+      },
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "count"
+          ],
+          "closeConnection": true
+        }
+      },
+      "operations": [
+        {
+          "name": "count",
+          "object": "collection",
+          "arguments": {
+            "filter": {}
+          },
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "count": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "Count fails on second attempt",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 2
+        },
+        "data": {
+          "failCommands": [
+            "count"
+          ],
+          "closeConnection": true
+        }
+      },
+      "operations": [
+        {
+          "name": "count",
+          "object": "collection",
+          "arguments": {
+            "filter": {}
+          },
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "count": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "count": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/countDocuments-serverErrors.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/countDocuments-serverErrors.json
new file mode 100644
index 0000000000000000000000000000000000000000..f45eadfa0c209d5e6b0a03aeba38c9fb19d5b1f5
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/countDocuments-serverErrors.json	
@@ -0,0 +1,910 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.0",
+      "topology": [
+        "single",
+        "replicaset"
+      ]
+    },
+    {
+      "minServerVersion": "4.1.7",
+      "topology": [
+        "sharded"
+      ]
+    }
+  ],
+  "database_name": "retryable-reads-tests",
+  "collection_name": "coll",
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    }
+  ],
+  "tests": [
+    {
+      "description": "CountDocuments succeeds after InterruptedAtShutdown",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "aggregate"
+          ],
+          "errorCode": 11600
+        }
+      },
+      "operations": [
+        {
+          "name": "countDocuments",
+          "object": "collection",
+          "arguments": {
+            "filter": {}
+          },
+          "result": 2
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "pipeline": [
+                {
+                  "$match": {}
+                },
+                {
+                  "$group": {
+                    "_id": 1,
+                    "n": {
+                      "$sum": 1
+                    }
+                  }
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "pipeline": [
+                {
+                  "$match": {}
+                },
+                {
+                  "$group": {
+                    "_id": 1,
+                    "n": {
+                      "$sum": 1
+                    }
+                  }
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "CountDocuments succeeds after InterruptedDueToReplStateChange",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "aggregate"
+          ],
+          "errorCode": 11602
+        }
+      },
+      "operations": [
+        {
+          "name": "countDocuments",
+          "object": "collection",
+          "arguments": {
+            "filter": {}
+          },
+          "result": 2
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "pipeline": [
+                {
+                  "$match": {}
+                },
+                {
+                  "$group": {
+                    "_id": 1,
+                    "n": {
+                      "$sum": 1
+                    }
+                  }
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "pipeline": [
+                {
+                  "$match": {}
+                },
+                {
+                  "$group": {
+                    "_id": 1,
+                    "n": {
+                      "$sum": 1
+                    }
+                  }
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "CountDocuments succeeds after NotMaster",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "aggregate"
+          ],
+          "errorCode": 10107
+        }
+      },
+      "operations": [
+        {
+          "name": "countDocuments",
+          "object": "collection",
+          "arguments": {
+            "filter": {}
+          },
+          "result": 2
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "pipeline": [
+                {
+                  "$match": {}
+                },
+                {
+                  "$group": {
+                    "_id": 1,
+                    "n": {
+                      "$sum": 1
+                    }
+                  }
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "pipeline": [
+                {
+                  "$match": {}
+                },
+                {
+                  "$group": {
+                    "_id": 1,
+                    "n": {
+                      "$sum": 1
+                    }
+                  }
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "CountDocuments succeeds after NotMasterNoSlaveOk",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "aggregate"
+          ],
+          "errorCode": 13435
+        }
+      },
+      "operations": [
+        {
+          "name": "countDocuments",
+          "object": "collection",
+          "arguments": {
+            "filter": {}
+          },
+          "result": 2
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "pipeline": [
+                {
+                  "$match": {}
+                },
+                {
+                  "$group": {
+                    "_id": 1,
+                    "n": {
+                      "$sum": 1
+                    }
+                  }
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "pipeline": [
+                {
+                  "$match": {}
+                },
+                {
+                  "$group": {
+                    "_id": 1,
+                    "n": {
+                      "$sum": 1
+                    }
+                  }
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "CountDocuments succeeds after NotMasterOrSecondary",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "aggregate"
+          ],
+          "errorCode": 13436
+        }
+      },
+      "operations": [
+        {
+          "name": "countDocuments",
+          "object": "collection",
+          "arguments": {
+            "filter": {}
+          },
+          "result": 2
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "pipeline": [
+                {
+                  "$match": {}
+                },
+                {
+                  "$group": {
+                    "_id": 1,
+                    "n": {
+                      "$sum": 1
+                    }
+                  }
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "pipeline": [
+                {
+                  "$match": {}
+                },
+                {
+                  "$group": {
+                    "_id": 1,
+                    "n": {
+                      "$sum": 1
+                    }
+                  }
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "CountDocuments succeeds after PrimarySteppedDown",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "aggregate"
+          ],
+          "errorCode": 189
+        }
+      },
+      "operations": [
+        {
+          "name": "countDocuments",
+          "object": "collection",
+          "arguments": {
+            "filter": {}
+          },
+          "result": 2
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "pipeline": [
+                {
+                  "$match": {}
+                },
+                {
+                  "$group": {
+                    "_id": 1,
+                    "n": {
+                      "$sum": 1
+                    }
+                  }
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "pipeline": [
+                {
+                  "$match": {}
+                },
+                {
+                  "$group": {
+                    "_id": 1,
+                    "n": {
+                      "$sum": 1
+                    }
+                  }
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "CountDocuments succeeds after ShutdownInProgress",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "aggregate"
+          ],
+          "errorCode": 91
+        }
+      },
+      "operations": [
+        {
+          "name": "countDocuments",
+          "object": "collection",
+          "arguments": {
+            "filter": {}
+          },
+          "result": 2
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "pipeline": [
+                {
+                  "$match": {}
+                },
+                {
+                  "$group": {
+                    "_id": 1,
+                    "n": {
+                      "$sum": 1
+                    }
+                  }
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "pipeline": [
+                {
+                  "$match": {}
+                },
+                {
+                  "$group": {
+                    "_id": 1,
+                    "n": {
+                      "$sum": 1
+                    }
+                  }
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "CountDocuments succeeds after HostNotFound",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "aggregate"
+          ],
+          "errorCode": 7
+        }
+      },
+      "operations": [
+        {
+          "name": "countDocuments",
+          "object": "collection",
+          "arguments": {
+            "filter": {}
+          },
+          "result": 2
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "pipeline": [
+                {
+                  "$match": {}
+                },
+                {
+                  "$group": {
+                    "_id": 1,
+                    "n": {
+                      "$sum": 1
+                    }
+                  }
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "pipeline": [
+                {
+                  "$match": {}
+                },
+                {
+                  "$group": {
+                    "_id": 1,
+                    "n": {
+                      "$sum": 1
+                    }
+                  }
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "CountDocuments succeeds after HostUnreachable",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "aggregate"
+          ],
+          "errorCode": 6
+        }
+      },
+      "operations": [
+        {
+          "name": "countDocuments",
+          "object": "collection",
+          "arguments": {
+            "filter": {}
+          },
+          "result": 2
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "pipeline": [
+                {
+                  "$match": {}
+                },
+                {
+                  "$group": {
+                    "_id": 1,
+                    "n": {
+                      "$sum": 1
+                    }
+                  }
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "pipeline": [
+                {
+                  "$match": {}
+                },
+                {
+                  "$group": {
+                    "_id": 1,
+                    "n": {
+                      "$sum": 1
+                    }
+                  }
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "CountDocuments succeeds after NetworkTimeout",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "aggregate"
+          ],
+          "errorCode": 89
+        }
+      },
+      "operations": [
+        {
+          "name": "countDocuments",
+          "object": "collection",
+          "arguments": {
+            "filter": {}
+          },
+          "result": 2
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "pipeline": [
+                {
+                  "$match": {}
+                },
+                {
+                  "$group": {
+                    "_id": 1,
+                    "n": {
+                      "$sum": 1
+                    }
+                  }
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "pipeline": [
+                {
+                  "$match": {}
+                },
+                {
+                  "$group": {
+                    "_id": 1,
+                    "n": {
+                      "$sum": 1
+                    }
+                  }
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "CountDocuments succeeds after SocketException",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "aggregate"
+          ],
+          "errorCode": 9001
+        }
+      },
+      "operations": [
+        {
+          "name": "countDocuments",
+          "object": "collection",
+          "arguments": {
+            "filter": {}
+          },
+          "result": 2
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "pipeline": [
+                {
+                  "$match": {}
+                },
+                {
+                  "$group": {
+                    "_id": 1,
+                    "n": {
+                      "$sum": 1
+                    }
+                  }
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "pipeline": [
+                {
+                  "$match": {}
+                },
+                {
+                  "$group": {
+                    "_id": 1,
+                    "n": {
+                      "$sum": 1
+                    }
+                  }
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "CountDocuments fails after two NotMaster errors",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 2
+        },
+        "data": {
+          "failCommands": [
+            "aggregate"
+          ],
+          "errorCode": 10107
+        }
+      },
+      "operations": [
+        {
+          "name": "countDocuments",
+          "object": "collection",
+          "arguments": {
+            "filter": {}
+          },
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "pipeline": [
+                {
+                  "$match": {}
+                },
+                {
+                  "$group": {
+                    "_id": 1,
+                    "n": {
+                      "$sum": 1
+                    }
+                  }
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "pipeline": [
+                {
+                  "$match": {}
+                },
+                {
+                  "$group": {
+                    "_id": 1,
+                    "n": {
+                      "$sum": 1
+                    }
+                  }
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "CountDocuments fails after NotMaster when retryReads is false",
+      "clientOptions": {
+        "retryReads": false
+      },
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "aggregate"
+          ],
+          "errorCode": 10107
+        }
+      },
+      "operations": [
+        {
+          "name": "countDocuments",
+          "object": "collection",
+          "arguments": {
+            "filter": {}
+          },
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "pipeline": [
+                {
+                  "$match": {}
+                },
+                {
+                  "$group": {
+                    "_id": 1,
+                    "n": {
+                      "$sum": 1
+                    }
+                  }
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/countDocuments.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/countDocuments.json
new file mode 100644
index 0000000000000000000000000000000000000000..b4ccf36684dec4337eeaa2c7a5df86507cc8b5a2
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/countDocuments.json	
@@ -0,0 +1,256 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.0",
+      "topology": [
+        "single",
+        "replicaset"
+      ]
+    },
+    {
+      "minServerVersion": "4.1.7",
+      "topology": [
+        "sharded"
+      ]
+    }
+  ],
+  "database_name": "retryable-reads-tests",
+  "collection_name": "coll",
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    }
+  ],
+  "tests": [
+    {
+      "description": "CountDocuments succeeds on first attempt",
+      "operations": [
+        {
+          "name": "countDocuments",
+          "object": "collection",
+          "arguments": {
+            "filter": {}
+          },
+          "result": 2
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "pipeline": [
+                {
+                  "$match": {}
+                },
+                {
+                  "$group": {
+                    "_id": 1,
+                    "n": {
+                      "$sum": 1
+                    }
+                  }
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "CountDocuments succeeds on second attempt",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "aggregate"
+          ],
+          "closeConnection": true
+        }
+      },
+      "operations": [
+        {
+          "name": "countDocuments",
+          "object": "collection",
+          "arguments": {
+            "filter": {}
+          },
+          "result": 2
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "pipeline": [
+                {
+                  "$match": {}
+                },
+                {
+                  "$group": {
+                    "_id": 1,
+                    "n": {
+                      "$sum": 1
+                    }
+                  }
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "pipeline": [
+                {
+                  "$match": {}
+                },
+                {
+                  "$group": {
+                    "_id": 1,
+                    "n": {
+                      "$sum": 1
+                    }
+                  }
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "CountDocuments fails on first attempt",
+      "clientOptions": {
+        "retryReads": false
+      },
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "aggregate"
+          ],
+          "closeConnection": true
+        }
+      },
+      "operations": [
+        {
+          "name": "countDocuments",
+          "object": "collection",
+          "arguments": {
+            "filter": {}
+          },
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "pipeline": [
+                {
+                  "$match": {}
+                },
+                {
+                  "$group": {
+                    "_id": 1,
+                    "n": {
+                      "$sum": 1
+                    }
+                  }
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "CountDocuments fails on second attempt",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 2
+        },
+        "data": {
+          "failCommands": [
+            "aggregate"
+          ],
+          "closeConnection": true
+        }
+      },
+      "operations": [
+        {
+          "name": "countDocuments",
+          "object": "collection",
+          "arguments": {
+            "filter": {}
+          },
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "pipeline": [
+                {
+                  "$match": {}
+                },
+                {
+                  "$group": {
+                    "_id": 1,
+                    "n": {
+                      "$sum": 1
+                    }
+                  }
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "coll",
+              "pipeline": [
+                {
+                  "$match": {}
+                },
+                {
+                  "$group": {
+                    "_id": 1,
+                    "n": {
+                      "$sum": 1
+                    }
+                  }
+                }
+              ]
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/distinct-serverErrors.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/distinct-serverErrors.json
new file mode 100644
index 0000000000000000000000000000000000000000..50fd6a55051288d787a21fb2e92999f2cadfb11e
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/distinct-serverErrors.json	
@@ -0,0 +1,837 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.0",
+      "topology": [
+        "single",
+        "replicaset"
+      ]
+    },
+    {
+      "minServerVersion": "4.1.7",
+      "topology": [
+        "sharded"
+      ]
+    }
+  ],
+  "database_name": "retryable-reads-tests",
+  "collection_name": "coll",
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    },
+    {
+      "_id": 3,
+      "x": 33
+    }
+  ],
+  "tests": [
+    {
+      "description": "Distinct succeeds after InterruptedAtShutdown",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "distinct"
+          ],
+          "errorCode": 11600
+        }
+      },
+      "operations": [
+        {
+          "name": "distinct",
+          "object": "collection",
+          "arguments": {
+            "fieldName": "x",
+            "filter": {
+              "_id": {
+                "$gt": 1
+              }
+            }
+          },
+          "result": [
+            22,
+            33
+          ]
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "distinct": "coll",
+              "key": "x",
+              "query": {
+                "_id": {
+                  "$gt": 1
+                }
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "distinct": "coll",
+              "key": "x",
+              "query": {
+                "_id": {
+                  "$gt": 1
+                }
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "Distinct succeeds after InterruptedDueToReplStateChange",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "distinct"
+          ],
+          "errorCode": 11602
+        }
+      },
+      "operations": [
+        {
+          "name": "distinct",
+          "object": "collection",
+          "arguments": {
+            "fieldName": "x",
+            "filter": {
+              "_id": {
+                "$gt": 1
+              }
+            }
+          },
+          "result": [
+            22,
+            33
+          ]
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "distinct": "coll",
+              "key": "x",
+              "query": {
+                "_id": {
+                  "$gt": 1
+                }
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "distinct": "coll",
+              "key": "x",
+              "query": {
+                "_id": {
+                  "$gt": 1
+                }
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "Distinct succeeds after NotMaster",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "distinct"
+          ],
+          "errorCode": 10107
+        }
+      },
+      "operations": [
+        {
+          "name": "distinct",
+          "object": "collection",
+          "arguments": {
+            "fieldName": "x",
+            "filter": {
+              "_id": {
+                "$gt": 1
+              }
+            }
+          },
+          "result": [
+            22,
+            33
+          ]
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "distinct": "coll",
+              "key": "x",
+              "query": {
+                "_id": {
+                  "$gt": 1
+                }
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "distinct": "coll",
+              "key": "x",
+              "query": {
+                "_id": {
+                  "$gt": 1
+                }
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "Distinct succeeds after NotMasterNoSlaveOk",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "distinct"
+          ],
+          "errorCode": 13435
+        }
+      },
+      "operations": [
+        {
+          "name": "distinct",
+          "object": "collection",
+          "arguments": {
+            "fieldName": "x",
+            "filter": {
+              "_id": {
+                "$gt": 1
+              }
+            }
+          },
+          "result": [
+            22,
+            33
+          ]
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "distinct": "coll",
+              "key": "x",
+              "query": {
+                "_id": {
+                  "$gt": 1
+                }
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "distinct": "coll",
+              "key": "x",
+              "query": {
+                "_id": {
+                  "$gt": 1
+                }
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "Distinct succeeds after NotMasterOrSecondary",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "distinct"
+          ],
+          "errorCode": 13436
+        }
+      },
+      "operations": [
+        {
+          "name": "distinct",
+          "object": "collection",
+          "arguments": {
+            "fieldName": "x",
+            "filter": {
+              "_id": {
+                "$gt": 1
+              }
+            }
+          },
+          "result": [
+            22,
+            33
+          ]
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "distinct": "coll",
+              "key": "x",
+              "query": {
+                "_id": {
+                  "$gt": 1
+                }
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "distinct": "coll",
+              "key": "x",
+              "query": {
+                "_id": {
+                  "$gt": 1
+                }
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "Distinct succeeds after PrimarySteppedDown",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "distinct"
+          ],
+          "errorCode": 189
+        }
+      },
+      "operations": [
+        {
+          "name": "distinct",
+          "object": "collection",
+          "arguments": {
+            "fieldName": "x",
+            "filter": {
+              "_id": {
+                "$gt": 1
+              }
+            }
+          },
+          "result": [
+            22,
+            33
+          ]
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "distinct": "coll",
+              "key": "x",
+              "query": {
+                "_id": {
+                  "$gt": 1
+                }
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "distinct": "coll",
+              "key": "x",
+              "query": {
+                "_id": {
+                  "$gt": 1
+                }
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "Distinct succeeds after ShutdownInProgress",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "distinct"
+          ],
+          "errorCode": 91
+        }
+      },
+      "operations": [
+        {
+          "name": "distinct",
+          "object": "collection",
+          "arguments": {
+            "fieldName": "x",
+            "filter": {
+              "_id": {
+                "$gt": 1
+              }
+            }
+          },
+          "result": [
+            22,
+            33
+          ]
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "distinct": "coll",
+              "key": "x",
+              "query": {
+                "_id": {
+                  "$gt": 1
+                }
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "distinct": "coll",
+              "key": "x",
+              "query": {
+                "_id": {
+                  "$gt": 1
+                }
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "Distinct succeeds after HostNotFound",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "distinct"
+          ],
+          "errorCode": 7
+        }
+      },
+      "operations": [
+        {
+          "name": "distinct",
+          "object": "collection",
+          "arguments": {
+            "fieldName": "x",
+            "filter": {
+              "_id": {
+                "$gt": 1
+              }
+            }
+          },
+          "result": [
+            22,
+            33
+          ]
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "distinct": "coll",
+              "key": "x",
+              "query": {
+                "_id": {
+                  "$gt": 1
+                }
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "distinct": "coll",
+              "key": "x",
+              "query": {
+                "_id": {
+                  "$gt": 1
+                }
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "Distinct succeeds after HostUnreachable",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "distinct"
+          ],
+          "errorCode": 6
+        }
+      },
+      "operations": [
+        {
+          "name": "distinct",
+          "object": "collection",
+          "arguments": {
+            "fieldName": "x",
+            "filter": {
+              "_id": {
+                "$gt": 1
+              }
+            }
+          },
+          "result": [
+            22,
+            33
+          ]
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "distinct": "coll",
+              "key": "x",
+              "query": {
+                "_id": {
+                  "$gt": 1
+                }
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "distinct": "coll",
+              "key": "x",
+              "query": {
+                "_id": {
+                  "$gt": 1
+                }
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "Distinct succeeds after NetworkTimeout",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "distinct"
+          ],
+          "errorCode": 89
+        }
+      },
+      "operations": [
+        {
+          "name": "distinct",
+          "object": "collection",
+          "arguments": {
+            "fieldName": "x",
+            "filter": {
+              "_id": {
+                "$gt": 1
+              }
+            }
+          },
+          "result": [
+            22,
+            33
+          ]
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "distinct": "coll",
+              "key": "x",
+              "query": {
+                "_id": {
+                  "$gt": 1
+                }
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "distinct": "coll",
+              "key": "x",
+              "query": {
+                "_id": {
+                  "$gt": 1
+                }
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "Distinct succeeds after SocketException",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "distinct"
+          ],
+          "errorCode": 9001
+        }
+      },
+      "operations": [
+        {
+          "name": "distinct",
+          "object": "collection",
+          "arguments": {
+            "fieldName": "x",
+            "filter": {
+              "_id": {
+                "$gt": 1
+              }
+            }
+          },
+          "result": [
+            22,
+            33
+          ]
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "distinct": "coll",
+              "key": "x",
+              "query": {
+                "_id": {
+                  "$gt": 1
+                }
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "distinct": "coll",
+              "key": "x",
+              "query": {
+                "_id": {
+                  "$gt": 1
+                }
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "Distinct fails after two NotMaster errors",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 2
+        },
+        "data": {
+          "failCommands": [
+            "distinct"
+          ],
+          "errorCode": 10107
+        }
+      },
+      "operations": [
+        {
+          "name": "distinct",
+          "object": "collection",
+          "arguments": {
+            "fieldName": "x",
+            "filter": {
+              "_id": {
+                "$gt": 1
+              }
+            }
+          },
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "distinct": "coll",
+              "key": "x",
+              "query": {
+                "_id": {
+                  "$gt": 1
+                }
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "distinct": "coll",
+              "key": "x",
+              "query": {
+                "_id": {
+                  "$gt": 1
+                }
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "Distinct fails after NotMaster when retryReads is false",
+      "clientOptions": {
+        "retryReads": false
+      },
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "distinct"
+          ],
+          "errorCode": 10107
+        }
+      },
+      "operations": [
+        {
+          "name": "distinct",
+          "object": "collection",
+          "arguments": {
+            "fieldName": "x",
+            "filter": {
+              "_id": {
+                "$gt": 1
+              }
+            }
+          },
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "distinct": "coll",
+              "key": "x",
+              "query": {
+                "_id": {
+                  "$gt": 1
+                }
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/distinct.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/distinct.json
new file mode 100644
index 0000000000000000000000000000000000000000..b5885e27eb732ea1f783fa4ac00f98ea4f6fc6ed
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/distinct.json	
@@ -0,0 +1,244 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.0",
+      "topology": [
+        "single",
+        "replicaset"
+      ]
+    },
+    {
+      "minServerVersion": "4.1.7",
+      "topology": [
+        "sharded"
+      ]
+    }
+  ],
+  "database_name": "retryable-reads-tests",
+  "collection_name": "coll",
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    },
+    {
+      "_id": 3,
+      "x": 33
+    }
+  ],
+  "tests": [
+    {
+      "description": "Distinct succeeds on first attempt",
+      "operations": [
+        {
+          "name": "distinct",
+          "object": "collection",
+          "arguments": {
+            "fieldName": "x",
+            "filter": {
+              "_id": {
+                "$gt": 1
+              }
+            }
+          },
+          "result": [
+            22,
+            33
+          ]
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "distinct": "coll",
+              "key": "x",
+              "query": {
+                "_id": {
+                  "$gt": 1
+                }
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "Distinct succeeds on second attempt",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "distinct"
+          ],
+          "closeConnection": true
+        }
+      },
+      "operations": [
+        {
+          "name": "distinct",
+          "object": "collection",
+          "arguments": {
+            "fieldName": "x",
+            "filter": {
+              "_id": {
+                "$gt": 1
+              }
+            }
+          },
+          "result": [
+            22,
+            33
+          ]
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "distinct": "coll",
+              "key": "x",
+              "query": {
+                "_id": {
+                  "$gt": 1
+                }
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "distinct": "coll",
+              "key": "x",
+              "query": {
+                "_id": {
+                  "$gt": 1
+                }
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "Distinct fails on first attempt",
+      "clientOptions": {
+        "retryReads": false
+      },
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "distinct"
+          ],
+          "closeConnection": true
+        }
+      },
+      "operations": [
+        {
+          "name": "distinct",
+          "object": "collection",
+          "arguments": {
+            "fieldName": "x",
+            "filter": {
+              "_id": {
+                "$gt": 1
+              }
+            }
+          },
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "distinct": "coll",
+              "key": "x",
+              "query": {
+                "_id": {
+                  "$gt": 1
+                }
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "Distinct fails on second attempt",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 2
+        },
+        "data": {
+          "failCommands": [
+            "distinct"
+          ],
+          "closeConnection": true
+        }
+      },
+      "operations": [
+        {
+          "name": "distinct",
+          "object": "collection",
+          "arguments": {
+            "fieldName": "x",
+            "filter": {
+              "_id": {
+                "$gt": 1
+              }
+            }
+          },
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "distinct": "coll",
+              "key": "x",
+              "query": {
+                "_id": {
+                  "$gt": 1
+                }
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "distinct": "coll",
+              "key": "x",
+              "query": {
+                "_id": {
+                  "$gt": 1
+                }
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/estimatedDocumentCount-serverErrors.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/estimatedDocumentCount-serverErrors.json
new file mode 100644
index 0000000000000000000000000000000000000000..1af21d1fe9247904a4ccc61a679b0d68c4984247
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/estimatedDocumentCount-serverErrors.json	
@@ -0,0 +1,546 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.0",
+      "topology": [
+        "single",
+        "replicaset"
+      ]
+    },
+    {
+      "minServerVersion": "4.1.7",
+      "topology": [
+        "sharded"
+      ]
+    }
+  ],
+  "database_name": "retryable-reads-tests",
+  "collection_name": "coll",
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    }
+  ],
+  "tests": [
+    {
+      "description": "EstimatedDocumentCount succeeds after InterruptedAtShutdown",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "count"
+          ],
+          "errorCode": 11600
+        }
+      },
+      "operations": [
+        {
+          "name": "estimatedDocumentCount",
+          "object": "collection",
+          "result": 2
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "count": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "count": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "EstimatedDocumentCount succeeds after InterruptedDueToReplStateChange",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "count"
+          ],
+          "errorCode": 11602
+        }
+      },
+      "operations": [
+        {
+          "name": "estimatedDocumentCount",
+          "object": "collection",
+          "result": 2
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "count": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "count": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "EstimatedDocumentCount succeeds after NotMaster",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "count"
+          ],
+          "errorCode": 10107
+        }
+      },
+      "operations": [
+        {
+          "name": "estimatedDocumentCount",
+          "object": "collection",
+          "result": 2
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "count": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "count": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "EstimatedDocumentCount succeeds after NotMasterNoSlaveOk",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "count"
+          ],
+          "errorCode": 13435
+        }
+      },
+      "operations": [
+        {
+          "name": "estimatedDocumentCount",
+          "object": "collection",
+          "result": 2
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "count": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "count": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "EstimatedDocumentCount succeeds after NotMasterOrSecondary",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "count"
+          ],
+          "errorCode": 13436
+        }
+      },
+      "operations": [
+        {
+          "name": "estimatedDocumentCount",
+          "object": "collection",
+          "result": 2
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "count": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "count": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "EstimatedDocumentCount succeeds after PrimarySteppedDown",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "count"
+          ],
+          "errorCode": 189
+        }
+      },
+      "operations": [
+        {
+          "name": "estimatedDocumentCount",
+          "object": "collection",
+          "result": 2
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "count": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "count": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "EstimatedDocumentCount succeeds after ShutdownInProgress",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "count"
+          ],
+          "errorCode": 91
+        }
+      },
+      "operations": [
+        {
+          "name": "estimatedDocumentCount",
+          "object": "collection",
+          "result": 2
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "count": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "count": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "EstimatedDocumentCount succeeds after HostNotFound",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "count"
+          ],
+          "errorCode": 7
+        }
+      },
+      "operations": [
+        {
+          "name": "estimatedDocumentCount",
+          "object": "collection",
+          "result": 2
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "count": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "count": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "EstimatedDocumentCount succeeds after HostUnreachable",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "count"
+          ],
+          "errorCode": 6
+        }
+      },
+      "operations": [
+        {
+          "name": "estimatedDocumentCount",
+          "object": "collection",
+          "result": 2
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "count": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "count": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "EstimatedDocumentCount succeeds after NetworkTimeout",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "count"
+          ],
+          "errorCode": 89
+        }
+      },
+      "operations": [
+        {
+          "name": "estimatedDocumentCount",
+          "object": "collection",
+          "result": 2
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "count": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "count": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "EstimatedDocumentCount succeeds after SocketException",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "count"
+          ],
+          "errorCode": 9001
+        }
+      },
+      "operations": [
+        {
+          "name": "estimatedDocumentCount",
+          "object": "collection",
+          "result": 2
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "count": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "count": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "EstimatedDocumentCount fails after two NotMaster errors",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 2
+        },
+        "data": {
+          "failCommands": [
+            "count"
+          ],
+          "errorCode": 10107
+        }
+      },
+      "operations": [
+        {
+          "name": "estimatedDocumentCount",
+          "object": "collection",
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "count": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "count": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "EstimatedDocumentCount fails after NotMaster when retryReads is false",
+      "clientOptions": {
+        "retryReads": false
+      },
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "count"
+          ],
+          "errorCode": 10107
+        }
+      },
+      "operations": [
+        {
+          "name": "estimatedDocumentCount",
+          "object": "collection",
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "count": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/estimatedDocumentCount.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/estimatedDocumentCount.json
new file mode 100644
index 0000000000000000000000000000000000000000..8dfa15a2cdb3ec5e5c00e37c17c6282b8966ed37
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/estimatedDocumentCount.json	
@@ -0,0 +1,166 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.0",
+      "topology": [
+        "single",
+        "replicaset"
+      ]
+    },
+    {
+      "minServerVersion": "4.1.7",
+      "topology": [
+        "sharded"
+      ]
+    }
+  ],
+  "database_name": "retryable-reads-tests",
+  "collection_name": "coll",
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    }
+  ],
+  "tests": [
+    {
+      "description": "EstimatedDocumentCount succeeds on first attempt",
+      "operations": [
+        {
+          "name": "estimatedDocumentCount",
+          "object": "collection",
+          "result": 2
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "count": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "EstimatedDocumentCount succeeds on second attempt",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "count"
+          ],
+          "closeConnection": true
+        }
+      },
+      "operations": [
+        {
+          "name": "estimatedDocumentCount",
+          "object": "collection",
+          "result": 2
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "count": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "count": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "EstimatedDocumentCount fails on first attempt",
+      "clientOptions": {
+        "retryReads": false
+      },
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "count"
+          ],
+          "closeConnection": true
+        }
+      },
+      "operations": [
+        {
+          "name": "estimatedDocumentCount",
+          "object": "collection",
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "count": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "EstimatedDocumentCount fails on second attempt",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 2
+        },
+        "data": {
+          "failCommands": [
+            "count"
+          ],
+          "closeConnection": true
+        }
+      },
+      "operations": [
+        {
+          "name": "estimatedDocumentCount",
+          "object": "collection",
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "count": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "count": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/find-serverErrors.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/find-serverErrors.json
new file mode 100644
index 0000000000000000000000000000000000000000..44ecf34d2fbc288a3ac0bc5612e072dd9bcf8ae5
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/find-serverErrors.json	
@@ -0,0 +1,961 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.0",
+      "topology": [
+        "single",
+        "replicaset"
+      ]
+    },
+    {
+      "minServerVersion": "4.1.7",
+      "topology": [
+        "sharded"
+      ]
+    }
+  ],
+  "database_name": "retryable-reads-tests",
+  "collection_name": "coll",
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    },
+    {
+      "_id": 3,
+      "x": 33
+    },
+    {
+      "_id": 4,
+      "x": 44
+    },
+    {
+      "_id": 5,
+      "x": 55
+    }
+  ],
+  "tests": [
+    {
+      "description": "Find succeeds after InterruptedAtShutdown",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "find"
+          ],
+          "errorCode": 11600
+        }
+      },
+      "operations": [
+        {
+          "name": "find",
+          "object": "collection",
+          "arguments": {
+            "filter": {},
+            "sort": {
+              "_id": 1
+            },
+            "limit": 4
+          },
+          "result": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            },
+            {
+              "_id": 4,
+              "x": 44
+            }
+          ]
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "find": "coll",
+              "filter": {},
+              "sort": {
+                "_id": 1
+              },
+              "limit": 4
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "coll",
+              "filter": {},
+              "sort": {
+                "_id": 1
+              },
+              "limit": 4
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "Find succeeds after InterruptedDueToReplStateChange",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "find"
+          ],
+          "errorCode": 11602
+        }
+      },
+      "operations": [
+        {
+          "name": "find",
+          "object": "collection",
+          "arguments": {
+            "filter": {},
+            "sort": {
+              "_id": 1
+            },
+            "limit": 4
+          },
+          "result": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            },
+            {
+              "_id": 4,
+              "x": 44
+            }
+          ]
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "find": "coll",
+              "filter": {},
+              "sort": {
+                "_id": 1
+              },
+              "limit": 4
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "coll",
+              "filter": {},
+              "sort": {
+                "_id": 1
+              },
+              "limit": 4
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "Find succeeds after NotMaster",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "find"
+          ],
+          "errorCode": 10107
+        }
+      },
+      "operations": [
+        {
+          "name": "find",
+          "object": "collection",
+          "arguments": {
+            "filter": {},
+            "sort": {
+              "_id": 1
+            },
+            "limit": 4
+          },
+          "result": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            },
+            {
+              "_id": 4,
+              "x": 44
+            }
+          ]
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "find": "coll",
+              "filter": {},
+              "sort": {
+                "_id": 1
+              },
+              "limit": 4
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "coll",
+              "filter": {},
+              "sort": {
+                "_id": 1
+              },
+              "limit": 4
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "Find succeeds after NotMasterNoSlaveOk",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "find"
+          ],
+          "errorCode": 13435
+        }
+      },
+      "operations": [
+        {
+          "name": "find",
+          "object": "collection",
+          "arguments": {
+            "filter": {},
+            "sort": {
+              "_id": 1
+            },
+            "limit": 4
+          },
+          "result": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            },
+            {
+              "_id": 4,
+              "x": 44
+            }
+          ]
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "find": "coll",
+              "filter": {},
+              "sort": {
+                "_id": 1
+              },
+              "limit": 4
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "coll",
+              "filter": {},
+              "sort": {
+                "_id": 1
+              },
+              "limit": 4
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "Find succeeds after NotMasterOrSecondary",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "find"
+          ],
+          "errorCode": 13436
+        }
+      },
+      "operations": [
+        {
+          "name": "find",
+          "object": "collection",
+          "arguments": {
+            "filter": {},
+            "sort": {
+              "_id": 1
+            },
+            "limit": 4
+          },
+          "result": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            },
+            {
+              "_id": 4,
+              "x": 44
+            }
+          ]
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "find": "coll",
+              "filter": {},
+              "sort": {
+                "_id": 1
+              },
+              "limit": 4
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "coll",
+              "filter": {},
+              "sort": {
+                "_id": 1
+              },
+              "limit": 4
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "Find succeeds after PrimarySteppedDown",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "find"
+          ],
+          "errorCode": 189
+        }
+      },
+      "operations": [
+        {
+          "name": "find",
+          "object": "collection",
+          "arguments": {
+            "filter": {},
+            "sort": {
+              "_id": 1
+            },
+            "limit": 4
+          },
+          "result": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            },
+            {
+              "_id": 4,
+              "x": 44
+            }
+          ]
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "find": "coll",
+              "filter": {},
+              "sort": {
+                "_id": 1
+              },
+              "limit": 4
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "coll",
+              "filter": {},
+              "sort": {
+                "_id": 1
+              },
+              "limit": 4
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "Find succeeds after ShutdownInProgress",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "find"
+          ],
+          "errorCode": 91
+        }
+      },
+      "operations": [
+        {
+          "name": "find",
+          "object": "collection",
+          "arguments": {
+            "filter": {},
+            "sort": {
+              "_id": 1
+            },
+            "limit": 4
+          },
+          "result": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            },
+            {
+              "_id": 4,
+              "x": 44
+            }
+          ]
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "find": "coll",
+              "filter": {},
+              "sort": {
+                "_id": 1
+              },
+              "limit": 4
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "coll",
+              "filter": {},
+              "sort": {
+                "_id": 1
+              },
+              "limit": 4
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "Find succeeds after HostNotFound",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "find"
+          ],
+          "errorCode": 7
+        }
+      },
+      "operations": [
+        {
+          "name": "find",
+          "object": "collection",
+          "arguments": {
+            "filter": {},
+            "sort": {
+              "_id": 1
+            },
+            "limit": 4
+          },
+          "result": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            },
+            {
+              "_id": 4,
+              "x": 44
+            }
+          ]
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "find": "coll",
+              "filter": {},
+              "sort": {
+                "_id": 1
+              },
+              "limit": 4
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "coll",
+              "filter": {},
+              "sort": {
+                "_id": 1
+              },
+              "limit": 4
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "Find succeeds after HostUnreachable",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "find"
+          ],
+          "errorCode": 6
+        }
+      },
+      "operations": [
+        {
+          "name": "find",
+          "object": "collection",
+          "arguments": {
+            "filter": {},
+            "sort": {
+              "_id": 1
+            },
+            "limit": 4
+          },
+          "result": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            },
+            {
+              "_id": 4,
+              "x": 44
+            }
+          ]
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "find": "coll",
+              "filter": {},
+              "sort": {
+                "_id": 1
+              },
+              "limit": 4
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "coll",
+              "filter": {},
+              "sort": {
+                "_id": 1
+              },
+              "limit": 4
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "Find succeeds after NetworkTimeout",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "find"
+          ],
+          "errorCode": 89
+        }
+      },
+      "operations": [
+        {
+          "name": "find",
+          "object": "collection",
+          "arguments": {
+            "filter": {},
+            "sort": {
+              "_id": 1
+            },
+            "limit": 4
+          },
+          "result": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            },
+            {
+              "_id": 4,
+              "x": 44
+            }
+          ]
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "find": "coll",
+              "filter": {},
+              "sort": {
+                "_id": 1
+              },
+              "limit": 4
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "coll",
+              "filter": {},
+              "sort": {
+                "_id": 1
+              },
+              "limit": 4
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "Find succeeds after SocketException",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "find"
+          ],
+          "errorCode": 9001
+        }
+      },
+      "operations": [
+        {
+          "name": "find",
+          "object": "collection",
+          "arguments": {
+            "filter": {},
+            "sort": {
+              "_id": 1
+            },
+            "limit": 4
+          },
+          "result": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            },
+            {
+              "_id": 4,
+              "x": 44
+            }
+          ]
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "find": "coll",
+              "filter": {},
+              "sort": {
+                "_id": 1
+              },
+              "limit": 4
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "coll",
+              "filter": {},
+              "sort": {
+                "_id": 1
+              },
+              "limit": 4
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "Find fails after two NotMaster errors",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 2
+        },
+        "data": {
+          "failCommands": [
+            "find"
+          ],
+          "errorCode": 10107
+        }
+      },
+      "operations": [
+        {
+          "name": "find",
+          "object": "collection",
+          "arguments": {
+            "filter": {},
+            "sort": {
+              "_id": 1
+            },
+            "limit": 4
+          },
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "find": "coll",
+              "filter": {},
+              "sort": {
+                "_id": 1
+              },
+              "limit": 4
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "coll",
+              "filter": {},
+              "sort": {
+                "_id": 1
+              },
+              "limit": 4
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "Find fails after NotMaster when retryReads is false",
+      "clientOptions": {
+        "retryReads": false
+      },
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "find"
+          ],
+          "errorCode": 10107
+        }
+      },
+      "operations": [
+        {
+          "name": "find",
+          "object": "collection",
+          "arguments": {
+            "filter": {},
+            "sort": {
+              "_id": 1
+            },
+            "limit": 4
+          },
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "find": "coll",
+              "filter": {},
+              "sort": {
+                "_id": 1
+              },
+              "limit": 4
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/find.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/find.json
new file mode 100644
index 0000000000000000000000000000000000000000..56479ff1d8711da8f9df1bada7c753f5fd2ad69e
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/find.json	
@@ -0,0 +1,347 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.0",
+      "topology": [
+        "single",
+        "replicaset"
+      ]
+    },
+    {
+      "minServerVersion": "4.1.7",
+      "topology": [
+        "sharded"
+      ]
+    }
+  ],
+  "database_name": "retryable-reads-tests",
+  "collection_name": "coll",
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    },
+    {
+      "_id": 3,
+      "x": 33
+    },
+    {
+      "_id": 4,
+      "x": 44
+    },
+    {
+      "_id": 5,
+      "x": 55
+    }
+  ],
+  "tests": [
+    {
+      "description": "Find succeeds on first attempt",
+      "operations": [
+        {
+          "name": "find",
+          "object": "collection",
+          "arguments": {
+            "filter": {},
+            "sort": {
+              "_id": 1
+            },
+            "limit": 4
+          },
+          "result": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            },
+            {
+              "_id": 4,
+              "x": 44
+            }
+          ]
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "find": "coll",
+              "filter": {},
+              "sort": {
+                "_id": 1
+              },
+              "limit": 4
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "Find succeeds on second attempt with explicit clientOptions",
+      "clientOptions": {
+        "retryReads": true
+      },
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "find"
+          ],
+          "closeConnection": true
+        }
+      },
+      "operations": [
+        {
+          "name": "find",
+          "object": "collection",
+          "arguments": {
+            "filter": {},
+            "sort": {
+              "_id": 1
+            },
+            "limit": 4
+          },
+          "result": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            },
+            {
+              "_id": 4,
+              "x": 44
+            }
+          ]
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "find": "coll",
+              "filter": {},
+              "sort": {
+                "_id": 1
+              },
+              "limit": 4
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "coll",
+              "filter": {},
+              "sort": {
+                "_id": 1
+              },
+              "limit": 4
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "Find succeeds on second attempt",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "find"
+          ],
+          "closeConnection": true
+        }
+      },
+      "operations": [
+        {
+          "name": "find",
+          "object": "collection",
+          "arguments": {
+            "filter": {},
+            "sort": {
+              "_id": 1
+            },
+            "limit": 4
+          },
+          "result": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            },
+            {
+              "_id": 4,
+              "x": 44
+            }
+          ]
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "find": "coll",
+              "filter": {},
+              "sort": {
+                "_id": 1
+              },
+              "limit": 4
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "coll",
+              "filter": {},
+              "sort": {
+                "_id": 1
+              },
+              "limit": 4
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "Find fails on first attempt",
+      "clientOptions": {
+        "retryReads": false
+      },
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "find"
+          ],
+          "closeConnection": true
+        }
+      },
+      "operations": [
+        {
+          "name": "find",
+          "object": "collection",
+          "arguments": {
+            "filter": {},
+            "sort": {
+              "_id": 1
+            },
+            "limit": 4
+          },
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "find": "coll",
+              "filter": {},
+              "sort": {
+                "_id": 1
+              },
+              "limit": 4
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "Find fails on second attempt",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 2
+        },
+        "data": {
+          "failCommands": [
+            "find"
+          ],
+          "closeConnection": true
+        }
+      },
+      "operations": [
+        {
+          "name": "find",
+          "object": "collection",
+          "arguments": {
+            "filter": {},
+            "sort": {
+              "_id": 1
+            },
+            "limit": 4
+          },
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "find": "coll",
+              "filter": {},
+              "sort": {
+                "_id": 1
+              },
+              "limit": 4
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "coll",
+              "filter": {},
+              "sort": {
+                "_id": 1
+              },
+              "limit": 4
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/findOne-serverErrors.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/findOne-serverErrors.json
new file mode 100644
index 0000000000000000000000000000000000000000..b8229483d2444aa984ef0bcb2d78d738fc0147c1
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/findOne-serverErrors.json	
@@ -0,0 +1,731 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.0",
+      "topology": [
+        "single",
+        "replicaset"
+      ]
+    },
+    {
+      "minServerVersion": "4.1.7",
+      "topology": [
+        "sharded"
+      ]
+    }
+  ],
+  "database_name": "retryable-reads-tests",
+  "collection_name": "coll",
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    },
+    {
+      "_id": 3,
+      "x": 33
+    },
+    {
+      "_id": 4,
+      "x": 44
+    },
+    {
+      "_id": 5,
+      "x": 55
+    }
+  ],
+  "tests": [
+    {
+      "description": "FindOne succeeds after InterruptedAtShutdown",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "find"
+          ],
+          "errorCode": 11600
+        }
+      },
+      "operations": [
+        {
+          "name": "findOne",
+          "object": "collection",
+          "arguments": {
+            "filter": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "_id": 1,
+            "x": 11
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "find": "coll",
+              "filter": {
+                "_id": 1
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "coll",
+              "filter": {
+                "_id": 1
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "FindOne succeeds after InterruptedDueToReplStateChange",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "find"
+          ],
+          "errorCode": 11602
+        }
+      },
+      "operations": [
+        {
+          "name": "findOne",
+          "object": "collection",
+          "arguments": {
+            "filter": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "_id": 1,
+            "x": 11
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "find": "coll",
+              "filter": {
+                "_id": 1
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "coll",
+              "filter": {
+                "_id": 1
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "FindOne succeeds after NotMaster",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "find"
+          ],
+          "errorCode": 10107
+        }
+      },
+      "operations": [
+        {
+          "name": "findOne",
+          "object": "collection",
+          "arguments": {
+            "filter": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "_id": 1,
+            "x": 11
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "find": "coll",
+              "filter": {
+                "_id": 1
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "coll",
+              "filter": {
+                "_id": 1
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "FindOne succeeds after NotMasterNoSlaveOk",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "find"
+          ],
+          "errorCode": 13435
+        }
+      },
+      "operations": [
+        {
+          "name": "findOne",
+          "object": "collection",
+          "arguments": {
+            "filter": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "_id": 1,
+            "x": 11
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "find": "coll",
+              "filter": {
+                "_id": 1
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "coll",
+              "filter": {
+                "_id": 1
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "FindOne succeeds after NotMasterOrSecondary",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "find"
+          ],
+          "errorCode": 13436
+        }
+      },
+      "operations": [
+        {
+          "name": "findOne",
+          "object": "collection",
+          "arguments": {
+            "filter": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "_id": 1,
+            "x": 11
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "find": "coll",
+              "filter": {
+                "_id": 1
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "coll",
+              "filter": {
+                "_id": 1
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "FindOne succeeds after PrimarySteppedDown",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "find"
+          ],
+          "errorCode": 189
+        }
+      },
+      "operations": [
+        {
+          "name": "findOne",
+          "object": "collection",
+          "arguments": {
+            "filter": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "_id": 1,
+            "x": 11
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "find": "coll",
+              "filter": {
+                "_id": 1
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "coll",
+              "filter": {
+                "_id": 1
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "FindOne succeeds after ShutdownInProgress",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "find"
+          ],
+          "errorCode": 91
+        }
+      },
+      "operations": [
+        {
+          "name": "findOne",
+          "object": "collection",
+          "arguments": {
+            "filter": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "_id": 1,
+            "x": 11
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "find": "coll",
+              "filter": {
+                "_id": 1
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "coll",
+              "filter": {
+                "_id": 1
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "FindOne succeeds after HostNotFound",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "find"
+          ],
+          "errorCode": 7
+        }
+      },
+      "operations": [
+        {
+          "name": "findOne",
+          "object": "collection",
+          "arguments": {
+            "filter": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "_id": 1,
+            "x": 11
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "find": "coll",
+              "filter": {
+                "_id": 1
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "coll",
+              "filter": {
+                "_id": 1
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "FindOne succeeds after HostUnreachable",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "find"
+          ],
+          "errorCode": 6
+        }
+      },
+      "operations": [
+        {
+          "name": "findOne",
+          "object": "collection",
+          "arguments": {
+            "filter": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "_id": 1,
+            "x": 11
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "find": "coll",
+              "filter": {
+                "_id": 1
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "coll",
+              "filter": {
+                "_id": 1
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "FindOne succeeds after NetworkTimeout",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "find"
+          ],
+          "errorCode": 89
+        }
+      },
+      "operations": [
+        {
+          "name": "findOne",
+          "object": "collection",
+          "arguments": {
+            "filter": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "_id": 1,
+            "x": 11
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "find": "coll",
+              "filter": {
+                "_id": 1
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "coll",
+              "filter": {
+                "_id": 1
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "FindOne succeeds after SocketException",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "find"
+          ],
+          "errorCode": 9001
+        }
+      },
+      "operations": [
+        {
+          "name": "findOne",
+          "object": "collection",
+          "arguments": {
+            "filter": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "_id": 1,
+            "x": 11
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "find": "coll",
+              "filter": {
+                "_id": 1
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "coll",
+              "filter": {
+                "_id": 1
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "FindOne fails after two NotMaster errors",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 2
+        },
+        "data": {
+          "failCommands": [
+            "find"
+          ],
+          "errorCode": 10107
+        }
+      },
+      "operations": [
+        {
+          "name": "findOne",
+          "object": "collection",
+          "arguments": {
+            "filter": {
+              "_id": 1
+            }
+          },
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "find": "coll",
+              "filter": {
+                "_id": 1
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "coll",
+              "filter": {
+                "_id": 1
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "FindOne fails after NotMaster when retryReads is false",
+      "clientOptions": {
+        "retryReads": false
+      },
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "find"
+          ],
+          "errorCode": 10107
+        }
+      },
+      "operations": [
+        {
+          "name": "findOne",
+          "object": "collection",
+          "arguments": {
+            "filter": {
+              "_id": 1
+            }
+          },
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "find": "coll",
+              "filter": {
+                "_id": 1
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/findOne.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/findOne.json
new file mode 100644
index 0000000000000000000000000000000000000000..d296a9cdb5e80eaa1d0efd54a4e7a28fcb2cf806
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/findOne.json	
@@ -0,0 +1,222 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.0",
+      "topology": [
+        "single",
+        "replicaset"
+      ]
+    },
+    {
+      "minServerVersion": "4.1.7",
+      "topology": [
+        "sharded"
+      ]
+    }
+  ],
+  "database_name": "retryable-reads-tests",
+  "collection_name": "coll",
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    },
+    {
+      "_id": 3,
+      "x": 33
+    },
+    {
+      "_id": 4,
+      "x": 44
+    },
+    {
+      "_id": 5,
+      "x": 55
+    }
+  ],
+  "tests": [
+    {
+      "description": "FindOne succeeds on first attempt",
+      "operations": [
+        {
+          "name": "findOne",
+          "object": "collection",
+          "arguments": {
+            "filter": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "_id": 1,
+            "x": 11
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "find": "coll",
+              "filter": {
+                "_id": 1
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "FindOne succeeds on second attempt",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "find"
+          ],
+          "closeConnection": true
+        }
+      },
+      "operations": [
+        {
+          "name": "findOne",
+          "object": "collection",
+          "arguments": {
+            "filter": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "_id": 1,
+            "x": 11
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "find": "coll",
+              "filter": {
+                "_id": 1
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "coll",
+              "filter": {
+                "_id": 1
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "FindOne fails on first attempt",
+      "clientOptions": {
+        "retryReads": false
+      },
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "find"
+          ],
+          "closeConnection": true
+        }
+      },
+      "operations": [
+        {
+          "name": "findOne",
+          "object": "collection",
+          "arguments": {
+            "filter": {
+              "_id": 1
+            }
+          },
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "find": "coll",
+              "filter": {
+                "_id": 1
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "FindOne fails on second attempt",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 2
+        },
+        "data": {
+          "failCommands": [
+            "find"
+          ],
+          "closeConnection": true
+        }
+      },
+      "operations": [
+        {
+          "name": "findOne",
+          "object": "collection",
+          "arguments": {
+            "filter": {
+              "_id": 1
+            }
+          },
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "find": "coll",
+              "filter": {
+                "_id": 1
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "coll",
+              "filter": {
+                "_id": 1
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/gridfs-download-serverErrors.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/gridfs-download-serverErrors.json
new file mode 100644
index 0000000000000000000000000000000000000000..84e50e370c43323dd32724bf301285be2e8cd6a3
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/gridfs-download-serverErrors.json	
@@ -0,0 +1,924 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.0",
+      "topology": [
+        "single",
+        "replicaset"
+      ]
+    },
+    {
+      "minServerVersion": "4.1.7",
+      "topology": [
+        "sharded"
+      ]
+    }
+  ],
+  "database_name": "retryable-reads-tests",
+  "bucket_name": "fs",
+  "data": {
+    "fs.files": [
+      {
+        "_id": {
+          "$oid": "000000000000000000000001"
+        },
+        "length": 1,
+        "chunkSize": 4,
+        "uploadDate": {
+          "$date": "1970-01-01T00:00:00.000Z"
+        },
+        "filename": "abc",
+        "metadata": {}
+      }
+    ],
+    "fs.chunks": [
+      {
+        "_id": {
+          "$oid": "000000000000000000000002"
+        },
+        "files_id": {
+          "$oid": "000000000000000000000001"
+        },
+        "n": 0,
+        "data": {
+          "$binary": {
+            "base64": "EQ==",
+            "subType": "00"
+          }
+        }
+      }
+    ]
+  },
+  "tests": [
+    {
+      "description": "Download succeeds after InterruptedAtShutdown",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "find"
+          ],
+          "errorCode": 11600
+        }
+      },
+      "operations": [
+        {
+          "name": "download",
+          "object": "gridfsbucket",
+          "arguments": {
+            "id": {
+              "$oid": "000000000000000000000001"
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "find": "fs.files",
+              "filter": {
+                "_id": {
+                  "$oid": "000000000000000000000001"
+                }
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "fs.files",
+              "filter": {
+                "_id": {
+                  "$oid": "000000000000000000000001"
+                }
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "fs.chunks",
+              "filter": {
+                "files_id": {
+                  "$oid": "000000000000000000000001"
+                }
+              },
+              "sort": {
+                "n": 1
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "Download succeeds after InterruptedDueToReplStateChange",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "find"
+          ],
+          "errorCode": 11602
+        }
+      },
+      "operations": [
+        {
+          "name": "download",
+          "object": "gridfsbucket",
+          "arguments": {
+            "id": {
+              "$oid": "000000000000000000000001"
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "find": "fs.files",
+              "filter": {
+                "_id": {
+                  "$oid": "000000000000000000000001"
+                }
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "fs.files",
+              "filter": {
+                "_id": {
+                  "$oid": "000000000000000000000001"
+                }
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "fs.chunks",
+              "filter": {
+                "files_id": {
+                  "$oid": "000000000000000000000001"
+                }
+              },
+              "sort": {
+                "n": 1
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "Download succeeds after NotMaster",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "find"
+          ],
+          "errorCode": 10107
+        }
+      },
+      "operations": [
+        {
+          "name": "download",
+          "object": "gridfsbucket",
+          "arguments": {
+            "id": {
+              "$oid": "000000000000000000000001"
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "find": "fs.files",
+              "filter": {
+                "_id": {
+                  "$oid": "000000000000000000000001"
+                }
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "fs.files",
+              "filter": {
+                "_id": {
+                  "$oid": "000000000000000000000001"
+                }
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "fs.chunks",
+              "filter": {
+                "files_id": {
+                  "$oid": "000000000000000000000001"
+                }
+              },
+              "sort": {
+                "n": 1
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "Download succeeds after NotMasterNoSlaveOk",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "find"
+          ],
+          "errorCode": 13435
+        }
+      },
+      "operations": [
+        {
+          "name": "download",
+          "object": "gridfsbucket",
+          "arguments": {
+            "id": {
+              "$oid": "000000000000000000000001"
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "find": "fs.files",
+              "filter": {
+                "_id": {
+                  "$oid": "000000000000000000000001"
+                }
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "fs.files",
+              "filter": {
+                "_id": {
+                  "$oid": "000000000000000000000001"
+                }
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "fs.chunks",
+              "filter": {
+                "files_id": {
+                  "$oid": "000000000000000000000001"
+                }
+              },
+              "sort": {
+                "n": 1
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "Download succeeds after NotMasterOrSecondary",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "find"
+          ],
+          "errorCode": 13436
+        }
+      },
+      "operations": [
+        {
+          "name": "download",
+          "object": "gridfsbucket",
+          "arguments": {
+            "id": {
+              "$oid": "000000000000000000000001"
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "find": "fs.files",
+              "filter": {
+                "_id": {
+                  "$oid": "000000000000000000000001"
+                }
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "fs.files",
+              "filter": {
+                "_id": {
+                  "$oid": "000000000000000000000001"
+                }
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "fs.chunks",
+              "filter": {
+                "files_id": {
+                  "$oid": "000000000000000000000001"
+                }
+              },
+              "sort": {
+                "n": 1
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "Download succeeds after PrimarySteppedDown",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "find"
+          ],
+          "errorCode": 189
+        }
+      },
+      "operations": [
+        {
+          "name": "download",
+          "object": "gridfsbucket",
+          "arguments": {
+            "id": {
+              "$oid": "000000000000000000000001"
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "find": "fs.files",
+              "filter": {
+                "_id": {
+                  "$oid": "000000000000000000000001"
+                }
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "fs.files",
+              "filter": {
+                "_id": {
+                  "$oid": "000000000000000000000001"
+                }
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "fs.chunks",
+              "filter": {
+                "files_id": {
+                  "$oid": "000000000000000000000001"
+                }
+              },
+              "sort": {
+                "n": 1
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "Download succeeds after ShutdownInProgress",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "find"
+          ],
+          "errorCode": 91
+        }
+      },
+      "operations": [
+        {
+          "name": "download",
+          "object": "gridfsbucket",
+          "arguments": {
+            "id": {
+              "$oid": "000000000000000000000001"
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "find": "fs.files",
+              "filter": {
+                "_id": {
+                  "$oid": "000000000000000000000001"
+                }
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "fs.files",
+              "filter": {
+                "_id": {
+                  "$oid": "000000000000000000000001"
+                }
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "fs.chunks",
+              "filter": {
+                "files_id": {
+                  "$oid": "000000000000000000000001"
+                }
+              },
+              "sort": {
+                "n": 1
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "Download succeeds after HostNotFound",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "find"
+          ],
+          "errorCode": 7
+        }
+      },
+      "operations": [
+        {
+          "name": "download",
+          "object": "gridfsbucket",
+          "arguments": {
+            "id": {
+              "$oid": "000000000000000000000001"
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "find": "fs.files",
+              "filter": {
+                "_id": {
+                  "$oid": "000000000000000000000001"
+                }
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "fs.files",
+              "filter": {
+                "_id": {
+                  "$oid": "000000000000000000000001"
+                }
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "fs.chunks",
+              "filter": {
+                "files_id": {
+                  "$oid": "000000000000000000000001"
+                }
+              },
+              "sort": {
+                "n": 1
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "Download succeeds after HostUnreachable",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "find"
+          ],
+          "errorCode": 6
+        }
+      },
+      "operations": [
+        {
+          "name": "download",
+          "object": "gridfsbucket",
+          "arguments": {
+            "id": {
+              "$oid": "000000000000000000000001"
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "find": "fs.files",
+              "filter": {
+                "_id": {
+                  "$oid": "000000000000000000000001"
+                }
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "fs.files",
+              "filter": {
+                "_id": {
+                  "$oid": "000000000000000000000001"
+                }
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "fs.chunks",
+              "filter": {
+                "files_id": {
+                  "$oid": "000000000000000000000001"
+                }
+              },
+              "sort": {
+                "n": 1
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "Download succeeds after NetworkTimeout",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "find"
+          ],
+          "errorCode": 89
+        }
+      },
+      "operations": [
+        {
+          "name": "download",
+          "object": "gridfsbucket",
+          "arguments": {
+            "id": {
+              "$oid": "000000000000000000000001"
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "find": "fs.files",
+              "filter": {
+                "_id": {
+                  "$oid": "000000000000000000000001"
+                }
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "fs.files",
+              "filter": {
+                "_id": {
+                  "$oid": "000000000000000000000001"
+                }
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "fs.chunks",
+              "filter": {
+                "files_id": {
+                  "$oid": "000000000000000000000001"
+                }
+              },
+              "sort": {
+                "n": 1
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "Download succeeds after SocketException",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "find"
+          ],
+          "errorCode": 9001
+        }
+      },
+      "operations": [
+        {
+          "name": "download",
+          "object": "gridfsbucket",
+          "arguments": {
+            "id": {
+              "$oid": "000000000000000000000001"
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "find": "fs.files",
+              "filter": {
+                "_id": {
+                  "$oid": "000000000000000000000001"
+                }
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "fs.files",
+              "filter": {
+                "_id": {
+                  "$oid": "000000000000000000000001"
+                }
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "fs.chunks",
+              "filter": {
+                "files_id": {
+                  "$oid": "000000000000000000000001"
+                }
+              },
+              "sort": {
+                "n": 1
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "Download fails after two NotMaster errors",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 2
+        },
+        "data": {
+          "failCommands": [
+            "find"
+          ],
+          "errorCode": 10107
+        }
+      },
+      "operations": [
+        {
+          "name": "download",
+          "object": "gridfsbucket",
+          "arguments": {
+            "id": {
+              "$oid": "000000000000000000000001"
+            }
+          },
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "find": "fs.files",
+              "filter": {
+                "_id": {
+                  "$oid": "000000000000000000000001"
+                }
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "fs.files",
+              "filter": {
+                "_id": {
+                  "$oid": "000000000000000000000001"
+                }
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "Download fails after NotMaster when retryReads is false",
+      "clientOptions": {
+        "retryReads": false
+      },
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "find"
+          ],
+          "errorCode": 10107
+        }
+      },
+      "operations": [
+        {
+          "name": "download",
+          "object": "gridfsbucket",
+          "arguments": {
+            "id": {
+              "$oid": "000000000000000000000001"
+            }
+          },
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "find": "fs.files",
+              "filter": {
+                "_id": {
+                  "$oid": "000000000000000000000001"
+                }
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/gridfs-download.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/gridfs-download.json
new file mode 100644
index 0000000000000000000000000000000000000000..a5c5ef4d5593b80be8191d6066d7306c9fff836c
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/gridfs-download.json	
@@ -0,0 +1,269 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.0",
+      "topology": [
+        "single",
+        "replicaset"
+      ]
+    },
+    {
+      "minServerVersion": "4.1.7",
+      "topology": [
+        "sharded"
+      ]
+    }
+  ],
+  "database_name": "retryable-reads-tests",
+  "bucket_name": "fs",
+  "data": {
+    "fs.files": [
+      {
+        "_id": {
+          "$oid": "000000000000000000000001"
+        },
+        "length": 1,
+        "chunkSize": 4,
+        "uploadDate": {
+          "$date": "1970-01-01T00:00:00.000Z"
+        },
+        "filename": "abc",
+        "metadata": {}
+      }
+    ],
+    "fs.chunks": [
+      {
+        "_id": {
+          "$oid": "000000000000000000000002"
+        },
+        "files_id": {
+          "$oid": "000000000000000000000001"
+        },
+        "n": 0,
+        "data": {
+          "$binary": {
+            "base64": "EQ==",
+            "subType": "00"
+          }
+        }
+      }
+    ]
+  },
+  "tests": [
+    {
+      "description": "Download succeeds on first attempt",
+      "operations": [
+        {
+          "name": "download",
+          "object": "gridfsbucket",
+          "arguments": {
+            "id": {
+              "$oid": "000000000000000000000001"
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "find": "fs.files",
+              "filter": {
+                "_id": {
+                  "$oid": "000000000000000000000001"
+                }
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "fs.chunks",
+              "filter": {
+                "files_id": {
+                  "$oid": "000000000000000000000001"
+                }
+              },
+              "sort": {
+                "n": 1
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "Download succeeds on second attempt",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "find"
+          ],
+          "closeConnection": true
+        }
+      },
+      "operations": [
+        {
+          "name": "download",
+          "object": "gridfsbucket",
+          "arguments": {
+            "id": {
+              "$oid": "000000000000000000000001"
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "find": "fs.files",
+              "filter": {
+                "_id": {
+                  "$oid": "000000000000000000000001"
+                }
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "fs.files",
+              "filter": {
+                "_id": {
+                  "$oid": "000000000000000000000001"
+                }
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "fs.chunks",
+              "filter": {
+                "files_id": {
+                  "$oid": "000000000000000000000001"
+                }
+              },
+              "sort": {
+                "n": 1
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "Download fails on first attempt",
+      "clientOptions": {
+        "retryReads": false
+      },
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "find"
+          ],
+          "closeConnection": true
+        }
+      },
+      "operations": [
+        {
+          "name": "download",
+          "object": "gridfsbucket",
+          "arguments": {
+            "id": {
+              "$oid": "000000000000000000000001"
+            }
+          },
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "find": "fs.files",
+              "filter": {
+                "_id": {
+                  "$oid": "000000000000000000000001"
+                }
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "Download fails on second attempt",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 2
+        },
+        "data": {
+          "failCommands": [
+            "find"
+          ],
+          "closeConnection": true
+        }
+      },
+      "operations": [
+        {
+          "name": "download",
+          "object": "gridfsbucket",
+          "arguments": {
+            "id": {
+              "$oid": "000000000000000000000001"
+            }
+          },
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "find": "fs.files",
+              "filter": {
+                "_id": {
+                  "$oid": "000000000000000000000001"
+                }
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "fs.files",
+              "filter": {
+                "_id": {
+                  "$oid": "000000000000000000000001"
+                }
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/gridfs-downloadByName-serverErrors.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/gridfs-downloadByName-serverErrors.json
new file mode 100644
index 0000000000000000000000000000000000000000..de439ce4b203001936f257eb968842a29f5148ca
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/gridfs-downloadByName-serverErrors.json	
@@ -0,0 +1,848 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.0",
+      "topology": [
+        "single",
+        "replicaset"
+      ]
+    },
+    {
+      "minServerVersion": "4.1.7",
+      "topology": [
+        "sharded"
+      ]
+    }
+  ],
+  "database_name": "retryable-reads-tests",
+  "bucket_name": "fs",
+  "data": {
+    "fs.files": [
+      {
+        "_id": {
+          "$oid": "000000000000000000000001"
+        },
+        "length": 1,
+        "chunkSize": 4,
+        "uploadDate": {
+          "$date": "1970-01-01T00:00:00.000Z"
+        },
+        "filename": "abc",
+        "metadata": {}
+      }
+    ],
+    "fs.chunks": [
+      {
+        "_id": {
+          "$oid": "000000000000000000000002"
+        },
+        "files_id": {
+          "$oid": "000000000000000000000001"
+        },
+        "n": 0,
+        "data": {
+          "$binary": {
+            "base64": "EQ==",
+            "subType": "00"
+          }
+        }
+      }
+    ]
+  },
+  "tests": [
+    {
+      "description": "DownloadByName succeeds after InterruptedAtShutdown",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "find"
+          ],
+          "errorCode": 11600
+        }
+      },
+      "operations": [
+        {
+          "name": "download_by_name",
+          "object": "gridfsbucket",
+          "arguments": {
+            "filename": "abc"
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "find": "fs.files",
+              "filter": {
+                "filename": "abc"
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "fs.files",
+              "filter": {
+                "filename": "abc"
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "fs.chunks",
+              "filter": {
+                "files_id": {
+                  "$oid": "000000000000000000000001"
+                }
+              },
+              "sort": {
+                "n": 1
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "DownloadByName succeeds after InterruptedDueToReplStateChange",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "find"
+          ],
+          "errorCode": 11602
+        }
+      },
+      "operations": [
+        {
+          "name": "download_by_name",
+          "object": "gridfsbucket",
+          "arguments": {
+            "filename": "abc"
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "find": "fs.files",
+              "filter": {
+                "filename": "abc"
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "fs.files",
+              "filter": {
+                "filename": "abc"
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "fs.chunks",
+              "filter": {
+                "files_id": {
+                  "$oid": "000000000000000000000001"
+                }
+              },
+              "sort": {
+                "n": 1
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "DownloadByName succeeds after NotMaster",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "find"
+          ],
+          "errorCode": 10107
+        }
+      },
+      "operations": [
+        {
+          "name": "download_by_name",
+          "object": "gridfsbucket",
+          "arguments": {
+            "filename": "abc"
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "find": "fs.files",
+              "filter": {
+                "filename": "abc"
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "fs.files",
+              "filter": {
+                "filename": "abc"
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "fs.chunks",
+              "filter": {
+                "files_id": {
+                  "$oid": "000000000000000000000001"
+                }
+              },
+              "sort": {
+                "n": 1
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "DownloadByName succeeds after NotMasterNoSlaveOk",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "find"
+          ],
+          "errorCode": 13435
+        }
+      },
+      "operations": [
+        {
+          "name": "download_by_name",
+          "object": "gridfsbucket",
+          "arguments": {
+            "filename": "abc"
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "find": "fs.files",
+              "filter": {
+                "filename": "abc"
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "fs.files",
+              "filter": {
+                "filename": "abc"
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "fs.chunks",
+              "filter": {
+                "files_id": {
+                  "$oid": "000000000000000000000001"
+                }
+              },
+              "sort": {
+                "n": 1
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "DownloadByName succeeds after NotMasterOrSecondary",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "find"
+          ],
+          "errorCode": 13436
+        }
+      },
+      "operations": [
+        {
+          "name": "download_by_name",
+          "object": "gridfsbucket",
+          "arguments": {
+            "filename": "abc"
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "find": "fs.files",
+              "filter": {
+                "filename": "abc"
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "fs.files",
+              "filter": {
+                "filename": "abc"
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "fs.chunks",
+              "filter": {
+                "files_id": {
+                  "$oid": "000000000000000000000001"
+                }
+              },
+              "sort": {
+                "n": 1
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "DownloadByName succeeds after PrimarySteppedDown",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "find"
+          ],
+          "errorCode": 189
+        }
+      },
+      "operations": [
+        {
+          "name": "download_by_name",
+          "object": "gridfsbucket",
+          "arguments": {
+            "filename": "abc"
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "find": "fs.files",
+              "filter": {
+                "filename": "abc"
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "fs.files",
+              "filter": {
+                "filename": "abc"
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "fs.chunks",
+              "filter": {
+                "files_id": {
+                  "$oid": "000000000000000000000001"
+                }
+              },
+              "sort": {
+                "n": 1
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "DownloadByName succeeds after ShutdownInProgress",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "find"
+          ],
+          "errorCode": 91
+        }
+      },
+      "operations": [
+        {
+          "name": "download_by_name",
+          "object": "gridfsbucket",
+          "arguments": {
+            "filename": "abc"
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "find": "fs.files",
+              "filter": {
+                "filename": "abc"
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "fs.files",
+              "filter": {
+                "filename": "abc"
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "fs.chunks",
+              "filter": {
+                "files_id": {
+                  "$oid": "000000000000000000000001"
+                }
+              },
+              "sort": {
+                "n": 1
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "DownloadByName succeeds after HostNotFound",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "find"
+          ],
+          "errorCode": 7
+        }
+      },
+      "operations": [
+        {
+          "name": "download_by_name",
+          "object": "gridfsbucket",
+          "arguments": {
+            "filename": "abc"
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "find": "fs.files",
+              "filter": {
+                "filename": "abc"
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "fs.files",
+              "filter": {
+                "filename": "abc"
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "fs.chunks",
+              "filter": {
+                "files_id": {
+                  "$oid": "000000000000000000000001"
+                }
+              },
+              "sort": {
+                "n": 1
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "DownloadByName succeeds after HostUnreachable",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "find"
+          ],
+          "errorCode": 6
+        }
+      },
+      "operations": [
+        {
+          "name": "download_by_name",
+          "object": "gridfsbucket",
+          "arguments": {
+            "filename": "abc"
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "find": "fs.files",
+              "filter": {
+                "filename": "abc"
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "fs.files",
+              "filter": {
+                "filename": "abc"
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "fs.chunks",
+              "filter": {
+                "files_id": {
+                  "$oid": "000000000000000000000001"
+                }
+              },
+              "sort": {
+                "n": 1
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "DownloadByName succeeds after NetworkTimeout",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "find"
+          ],
+          "errorCode": 89
+        }
+      },
+      "operations": [
+        {
+          "name": "download_by_name",
+          "object": "gridfsbucket",
+          "arguments": {
+            "filename": "abc"
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "find": "fs.files",
+              "filter": {
+                "filename": "abc"
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "fs.files",
+              "filter": {
+                "filename": "abc"
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "fs.chunks",
+              "filter": {
+                "files_id": {
+                  "$oid": "000000000000000000000001"
+                }
+              },
+              "sort": {
+                "n": 1
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "DownloadByName succeeds after SocketException",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "find"
+          ],
+          "errorCode": 9001
+        }
+      },
+      "operations": [
+        {
+          "name": "download_by_name",
+          "object": "gridfsbucket",
+          "arguments": {
+            "filename": "abc"
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "find": "fs.files",
+              "filter": {
+                "filename": "abc"
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "fs.files",
+              "filter": {
+                "filename": "abc"
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "fs.chunks",
+              "filter": {
+                "files_id": {
+                  "$oid": "000000000000000000000001"
+                }
+              },
+              "sort": {
+                "n": 1
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "DownloadByName fails after two NotMaster errors",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 2
+        },
+        "data": {
+          "failCommands": [
+            "find"
+          ],
+          "errorCode": 10107
+        }
+      },
+      "operations": [
+        {
+          "name": "download_by_name",
+          "object": "gridfsbucket",
+          "arguments": {
+            "filename": "abc"
+          },
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "find": "fs.files",
+              "filter": {
+                "filename": "abc"
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "fs.files",
+              "filter": {
+                "filename": "abc"
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "DownloadByName fails after NotMaster when retryReads is false",
+      "clientOptions": {
+        "retryReads": false
+      },
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "find"
+          ],
+          "errorCode": 10107
+        }
+      },
+      "operations": [
+        {
+          "name": "download_by_name",
+          "object": "gridfsbucket",
+          "arguments": {
+            "filename": "abc"
+          },
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "find": "fs.files",
+              "filter": {
+                "filename": "abc"
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/gridfs-downloadByName.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/gridfs-downloadByName.json
new file mode 100644
index 0000000000000000000000000000000000000000..0634a09bff4f210dd2f448ac22c1b7fe6c34c50e
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/gridfs-downloadByName.json	
@@ -0,0 +1,249 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.0",
+      "topology": [
+        "single",
+        "replicaset"
+      ]
+    },
+    {
+      "minServerVersion": "4.1.7",
+      "topology": [
+        "sharded"
+      ]
+    }
+  ],
+  "database_name": "retryable-reads-tests",
+  "bucket_name": "fs",
+  "data": {
+    "fs.files": [
+      {
+        "_id": {
+          "$oid": "000000000000000000000001"
+        },
+        "length": 1,
+        "chunkSize": 4,
+        "uploadDate": {
+          "$date": "1970-01-01T00:00:00.000Z"
+        },
+        "filename": "abc",
+        "metadata": {}
+      }
+    ],
+    "fs.chunks": [
+      {
+        "_id": {
+          "$oid": "000000000000000000000002"
+        },
+        "files_id": {
+          "$oid": "000000000000000000000001"
+        },
+        "n": 0,
+        "data": {
+          "$binary": {
+            "base64": "EQ==",
+            "subType": "00"
+          }
+        }
+      }
+    ]
+  },
+  "tests": [
+    {
+      "description": "DownloadByName succeeds on first attempt",
+      "operations": [
+        {
+          "name": "download_by_name",
+          "object": "gridfsbucket",
+          "arguments": {
+            "filename": "abc"
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "find": "fs.files",
+              "filter": {
+                "filename": "abc"
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "fs.chunks",
+              "filter": {
+                "files_id": {
+                  "$oid": "000000000000000000000001"
+                }
+              },
+              "sort": {
+                "n": 1
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "DownloadByName succeeds on second attempt",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "find"
+          ],
+          "closeConnection": true
+        }
+      },
+      "operations": [
+        {
+          "name": "download_by_name",
+          "object": "gridfsbucket",
+          "arguments": {
+            "filename": "abc"
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "find": "fs.files",
+              "filter": {
+                "filename": "abc"
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "fs.files",
+              "filter": {
+                "filename": "abc"
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "fs.chunks",
+              "filter": {
+                "files_id": {
+                  "$oid": "000000000000000000000001"
+                }
+              },
+              "sort": {
+                "n": 1
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "DownloadByName fails on first attempt",
+      "clientOptions": {
+        "retryReads": false
+      },
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "find"
+          ],
+          "closeConnection": true
+        }
+      },
+      "operations": [
+        {
+          "name": "download_by_name",
+          "object": "gridfsbucket",
+          "arguments": {
+            "filename": "abc"
+          },
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "find": "fs.files",
+              "filter": {
+                "filename": "abc"
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "DownloadByName fails on second attempt",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 2
+        },
+        "data": {
+          "failCommands": [
+            "find"
+          ],
+          "closeConnection": true
+        }
+      },
+      "operations": [
+        {
+          "name": "download_by_name",
+          "object": "gridfsbucket",
+          "arguments": {
+            "filename": "abc"
+          },
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "find": "fs.files",
+              "filter": {
+                "filename": "abc"
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "fs.files",
+              "filter": {
+                "filename": "abc"
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/listCollectionNames-serverErrors.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/listCollectionNames-serverErrors.json
new file mode 100644
index 0000000000000000000000000000000000000000..27c13d6301c144e16444d413caebb3d867cc477b
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/listCollectionNames-serverErrors.json	
@@ -0,0 +1,501 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.0",
+      "topology": [
+        "single",
+        "replicaset"
+      ]
+    },
+    {
+      "minServerVersion": "4.1.7",
+      "topology": [
+        "sharded"
+      ]
+    }
+  ],
+  "database_name": "retryable-reads-tests",
+  "collection_name": "coll",
+  "data": [],
+  "tests": [
+    {
+      "description": "ListCollectionNames succeeds after InterruptedAtShutdown",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listCollections"
+          ],
+          "errorCode": 11600
+        }
+      },
+      "operations": [
+        {
+          "name": "listCollectionNames",
+          "object": "database"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListCollectionNames succeeds after InterruptedDueToReplStateChange",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listCollections"
+          ],
+          "errorCode": 11602
+        }
+      },
+      "operations": [
+        {
+          "name": "listCollectionNames",
+          "object": "database"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListCollectionNames succeeds after NotMaster",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listCollections"
+          ],
+          "errorCode": 10107
+        }
+      },
+      "operations": [
+        {
+          "name": "listCollectionNames",
+          "object": "database"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListCollectionNames succeeds after NotMasterNoSlaveOk",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listCollections"
+          ],
+          "errorCode": 13435
+        }
+      },
+      "operations": [
+        {
+          "name": "listCollectionNames",
+          "object": "database"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListCollectionNames succeeds after NotMasterOrSecondary",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listCollections"
+          ],
+          "errorCode": 13436
+        }
+      },
+      "operations": [
+        {
+          "name": "listCollectionNames",
+          "object": "database"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListCollectionNames succeeds after PrimarySteppedDown",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listCollections"
+          ],
+          "errorCode": 189
+        }
+      },
+      "operations": [
+        {
+          "name": "listCollectionNames",
+          "object": "database"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListCollectionNames succeeds after ShutdownInProgress",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listCollections"
+          ],
+          "errorCode": 91
+        }
+      },
+      "operations": [
+        {
+          "name": "listCollectionNames",
+          "object": "database"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListCollectionNames succeeds after HostNotFound",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listCollections"
+          ],
+          "errorCode": 7
+        }
+      },
+      "operations": [
+        {
+          "name": "listCollectionNames",
+          "object": "database"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListCollectionNames succeeds after HostUnreachable",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listCollections"
+          ],
+          "errorCode": 6
+        }
+      },
+      "operations": [
+        {
+          "name": "listCollectionNames",
+          "object": "database"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListCollectionNames succeeds after NetworkTimeout",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listCollections"
+          ],
+          "errorCode": 89
+        }
+      },
+      "operations": [
+        {
+          "name": "listCollectionNames",
+          "object": "database"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListCollectionNames succeeds after SocketException",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listCollections"
+          ],
+          "errorCode": 9001
+        }
+      },
+      "operations": [
+        {
+          "name": "listCollectionNames",
+          "object": "database"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListCollectionNames fails after two NotMaster errors",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 2
+        },
+        "data": {
+          "failCommands": [
+            "listCollections"
+          ],
+          "errorCode": 10107
+        }
+      },
+      "operations": [
+        {
+          "name": "listCollectionNames",
+          "object": "database",
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListCollectionNames fails after NotMaster when retryReads is false",
+      "clientOptions": {
+        "retryReads": false
+      },
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listCollections"
+          ],
+          "errorCode": 10107
+        }
+      },
+      "operations": [
+        {
+          "name": "listCollectionNames",
+          "object": "database",
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/listCollectionNames.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/listCollectionNames.json
new file mode 100644
index 0000000000000000000000000000000000000000..437fc36a40e762353a0afe0e4bb4df3d252c14d1
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/listCollectionNames.json	
@@ -0,0 +1,149 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.0",
+      "topology": [
+        "single",
+        "replicaset"
+      ]
+    },
+    {
+      "minServerVersion": "4.1.7",
+      "topology": [
+        "sharded"
+      ]
+    }
+  ],
+  "database_name": "retryable-reads-tests",
+  "collection_name": "coll",
+  "data": [],
+  "tests": [
+    {
+      "description": "ListCollectionNames succeeds on first attempt",
+      "operations": [
+        {
+          "name": "listCollectionNames",
+          "object": "database"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListCollectionNames succeeds on second attempt",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listCollections"
+          ],
+          "closeConnection": true
+        }
+      },
+      "operations": [
+        {
+          "name": "listCollectionNames",
+          "object": "database"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListCollectionNames fails on first attempt",
+      "clientOptions": {
+        "retryReads": false
+      },
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listCollections"
+          ],
+          "closeConnection": true
+        }
+      },
+      "operations": [
+        {
+          "name": "listCollectionNames",
+          "object": "database",
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListCollectionNames fails on second attempt",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 2
+        },
+        "data": {
+          "failCommands": [
+            "listCollections"
+          ],
+          "closeConnection": true
+        }
+      },
+      "operations": [
+        {
+          "name": "listCollectionNames",
+          "object": "database",
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/listCollectionObjects-serverErrors.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/listCollectionObjects-serverErrors.json
new file mode 100644
index 0000000000000000000000000000000000000000..3922713df9cebc1be0a087312f5079f784966cec
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/listCollectionObjects-serverErrors.json	
@@ -0,0 +1,501 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.0",
+      "topology": [
+        "single",
+        "replicaset"
+      ]
+    },
+    {
+      "minServerVersion": "4.1.7",
+      "topology": [
+        "sharded"
+      ]
+    }
+  ],
+  "database_name": "retryable-reads-tests",
+  "collection_name": "coll",
+  "data": [],
+  "tests": [
+    {
+      "description": "ListCollectionObjects succeeds after InterruptedAtShutdown",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listCollections"
+          ],
+          "errorCode": 11600
+        }
+      },
+      "operations": [
+        {
+          "name": "listCollectionObjects",
+          "object": "database"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListCollectionObjects succeeds after InterruptedDueToReplStateChange",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listCollections"
+          ],
+          "errorCode": 11602
+        }
+      },
+      "operations": [
+        {
+          "name": "listCollectionObjects",
+          "object": "database"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListCollectionObjects succeeds after NotMaster",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listCollections"
+          ],
+          "errorCode": 10107
+        }
+      },
+      "operations": [
+        {
+          "name": "listCollectionObjects",
+          "object": "database"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListCollectionObjects succeeds after NotMasterNoSlaveOk",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listCollections"
+          ],
+          "errorCode": 13435
+        }
+      },
+      "operations": [
+        {
+          "name": "listCollectionObjects",
+          "object": "database"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListCollectionObjects succeeds after NotMasterOrSecondary",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listCollections"
+          ],
+          "errorCode": 13436
+        }
+      },
+      "operations": [
+        {
+          "name": "listCollectionObjects",
+          "object": "database"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListCollectionObjects succeeds after PrimarySteppedDown",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listCollections"
+          ],
+          "errorCode": 189
+        }
+      },
+      "operations": [
+        {
+          "name": "listCollectionObjects",
+          "object": "database"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListCollectionObjects succeeds after ShutdownInProgress",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listCollections"
+          ],
+          "errorCode": 91
+        }
+      },
+      "operations": [
+        {
+          "name": "listCollectionObjects",
+          "object": "database"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListCollectionObjects succeeds after HostNotFound",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listCollections"
+          ],
+          "errorCode": 7
+        }
+      },
+      "operations": [
+        {
+          "name": "listCollectionObjects",
+          "object": "database"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListCollectionObjects succeeds after HostUnreachable",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listCollections"
+          ],
+          "errorCode": 6
+        }
+      },
+      "operations": [
+        {
+          "name": "listCollectionObjects",
+          "object": "database"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListCollectionObjects succeeds after NetworkTimeout",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listCollections"
+          ],
+          "errorCode": 89
+        }
+      },
+      "operations": [
+        {
+          "name": "listCollectionObjects",
+          "object": "database"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListCollectionObjects succeeds after SocketException",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listCollections"
+          ],
+          "errorCode": 9001
+        }
+      },
+      "operations": [
+        {
+          "name": "listCollectionObjects",
+          "object": "database"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListCollectionObjects fails after two NotMaster errors",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 2
+        },
+        "data": {
+          "failCommands": [
+            "listCollections"
+          ],
+          "errorCode": 10107
+        }
+      },
+      "operations": [
+        {
+          "name": "listCollectionObjects",
+          "object": "database",
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListCollectionObjects fails after NotMaster when retryReads is false",
+      "clientOptions": {
+        "retryReads": false
+      },
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listCollections"
+          ],
+          "errorCode": 10107
+        }
+      },
+      "operations": [
+        {
+          "name": "listCollectionObjects",
+          "object": "database",
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/listCollectionObjects.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/listCollectionObjects.json
new file mode 100644
index 0000000000000000000000000000000000000000..1f537b743f07b7e4a2eba4a4c17e0e54cbc83853
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/listCollectionObjects.json	
@@ -0,0 +1,149 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.0",
+      "topology": [
+        "single",
+        "replicaset"
+      ]
+    },
+    {
+      "minServerVersion": "4.1.7",
+      "topology": [
+        "sharded"
+      ]
+    }
+  ],
+  "database_name": "retryable-reads-tests",
+  "collection_name": "coll",
+  "data": [],
+  "tests": [
+    {
+      "description": "ListCollectionObjects succeeds on first attempt",
+      "operations": [
+        {
+          "name": "listCollectionObjects",
+          "object": "database"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListCollectionObjects succeeds on second attempt",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listCollections"
+          ],
+          "closeConnection": true
+        }
+      },
+      "operations": [
+        {
+          "name": "listCollectionObjects",
+          "object": "database"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListCollectionObjects fails on first attempt",
+      "clientOptions": {
+        "retryReads": false
+      },
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listCollections"
+          ],
+          "closeConnection": true
+        }
+      },
+      "operations": [
+        {
+          "name": "listCollectionObjects",
+          "object": "database",
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListCollectionObjects fails on second attempt",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 2
+        },
+        "data": {
+          "failCommands": [
+            "listCollections"
+          ],
+          "closeConnection": true
+        }
+      },
+      "operations": [
+        {
+          "name": "listCollectionObjects",
+          "object": "database",
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/listCollections-serverErrors.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/listCollections-serverErrors.json
new file mode 100644
index 0000000000000000000000000000000000000000..6972073b181afaa7f0238e0ae58474c4968fd65c
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/listCollections-serverErrors.json	
@@ -0,0 +1,501 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.0",
+      "topology": [
+        "single",
+        "replicaset"
+      ]
+    },
+    {
+      "minServerVersion": "4.1.7",
+      "topology": [
+        "sharded"
+      ]
+    }
+  ],
+  "database_name": "retryable-reads-tests",
+  "collection_name": "coll",
+  "data": [],
+  "tests": [
+    {
+      "description": "ListCollections succeeds after InterruptedAtShutdown",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listCollections"
+          ],
+          "errorCode": 11600
+        }
+      },
+      "operations": [
+        {
+          "name": "listCollections",
+          "object": "database"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListCollections succeeds after InterruptedDueToReplStateChange",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listCollections"
+          ],
+          "errorCode": 11602
+        }
+      },
+      "operations": [
+        {
+          "name": "listCollections",
+          "object": "database"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListCollections succeeds after NotMaster",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listCollections"
+          ],
+          "errorCode": 10107
+        }
+      },
+      "operations": [
+        {
+          "name": "listCollections",
+          "object": "database"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListCollections succeeds after NotMasterNoSlaveOk",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listCollections"
+          ],
+          "errorCode": 13435
+        }
+      },
+      "operations": [
+        {
+          "name": "listCollections",
+          "object": "database"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListCollections succeeds after NotMasterOrSecondary",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listCollections"
+          ],
+          "errorCode": 13436
+        }
+      },
+      "operations": [
+        {
+          "name": "listCollections",
+          "object": "database"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListCollections succeeds after PrimarySteppedDown",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listCollections"
+          ],
+          "errorCode": 189
+        }
+      },
+      "operations": [
+        {
+          "name": "listCollections",
+          "object": "database"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListCollections succeeds after ShutdownInProgress",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listCollections"
+          ],
+          "errorCode": 91
+        }
+      },
+      "operations": [
+        {
+          "name": "listCollections",
+          "object": "database"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListCollections succeeds after HostNotFound",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listCollections"
+          ],
+          "errorCode": 7
+        }
+      },
+      "operations": [
+        {
+          "name": "listCollections",
+          "object": "database"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListCollections succeeds after HostUnreachable",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listCollections"
+          ],
+          "errorCode": 6
+        }
+      },
+      "operations": [
+        {
+          "name": "listCollections",
+          "object": "database"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListCollections succeeds after NetworkTimeout",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listCollections"
+          ],
+          "errorCode": 89
+        }
+      },
+      "operations": [
+        {
+          "name": "listCollections",
+          "object": "database"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListCollections succeeds after SocketException",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listCollections"
+          ],
+          "errorCode": 9001
+        }
+      },
+      "operations": [
+        {
+          "name": "listCollections",
+          "object": "database"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListCollections fails after two NotMaster errors",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 2
+        },
+        "data": {
+          "failCommands": [
+            "listCollections"
+          ],
+          "errorCode": 10107
+        }
+      },
+      "operations": [
+        {
+          "name": "listCollections",
+          "object": "database",
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListCollections fails after NotMaster when retryReads is false",
+      "clientOptions": {
+        "retryReads": false
+      },
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listCollections"
+          ],
+          "errorCode": 10107
+        }
+      },
+      "operations": [
+        {
+          "name": "listCollections",
+          "object": "database",
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/listCollections.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/listCollections.json
new file mode 100644
index 0000000000000000000000000000000000000000..a6b452e64f086775ec9f6a119e3f1416e1a2282b
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/listCollections.json	
@@ -0,0 +1,149 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.0",
+      "topology": [
+        "single",
+        "replicaset"
+      ]
+    },
+    {
+      "minServerVersion": "4.1.7",
+      "topology": [
+        "sharded"
+      ]
+    }
+  ],
+  "database_name": "retryable-reads-tests",
+  "collection_name": "coll",
+  "data": [],
+  "tests": [
+    {
+      "description": "ListCollections succeeds on first attempt",
+      "operations": [
+        {
+          "name": "listCollections",
+          "object": "database"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListCollections succeeds on second attempt",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listCollections"
+          ],
+          "closeConnection": true
+        }
+      },
+      "operations": [
+        {
+          "name": "listCollections",
+          "object": "database"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListCollections fails on first attempt",
+      "clientOptions": {
+        "retryReads": false
+      },
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listCollections"
+          ],
+          "closeConnection": true
+        }
+      },
+      "operations": [
+        {
+          "name": "listCollections",
+          "object": "database",
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListCollections fails on second attempt",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 2
+        },
+        "data": {
+          "failCommands": [
+            "listCollections"
+          ],
+          "closeConnection": true
+        }
+      },
+      "operations": [
+        {
+          "name": "listCollections",
+          "object": "database",
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listCollections": 1
+            }
+          }
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/listDatabaseNames-serverErrors.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/listDatabaseNames-serverErrors.json
new file mode 100644
index 0000000000000000000000000000000000000000..11faf58bf0439ff3616b5683f5a4af5c3a7413d2
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/listDatabaseNames-serverErrors.json	
@@ -0,0 +1,501 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.0",
+      "topology": [
+        "single",
+        "replicaset"
+      ]
+    },
+    {
+      "minServerVersion": "4.1.7",
+      "topology": [
+        "sharded"
+      ]
+    }
+  ],
+  "database_name": "retryable-reads-tests",
+  "collection_name": "coll",
+  "data": [],
+  "tests": [
+    {
+      "description": "ListDatabaseNames succeeds after InterruptedAtShutdown",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listDatabases"
+          ],
+          "errorCode": 11600
+        }
+      },
+      "operations": [
+        {
+          "name": "listDatabaseNames",
+          "object": "client"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListDatabaseNames succeeds after InterruptedDueToReplStateChange",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listDatabases"
+          ],
+          "errorCode": 11602
+        }
+      },
+      "operations": [
+        {
+          "name": "listDatabaseNames",
+          "object": "client"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListDatabaseNames succeeds after NotMaster",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listDatabases"
+          ],
+          "errorCode": 10107
+        }
+      },
+      "operations": [
+        {
+          "name": "listDatabaseNames",
+          "object": "client"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListDatabaseNames succeeds after NotMasterNoSlaveOk",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listDatabases"
+          ],
+          "errorCode": 13435
+        }
+      },
+      "operations": [
+        {
+          "name": "listDatabaseNames",
+          "object": "client"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListDatabaseNames succeeds after NotMasterOrSecondary",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listDatabases"
+          ],
+          "errorCode": 13436
+        }
+      },
+      "operations": [
+        {
+          "name": "listDatabaseNames",
+          "object": "client"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListDatabaseNames succeeds after PrimarySteppedDown",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listDatabases"
+          ],
+          "errorCode": 189
+        }
+      },
+      "operations": [
+        {
+          "name": "listDatabaseNames",
+          "object": "client"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListDatabaseNames succeeds after ShutdownInProgress",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listDatabases"
+          ],
+          "errorCode": 91
+        }
+      },
+      "operations": [
+        {
+          "name": "listDatabaseNames",
+          "object": "client"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListDatabaseNames succeeds after HostNotFound",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listDatabases"
+          ],
+          "errorCode": 7
+        }
+      },
+      "operations": [
+        {
+          "name": "listDatabaseNames",
+          "object": "client"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListDatabaseNames succeeds after HostUnreachable",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listDatabases"
+          ],
+          "errorCode": 6
+        }
+      },
+      "operations": [
+        {
+          "name": "listDatabaseNames",
+          "object": "client"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListDatabaseNames succeeds after NetworkTimeout",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listDatabases"
+          ],
+          "errorCode": 89
+        }
+      },
+      "operations": [
+        {
+          "name": "listDatabaseNames",
+          "object": "client"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListDatabaseNames succeeds after SocketException",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listDatabases"
+          ],
+          "errorCode": 9001
+        }
+      },
+      "operations": [
+        {
+          "name": "listDatabaseNames",
+          "object": "client"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListDatabaseNames fails after two NotMaster errors",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 2
+        },
+        "data": {
+          "failCommands": [
+            "listDatabases"
+          ],
+          "errorCode": 10107
+        }
+      },
+      "operations": [
+        {
+          "name": "listDatabaseNames",
+          "object": "client",
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListDatabaseNames fails after NotMaster when retryReads is false",
+      "clientOptions": {
+        "retryReads": false
+      },
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listDatabases"
+          ],
+          "errorCode": 10107
+        }
+      },
+      "operations": [
+        {
+          "name": "listDatabaseNames",
+          "object": "client",
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/listDatabaseNames.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/listDatabaseNames.json
new file mode 100644
index 0000000000000000000000000000000000000000..b35f7ab185f4a16366494b541a61956cb4482288
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/listDatabaseNames.json	
@@ -0,0 +1,149 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.0",
+      "topology": [
+        "single",
+        "replicaset"
+      ]
+    },
+    {
+      "minServerVersion": "4.1.7",
+      "topology": [
+        "sharded"
+      ]
+    }
+  ],
+  "database_name": "retryable-reads-tests",
+  "collection_name": "coll",
+  "data": [],
+  "tests": [
+    {
+      "description": "ListDatabaseNames succeeds on first attempt",
+      "operations": [
+        {
+          "name": "listDatabaseNames",
+          "object": "client"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListDatabaseNames succeeds on second attempt",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listDatabases"
+          ],
+          "closeConnection": true
+        }
+      },
+      "operations": [
+        {
+          "name": "listDatabaseNames",
+          "object": "client"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListDatabaseNames fails on first attempt",
+      "clientOptions": {
+        "retryReads": false
+      },
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listDatabases"
+          ],
+          "closeConnection": true
+        }
+      },
+      "operations": [
+        {
+          "name": "listDatabaseNames",
+          "object": "client",
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListDatabaseNames fails on second attempt",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 2
+        },
+        "data": {
+          "failCommands": [
+            "listDatabases"
+          ],
+          "closeConnection": true
+        }
+      },
+      "operations": [
+        {
+          "name": "listDatabaseNames",
+          "object": "client",
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/listDatabaseObjects-serverErrors.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/listDatabaseObjects-serverErrors.json
new file mode 100644
index 0000000000000000000000000000000000000000..38082f2e28b06a8473138e80d087be0a9085e5ac
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/listDatabaseObjects-serverErrors.json	
@@ -0,0 +1,501 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.0",
+      "topology": [
+        "single",
+        "replicaset"
+      ]
+    },
+    {
+      "minServerVersion": "4.1.7",
+      "topology": [
+        "sharded"
+      ]
+    }
+  ],
+  "database_name": "retryable-reads-tests",
+  "collection_name": "coll",
+  "data": [],
+  "tests": [
+    {
+      "description": "ListDatabaseObjects succeeds after InterruptedAtShutdown",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listDatabases"
+          ],
+          "errorCode": 11600
+        }
+      },
+      "operations": [
+        {
+          "name": "listDatabaseObjects",
+          "object": "client"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListDatabaseObjects succeeds after InterruptedDueToReplStateChange",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listDatabases"
+          ],
+          "errorCode": 11602
+        }
+      },
+      "operations": [
+        {
+          "name": "listDatabaseObjects",
+          "object": "client"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListDatabaseObjects succeeds after NotMaster",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listDatabases"
+          ],
+          "errorCode": 10107
+        }
+      },
+      "operations": [
+        {
+          "name": "listDatabaseObjects",
+          "object": "client"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListDatabaseObjects succeeds after NotMasterNoSlaveOk",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listDatabases"
+          ],
+          "errorCode": 13435
+        }
+      },
+      "operations": [
+        {
+          "name": "listDatabaseObjects",
+          "object": "client"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListDatabaseObjects succeeds after NotMasterOrSecondary",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listDatabases"
+          ],
+          "errorCode": 13436
+        }
+      },
+      "operations": [
+        {
+          "name": "listDatabaseObjects",
+          "object": "client"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListDatabaseObjects succeeds after PrimarySteppedDown",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listDatabases"
+          ],
+          "errorCode": 189
+        }
+      },
+      "operations": [
+        {
+          "name": "listDatabaseObjects",
+          "object": "client"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListDatabaseObjects succeeds after ShutdownInProgress",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listDatabases"
+          ],
+          "errorCode": 91
+        }
+      },
+      "operations": [
+        {
+          "name": "listDatabaseObjects",
+          "object": "client"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListDatabaseObjects succeeds after HostNotFound",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listDatabases"
+          ],
+          "errorCode": 7
+        }
+      },
+      "operations": [
+        {
+          "name": "listDatabaseObjects",
+          "object": "client"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListDatabaseObjects succeeds after HostUnreachable",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listDatabases"
+          ],
+          "errorCode": 6
+        }
+      },
+      "operations": [
+        {
+          "name": "listDatabaseObjects",
+          "object": "client"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListDatabaseObjects succeeds after NetworkTimeout",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listDatabases"
+          ],
+          "errorCode": 89
+        }
+      },
+      "operations": [
+        {
+          "name": "listDatabaseObjects",
+          "object": "client"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListDatabaseObjects succeeds after SocketException",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listDatabases"
+          ],
+          "errorCode": 9001
+        }
+      },
+      "operations": [
+        {
+          "name": "listDatabaseObjects",
+          "object": "client"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListDatabaseObjects fails after two NotMaster errors",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 2
+        },
+        "data": {
+          "failCommands": [
+            "listDatabases"
+          ],
+          "errorCode": 10107
+        }
+      },
+      "operations": [
+        {
+          "name": "listDatabaseObjects",
+          "object": "client",
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListDatabaseObjects fails after NotMaster when retryReads is false",
+      "clientOptions": {
+        "retryReads": false
+      },
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listDatabases"
+          ],
+          "errorCode": 10107
+        }
+      },
+      "operations": [
+        {
+          "name": "listDatabaseObjects",
+          "object": "client",
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/listDatabaseObjects.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/listDatabaseObjects.json
new file mode 100644
index 0000000000000000000000000000000000000000..cbd2c6763a3beaeabec0696ceaecc623eb28aa8f
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/listDatabaseObjects.json	
@@ -0,0 +1,149 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.0",
+      "topology": [
+        "single",
+        "replicaset"
+      ]
+    },
+    {
+      "minServerVersion": "4.1.7",
+      "topology": [
+        "sharded"
+      ]
+    }
+  ],
+  "database_name": "retryable-reads-tests",
+  "collection_name": "coll",
+  "data": [],
+  "tests": [
+    {
+      "description": "ListDatabaseObjects succeeds on first attempt",
+      "operations": [
+        {
+          "name": "listDatabaseObjects",
+          "object": "client"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListDatabaseObjects succeeds on second attempt",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listDatabases"
+          ],
+          "closeConnection": true
+        }
+      },
+      "operations": [
+        {
+          "name": "listDatabaseObjects",
+          "object": "client"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListDatabaseObjects fails on first attempt",
+      "clientOptions": {
+        "retryReads": false
+      },
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listDatabases"
+          ],
+          "closeConnection": true
+        }
+      },
+      "operations": [
+        {
+          "name": "listDatabaseObjects",
+          "object": "client",
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListDatabaseObjects fails on second attempt",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 2
+        },
+        "data": {
+          "failCommands": [
+            "listDatabases"
+          ],
+          "closeConnection": true
+        }
+      },
+      "operations": [
+        {
+          "name": "listDatabaseObjects",
+          "object": "client",
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/listDatabases-serverErrors.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/listDatabases-serverErrors.json
new file mode 100644
index 0000000000000000000000000000000000000000..4047f749ffcece26e15454cafda24f7bf7936ee6
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/listDatabases-serverErrors.json	
@@ -0,0 +1,501 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.0",
+      "topology": [
+        "single",
+        "replicaset"
+      ]
+    },
+    {
+      "minServerVersion": "4.1.7",
+      "topology": [
+        "sharded"
+      ]
+    }
+  ],
+  "database_name": "retryable-reads-tests",
+  "collection_name": "coll",
+  "data": [],
+  "tests": [
+    {
+      "description": "ListDatabases succeeds after InterruptedAtShutdown",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listDatabases"
+          ],
+          "errorCode": 11600
+        }
+      },
+      "operations": [
+        {
+          "name": "listDatabases",
+          "object": "client"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListDatabases succeeds after InterruptedDueToReplStateChange",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listDatabases"
+          ],
+          "errorCode": 11602
+        }
+      },
+      "operations": [
+        {
+          "name": "listDatabases",
+          "object": "client"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListDatabases succeeds after NotMaster",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listDatabases"
+          ],
+          "errorCode": 10107
+        }
+      },
+      "operations": [
+        {
+          "name": "listDatabases",
+          "object": "client"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListDatabases succeeds after NotMasterNoSlaveOk",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listDatabases"
+          ],
+          "errorCode": 13435
+        }
+      },
+      "operations": [
+        {
+          "name": "listDatabases",
+          "object": "client"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListDatabases succeeds after NotMasterOrSecondary",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listDatabases"
+          ],
+          "errorCode": 13436
+        }
+      },
+      "operations": [
+        {
+          "name": "listDatabases",
+          "object": "client"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListDatabases succeeds after PrimarySteppedDown",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listDatabases"
+          ],
+          "errorCode": 189
+        }
+      },
+      "operations": [
+        {
+          "name": "listDatabases",
+          "object": "client"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListDatabases succeeds after ShutdownInProgress",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listDatabases"
+          ],
+          "errorCode": 91
+        }
+      },
+      "operations": [
+        {
+          "name": "listDatabases",
+          "object": "client"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListDatabases succeeds after HostNotFound",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listDatabases"
+          ],
+          "errorCode": 7
+        }
+      },
+      "operations": [
+        {
+          "name": "listDatabases",
+          "object": "client"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListDatabases succeeds after HostUnreachable",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listDatabases"
+          ],
+          "errorCode": 6
+        }
+      },
+      "operations": [
+        {
+          "name": "listDatabases",
+          "object": "client"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListDatabases succeeds after NetworkTimeout",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listDatabases"
+          ],
+          "errorCode": 89
+        }
+      },
+      "operations": [
+        {
+          "name": "listDatabases",
+          "object": "client"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListDatabases succeeds after SocketException",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listDatabases"
+          ],
+          "errorCode": 9001
+        }
+      },
+      "operations": [
+        {
+          "name": "listDatabases",
+          "object": "client"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListDatabases fails after two NotMaster errors",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 2
+        },
+        "data": {
+          "failCommands": [
+            "listDatabases"
+          ],
+          "errorCode": 10107
+        }
+      },
+      "operations": [
+        {
+          "name": "listDatabases",
+          "object": "client",
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListDatabases fails after NotMaster when retryReads is false",
+      "clientOptions": {
+        "retryReads": false
+      },
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listDatabases"
+          ],
+          "errorCode": 10107
+        }
+      },
+      "operations": [
+        {
+          "name": "listDatabases",
+          "object": "client",
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/listDatabases.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/listDatabases.json
new file mode 100644
index 0000000000000000000000000000000000000000..3cb8bbd083cc40092321fcd7fb63082a5a720049
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/listDatabases.json	
@@ -0,0 +1,149 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.0",
+      "topology": [
+        "single",
+        "replicaset"
+      ]
+    },
+    {
+      "minServerVersion": "4.1.7",
+      "topology": [
+        "sharded"
+      ]
+    }
+  ],
+  "database_name": "retryable-reads-tests",
+  "collection_name": "coll",
+  "data": [],
+  "tests": [
+    {
+      "description": "ListDatabases succeeds on first attempt",
+      "operations": [
+        {
+          "name": "listDatabases",
+          "object": "client"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListDatabases succeeds on second attempt",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listDatabases"
+          ],
+          "closeConnection": true
+        }
+      },
+      "operations": [
+        {
+          "name": "listDatabases",
+          "object": "client"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListDatabases fails on first attempt",
+      "clientOptions": {
+        "retryReads": false
+      },
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listDatabases"
+          ],
+          "closeConnection": true
+        }
+      },
+      "operations": [
+        {
+          "name": "listDatabases",
+          "object": "client",
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListDatabases fails on second attempt",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 2
+        },
+        "data": {
+          "failCommands": [
+            "listDatabases"
+          ],
+          "closeConnection": true
+        }
+      },
+      "operations": [
+        {
+          "name": "listDatabases",
+          "object": "client",
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listDatabases": 1
+            }
+          }
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/listIndexNames-serverErrors.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/listIndexNames-serverErrors.json
new file mode 100644
index 0000000000000000000000000000000000000000..1a9ba83bc699c278234e5061509e668c2688afbf
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/listIndexNames-serverErrors.json	
@@ -0,0 +1,526 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.0",
+      "topology": [
+        "single",
+        "replicaset"
+      ]
+    },
+    {
+      "minServerVersion": "4.1.7",
+      "topology": [
+        "sharded"
+      ]
+    }
+  ],
+  "database_name": "retryable-reads-tests",
+  "collection_name": "coll",
+  "data": [],
+  "tests": [
+    {
+      "description": "ListIndexNames succeeds after InterruptedAtShutdown",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listIndexes"
+          ],
+          "errorCode": 11600
+        }
+      },
+      "operations": [
+        {
+          "name": "listIndexNames",
+          "object": "collection"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listIndexes": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listIndexes": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListIndexNames succeeds after InterruptedDueToReplStateChange",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listIndexes"
+          ],
+          "errorCode": 11602
+        }
+      },
+      "operations": [
+        {
+          "name": "listIndexNames",
+          "object": "collection"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listIndexes": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listIndexes": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListIndexNames succeeds after NotMaster",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listIndexes"
+          ],
+          "errorCode": 10107
+        }
+      },
+      "operations": [
+        {
+          "name": "listIndexNames",
+          "object": "collection"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listIndexes": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listIndexes": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListIndexNames succeeds after NotMasterNoSlaveOk",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listIndexes"
+          ],
+          "errorCode": 13435
+        }
+      },
+      "operations": [
+        {
+          "name": "listIndexNames",
+          "object": "collection"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listIndexes": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listIndexes": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListIndexNames succeeds after NotMasterOrSecondary",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listIndexes"
+          ],
+          "errorCode": 13436
+        }
+      },
+      "operations": [
+        {
+          "name": "listIndexNames",
+          "object": "collection"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listIndexes": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listIndexes": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListIndexNames succeeds after PrimarySteppedDown",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listIndexes"
+          ],
+          "errorCode": 189
+        }
+      },
+      "operations": [
+        {
+          "name": "listIndexNames",
+          "object": "collection"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listIndexes": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listIndexes": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListIndexNames succeeds after ShutdownInProgress",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listIndexes"
+          ],
+          "errorCode": 91
+        }
+      },
+      "operations": [
+        {
+          "name": "listIndexNames",
+          "object": "collection"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listIndexes": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listIndexes": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListIndexNames succeeds after HostNotFound",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listIndexes"
+          ],
+          "errorCode": 7
+        }
+      },
+      "operations": [
+        {
+          "name": "listIndexNames",
+          "object": "collection"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listIndexes": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listIndexes": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListIndexNames succeeds after HostUnreachable",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listIndexes"
+          ],
+          "errorCode": 6
+        }
+      },
+      "operations": [
+        {
+          "name": "listIndexNames",
+          "object": "collection"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listIndexes": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listIndexes": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListIndexNames succeeds after NetworkTimeout",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listIndexes"
+          ],
+          "errorCode": 89
+        }
+      },
+      "operations": [
+        {
+          "name": "listIndexNames",
+          "object": "collection"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listIndexes": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listIndexes": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListIndexNames succeeds after SocketException",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listIndexes"
+          ],
+          "errorCode": 9001
+        }
+      },
+      "operations": [
+        {
+          "name": "listIndexNames",
+          "object": "collection"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listIndexes": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listIndexes": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListIndexNames fails after two NotMaster errors",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 2
+        },
+        "data": {
+          "failCommands": [
+            "listIndexes"
+          ],
+          "errorCode": 10107
+        }
+      },
+      "operations": [
+        {
+          "name": "listIndexNames",
+          "object": "collection",
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listIndexes": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listIndexes": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListIndexNames fails after NotMaster when retryReads is false",
+      "clientOptions": {
+        "retryReads": false
+      },
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listIndexes"
+          ],
+          "errorCode": 10107
+        }
+      },
+      "operations": [
+        {
+          "name": "listIndexNames",
+          "object": "collection",
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listIndexes": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/listIndexNames.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/listIndexNames.json
new file mode 100644
index 0000000000000000000000000000000000000000..912c706015f96b957f1277d93f2f94abfeafe995
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/listIndexNames.json	
@@ -0,0 +1,155 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.0",
+      "topology": [
+        "single",
+        "replicaset"
+      ]
+    },
+    {
+      "minServerVersion": "4.1.7",
+      "topology": [
+        "sharded"
+      ]
+    }
+  ],
+  "database_name": "retryable-reads-tests",
+  "collection_name": "coll",
+  "data": [],
+  "tests": [
+    {
+      "description": "ListIndexNames succeeds on first attempt",
+      "operations": [
+        {
+          "name": "listIndexNames",
+          "object": "collection"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listIndexes": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListIndexNames succeeds on second attempt",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listIndexes"
+          ],
+          "closeConnection": true
+        }
+      },
+      "operations": [
+        {
+          "name": "listIndexNames",
+          "object": "collection"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listIndexes": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listIndexes": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListIndexNames fails on first attempt",
+      "clientOptions": {
+        "retryReads": false
+      },
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listIndexes"
+          ],
+          "closeConnection": true
+        }
+      },
+      "operations": [
+        {
+          "name": "listIndexNames",
+          "object": "collection",
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listIndexes": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListIndexNames fails on second attempt",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 2
+        },
+        "data": {
+          "failCommands": [
+            "listIndexes"
+          ],
+          "closeConnection": true
+        }
+      },
+      "operations": [
+        {
+          "name": "listIndexNames",
+          "object": "collection",
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listIndexes": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listIndexes": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/listIndexes-serverErrors.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/listIndexes-serverErrors.json
new file mode 100644
index 0000000000000000000000000000000000000000..16b61d535d62d04fee9cfec35710e17e38120a1f
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/listIndexes-serverErrors.json	
@@ -0,0 +1,526 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.0",
+      "topology": [
+        "single",
+        "replicaset"
+      ]
+    },
+    {
+      "minServerVersion": "4.1.7",
+      "topology": [
+        "sharded"
+      ]
+    }
+  ],
+  "database_name": "retryable-reads-tests",
+  "collection_name": "coll",
+  "data": [],
+  "tests": [
+    {
+      "description": "ListIndexes succeeds after InterruptedAtShutdown",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listIndexes"
+          ],
+          "errorCode": 11600
+        }
+      },
+      "operations": [
+        {
+          "name": "listIndexes",
+          "object": "collection"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listIndexes": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listIndexes": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListIndexes succeeds after InterruptedDueToReplStateChange",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listIndexes"
+          ],
+          "errorCode": 11602
+        }
+      },
+      "operations": [
+        {
+          "name": "listIndexes",
+          "object": "collection"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listIndexes": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listIndexes": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListIndexes succeeds after NotMaster",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listIndexes"
+          ],
+          "errorCode": 10107
+        }
+      },
+      "operations": [
+        {
+          "name": "listIndexes",
+          "object": "collection"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listIndexes": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listIndexes": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListIndexes succeeds after NotMasterNoSlaveOk",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listIndexes"
+          ],
+          "errorCode": 13435
+        }
+      },
+      "operations": [
+        {
+          "name": "listIndexes",
+          "object": "collection"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listIndexes": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listIndexes": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListIndexes succeeds after NotMasterOrSecondary",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listIndexes"
+          ],
+          "errorCode": 13436
+        }
+      },
+      "operations": [
+        {
+          "name": "listIndexes",
+          "object": "collection"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listIndexes": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listIndexes": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListIndexes succeeds after PrimarySteppedDown",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listIndexes"
+          ],
+          "errorCode": 189
+        }
+      },
+      "operations": [
+        {
+          "name": "listIndexes",
+          "object": "collection"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listIndexes": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listIndexes": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListIndexes succeeds after ShutdownInProgress",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listIndexes"
+          ],
+          "errorCode": 91
+        }
+      },
+      "operations": [
+        {
+          "name": "listIndexes",
+          "object": "collection"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listIndexes": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listIndexes": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListIndexes succeeds after HostNotFound",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listIndexes"
+          ],
+          "errorCode": 7
+        }
+      },
+      "operations": [
+        {
+          "name": "listIndexes",
+          "object": "collection"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listIndexes": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listIndexes": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListIndexes succeeds after HostUnreachable",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listIndexes"
+          ],
+          "errorCode": 6
+        }
+      },
+      "operations": [
+        {
+          "name": "listIndexes",
+          "object": "collection"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listIndexes": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listIndexes": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListIndexes succeeds after NetworkTimeout",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listIndexes"
+          ],
+          "errorCode": 89
+        }
+      },
+      "operations": [
+        {
+          "name": "listIndexes",
+          "object": "collection"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listIndexes": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listIndexes": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListIndexes succeeds after SocketException",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listIndexes"
+          ],
+          "errorCode": 9001
+        }
+      },
+      "operations": [
+        {
+          "name": "listIndexes",
+          "object": "collection"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listIndexes": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listIndexes": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListIndexes fails after two NotMaster errors",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 2
+        },
+        "data": {
+          "failCommands": [
+            "listIndexes"
+          ],
+          "errorCode": 10107
+        }
+      },
+      "operations": [
+        {
+          "name": "listIndexes",
+          "object": "collection",
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listIndexes": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listIndexes": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListIndexes fails after NotMaster when retryReads is false",
+      "clientOptions": {
+        "retryReads": false
+      },
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listIndexes"
+          ],
+          "errorCode": 10107
+        }
+      },
+      "operations": [
+        {
+          "name": "listIndexes",
+          "object": "collection",
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listIndexes": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/listIndexes.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/listIndexes.json
new file mode 100644
index 0000000000000000000000000000000000000000..f460ea7684fd8ba84549a69b5903bcf57c378cf7
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/listIndexes.json	
@@ -0,0 +1,155 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.0",
+      "topology": [
+        "single",
+        "replicaset"
+      ]
+    },
+    {
+      "minServerVersion": "4.1.7",
+      "topology": [
+        "sharded"
+      ]
+    }
+  ],
+  "database_name": "retryable-reads-tests",
+  "collection_name": "coll",
+  "data": [],
+  "tests": [
+    {
+      "description": "ListIndexes succeeds on first attempt",
+      "operations": [
+        {
+          "name": "listIndexes",
+          "object": "collection"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listIndexes": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListIndexes succeeds on second attempt",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listIndexes"
+          ],
+          "closeConnection": true
+        }
+      },
+      "operations": [
+        {
+          "name": "listIndexes",
+          "object": "collection"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listIndexes": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listIndexes": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListIndexes fails on first attempt",
+      "clientOptions": {
+        "retryReads": false
+      },
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "listIndexes"
+          ],
+          "closeConnection": true
+        }
+      },
+      "operations": [
+        {
+          "name": "listIndexes",
+          "object": "collection",
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listIndexes": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "ListIndexes fails on second attempt",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 2
+        },
+        "data": {
+          "failCommands": [
+            "listIndexes"
+          ],
+          "closeConnection": true
+        }
+      },
+      "operations": [
+        {
+          "name": "listIndexes",
+          "object": "collection",
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "listIndexes": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "listIndexes": "coll"
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/mapReduce.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/mapReduce.json
new file mode 100644
index 0000000000000000000000000000000000000000..3cb35fd49c5e4b0e0dc5633e23908836c387c89d
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-reads/mapReduce.json	
@@ -0,0 +1,187 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.0",
+      "topology": [
+        "single",
+        "replicaset"
+      ]
+    },
+    {
+      "minServerVersion": "4.1.7",
+      "topology": [
+        "sharded"
+      ]
+    }
+  ],
+  "database_name": "retryable-reads-tests",
+  "collection_name": "coll",
+  "data": [
+    {
+      "_id": 1,
+      "x": 0
+    },
+    {
+      "_id": 2,
+      "x": 1
+    },
+    {
+      "_id": 3,
+      "x": 2
+    }
+  ],
+  "tests": [
+    {
+      "description": "MapReduce succeeds with retry on",
+      "operations": [
+        {
+          "name": "mapReduce",
+          "object": "collection",
+          "arguments": {
+            "map": {
+              "$code": "function inc() { return emit(0, this.x + 1) }"
+            },
+            "reduce": {
+              "$code": "function sum(key, values) { return values.reduce((acc, x) => acc + x); }"
+            },
+            "out": {
+              "inline": 1
+            }
+          },
+          "result": [
+            {
+              "_id": 0.0,
+              "value": 6.0
+            }
+          ]
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "mapReduce": "coll",
+              "map": {
+                "$code": "function inc() { return emit(0, this.x + 1) }"
+              },
+              "reduce": {
+                "$code": "function sum(key, values) { return values.reduce((acc, x) => acc + x); }"
+              },
+              "out": {
+                "inline": 1
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "MapReduce fails with retry on",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "mapReduce"
+          ],
+          "closeConnection": true
+        }
+      },
+      "operations": [
+        {
+          "name": "mapReduce",
+          "object": "collection",
+          "arguments": {
+            "map": {
+              "$code": "function inc() { return emit(0, this.x + 1) }"
+            },
+            "reduce": {
+              "$code": "function sum(key, values) { return values.reduce((acc, x) => acc + x); }"
+            },
+            "out": {
+              "inline": 1
+            }
+          },
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "mapReduce": "coll",
+              "map": {
+                "$code": "function inc() { return emit(0, this.x + 1) }"
+              },
+              "reduce": {
+                "$code": "function sum(key, values) { return values.reduce((acc, x) => acc + x); }"
+              },
+              "out": {
+                "inline": 1
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    },
+    {
+      "description": "MapReduce fails with retry off",
+      "clientOptions": {
+        "retryReads": false
+      },
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "mapReduce"
+          ],
+          "closeConnection": true
+        }
+      },
+      "operations": [
+        {
+          "name": "mapReduce",
+          "object": "collection",
+          "arguments": {
+            "map": {
+              "$code": "function inc() { return emit(0, this.x + 1) }"
+            },
+            "reduce": {
+              "$code": "function sum(key, values) { return values.reduce((acc, x) => acc + x); }"
+            },
+            "out": {
+              "inline": 1
+            }
+          },
+          "error": true
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "mapReduce": "coll",
+              "map": {
+                "$code": "function inc() { return emit(0, this.x + 1) }"
+              },
+              "reduce": {
+                "$code": "function sum(key, values) { return values.reduce((acc, x) => acc + x); }"
+              },
+              "out": {
+                "inline": 1
+              }
+            },
+            "database_name": "retryable-reads-tests"
+          }
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-writes/bulkWrite-errorLabels.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-writes/bulkWrite-errorLabels.json
new file mode 100644
index 0000000000000000000000000000000000000000..94ea3ea989fb08769f54e54d0ed8502eb3450daf
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-writes/bulkWrite-errorLabels.json	
@@ -0,0 +1,182 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.3.1",
+      "topology": [
+        "replicaset",
+        "sharded"
+      ]
+    }
+  ],
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    }
+  ],
+  "tests": [
+    {
+      "description": "BulkWrite succeeds with RetryableWriteError from server",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "update"
+          ],
+          "errorCode": 112,
+          "errorLabels": [
+            "RetryableWriteError"
+          ]
+        }
+      },
+      "operation": {
+        "name": "bulkWrite",
+        "arguments": {
+          "requests": [
+            {
+              "name": "deleteOne",
+              "arguments": {
+                "filter": {
+                  "_id": 1
+                }
+              }
+            },
+            {
+              "name": "insertOne",
+              "arguments": {
+                "document": {
+                  "_id": 3,
+                  "x": 33
+                }
+              }
+            },
+            {
+              "name": "updateOne",
+              "arguments": {
+                "filter": {
+                  "_id": 2
+                },
+                "update": {
+                  "$inc": {
+                    "x": 1
+                  }
+                }
+              }
+            }
+          ],
+          "options": {
+            "ordered": true
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "deletedCount": 1,
+          "insertedCount": 1,
+          "insertedIds": {
+            "1": 3
+          },
+          "matchedCount": 1,
+          "modifiedCount": 1,
+          "upsertedCount": 0,
+          "upsertedIds": {}
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 2,
+              "x": 23
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "BulkWrite fails if server does not return RetryableWriteError",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "update"
+          ],
+          "errorCode": 11600,
+          "errorLabels": []
+        }
+      },
+      "operation": {
+        "name": "bulkWrite",
+        "arguments": {
+          "requests": [
+            {
+              "name": "deleteOne",
+              "arguments": {
+                "filter": {
+                  "_id": 1
+                }
+              }
+            },
+            {
+              "name": "insertOne",
+              "arguments": {
+                "document": {
+                  "_id": 3,
+                  "x": 33
+                }
+              }
+            },
+            {
+              "name": "updateOne",
+              "arguments": {
+                "filter": {
+                  "_id": 2
+                },
+                "update": {
+                  "$inc": {
+                    "x": 1
+                  }
+                }
+              }
+            }
+          ],
+          "options": {
+            "ordered": true
+          }
+        }
+      },
+      "outcome": {
+        "error": true,
+        "result": {
+          "errorLabelsOmit": [
+            "RetryableWriteError"
+          ]
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-writes/bulkWrite-serverErrors.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-writes/bulkWrite-serverErrors.json
new file mode 100644
index 0000000000000000000000000000000000000000..d9561d568c09a1e91ab6af980dcd899d226d3f64
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-writes/bulkWrite-serverErrors.json	
@@ -0,0 +1,272 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.0",
+      "topology": [
+        "replicaset"
+      ]
+    },
+    {
+      "minServerVersion": "4.1.7",
+      "topology": [
+        "sharded"
+      ]
+    }
+  ],
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    }
+  ],
+  "tests": [
+    {
+      "description": "BulkWrite succeeds after PrimarySteppedDown",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "update"
+          ],
+          "errorCode": 189,
+          "errorLabels": [
+            "RetryableWriteError"
+          ]
+        }
+      },
+      "operation": {
+        "name": "bulkWrite",
+        "arguments": {
+          "requests": [
+            {
+              "name": "deleteOne",
+              "arguments": {
+                "filter": {
+                  "_id": 1
+                }
+              }
+            },
+            {
+              "name": "insertOne",
+              "arguments": {
+                "document": {
+                  "_id": 3,
+                  "x": 33
+                }
+              }
+            },
+            {
+              "name": "updateOne",
+              "arguments": {
+                "filter": {
+                  "_id": 2
+                },
+                "update": {
+                  "$inc": {
+                    "x": 1
+                  }
+                }
+              }
+            }
+          ],
+          "options": {
+            "ordered": true
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "deletedCount": 1,
+          "insertedCount": 1,
+          "insertedIds": {
+            "1": 3
+          },
+          "matchedCount": 1,
+          "modifiedCount": 1,
+          "upsertedCount": 0,
+          "upsertedIds": {}
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 2,
+              "x": 23
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "BulkWrite succeeds after WriteConcernError ShutdownInProgress",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "insert"
+          ],
+          "writeConcernError": {
+            "code": 91,
+            "errmsg": "Replication is being shut down",
+            "errorLabels": [
+              "RetryableWriteError"
+            ]
+          }
+        }
+      },
+      "operation": {
+        "name": "bulkWrite",
+        "arguments": {
+          "requests": [
+            {
+              "name": "deleteOne",
+              "arguments": {
+                "filter": {
+                  "_id": 1
+                }
+              }
+            },
+            {
+              "name": "insertOne",
+              "arguments": {
+                "document": {
+                  "_id": 3,
+                  "x": 33
+                }
+              }
+            },
+            {
+              "name": "updateOne",
+              "arguments": {
+                "filter": {
+                  "_id": 2
+                },
+                "update": {
+                  "$inc": {
+                    "x": 1
+                  }
+                }
+              }
+            }
+          ],
+          "options": {
+            "ordered": true
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "deletedCount": 1,
+          "insertedCount": 1,
+          "insertedIds": {
+            "1": 3
+          },
+          "matchedCount": 1,
+          "modifiedCount": 1,
+          "upsertedCount": 0,
+          "upsertedIds": {}
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 2,
+              "x": 23
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "BulkWrite fails with a RetryableWriteError label after two connection failures",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 2
+        },
+        "data": {
+          "failCommands": [
+            "update"
+          ],
+          "closeConnection": true
+        }
+      },
+      "operation": {
+        "name": "bulkWrite",
+        "arguments": {
+          "requests": [
+            {
+              "name": "deleteOne",
+              "arguments": {
+                "filter": {
+                  "_id": 1
+                }
+              }
+            },
+            {
+              "name": "insertOne",
+              "arguments": {
+                "document": {
+                  "_id": 3,
+                  "x": 33
+                }
+              }
+            },
+            {
+              "name": "updateOne",
+              "arguments": {
+                "filter": {
+                  "_id": 2
+                },
+                "update": {
+                  "$inc": {
+                    "x": 1
+                  }
+                }
+              }
+            }
+          ],
+          "options": {
+            "ordered": true
+          }
+        }
+      },
+      "outcome": {
+        "error": true,
+        "result": {
+          "errorLabelsContain": [
+            "RetryableWriteError"
+          ]
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-writes/bulkWrite.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-writes/bulkWrite.json
new file mode 100644
index 0000000000000000000000000000000000000000..72a8d0189397b0d016f025088bdbc3908bc7a122
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-writes/bulkWrite.json	
@@ -0,0 +1,806 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "3.6",
+      "topology": [
+        "replicaset"
+      ]
+    }
+  ],
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    }
+  ],
+  "tests": [
+    {
+      "description": "First command is retried",
+      "failPoint": {
+        "configureFailPoint": "onPrimaryTransactionalWrite",
+        "mode": {
+          "times": 1
+        }
+      },
+      "operation": {
+        "name": "bulkWrite",
+        "arguments": {
+          "requests": [
+            {
+              "name": "insertOne",
+              "arguments": {
+                "document": {
+                  "_id": 2,
+                  "x": 22
+                }
+              }
+            },
+            {
+              "name": "updateOne",
+              "arguments": {
+                "filter": {
+                  "_id": 2
+                },
+                "update": {
+                  "$inc": {
+                    "x": 1
+                  }
+                }
+              }
+            },
+            {
+              "name": "deleteOne",
+              "arguments": {
+                "filter": {
+                  "_id": 1
+                }
+              }
+            }
+          ],
+          "options": {
+            "ordered": true
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "deletedCount": 1,
+          "insertedCount": 1,
+          "insertedIds": {
+            "0": 2
+          },
+          "matchedCount": 1,
+          "modifiedCount": 1,
+          "upsertedCount": 0,
+          "upsertedIds": {}
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 2,
+              "x": 23
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "All commands are retried",
+      "failPoint": {
+        "configureFailPoint": "onPrimaryTransactionalWrite",
+        "mode": {
+          "times": 7
+        }
+      },
+      "operation": {
+        "name": "bulkWrite",
+        "arguments": {
+          "requests": [
+            {
+              "name": "insertOne",
+              "arguments": {
+                "document": {
+                  "_id": 2,
+                  "x": 22
+                }
+              }
+            },
+            {
+              "name": "updateOne",
+              "arguments": {
+                "filter": {
+                  "_id": 2
+                },
+                "update": {
+                  "$inc": {
+                    "x": 1
+                  }
+                }
+              }
+            },
+            {
+              "name": "insertOne",
+              "arguments": {
+                "document": {
+                  "_id": 3,
+                  "x": 33
+                }
+              }
+            },
+            {
+              "name": "updateOne",
+              "arguments": {
+                "filter": {
+                  "_id": 4,
+                  "x": 44
+                },
+                "update": {
+                  "$inc": {
+                    "x": 1
+                  }
+                },
+                "upsert": true
+              }
+            },
+            {
+              "name": "insertOne",
+              "arguments": {
+                "document": {
+                  "_id": 5,
+                  "x": 55
+                }
+              }
+            },
+            {
+              "name": "replaceOne",
+              "arguments": {
+                "filter": {
+                  "_id": 3
+                },
+                "replacement": {
+                  "_id": 3,
+                  "x": 333
+                }
+              }
+            },
+            {
+              "name": "deleteOne",
+              "arguments": {
+                "filter": {
+                  "_id": 1
+                }
+              }
+            }
+          ],
+          "options": {
+            "ordered": true
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "deletedCount": 1,
+          "insertedCount": 3,
+          "insertedIds": {
+            "0": 2,
+            "2": 3,
+            "4": 5
+          },
+          "matchedCount": 2,
+          "modifiedCount": 2,
+          "upsertedCount": 1,
+          "upsertedIds": {
+            "3": 4
+          }
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 2,
+              "x": 23
+            },
+            {
+              "_id": 3,
+              "x": 333
+            },
+            {
+              "_id": 4,
+              "x": 45
+            },
+            {
+              "_id": 5,
+              "x": 55
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "Both commands are retried after their first statement fails",
+      "failPoint": {
+        "configureFailPoint": "onPrimaryTransactionalWrite",
+        "mode": {
+          "times": 2
+        }
+      },
+      "operation": {
+        "name": "bulkWrite",
+        "arguments": {
+          "requests": [
+            {
+              "name": "insertOne",
+              "arguments": {
+                "document": {
+                  "_id": 2,
+                  "x": 22
+                }
+              }
+            },
+            {
+              "name": "updateOne",
+              "arguments": {
+                "filter": {
+                  "_id": 1
+                },
+                "update": {
+                  "$inc": {
+                    "x": 1
+                  }
+                }
+              }
+            },
+            {
+              "name": "updateOne",
+              "arguments": {
+                "filter": {
+                  "_id": 2
+                },
+                "update": {
+                  "$inc": {
+                    "x": 1
+                  }
+                }
+              }
+            }
+          ],
+          "options": {
+            "ordered": true
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "deletedCount": 0,
+          "insertedCount": 1,
+          "insertedIds": {
+            "0": 2
+          },
+          "matchedCount": 2,
+          "modifiedCount": 2,
+          "upsertedCount": 0,
+          "upsertedIds": {}
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 12
+            },
+            {
+              "_id": 2,
+              "x": 23
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "Second command is retried after its second statement fails",
+      "failPoint": {
+        "configureFailPoint": "onPrimaryTransactionalWrite",
+        "mode": {
+          "skip": 2
+        }
+      },
+      "operation": {
+        "name": "bulkWrite",
+        "arguments": {
+          "requests": [
+            {
+              "name": "insertOne",
+              "arguments": {
+                "document": {
+                  "_id": 2,
+                  "x": 22
+                }
+              }
+            },
+            {
+              "name": "updateOne",
+              "arguments": {
+                "filter": {
+                  "_id": 1
+                },
+                "update": {
+                  "$inc": {
+                    "x": 1
+                  }
+                }
+              }
+            },
+            {
+              "name": "updateOne",
+              "arguments": {
+                "filter": {
+                  "_id": 2
+                },
+                "update": {
+                  "$inc": {
+                    "x": 1
+                  }
+                }
+              }
+            }
+          ],
+          "options": {
+            "ordered": true
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "deletedCount": 0,
+          "insertedCount": 1,
+          "insertedIds": {
+            "0": 2
+          },
+          "matchedCount": 2,
+          "modifiedCount": 2,
+          "upsertedCount": 0,
+          "upsertedIds": {}
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 12
+            },
+            {
+              "_id": 2,
+              "x": 23
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "BulkWrite with unordered execution",
+      "failPoint": {
+        "configureFailPoint": "onPrimaryTransactionalWrite",
+        "mode": {
+          "times": 1
+        }
+      },
+      "operation": {
+        "name": "bulkWrite",
+        "arguments": {
+          "requests": [
+            {
+              "name": "insertOne",
+              "arguments": {
+                "document": {
+                  "_id": 2,
+                  "x": 22
+                }
+              }
+            },
+            {
+              "name": "insertOne",
+              "arguments": {
+                "document": {
+                  "_id": 3,
+                  "x": 33
+                }
+              }
+            }
+          ],
+          "options": {
+            "ordered": false
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "deletedCount": 0,
+          "insertedCount": 2,
+          "insertedIds": {
+            "0": 2,
+            "1": 3
+          },
+          "matchedCount": 0,
+          "modifiedCount": 0,
+          "upsertedCount": 0,
+          "upsertedIds": {}
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "First insertOne is never committed",
+      "failPoint": {
+        "configureFailPoint": "onPrimaryTransactionalWrite",
+        "mode": {
+          "times": 2
+        },
+        "data": {
+          "failBeforeCommitExceptionCode": 1
+        }
+      },
+      "operation": {
+        "name": "bulkWrite",
+        "arguments": {
+          "requests": [
+            {
+              "name": "insertOne",
+              "arguments": {
+                "document": {
+                  "_id": 2,
+                  "x": 22
+                }
+              }
+            },
+            {
+              "name": "updateOne",
+              "arguments": {
+                "filter": {
+                  "_id": 2
+                },
+                "update": {
+                  "$inc": {
+                    "x": 1
+                  }
+                }
+              }
+            },
+            {
+              "name": "deleteOne",
+              "arguments": {
+                "filter": {
+                  "_id": 1
+                }
+              }
+            }
+          ],
+          "options": {
+            "ordered": true
+          }
+        }
+      },
+      "outcome": {
+        "error": true,
+        "result": {
+          "deletedCount": 0,
+          "insertedCount": 0,
+          "insertedIds": {},
+          "matchedCount": 0,
+          "modifiedCount": 0,
+          "upsertedCount": 0,
+          "upsertedIds": {}
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "Second updateOne is never committed",
+      "failPoint": {
+        "configureFailPoint": "onPrimaryTransactionalWrite",
+        "mode": {
+          "skip": 1
+        },
+        "data": {
+          "failBeforeCommitExceptionCode": 1
+        }
+      },
+      "operation": {
+        "name": "bulkWrite",
+        "arguments": {
+          "requests": [
+            {
+              "name": "insertOne",
+              "arguments": {
+                "document": {
+                  "_id": 2,
+                  "x": 22
+                }
+              }
+            },
+            {
+              "name": "updateOne",
+              "arguments": {
+                "filter": {
+                  "_id": 2
+                },
+                "update": {
+                  "$inc": {
+                    "x": 1
+                  }
+                }
+              }
+            },
+            {
+              "name": "deleteOne",
+              "arguments": {
+                "filter": {
+                  "_id": 1
+                }
+              }
+            }
+          ],
+          "options": {
+            "ordered": true
+          }
+        }
+      },
+      "outcome": {
+        "error": true,
+        "result": {
+          "deletedCount": 0,
+          "insertedCount": 1,
+          "insertedIds": {
+            "0": 2
+          },
+          "matchedCount": 0,
+          "modifiedCount": 0,
+          "upsertedCount": 0,
+          "upsertedIds": {}
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "Third updateOne is never committed",
+      "failPoint": {
+        "configureFailPoint": "onPrimaryTransactionalWrite",
+        "mode": {
+          "skip": 2
+        },
+        "data": {
+          "failBeforeCommitExceptionCode": 1
+        }
+      },
+      "operation": {
+        "name": "bulkWrite",
+        "arguments": {
+          "requests": [
+            {
+              "name": "updateOne",
+              "arguments": {
+                "filter": {
+                  "_id": 1
+                },
+                "update": {
+                  "$inc": {
+                    "x": 1
+                  }
+                }
+              }
+            },
+            {
+              "name": "insertOne",
+              "arguments": {
+                "document": {
+                  "_id": 2,
+                  "x": 22
+                }
+              }
+            },
+            {
+              "name": "updateOne",
+              "arguments": {
+                "filter": {
+                  "_id": 2
+                },
+                "update": {
+                  "$inc": {
+                    "x": 1
+                  }
+                }
+              }
+            }
+          ],
+          "options": {
+            "ordered": true
+          }
+        }
+      },
+      "outcome": {
+        "error": true,
+        "result": {
+          "deletedCount": 0,
+          "insertedCount": 1,
+          "insertedIds": {
+            "1": 2
+          },
+          "matchedCount": 1,
+          "modifiedCount": 1,
+          "upsertedCount": 0,
+          "upsertedIds": {}
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 12
+            },
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "Single-document write following deleteMany is retried",
+      "failPoint": {
+        "configureFailPoint": "onPrimaryTransactionalWrite",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failBeforeCommitExceptionCode": 1
+        }
+      },
+      "operation": {
+        "name": "bulkWrite",
+        "arguments": {
+          "requests": [
+            {
+              "name": "deleteMany",
+              "arguments": {
+                "filter": {
+                  "x": 11
+                }
+              }
+            },
+            {
+              "name": "insertOne",
+              "arguments": {
+                "document": {
+                  "_id": 2,
+                  "x": 22
+                }
+              }
+            }
+          ],
+          "options": {
+            "ordered": true
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "deletedCount": 1,
+          "insertedCount": 1,
+          "insertedIds": {
+            "1": 2
+          },
+          "matchedCount": 0,
+          "modifiedCount": 0,
+          "upsertedCount": 0,
+          "upsertedIds": {}
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "Single-document write following updateMany is retried",
+      "failPoint": {
+        "configureFailPoint": "onPrimaryTransactionalWrite",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failBeforeCommitExceptionCode": 1
+        }
+      },
+      "operation": {
+        "name": "bulkWrite",
+        "arguments": {
+          "requests": [
+            {
+              "name": "updateMany",
+              "arguments": {
+                "filter": {
+                  "x": 11
+                },
+                "update": {
+                  "$inc": {
+                    "x": 1
+                  }
+                }
+              }
+            },
+            {
+              "name": "insertOne",
+              "arguments": {
+                "document": {
+                  "_id": 2,
+                  "x": 22
+                }
+              }
+            }
+          ],
+          "options": {
+            "ordered": true
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "deletedCount": 0,
+          "insertedCount": 1,
+          "insertedIds": {
+            "1": 2
+          },
+          "matchedCount": 1,
+          "modifiedCount": 1,
+          "upsertedCount": 0,
+          "upsertedIds": {}
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 12
+            },
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-writes/deleteMany.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-writes/deleteMany.json
new file mode 100644
index 0000000000000000000000000000000000000000..642ad11fb47fe27c9c6348a6c4ab99456aff9d31
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-writes/deleteMany.json	
@@ -0,0 +1,41 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "3.6",
+      "topology": [
+        "replicaset",
+        "sharded"
+      ]
+    }
+  ],
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    }
+  ],
+  "tests": [
+    {
+      "description": "DeleteMany ignores retryWrites",
+      "useMultipleMongoses": true,
+      "operation": {
+        "name": "deleteMany",
+        "arguments": {
+          "filter": {}
+        }
+      },
+      "outcome": {
+        "result": {
+          "deletedCount": 2
+        },
+        "collection": {
+          "data": []
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-writes/deleteOne-errorLabels.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-writes/deleteOne-errorLabels.json
new file mode 100644
index 0000000000000000000000000000000000000000..bff02e1f94dcf944c690a33108f3e48d1a9267f1
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-writes/deleteOne-errorLabels.json	
@@ -0,0 +1,106 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.3.1",
+      "topology": [
+        "replicaset",
+        "sharded"
+      ]
+    }
+  ],
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    }
+  ],
+  "tests": [
+    {
+      "description": "DeleteOne succeeds with RetryableWriteError from server",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "delete"
+          ],
+          "errorCode": 112,
+          "errorLabels": [
+            "RetryableWriteError"
+          ]
+        }
+      },
+      "operation": {
+        "name": "deleteOne",
+        "arguments": {
+          "filter": {
+            "_id": 1
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "deletedCount": 1
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "DeleteOne fails if server does not return RetryableWriteError",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "delete"
+          ],
+          "errorCode": 11600,
+          "errorLabels": []
+        }
+      },
+      "operation": {
+        "name": "deleteOne",
+        "arguments": {
+          "filter": {
+            "_id": 1
+          }
+        }
+      },
+      "outcome": {
+        "error": true,
+        "result": {
+          "errorLabelsOmit": [
+            "RetryableWriteError"
+          ]
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-writes/deleteOne-serverErrors.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-writes/deleteOne-serverErrors.json
new file mode 100644
index 0000000000000000000000000000000000000000..69d225759c41e94def7422e3f2c6275a596223dc
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-writes/deleteOne-serverErrors.json	
@@ -0,0 +1,152 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.0",
+      "topology": [
+        "replicaset"
+      ]
+    },
+    {
+      "minServerVersion": "4.1.7",
+      "topology": [
+        "sharded"
+      ]
+    }
+  ],
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    }
+  ],
+  "tests": [
+    {
+      "description": "DeleteOne succeeds after PrimarySteppedDown",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "delete"
+          ],
+          "errorCode": 189,
+          "errorLabels": [
+            "RetryableWriteError"
+          ]
+        }
+      },
+      "operation": {
+        "name": "deleteOne",
+        "arguments": {
+          "filter": {
+            "_id": 1
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "deletedCount": 1
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "DeleteOne succeeds after WriteConcernError ShutdownInProgress",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "delete"
+          ],
+          "writeConcernError": {
+            "code": 91,
+            "errmsg": "Replication is being shut down",
+            "errorLabels": [
+              "RetryableWriteError"
+            ]
+          }
+        }
+      },
+      "operation": {
+        "name": "deleteOne",
+        "arguments": {
+          "filter": {
+            "_id": 1
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "deletedCount": 1
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "DeleteOne fails with RetryableWriteError label after two connection failures",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 2
+        },
+        "data": {
+          "failCommands": [
+            "delete"
+          ],
+          "closeConnection": true
+        }
+      },
+      "operation": {
+        "name": "deleteOne",
+        "arguments": {
+          "filter": {
+            "_id": 1
+          }
+        }
+      },
+      "outcome": {
+        "error": true,
+        "result": {
+          "errorLabelsContain": [
+            "RetryableWriteError"
+          ]
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-writes/deleteOne.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-writes/deleteOne.json
new file mode 100644
index 0000000000000000000000000000000000000000..592937acedd50938c6efffafcce00929237e647f
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-writes/deleteOne.json	
@@ -0,0 +1,120 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "3.6",
+      "topology": [
+        "replicaset"
+      ]
+    }
+  ],
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    }
+  ],
+  "tests": [
+    {
+      "description": "DeleteOne is committed on first attempt",
+      "failPoint": {
+        "configureFailPoint": "onPrimaryTransactionalWrite",
+        "mode": {
+          "times": 1
+        }
+      },
+      "operation": {
+        "name": "deleteOne",
+        "arguments": {
+          "filter": {
+            "_id": 1
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "deletedCount": 1
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "DeleteOne is not committed on first attempt",
+      "failPoint": {
+        "configureFailPoint": "onPrimaryTransactionalWrite",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failBeforeCommitExceptionCode": 1
+        }
+      },
+      "operation": {
+        "name": "deleteOne",
+        "arguments": {
+          "filter": {
+            "_id": 1
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "deletedCount": 1
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "DeleteOne is never committed",
+      "failPoint": {
+        "configureFailPoint": "onPrimaryTransactionalWrite",
+        "mode": {
+          "times": 2
+        },
+        "data": {
+          "failBeforeCommitExceptionCode": 1
+        }
+      },
+      "operation": {
+        "name": "deleteOne",
+        "arguments": {
+          "filter": {
+            "_id": 1
+          }
+        }
+      },
+      "outcome": {
+        "error": true,
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-writes/findOneAndDelete-errorLabels.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-writes/findOneAndDelete-errorLabels.json
new file mode 100644
index 0000000000000000000000000000000000000000..efa62dba2e6628ad17ad796bdafc0ab1bb66eb8b
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-writes/findOneAndDelete-errorLabels.json	
@@ -0,0 +1,117 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.3.1",
+      "topology": [
+        "replicaset",
+        "sharded"
+      ]
+    }
+  ],
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    }
+  ],
+  "tests": [
+    {
+      "description": "FindOneAndDelete succeeds with RetryableWriteError from server",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "findAndModify"
+          ],
+          "errorCode": 112,
+          "errorLabels": [
+            "RetryableWriteError"
+          ]
+        }
+      },
+      "operation": {
+        "name": "findOneAndDelete",
+        "arguments": {
+          "filter": {
+            "x": {
+              "$gte": 11
+            }
+          },
+          "sort": {
+            "x": 1
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "_id": 1,
+          "x": 11
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "FindOneAndDelete fails if server does not return RetryableWriteError",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "findAndModify"
+          ],
+          "errorCode": 11600,
+          "errorLabels": []
+        }
+      },
+      "operation": {
+        "name": "findOneAndDelete",
+        "arguments": {
+          "filter": {
+            "x": {
+              "$gte": 11
+            }
+          },
+          "sort": {
+            "x": 1
+          }
+        }
+      },
+      "outcome": {
+        "error": true,
+        "result": {
+          "errorLabelsOmit": [
+            "RetryableWriteError"
+          ]
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-writes/findOneAndDelete-serverErrors.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-writes/findOneAndDelete-serverErrors.json
new file mode 100644
index 0000000000000000000000000000000000000000..0785e5d035c24a06f32a6b153e0727b0a6632176
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-writes/findOneAndDelete-serverErrors.json	
@@ -0,0 +1,169 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.0",
+      "topology": [
+        "replicaset"
+      ]
+    },
+    {
+      "minServerVersion": "4.1.7",
+      "topology": [
+        "sharded"
+      ]
+    }
+  ],
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    }
+  ],
+  "tests": [
+    {
+      "description": "FindOneAndDelete succeeds after PrimarySteppedDown",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "findAndModify"
+          ],
+          "errorCode": 189,
+          "errorLabels": [
+            "RetryableWriteError"
+          ]
+        }
+      },
+      "operation": {
+        "name": "findOneAndDelete",
+        "arguments": {
+          "filter": {
+            "x": {
+              "$gte": 11
+            }
+          },
+          "sort": {
+            "x": 1
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "_id": 1,
+          "x": 11
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "FindOneAndDelete succeeds after WriteConcernError ShutdownInProgress",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "findAndModify"
+          ],
+          "writeConcernError": {
+            "code": 91,
+            "errmsg": "Replication is being shut down",
+            "errorLabels": [
+              "RetryableWriteError"
+            ]
+          }
+        }
+      },
+      "operation": {
+        "name": "findOneAndDelete",
+        "arguments": {
+          "filter": {
+            "x": {
+              "$gte": 11
+            }
+          },
+          "sort": {
+            "x": 1
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "_id": 1,
+          "x": 11
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "FindOneAndDelete fails with a RetryableWriteError label after two connection failures",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 2
+        },
+        "data": {
+          "failCommands": [
+            "findAndModify"
+          ],
+          "closeConnection": true
+        }
+      },
+      "operation": {
+        "name": "findOneAndDelete",
+        "arguments": {
+          "filter": {
+            "x": {
+              "$gte": 11
+            }
+          },
+          "sort": {
+            "x": 1
+          }
+        }
+      },
+      "outcome": {
+        "error": true,
+        "result": {
+          "errorLabelsContain": [
+            "RetryableWriteError"
+          ]
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-writes/findOneAndDelete.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-writes/findOneAndDelete.json
new file mode 100644
index 0000000000000000000000000000000000000000..0cbe18108bd2a8df10d6482f9a7f47e99c620cf6
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-writes/findOneAndDelete.json	
@@ -0,0 +1,137 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "3.6",
+      "topology": [
+        "replicaset"
+      ]
+    }
+  ],
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    }
+  ],
+  "tests": [
+    {
+      "description": "FindOneAndDelete is committed on first attempt",
+      "failPoint": {
+        "configureFailPoint": "onPrimaryTransactionalWrite",
+        "mode": {
+          "times": 1
+        }
+      },
+      "operation": {
+        "name": "findOneAndDelete",
+        "arguments": {
+          "filter": {
+            "x": {
+              "$gte": 11
+            }
+          },
+          "sort": {
+            "x": 1
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "_id": 1,
+          "x": 11
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "FindOneAndDelete is not committed on first attempt",
+      "failPoint": {
+        "configureFailPoint": "onPrimaryTransactionalWrite",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failBeforeCommitExceptionCode": 1
+        }
+      },
+      "operation": {
+        "name": "findOneAndDelete",
+        "arguments": {
+          "filter": {
+            "x": {
+              "$gte": 11
+            }
+          },
+          "sort": {
+            "x": 1
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "_id": 1,
+          "x": 11
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "FindOneAndDelete is never committed",
+      "failPoint": {
+        "configureFailPoint": "onPrimaryTransactionalWrite",
+        "mode": {
+          "times": 2
+        },
+        "data": {
+          "failBeforeCommitExceptionCode": 1
+        }
+      },
+      "operation": {
+        "name": "findOneAndDelete",
+        "arguments": {
+          "filter": {
+            "x": {
+              "$gte": 11
+            }
+          },
+          "sort": {
+            "x": 1
+          }
+        }
+      },
+      "outcome": {
+        "error": true,
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-writes/findOneAndReplace-errorLabels.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-writes/findOneAndReplace-errorLabels.json
new file mode 100644
index 0000000000000000000000000000000000000000..d9473d139a0a3913da84e94e4f1dfca9d69754a5
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-writes/findOneAndReplace-errorLabels.json	
@@ -0,0 +1,121 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.3.1",
+      "topology": [
+        "replicaset",
+        "sharded"
+      ]
+    }
+  ],
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    }
+  ],
+  "tests": [
+    {
+      "description": "FindOneAndReplace succeeds with RetryableWriteError from server",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "findAndModify"
+          ],
+          "errorCode": 112,
+          "errorLabels": [
+            "RetryableWriteError"
+          ]
+        }
+      },
+      "operation": {
+        "name": "findOneAndReplace",
+        "arguments": {
+          "filter": {
+            "_id": 1
+          },
+          "replacement": {
+            "_id": 1,
+            "x": 111
+          },
+          "returnDocument": "Before"
+        }
+      },
+      "outcome": {
+        "result": {
+          "_id": 1,
+          "x": 11
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 111
+            },
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "FindOneAndReplace fails if server does not return RetryableWriteError",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "findAndModify"
+          ],
+          "errorCode": 11600,
+          "errorLabels": []
+        }
+      },
+      "operation": {
+        "name": "findOneAndReplace",
+        "arguments": {
+          "filter": {
+            "_id": 1
+          },
+          "replacement": {
+            "_id": 1,
+            "x": 111
+          },
+          "returnDocument": "Before"
+        }
+      },
+      "outcome": {
+        "error": true,
+        "result": {
+          "errorLabelsOmit": [
+            "RetryableWriteError"
+          ]
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-writes/findOneAndReplace-serverErrors.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-writes/findOneAndReplace-serverErrors.json
new file mode 100644
index 0000000000000000000000000000000000000000..6ebe057cfd43a8f0546b4ddb94db85277ae0c1a2
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-writes/findOneAndReplace-serverErrors.json	
@@ -0,0 +1,177 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.0",
+      "topology": [
+        "replicaset"
+      ]
+    },
+    {
+      "minServerVersion": "4.1.7",
+      "topology": [
+        "sharded"
+      ]
+    }
+  ],
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    }
+  ],
+  "tests": [
+    {
+      "description": "FindOneAndReplace succeeds after PrimarySteppedDown",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "findAndModify"
+          ],
+          "errorCode": 189,
+          "errorLabels": [
+            "RetryableWriteError"
+          ]
+        }
+      },
+      "operation": {
+        "name": "findOneAndReplace",
+        "arguments": {
+          "filter": {
+            "_id": 1
+          },
+          "replacement": {
+            "_id": 1,
+            "x": 111
+          },
+          "returnDocument": "Before"
+        }
+      },
+      "outcome": {
+        "result": {
+          "_id": 1,
+          "x": 11
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 111
+            },
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "FindOneAndReplace succeeds after WriteConcernError ShutdownInProgress",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "findAndModify"
+          ],
+          "writeConcernError": {
+            "code": 91,
+            "errmsg": "Replication is being shut down",
+            "errorLabels": [
+              "RetryableWriteError"
+            ]
+          }
+        }
+      },
+      "operation": {
+        "name": "findOneAndReplace",
+        "arguments": {
+          "filter": {
+            "_id": 1
+          },
+          "replacement": {
+            "_id": 1,
+            "x": 111
+          },
+          "returnDocument": "Before"
+        }
+      },
+      "outcome": {
+        "result": {
+          "_id": 1,
+          "x": 11
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 111
+            },
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "FindOneAndReplace fails with a RetryableWriteError label after two connection failures",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 2
+        },
+        "data": {
+          "failCommands": [
+            "findAndModify"
+          ],
+          "closeConnection": true
+        }
+      },
+      "operation": {
+        "name": "findOneAndReplace",
+        "arguments": {
+          "filter": {
+            "_id": 1
+          },
+          "replacement": {
+            "_id": 1,
+            "x": 111
+          },
+          "returnDocument": "Before"
+        }
+      },
+      "outcome": {
+        "error": true,
+        "result": {
+          "errorLabelsContain": [
+            "RetryableWriteError"
+          ]
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-writes/findOneAndReplace.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-writes/findOneAndReplace.json
new file mode 100644
index 0000000000000000000000000000000000000000..e1f9ab7f8c345a7d73f41b5a487498de84d958b4
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-writes/findOneAndReplace.json	
@@ -0,0 +1,145 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "3.6",
+      "topology": [
+        "replicaset"
+      ]
+    }
+  ],
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    }
+  ],
+  "tests": [
+    {
+      "description": "FindOneAndReplace is committed on first attempt",
+      "failPoint": {
+        "configureFailPoint": "onPrimaryTransactionalWrite",
+        "mode": {
+          "times": 1
+        }
+      },
+      "operation": {
+        "name": "findOneAndReplace",
+        "arguments": {
+          "filter": {
+            "_id": 1
+          },
+          "replacement": {
+            "_id": 1,
+            "x": 111
+          },
+          "returnDocument": "Before"
+        }
+      },
+      "outcome": {
+        "result": {
+          "_id": 1,
+          "x": 11
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 111
+            },
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "FindOneAndReplace is not committed on first attempt",
+      "failPoint": {
+        "configureFailPoint": "onPrimaryTransactionalWrite",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failBeforeCommitExceptionCode": 1
+        }
+      },
+      "operation": {
+        "name": "findOneAndReplace",
+        "arguments": {
+          "filter": {
+            "_id": 1
+          },
+          "replacement": {
+            "_id": 1,
+            "x": 111
+          },
+          "returnDocument": "Before"
+        }
+      },
+      "outcome": {
+        "result": {
+          "_id": 1,
+          "x": 11
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 111
+            },
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "FindOneAndReplace is never committed",
+      "failPoint": {
+        "configureFailPoint": "onPrimaryTransactionalWrite",
+        "mode": {
+          "times": 2
+        },
+        "data": {
+          "failBeforeCommitExceptionCode": 1
+        }
+      },
+      "operation": {
+        "name": "findOneAndReplace",
+        "arguments": {
+          "filter": {
+            "_id": 1
+          },
+          "replacement": {
+            "_id": 1,
+            "x": 111
+          },
+          "returnDocument": "Before"
+        }
+      },
+      "outcome": {
+        "error": true,
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-writes/findOneAndUpdate-errorLabels.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-writes/findOneAndUpdate-errorLabels.json
new file mode 100644
index 0000000000000000000000000000000000000000..1926d7fa5c319d5bd957d4552abbe7dca48d3d1d
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-writes/findOneAndUpdate-errorLabels.json	
@@ -0,0 +1,123 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.3.1",
+      "topology": [
+        "replicaset",
+        "sharded"
+      ]
+    }
+  ],
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    }
+  ],
+  "tests": [
+    {
+      "description": "FindOneAndUpdate succeeds with RetryableWriteError from server",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "findAndModify"
+          ],
+          "errorCode": 112,
+          "errorLabels": [
+            "RetryableWriteError"
+          ]
+        }
+      },
+      "operation": {
+        "name": "findOneAndUpdate",
+        "arguments": {
+          "filter": {
+            "_id": 1
+          },
+          "update": {
+            "$inc": {
+              "x": 1
+            }
+          },
+          "returnDocument": "Before"
+        }
+      },
+      "outcome": {
+        "result": {
+          "_id": 1,
+          "x": 11
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 12
+            },
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "FindOneAndUpdate fails if server does not return RetryableWriteError",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "findAndModify"
+          ],
+          "errorCode": 11600,
+          "errorLabels": []
+        }
+      },
+      "operation": {
+        "name": "findOneAndUpdate",
+        "arguments": {
+          "filter": {
+            "_id": 1
+          },
+          "update": {
+            "$inc": {
+              "x": 1
+            }
+          },
+          "returnDocument": "Before"
+        }
+      },
+      "outcome": {
+        "error": true,
+        "result": {
+          "errorLabelsOmit": [
+            "RetryableWriteError"
+          ]
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-writes/findOneAndUpdate-serverErrors.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-writes/findOneAndUpdate-serverErrors.json
new file mode 100644
index 0000000000000000000000000000000000000000..e6e369c13934ed3225bf9c89dd86fdee595d4004
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-writes/findOneAndUpdate-serverErrors.json	
@@ -0,0 +1,180 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.0",
+      "topology": [
+        "replicaset"
+      ]
+    },
+    {
+      "minServerVersion": "4.1.7",
+      "topology": [
+        "sharded"
+      ]
+    }
+  ],
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    }
+  ],
+  "tests": [
+    {
+      "description": "FindOneAndUpdate succeeds after PrimarySteppedDown",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "findAndModify"
+          ],
+          "errorCode": 189,
+          "errorLabels": [
+            "RetryableWriteError"
+          ]
+        }
+      },
+      "operation": {
+        "name": "findOneAndUpdate",
+        "arguments": {
+          "filter": {
+            "_id": 1
+          },
+          "update": {
+            "$inc": {
+              "x": 1
+            }
+          },
+          "returnDocument": "Before"
+        }
+      },
+      "outcome": {
+        "result": {
+          "_id": 1,
+          "x": 11
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 12
+            },
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "FindOneAndUpdate succeeds after WriteConcernError ShutdownInProgress",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "findAndModify"
+          ],
+          "writeConcernError": {
+            "code": 91,
+            "errmsg": "Replication is being shut down",
+            "errorLabels": [
+              "RetryableWriteError"
+            ]
+          }
+        }
+      },
+      "operation": {
+        "name": "findOneAndUpdate",
+        "arguments": {
+          "filter": {
+            "_id": 1
+          },
+          "update": {
+            "$inc": {
+              "x": 1
+            }
+          },
+          "returnDocument": "Before"
+        }
+      },
+      "outcome": {
+        "result": {
+          "_id": 1,
+          "x": 11
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 12
+            },
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "FindOneAndUpdate fails with a RetryableWriteError label after two connection failures",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 2
+        },
+        "data": {
+          "failCommands": [
+            "findAndModify"
+          ],
+          "closeConnection": true
+        }
+      },
+      "operation": {
+        "name": "findOneAndUpdate",
+        "arguments": {
+          "filter": {
+            "_id": 1
+          },
+          "update": {
+            "$inc": {
+              "x": 1
+            }
+          },
+          "returnDocument": "Before"
+        }
+      },
+      "outcome": {
+        "error": true,
+        "result": {
+          "errorLabelsContain": [
+            "RetryableWriteError"
+          ]
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-writes/findOneAndUpdate.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-writes/findOneAndUpdate.json
new file mode 100644
index 0000000000000000000000000000000000000000..9ae2d87d82103d19530c5505dd8e0b39f8261287
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-writes/findOneAndUpdate.json	
@@ -0,0 +1,147 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "3.6",
+      "topology": [
+        "replicaset"
+      ]
+    }
+  ],
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    }
+  ],
+  "tests": [
+    {
+      "description": "FindOneAndUpdate is committed on first attempt",
+      "failPoint": {
+        "configureFailPoint": "onPrimaryTransactionalWrite",
+        "mode": {
+          "times": 1
+        }
+      },
+      "operation": {
+        "name": "findOneAndUpdate",
+        "arguments": {
+          "filter": {
+            "_id": 1
+          },
+          "update": {
+            "$inc": {
+              "x": 1
+            }
+          },
+          "returnDocument": "Before"
+        }
+      },
+      "outcome": {
+        "result": {
+          "_id": 1,
+          "x": 11
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 12
+            },
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "FindOneAndUpdate is not committed on first attempt",
+      "failPoint": {
+        "configureFailPoint": "onPrimaryTransactionalWrite",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failBeforeCommitExceptionCode": 1
+        }
+      },
+      "operation": {
+        "name": "findOneAndUpdate",
+        "arguments": {
+          "filter": {
+            "_id": 1
+          },
+          "update": {
+            "$inc": {
+              "x": 1
+            }
+          },
+          "returnDocument": "Before"
+        }
+      },
+      "outcome": {
+        "result": {
+          "_id": 1,
+          "x": 11
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 12
+            },
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "FindOneAndUpdate is never committed",
+      "failPoint": {
+        "configureFailPoint": "onPrimaryTransactionalWrite",
+        "mode": {
+          "times": 2
+        },
+        "data": {
+          "failBeforeCommitExceptionCode": 1
+        }
+      },
+      "operation": {
+        "name": "findOneAndUpdate",
+        "arguments": {
+          "filter": {
+            "_id": 1
+          },
+          "update": {
+            "$inc": {
+              "x": 1
+            }
+          }
+        }
+      },
+      "outcome": {
+        "error": true,
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-writes/insertMany-errorLabels.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-writes/insertMany-errorLabels.json
new file mode 100644
index 0000000000000000000000000000000000000000..c78946e90a369cb124d9856e38301856f5a463e8
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-writes/insertMany-errorLabels.json	
@@ -0,0 +1,129 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.3.1",
+      "topology": [
+        "replicaset",
+        "sharded"
+      ]
+    }
+  ],
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    }
+  ],
+  "tests": [
+    {
+      "description": "InsertMany succeeds with RetryableWriteError from server",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "insert"
+          ],
+          "errorCode": 112,
+          "errorLabels": [
+            "RetryableWriteError"
+          ]
+        }
+      },
+      "operation": {
+        "name": "insertMany",
+        "arguments": {
+          "documents": [
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ],
+          "options": {
+            "ordered": true
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "insertedIds": {
+            "0": 2,
+            "1": 3
+          }
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "InsertMany fails if server does not return RetryableWriteError",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "insert"
+          ],
+          "errorCode": 11600,
+          "errorLabels": []
+        }
+      },
+      "operation": {
+        "name": "insertMany",
+        "arguments": {
+          "documents": [
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ],
+          "options": {
+            "ordered": true
+          }
+        }
+      },
+      "outcome": {
+        "error": true,
+        "result": {
+          "errorLabelsOmit": [
+            "RetryableWriteError"
+          ]
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-writes/insertMany-serverErrors.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-writes/insertMany-serverErrors.json
new file mode 100644
index 0000000000000000000000000000000000000000..1c6ebafc28b2b3ece4681557c865f2560d433ec3
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-writes/insertMany-serverErrors.json	
@@ -0,0 +1,196 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.0",
+      "topology": [
+        "replicaset"
+      ]
+    },
+    {
+      "minServerVersion": "4.1.7",
+      "topology": [
+        "sharded"
+      ]
+    }
+  ],
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    }
+  ],
+  "tests": [
+    {
+      "description": "InsertMany succeeds after PrimarySteppedDown",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "insert"
+          ],
+          "errorCode": 189,
+          "errorLabels": [
+            "RetryableWriteError"
+          ]
+        }
+      },
+      "operation": {
+        "name": "insertMany",
+        "arguments": {
+          "documents": [
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ],
+          "options": {
+            "ordered": true
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "insertedIds": {
+            "0": 2,
+            "1": 3
+          }
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "InsertMany succeeds after WriteConcernError ShutdownInProgress",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "insert"
+          ],
+          "writeConcernError": {
+            "code": 91,
+            "errmsg": "Replication is being shut down",
+            "errorLabels": [
+              "RetryableWriteError"
+            ]
+          }
+        }
+      },
+      "operation": {
+        "name": "insertMany",
+        "arguments": {
+          "documents": [
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ],
+          "options": {
+            "ordered": true
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "insertedIds": {
+            "0": 2,
+            "1": 3
+          }
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "InsertMany fails with a RetryableWriteError label after two connection failures",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 2
+        },
+        "data": {
+          "failCommands": [
+            "insert"
+          ],
+          "closeConnection": true
+        }
+      },
+      "operation": {
+        "name": "insertMany",
+        "arguments": {
+          "documents": [
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ],
+          "options": {
+            "ordered": true
+          }
+        }
+      },
+      "outcome": {
+        "error": true,
+        "result": {
+          "errorLabelsContain": [
+            "RetryableWriteError"
+          ]
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-writes/insertMany.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-writes/insertMany.json
new file mode 100644
index 0000000000000000000000000000000000000000..0ad326e2dc9ac6f16b2b3f11e16d063f909c6601
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-writes/insertMany.json	
@@ -0,0 +1,163 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "3.6",
+      "topology": [
+        "replicaset"
+      ]
+    }
+  ],
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    }
+  ],
+  "tests": [
+    {
+      "description": "InsertMany succeeds after one network error",
+      "failPoint": {
+        "configureFailPoint": "onPrimaryTransactionalWrite",
+        "mode": {
+          "times": 1
+        }
+      },
+      "operation": {
+        "name": "insertMany",
+        "arguments": {
+          "documents": [
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ],
+          "options": {
+            "ordered": true
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "insertedIds": {
+            "0": 2,
+            "1": 3
+          }
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "InsertMany with unordered execution",
+      "failPoint": {
+        "configureFailPoint": "onPrimaryTransactionalWrite",
+        "mode": {
+          "times": 1
+        }
+      },
+      "operation": {
+        "name": "insertMany",
+        "arguments": {
+          "documents": [
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ],
+          "options": {
+            "ordered": false
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "insertedIds": {
+            "0": 2,
+            "1": 3
+          }
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "InsertMany fails after multiple network errors",
+      "failPoint": {
+        "configureFailPoint": "onPrimaryTransactionalWrite",
+        "mode": "alwaysOn",
+        "data": {
+          "failBeforeCommitExceptionCode": 1
+        }
+      },
+      "operation": {
+        "name": "insertMany",
+        "arguments": {
+          "documents": [
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            },
+            {
+              "_id": 4,
+              "x": 44
+            }
+          ],
+          "options": {
+            "ordered": true
+          }
+        }
+      },
+      "outcome": {
+        "error": true,
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-writes/insertOne-errorLabels.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-writes/insertOne-errorLabels.json
new file mode 100644
index 0000000000000000000000000000000000000000..9b8d13d5240165a19219bd507feca67f0f8e693d
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-writes/insertOne-errorLabels.json	
@@ -0,0 +1,90 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.3.1",
+      "topology": [
+        "replicaset",
+        "sharded"
+      ]
+    }
+  ],
+  "data": [],
+  "tests": [
+    {
+      "description": "InsertOne succeeds with RetryableWriteError from server",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "insert"
+          ],
+          "errorCode": 112,
+          "errorLabels": [
+            "RetryableWriteError"
+          ]
+        }
+      },
+      "operation": {
+        "name": "insertOne",
+        "arguments": {
+          "document": {
+            "_id": 1,
+            "x": 11
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "insertedId": 1
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "InsertOne fails if server does not return RetryableWriteError",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "insert"
+          ],
+          "errorCode": 11600,
+          "errorLabels": []
+        }
+      },
+      "operation": {
+        "name": "insertOne",
+        "arguments": {
+          "document": {
+            "_id": 1,
+            "x": 11
+          }
+        }
+      },
+      "outcome": {
+        "error": true,
+        "result": {
+          "errorLabelsOmit": [
+            "RetryableWriteError"
+          ]
+        },
+        "collection": {
+          "data": []
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-writes/insertOne-serverErrors.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-writes/insertOne-serverErrors.json
new file mode 100644
index 0000000000000000000000000000000000000000..cb1e6f826be575818bb046150103091a8666d8e1
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-writes/insertOne-serverErrors.json	
@@ -0,0 +1,1161 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.0",
+      "topology": [
+        "replicaset"
+      ]
+    },
+    {
+      "minServerVersion": "4.1.7",
+      "topology": [
+        "sharded"
+      ]
+    }
+  ],
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    }
+  ],
+  "tests": [
+    {
+      "description": "InsertOne succeeds after connection failure",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "insert"
+          ],
+          "closeConnection": true
+        }
+      },
+      "operation": {
+        "name": "insertOne",
+        "arguments": {
+          "document": {
+            "_id": 3,
+            "x": 33
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "insertedId": 3
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "InsertOne fails after connection failure when retryWrites option is false",
+      "clientOptions": {
+        "retryWrites": false
+      },
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "insert"
+          ],
+          "closeConnection": true
+        }
+      },
+      "operation": {
+        "name": "insertOne",
+        "arguments": {
+          "document": {
+            "_id": 3,
+            "x": 33
+          }
+        }
+      },
+      "outcome": {
+        "error": true,
+        "result": {
+          "errorLabelsOmit": [
+            "RetryableWriteError"
+          ]
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "InsertOne succeeds after NotMaster",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "insert"
+          ],
+          "errorCode": 10107,
+          "errorLabels": [
+            "RetryableWriteError"
+          ],
+          "closeConnection": false
+        }
+      },
+      "operation": {
+        "name": "insertOne",
+        "arguments": {
+          "document": {
+            "_id": 3,
+            "x": 33
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "insertedId": 3
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "InsertOne succeeds after NotMasterOrSecondary",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "insert"
+          ],
+          "errorCode": 13436,
+          "errorLabels": [
+            "RetryableWriteError"
+          ],
+          "closeConnection": false
+        }
+      },
+      "operation": {
+        "name": "insertOne",
+        "arguments": {
+          "document": {
+            "_id": 3,
+            "x": 33
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "insertedId": 3
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "InsertOne succeeds after NotMasterNoSlaveOk",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "insert"
+          ],
+          "errorCode": 13435,
+          "errorLabels": [
+            "RetryableWriteError"
+          ],
+          "closeConnection": false
+        }
+      },
+      "operation": {
+        "name": "insertOne",
+        "arguments": {
+          "document": {
+            "_id": 3,
+            "x": 33
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "insertedId": 3
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "InsertOne succeeds after InterruptedDueToReplStateChange",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "insert"
+          ],
+          "errorCode": 11602,
+          "errorLabels": [
+            "RetryableWriteError"
+          ],
+          "closeConnection": false
+        }
+      },
+      "operation": {
+        "name": "insertOne",
+        "arguments": {
+          "document": {
+            "_id": 3,
+            "x": 33
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "insertedId": 3
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "InsertOne succeeds after InterruptedAtShutdown",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "insert"
+          ],
+          "errorCode": 11600,
+          "errorLabels": [
+            "RetryableWriteError"
+          ],
+          "closeConnection": false
+        }
+      },
+      "operation": {
+        "name": "insertOne",
+        "arguments": {
+          "document": {
+            "_id": 3,
+            "x": 33
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "insertedId": 3
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "InsertOne succeeds after PrimarySteppedDown",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "insert"
+          ],
+          "errorCode": 189,
+          "errorLabels": [
+            "RetryableWriteError"
+          ],
+          "closeConnection": false
+        }
+      },
+      "operation": {
+        "name": "insertOne",
+        "arguments": {
+          "document": {
+            "_id": 3,
+            "x": 33
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "insertedId": 3
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "InsertOne succeeds after ShutdownInProgress",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "insert"
+          ],
+          "errorCode": 91,
+          "errorLabels": [
+            "RetryableWriteError"
+          ],
+          "closeConnection": false
+        }
+      },
+      "operation": {
+        "name": "insertOne",
+        "arguments": {
+          "document": {
+            "_id": 3,
+            "x": 33
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "insertedId": 3
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "InsertOne succeeds after HostNotFound",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "insert"
+          ],
+          "errorCode": 7,
+          "errorLabels": [
+            "RetryableWriteError"
+          ],
+          "closeConnection": false
+        }
+      },
+      "operation": {
+        "name": "insertOne",
+        "arguments": {
+          "document": {
+            "_id": 3,
+            "x": 33
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "insertedId": 3
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "InsertOne succeeds after HostUnreachable",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "insert"
+          ],
+          "errorCode": 6,
+          "errorLabels": [
+            "RetryableWriteError"
+          ],
+          "closeConnection": false
+        }
+      },
+      "operation": {
+        "name": "insertOne",
+        "arguments": {
+          "document": {
+            "_id": 3,
+            "x": 33
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "insertedId": 3
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "InsertOne succeeds after SocketException",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "insert"
+          ],
+          "errorCode": 9001,
+          "errorLabels": [
+            "RetryableWriteError"
+          ],
+          "closeConnection": false
+        }
+      },
+      "operation": {
+        "name": "insertOne",
+        "arguments": {
+          "document": {
+            "_id": 3,
+            "x": 33
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "insertedId": 3
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "InsertOne succeeds after NetworkTimeout",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "insert"
+          ],
+          "errorCode": 89,
+          "errorLabels": [
+            "RetryableWriteError"
+          ],
+          "closeConnection": false
+        }
+      },
+      "operation": {
+        "name": "insertOne",
+        "arguments": {
+          "document": {
+            "_id": 3,
+            "x": 33
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "insertedId": 3
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "InsertOne succeeds after ExceededTimeLimit",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "insert"
+          ],
+          "errorCode": 262,
+          "errorLabels": [
+            "RetryableWriteError"
+          ],
+          "closeConnection": false
+        }
+      },
+      "operation": {
+        "name": "insertOne",
+        "arguments": {
+          "document": {
+            "_id": 3,
+            "x": 33
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "insertedId": 3
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "InsertOne fails after Interrupted",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "insert"
+          ],
+          "errorCode": 11601,
+          "closeConnection": false
+        }
+      },
+      "operation": {
+        "name": "insertOne",
+        "arguments": {
+          "document": {
+            "_id": 3,
+            "x": 33
+          }
+        }
+      },
+      "outcome": {
+        "error": true,
+        "result": {
+          "errorLabelsOmit": [
+            "RetryableWriteError"
+          ]
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "InsertOne succeeds after WriteConcernError InterruptedAtShutdown",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "insert"
+          ],
+          "writeConcernError": {
+            "code": 11600,
+            "errmsg": "Replication is being shut down",
+            "errorLabels": [
+              "RetryableWriteError"
+            ]
+          }
+        }
+      },
+      "operation": {
+        "name": "insertOne",
+        "arguments": {
+          "document": {
+            "_id": 3,
+            "x": 33
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "insertedId": 3
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "InsertOne succeeds after WriteConcernError InterruptedDueToReplStateChange",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "insert"
+          ],
+          "writeConcernError": {
+            "code": 11602,
+            "errmsg": "Replication is being shut down",
+            "errorLabels": [
+              "RetryableWriteError"
+            ]
+          }
+        }
+      },
+      "operation": {
+        "name": "insertOne",
+        "arguments": {
+          "document": {
+            "_id": 3,
+            "x": 33
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "insertedId": 3
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "InsertOne succeeds after WriteConcernError PrimarySteppedDown",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "insert"
+          ],
+          "writeConcernError": {
+            "code": 189,
+            "errmsg": "Replication is being shut down",
+            "errorLabels": [
+              "RetryableWriteError"
+            ]
+          }
+        }
+      },
+      "operation": {
+        "name": "insertOne",
+        "arguments": {
+          "document": {
+            "_id": 3,
+            "x": 33
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "insertedId": 3
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "InsertOne succeeds after WriteConcernError ShutdownInProgress",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "insert"
+          ],
+          "writeConcernError": {
+            "code": 91,
+            "errmsg": "Replication is being shut down",
+            "errorLabels": [
+              "RetryableWriteError"
+            ]
+          }
+        }
+      },
+      "operation": {
+        "name": "insertOne",
+        "arguments": {
+          "document": {
+            "_id": 3,
+            "x": 33
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "insertedId": 3
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "InsertOne fails after multiple retryable writeConcernErrors",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 2
+        },
+        "data": {
+          "failCommands": [
+            "insert"
+          ],
+          "writeConcernError": {
+            "code": 91,
+            "errmsg": "Replication is being shut down",
+            "errorLabels": [
+              "RetryableWriteError"
+            ]
+          }
+        }
+      },
+      "operation": {
+        "name": "insertOne",
+        "arguments": {
+          "document": {
+            "_id": 3,
+            "x": 33
+          }
+        }
+      },
+      "outcome": {
+        "error": true,
+        "result": {
+          "errorLabelsContain": [
+            "RetryableWriteError"
+          ]
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "InsertOne fails after WriteConcernError Interrupted",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "insert"
+          ],
+          "writeConcernError": {
+            "code": 11601,
+            "errmsg": "operation was interrupted"
+          }
+        }
+      },
+      "operation": {
+        "name": "insertOne",
+        "arguments": {
+          "document": {
+            "_id": 3,
+            "x": 33
+          }
+        }
+      },
+      "outcome": {
+        "error": true,
+        "result": {
+          "errorLabelsOmit": [
+            "RetryableWriteError"
+          ]
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "InsertOne fails after WriteConcernError WriteConcernFailed",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "insert"
+          ],
+          "writeConcernError": {
+            "code": 64,
+            "codeName": "WriteConcernFailed",
+            "errmsg": "waiting for replication timed out",
+            "errInfo": {
+              "wtimeout": true
+            }
+          }
+        }
+      },
+      "operation": {
+        "name": "insertOne",
+        "arguments": {
+          "document": {
+            "_id": 3,
+            "x": 33
+          }
+        }
+      },
+      "outcome": {
+        "error": true,
+        "result": {
+          "errorLabelsOmit": [
+            "RetryableWriteError"
+          ]
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "InsertOne fails with a RetryableWriteError label after two connection failures",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 2
+        },
+        "data": {
+          "failCommands": [
+            "insert"
+          ],
+          "closeConnection": true
+        }
+      },
+      "operation": {
+        "name": "insertOne",
+        "arguments": {
+          "document": {
+            "_id": 3,
+            "x": 33
+          }
+        }
+      },
+      "outcome": {
+        "error": true,
+        "result": {
+          "errorLabelsContain": [
+            "RetryableWriteError"
+          ]
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-writes/insertOne.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-writes/insertOne.json
new file mode 100644
index 0000000000000000000000000000000000000000..04dee6dd68acbcf57c83387f44db61b81d8303e0
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-writes/insertOne.json	
@@ -0,0 +1,139 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "3.6",
+      "topology": [
+        "replicaset"
+      ]
+    }
+  ],
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    }
+  ],
+  "tests": [
+    {
+      "description": "InsertOne is committed on first attempt",
+      "failPoint": {
+        "configureFailPoint": "onPrimaryTransactionalWrite",
+        "mode": {
+          "times": 1
+        }
+      },
+      "operation": {
+        "name": "insertOne",
+        "arguments": {
+          "document": {
+            "_id": 3,
+            "x": 33
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "insertedId": 3
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "InsertOne is not committed on first attempt",
+      "failPoint": {
+        "configureFailPoint": "onPrimaryTransactionalWrite",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failBeforeCommitExceptionCode": 1
+        }
+      },
+      "operation": {
+        "name": "insertOne",
+        "arguments": {
+          "document": {
+            "_id": 3,
+            "x": 33
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "insertedId": 3
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "InsertOne is never committed",
+      "failPoint": {
+        "configureFailPoint": "onPrimaryTransactionalWrite",
+        "mode": {
+          "times": 2
+        },
+        "data": {
+          "failBeforeCommitExceptionCode": 1
+        }
+      },
+      "operation": {
+        "name": "insertOne",
+        "arguments": {
+          "document": {
+            "_id": 3,
+            "x": 33
+          }
+        }
+      },
+      "outcome": {
+        "error": true,
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-writes/replaceOne-errorLabels.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-writes/replaceOne-errorLabels.json
new file mode 100644
index 0000000000000000000000000000000000000000..06867e5159ce5f2b3cc7d789a1d5bc759d93f245
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-writes/replaceOne-errorLabels.json	
@@ -0,0 +1,120 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.3.1",
+      "topology": [
+        "replicaset",
+        "sharded"
+      ]
+    }
+  ],
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    }
+  ],
+  "tests": [
+    {
+      "description": "ReplaceOne succeeds with RetryableWriteError from server",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "update"
+          ],
+          "errorCode": 112,
+          "errorLabels": [
+            "RetryableWriteError"
+          ]
+        }
+      },
+      "operation": {
+        "name": "replaceOne",
+        "arguments": {
+          "filter": {
+            "_id": 1
+          },
+          "replacement": {
+            "_id": 1,
+            "x": 111
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "matchedCount": 1,
+          "modifiedCount": 1,
+          "upsertedCount": 0
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 111
+            },
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "ReplaceOne fails if server does not return RetryableWriteError",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "update"
+          ],
+          "errorCode": 11600,
+          "errorLabels": []
+        }
+      },
+      "operation": {
+        "name": "replaceOne",
+        "arguments": {
+          "filter": {
+            "_id": 1
+          },
+          "replacement": {
+            "_id": 1,
+            "x": 111
+          }
+        }
+      },
+      "outcome": {
+        "error": true,
+        "result": {
+          "errorLabelsOmit": [
+            "RetryableWriteError"
+          ]
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-writes/replaceOne-serverErrors.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-writes/replaceOne-serverErrors.json
new file mode 100644
index 0000000000000000000000000000000000000000..af18bcf1a2e82222d23b20a790b128157f76a8df
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-writes/replaceOne-serverErrors.json	
@@ -0,0 +1,176 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.0",
+      "topology": [
+        "replicaset"
+      ]
+    },
+    {
+      "minServerVersion": "4.1.7",
+      "topology": [
+        "sharded"
+      ]
+    }
+  ],
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    }
+  ],
+  "tests": [
+    {
+      "description": "ReplaceOne succeeds after PrimarySteppedDown",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "update"
+          ],
+          "errorCode": 189,
+          "errorLabels": [
+            "RetryableWriteError"
+          ]
+        }
+      },
+      "operation": {
+        "name": "replaceOne",
+        "arguments": {
+          "filter": {
+            "_id": 1
+          },
+          "replacement": {
+            "_id": 1,
+            "x": 111
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "matchedCount": 1,
+          "modifiedCount": 1,
+          "upsertedCount": 0
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 111
+            },
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "ReplaceOne succeeds after WriteConcernError ShutdownInProgress",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "update"
+          ],
+          "writeConcernError": {
+            "code": 91,
+            "errmsg": "Replication is being shut down",
+            "errorLabels": [
+              "RetryableWriteError"
+            ]
+          }
+        }
+      },
+      "operation": {
+        "name": "replaceOne",
+        "arguments": {
+          "filter": {
+            "_id": 1
+          },
+          "replacement": {
+            "_id": 1,
+            "x": 111
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "matchedCount": 1,
+          "modifiedCount": 1,
+          "upsertedCount": 0
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 111
+            },
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "ReplaceOne fails with a RetryableWriteError label after two connection failures",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 2
+        },
+        "data": {
+          "failCommands": [
+            "update"
+          ],
+          "closeConnection": true
+        }
+      },
+      "operation": {
+        "name": "replaceOne",
+        "arguments": {
+          "filter": {
+            "_id": 1
+          },
+          "replacement": {
+            "_id": 1,
+            "x": 111
+          }
+        }
+      },
+      "outcome": {
+        "error": true,
+        "result": {
+          "errorLabelsContain": [
+            "RetryableWriteError"
+          ]
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-writes/replaceOne.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-writes/replaceOne.json
new file mode 100644
index 0000000000000000000000000000000000000000..e5b8cf8eabbed381690af11437ab438d39fb587b
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-writes/replaceOne.json	
@@ -0,0 +1,144 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "3.6",
+      "topology": [
+        "replicaset"
+      ]
+    }
+  ],
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    }
+  ],
+  "tests": [
+    {
+      "description": "ReplaceOne is committed on first attempt",
+      "failPoint": {
+        "configureFailPoint": "onPrimaryTransactionalWrite",
+        "mode": {
+          "times": 1
+        }
+      },
+      "operation": {
+        "name": "replaceOne",
+        "arguments": {
+          "filter": {
+            "_id": 1
+          },
+          "replacement": {
+            "_id": 1,
+            "x": 111
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "matchedCount": 1,
+          "modifiedCount": 1,
+          "upsertedCount": 0
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 111
+            },
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "ReplaceOne is not committed on first attempt",
+      "failPoint": {
+        "configureFailPoint": "onPrimaryTransactionalWrite",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failBeforeCommitExceptionCode": 1
+        }
+      },
+      "operation": {
+        "name": "replaceOne",
+        "arguments": {
+          "filter": {
+            "_id": 1
+          },
+          "replacement": {
+            "_id": 1,
+            "x": 111
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "matchedCount": 1,
+          "modifiedCount": 1,
+          "upsertedCount": 0
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 111
+            },
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "ReplaceOne is never committed",
+      "failPoint": {
+        "configureFailPoint": "onPrimaryTransactionalWrite",
+        "mode": {
+          "times": 2
+        },
+        "data": {
+          "failBeforeCommitExceptionCode": 1
+        }
+      },
+      "operation": {
+        "name": "replaceOne",
+        "arguments": {
+          "filter": {
+            "_id": 1
+          },
+          "replacement": {
+            "_id": 1,
+            "x": 111
+          }
+        }
+      },
+      "outcome": {
+        "error": true,
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-writes/updateMany.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-writes/updateMany.json
new file mode 100644
index 0000000000000000000000000000000000000000..14288c2860dcf99738ff999755bc4e5d2ceb4d0f
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-writes/updateMany.json	
@@ -0,0 +1,57 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "3.6",
+      "topology": [
+        "replicaset",
+        "sharded"
+      ]
+    }
+  ],
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    }
+  ],
+  "tests": [
+    {
+      "description": "UpdateMany ignores retryWrites",
+      "useMultipleMongoses": true,
+      "operation": {
+        "name": "updateMany",
+        "arguments": {
+          "filter": {},
+          "update": {
+            "$inc": {
+              "x": 1
+            }
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "matchedCount": 2,
+          "modifiedCount": 2,
+          "upsertedCount": 0
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 12
+            },
+            {
+              "_id": 2,
+              "x": 23
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-writes/updateOne-errorLabels.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-writes/updateOne-errorLabels.json
new file mode 100644
index 0000000000000000000000000000000000000000..4a6be3ffbaae869a8f3ea7e21d22abce8687ea9f
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-writes/updateOne-errorLabels.json	
@@ -0,0 +1,122 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.3.1",
+      "topology": [
+        "replicaset",
+        "sharded"
+      ]
+    }
+  ],
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    }
+  ],
+  "tests": [
+    {
+      "description": "UpdateOne succeeds with RetryableWriteError from server",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "update"
+          ],
+          "errorCode": 112,
+          "errorLabels": [
+            "RetryableWriteError"
+          ]
+        }
+      },
+      "operation": {
+        "name": "updateOne",
+        "arguments": {
+          "filter": {
+            "_id": 1
+          },
+          "update": {
+            "$inc": {
+              "x": 1
+            }
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "matchedCount": 1,
+          "modifiedCount": 1,
+          "upsertedCount": 0
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 12
+            },
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "UpdateOne fails if server does not return RetryableWriteError",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "update"
+          ],
+          "errorCode": 11600,
+          "errorLabels": []
+        }
+      },
+      "operation": {
+        "name": "updateOne",
+        "arguments": {
+          "filter": {
+            "_id": 1
+          },
+          "update": {
+            "$inc": {
+              "x": 1
+            }
+          }
+        }
+      },
+      "outcome": {
+        "error": true,
+        "result": {
+          "errorLabelsOmit": [
+            "RetryableWriteError"
+          ]
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-writes/updateOne-serverErrors.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-writes/updateOne-serverErrors.json
new file mode 100644
index 0000000000000000000000000000000000000000..bb442eb68a96295be26205a36ef83c8fa9593bd8
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-writes/updateOne-serverErrors.json	
@@ -0,0 +1,179 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.0",
+      "topology": [
+        "replicaset"
+      ]
+    },
+    {
+      "minServerVersion": "4.1.7",
+      "topology": [
+        "sharded"
+      ]
+    }
+  ],
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    }
+  ],
+  "tests": [
+    {
+      "description": "UpdateOne succeeds after PrimarySteppedDown",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "update"
+          ],
+          "errorCode": 189,
+          "errorLabels": [
+            "RetryableWriteError"
+          ]
+        }
+      },
+      "operation": {
+        "name": "updateOne",
+        "arguments": {
+          "filter": {
+            "_id": 1
+          },
+          "update": {
+            "$inc": {
+              "x": 1
+            }
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "matchedCount": 1,
+          "modifiedCount": 1,
+          "upsertedCount": 0
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 12
+            },
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "UpdateOne succeeds after WriteConcernError ShutdownInProgress",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "update"
+          ],
+          "writeConcernError": {
+            "code": 91,
+            "errmsg": "Replication is being shut down",
+            "errorLabels": [
+              "RetryableWriteError"
+            ]
+          }
+        }
+      },
+      "operation": {
+        "name": "updateOne",
+        "arguments": {
+          "filter": {
+            "_id": 1
+          },
+          "update": {
+            "$inc": {
+              "x": 1
+            }
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "matchedCount": 1,
+          "modifiedCount": 1,
+          "upsertedCount": 0
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 12
+            },
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "UpdateOne fails with a RetryableWriteError label after two connection failures",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 2
+        },
+        "data": {
+          "failCommands": [
+            "update"
+          ],
+          "closeConnection": true
+        }
+      },
+      "operation": {
+        "name": "updateOne",
+        "arguments": {
+          "filter": {
+            "_id": 1
+          },
+          "update": {
+            "$inc": {
+              "x": 1
+            }
+          }
+        }
+      },
+      "outcome": {
+        "error": true,
+        "result": {
+          "errorLabelsContain": [
+            "RetryableWriteError"
+          ]
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-writes/updateOne.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-writes/updateOne.json
new file mode 100644
index 0000000000000000000000000000000000000000..0f806dc3d8485291e5a073c89bb278cf324f764e
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/retryable-writes/updateOne.json	
@@ -0,0 +1,288 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "3.6",
+      "topology": [
+        "replicaset"
+      ]
+    }
+  ],
+  "data": [
+    {
+      "_id": 1,
+      "x": 11
+    },
+    {
+      "_id": 2,
+      "x": 22
+    }
+  ],
+  "tests": [
+    {
+      "description": "UpdateOne is committed on first attempt",
+      "failPoint": {
+        "configureFailPoint": "onPrimaryTransactionalWrite",
+        "mode": {
+          "times": 1
+        }
+      },
+      "operation": {
+        "name": "updateOne",
+        "arguments": {
+          "filter": {
+            "_id": 1
+          },
+          "update": {
+            "$inc": {
+              "x": 1
+            }
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "matchedCount": 1,
+          "modifiedCount": 1,
+          "upsertedCount": 0
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 12
+            },
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "UpdateOne is not committed on first attempt",
+      "failPoint": {
+        "configureFailPoint": "onPrimaryTransactionalWrite",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failBeforeCommitExceptionCode": 1
+        }
+      },
+      "operation": {
+        "name": "updateOne",
+        "arguments": {
+          "filter": {
+            "_id": 1
+          },
+          "update": {
+            "$inc": {
+              "x": 1
+            }
+          }
+        }
+      },
+      "outcome": {
+        "result": {
+          "matchedCount": 1,
+          "modifiedCount": 1,
+          "upsertedCount": 0
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 12
+            },
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "UpdateOne is never committed",
+      "failPoint": {
+        "configureFailPoint": "onPrimaryTransactionalWrite",
+        "mode": {
+          "times": 2
+        },
+        "data": {
+          "failBeforeCommitExceptionCode": 1
+        }
+      },
+      "operation": {
+        "name": "updateOne",
+        "arguments": {
+          "filter": {
+            "_id": 1
+          },
+          "update": {
+            "$inc": {
+              "x": 1
+            }
+          }
+        }
+      },
+      "outcome": {
+        "error": true,
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "UpdateOne with upsert is committed on first attempt",
+      "failPoint": {
+        "configureFailPoint": "onPrimaryTransactionalWrite",
+        "mode": {
+          "times": 1
+        }
+      },
+      "operation": {
+        "name": "updateOne",
+        "arguments": {
+          "filter": {
+            "_id": 3,
+            "x": 33
+          },
+          "update": {
+            "$inc": {
+              "x": 1
+            }
+          },
+          "upsert": true
+        }
+      },
+      "outcome": {
+        "result": {
+          "matchedCount": 0,
+          "modifiedCount": 0,
+          "upsertedCount": 1,
+          "upsertedId": 3
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 34
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "UpdateOne with upsert is not committed on first attempt",
+      "failPoint": {
+        "configureFailPoint": "onPrimaryTransactionalWrite",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failBeforeCommitExceptionCode": 1
+        }
+      },
+      "operation": {
+        "name": "updateOne",
+        "arguments": {
+          "filter": {
+            "_id": 3,
+            "x": 33
+          },
+          "update": {
+            "$inc": {
+              "x": 1
+            }
+          },
+          "upsert": true
+        }
+      },
+      "outcome": {
+        "result": {
+          "matchedCount": 0,
+          "modifiedCount": 0,
+          "upsertedCount": 1,
+          "upsertedId": 3
+        },
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 34
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "UpdateOne with upsert is never committed",
+      "failPoint": {
+        "configureFailPoint": "onPrimaryTransactionalWrite",
+        "mode": {
+          "times": 2
+        },
+        "data": {
+          "failBeforeCommitExceptionCode": 1
+        }
+      },
+      "operation": {
+        "name": "updateOne",
+        "arguments": {
+          "filter": {
+            "_id": 3,
+            "x": 33
+          },
+          "update": {
+            "$inc": {
+              "x": 1
+            }
+          },
+          "upsert": true
+        }
+      },
+      "outcome": {
+        "error": true,
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions-convenient-api/callback-aborts.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions-convenient-api/callback-aborts.json
new file mode 100644
index 0000000000000000000000000000000000000000..2a3038e8baab9d0f0f261da97903e11503fa14d9
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions-convenient-api/callback-aborts.json	
@@ -0,0 +1,244 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.0",
+      "topology": [
+        "replicaset"
+      ]
+    },
+    {
+      "minServerVersion": "4.1.8",
+      "topology": [
+        "sharded"
+      ]
+    }
+  ],
+  "database_name": "withTransaction-tests",
+  "collection_name": "test",
+  "data": [],
+  "tests": [
+    {
+      "description": "withTransaction succeeds if callback aborts",
+      "useMultipleMongoses": true,
+      "operations": [
+        {
+          "name": "withTransaction",
+          "object": "session0",
+          "arguments": {
+            "callback": {
+              "operations": [
+                {
+                  "name": "insertOne",
+                  "object": "collection",
+                  "arguments": {
+                    "session": "session0",
+                    "document": {
+                      "_id": 1
+                    }
+                  },
+                  "result": {
+                    "insertedId": 1
+                  }
+                },
+                {
+                  "name": "abortTransaction",
+                  "object": "session0"
+                }
+              ]
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "readConcern": null,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "withTransaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "abortTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "autocommit": false,
+              "readConcern": null,
+              "startTransaction": null,
+              "writeConcern": null
+            },
+            "command_name": "abortTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": []
+        }
+      }
+    },
+    {
+      "description": "withTransaction succeeds if callback aborts with no ops",
+      "useMultipleMongoses": true,
+      "operations": [
+        {
+          "name": "withTransaction",
+          "object": "session0",
+          "arguments": {
+            "callback": {
+              "operations": [
+                {
+                  "name": "abortTransaction",
+                  "object": "session0"
+                }
+              ]
+            }
+          }
+        }
+      ],
+      "expectations": [],
+      "outcome": {
+        "collection": {
+          "data": []
+        }
+      }
+    },
+    {
+      "description": "withTransaction still succeeds if callback aborts and runs extra op",
+      "useMultipleMongoses": true,
+      "operations": [
+        {
+          "name": "withTransaction",
+          "object": "session0",
+          "arguments": {
+            "callback": {
+              "operations": [
+                {
+                  "name": "insertOne",
+                  "object": "collection",
+                  "arguments": {
+                    "session": "session0",
+                    "document": {
+                      "_id": 1
+                    }
+                  },
+                  "result": {
+                    "insertedId": 1
+                  }
+                },
+                {
+                  "name": "abortTransaction",
+                  "object": "session0"
+                },
+                {
+                  "name": "insertOne",
+                  "object": "collection",
+                  "arguments": {
+                    "session": "session0",
+                    "document": {
+                      "_id": 2
+                    }
+                  },
+                  "result": {
+                    "insertedId": 2
+                  }
+                }
+              ]
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "readConcern": null,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "withTransaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "abortTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "autocommit": false,
+              "readConcern": null,
+              "startTransaction": null,
+              "writeConcern": null
+            },
+            "command_name": "abortTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 2
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "autocommit": null,
+              "readConcern": null,
+              "startTransaction": null,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "withTransaction-tests"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 2
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions-convenient-api/callback-commits.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions-convenient-api/callback-commits.json
new file mode 100644
index 0000000000000000000000000000000000000000..4abbbdd0e637b92a264e0c536eb1707b677a48bd
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions-convenient-api/callback-commits.json	
@@ -0,0 +1,303 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.0",
+      "topology": [
+        "replicaset"
+      ]
+    },
+    {
+      "minServerVersion": "4.1.8",
+      "topology": [
+        "sharded"
+      ]
+    }
+  ],
+  "database_name": "withTransaction-tests",
+  "collection_name": "test",
+  "data": [],
+  "tests": [
+    {
+      "description": "withTransaction succeeds if callback commits",
+      "useMultipleMongoses": true,
+      "operations": [
+        {
+          "name": "withTransaction",
+          "object": "session0",
+          "arguments": {
+            "callback": {
+              "operations": [
+                {
+                  "name": "insertOne",
+                  "object": "collection",
+                  "arguments": {
+                    "session": "session0",
+                    "document": {
+                      "_id": 1
+                    }
+                  },
+                  "result": {
+                    "insertedId": 1
+                  }
+                },
+                {
+                  "name": "insertOne",
+                  "object": "collection",
+                  "arguments": {
+                    "session": "session0",
+                    "document": {
+                      "_id": 2
+                    }
+                  },
+                  "result": {
+                    "insertedId": 2
+                  }
+                },
+                {
+                  "name": "commitTransaction",
+                  "object": "session0"
+                }
+              ]
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "readConcern": null,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "withTransaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 2
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "autocommit": false,
+              "readConcern": null,
+              "startTransaction": null,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "withTransaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "autocommit": false,
+              "readConcern": null,
+              "startTransaction": null,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "withTransaction still succeeds if callback commits and runs extra op",
+      "useMultipleMongoses": true,
+      "operations": [
+        {
+          "name": "withTransaction",
+          "object": "session0",
+          "arguments": {
+            "callback": {
+              "operations": [
+                {
+                  "name": "insertOne",
+                  "object": "collection",
+                  "arguments": {
+                    "session": "session0",
+                    "document": {
+                      "_id": 1
+                    }
+                  },
+                  "result": {
+                    "insertedId": 1
+                  }
+                },
+                {
+                  "name": "insertOne",
+                  "object": "collection",
+                  "arguments": {
+                    "session": "session0",
+                    "document": {
+                      "_id": 2
+                    }
+                  },
+                  "result": {
+                    "insertedId": 2
+                  }
+                },
+                {
+                  "name": "commitTransaction",
+                  "object": "session0"
+                },
+                {
+                  "name": "insertOne",
+                  "object": "collection",
+                  "arguments": {
+                    "session": "session0",
+                    "document": {
+                      "_id": 3
+                    }
+                  },
+                  "result": {
+                    "insertedId": 3
+                  }
+                }
+              ]
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "readConcern": null,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "withTransaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 2
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "autocommit": false,
+              "readConcern": null,
+              "startTransaction": null,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "withTransaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "autocommit": false,
+              "readConcern": null,
+              "startTransaction": null,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 3
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "autocommit": null,
+              "readConcern": null,
+              "startTransaction": null,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "withTransaction-tests"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            },
+            {
+              "_id": 3
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions-convenient-api/callback-retry.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions-convenient-api/callback-retry.json
new file mode 100644
index 0000000000000000000000000000000000000000..a0391c1b5d0bcd58ca16ee324e9e7192fcb4be0c
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions-convenient-api/callback-retry.json	
@@ -0,0 +1,315 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.0",
+      "topology": [
+        "replicaset"
+      ]
+    },
+    {
+      "minServerVersion": "4.1.8",
+      "topology": [
+        "sharded"
+      ]
+    }
+  ],
+  "database_name": "withTransaction-tests",
+  "collection_name": "test",
+  "data": [],
+  "tests": [
+    {
+      "description": "callback succeeds after multiple connection errors",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 2
+        },
+        "data": {
+          "failCommands": [
+            "insert"
+          ],
+          "closeConnection": true
+        }
+      },
+      "operations": [
+        {
+          "name": "withTransaction",
+          "object": "session0",
+          "arguments": {
+            "callback": {
+              "operations": [
+                {
+                  "name": "insertOne",
+                  "object": "collection",
+                  "arguments": {
+                    "session": "session0",
+                    "document": {
+                      "_id": 1
+                    }
+                  }
+                }
+              ]
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "readConcern": null,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "withTransaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "abortTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "autocommit": false,
+              "readConcern": null,
+              "startTransaction": null,
+              "writeConcern": null
+            },
+            "command_name": "abortTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "readConcern": {
+                "afterClusterTime": 42
+              },
+              "txnNumber": {
+                "$numberLong": "2"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "withTransaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "abortTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "2"
+              },
+              "autocommit": false,
+              "readConcern": null,
+              "startTransaction": null,
+              "writeConcern": null
+            },
+            "command_name": "abortTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "readConcern": {
+                "afterClusterTime": 42
+              },
+              "txnNumber": {
+                "$numberLong": "3"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "withTransaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "3"
+              },
+              "autocommit": false,
+              "readConcern": null,
+              "startTransaction": null,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "callback is not retried after non-transient error (DuplicateKeyError)",
+      "useMultipleMongoses": true,
+      "operations": [
+        {
+          "name": "withTransaction",
+          "object": "session0",
+          "arguments": {
+            "callback": {
+              "operations": [
+                {
+                  "name": "insertOne",
+                  "object": "collection",
+                  "arguments": {
+                    "session": "session0",
+                    "document": {
+                      "_id": 1
+                    }
+                  },
+                  "result": {
+                    "insertedId": 1
+                  }
+                },
+                {
+                  "name": "insertOne",
+                  "object": "collection",
+                  "arguments": {
+                    "session": "session0",
+                    "document": {
+                      "_id": 1
+                    }
+                  },
+                  "result": {
+                    "errorLabelsOmit": [
+                      "TransientTransactionError",
+                      "UnknownTransactionCommitResult"
+                    ]
+                  }
+                }
+              ]
+            }
+          },
+          "result": {
+            "errorLabelsOmit": [
+              "TransientTransactionError",
+              "UnknownTransactionCommitResult"
+            ],
+            "errorContains": "E11000"
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "readConcern": null,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "withTransaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "autocommit": false,
+              "readConcern": null,
+              "startTransaction": null,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "withTransaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "abortTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "autocommit": false,
+              "readConcern": null,
+              "startTransaction": null,
+              "writeConcern": null
+            },
+            "command_name": "abortTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": []
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions-convenient-api/commit-retry.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions-convenient-api/commit-retry.json
new file mode 100644
index 0000000000000000000000000000000000000000..312116253b39237d431aeec589f28aaff68a9478
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions-convenient-api/commit-retry.json	
@@ -0,0 +1,531 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.0",
+      "topology": [
+        "replicaset"
+      ]
+    },
+    {
+      "minServerVersion": "4.1.8",
+      "topology": [
+        "sharded"
+      ]
+    }
+  ],
+  "database_name": "withTransaction-tests",
+  "collection_name": "test",
+  "data": [],
+  "tests": [
+    {
+      "description": "commitTransaction succeeds after multiple connection errors",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 2
+        },
+        "data": {
+          "failCommands": [
+            "commitTransaction"
+          ],
+          "closeConnection": true
+        }
+      },
+      "operations": [
+        {
+          "name": "withTransaction",
+          "object": "session0",
+          "arguments": {
+            "callback": {
+              "operations": [
+                {
+                  "name": "insertOne",
+                  "object": "collection",
+                  "arguments": {
+                    "session": "session0",
+                    "document": {
+                      "_id": 1
+                    }
+                  },
+                  "result": {
+                    "insertedId": 1
+                  }
+                }
+              ]
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "readConcern": null,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "withTransaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "autocommit": false,
+              "readConcern": null,
+              "startTransaction": null,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "autocommit": false,
+              "writeConcern": {
+                "w": "majority",
+                "wtimeout": 10000
+              },
+              "readConcern": null,
+              "startTransaction": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "autocommit": false,
+              "writeConcern": {
+                "w": "majority",
+                "wtimeout": 10000
+              },
+              "readConcern": null,
+              "startTransaction": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "commitTransaction retry only overwrites write concern w option",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 2
+        },
+        "data": {
+          "failCommands": [
+            "commitTransaction"
+          ],
+          "closeConnection": true
+        }
+      },
+      "operations": [
+        {
+          "name": "withTransaction",
+          "object": "session0",
+          "arguments": {
+            "callback": {
+              "operations": [
+                {
+                  "name": "insertOne",
+                  "object": "collection",
+                  "arguments": {
+                    "session": "session0",
+                    "document": {
+                      "_id": 1
+                    }
+                  },
+                  "result": {
+                    "insertedId": 1
+                  }
+                }
+              ]
+            },
+            "options": {
+              "writeConcern": {
+                "w": 2,
+                "j": true,
+                "wtimeout": 5000
+              }
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "readConcern": null,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "withTransaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "autocommit": false,
+              "writeConcern": {
+                "w": 2,
+                "j": true,
+                "wtimeout": 5000
+              },
+              "readConcern": null,
+              "startTransaction": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "autocommit": false,
+              "writeConcern": {
+                "w": "majority",
+                "j": true,
+                "wtimeout": 5000
+              },
+              "readConcern": null,
+              "startTransaction": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "autocommit": false,
+              "writeConcern": {
+                "w": "majority",
+                "j": true,
+                "wtimeout": 5000
+              },
+              "readConcern": null,
+              "startTransaction": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "commit is retried after commitTransaction UnknownTransactionCommitResult (NotMaster)",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 2
+        },
+        "data": {
+          "failCommands": [
+            "commitTransaction"
+          ],
+          "errorCode": 10107,
+          "errorLabels": [
+            "RetryableWriteError"
+          ],
+          "closeConnection": false
+        }
+      },
+      "operations": [
+        {
+          "name": "withTransaction",
+          "object": "session0",
+          "arguments": {
+            "callback": {
+              "operations": [
+                {
+                  "name": "insertOne",
+                  "object": "collection",
+                  "arguments": {
+                    "session": "session0",
+                    "document": {
+                      "_id": 1
+                    }
+                  },
+                  "result": {
+                    "insertedId": 1
+                  }
+                }
+              ]
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "readConcern": null,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "withTransaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "autocommit": false,
+              "readConcern": null,
+              "startTransaction": null,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "autocommit": false,
+              "writeConcern": {
+                "w": "majority",
+                "wtimeout": 10000
+              },
+              "readConcern": null,
+              "startTransaction": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "autocommit": false,
+              "writeConcern": {
+                "w": "majority",
+                "wtimeout": 10000
+              },
+              "readConcern": null,
+              "startTransaction": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "commit is not retried after MaxTimeMSExpired error",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "commitTransaction"
+          ],
+          "errorCode": 50
+        }
+      },
+      "operations": [
+        {
+          "name": "withTransaction",
+          "object": "session0",
+          "arguments": {
+            "callback": {
+              "operations": [
+                {
+                  "name": "insertOne",
+                  "object": "collection",
+                  "arguments": {
+                    "session": "session0",
+                    "document": {
+                      "_id": 1
+                    }
+                  },
+                  "result": {
+                    "insertedId": 1
+                  }
+                }
+              ]
+            },
+            "options": {
+              "maxCommitTimeMS": 60000
+            }
+          },
+          "result": {
+            "errorCodeName": "MaxTimeMSExpired",
+            "errorLabelsContain": [
+              "UnknownTransactionCommitResult"
+            ],
+            "errorLabelsOmit": [
+              "TransientTransactionError"
+            ]
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "readConcern": null,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "withTransaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "autocommit": false,
+              "maxTimeMS": 60000,
+              "readConcern": null,
+              "startTransaction": null,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": []
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions-convenient-api/commit-transienttransactionerror-4.2.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions-convenient-api/commit-transienttransactionerror-4.2.json
new file mode 100644
index 0000000000000000000000000000000000000000..7663bb54e18a5b76e95d4f6fd1d40c828b01f0e7
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions-convenient-api/commit-transienttransactionerror-4.2.json	
@@ -0,0 +1,197 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.1.6",
+      "topology": [
+        "replicaset"
+      ]
+    },
+    {
+      "minServerVersion": "4.1.8",
+      "topology": [
+        "sharded"
+      ]
+    }
+  ],
+  "database_name": "withTransaction-tests",
+  "collection_name": "test",
+  "data": [],
+  "tests": [
+    {
+      "description": "transaction is retried after commitTransaction TransientTransactionError (PreparedTransactionInProgress)",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 2
+        },
+        "data": {
+          "failCommands": [
+            "commitTransaction"
+          ],
+          "errorCode": 267,
+          "closeConnection": false
+        }
+      },
+      "operations": [
+        {
+          "name": "withTransaction",
+          "object": "session0",
+          "arguments": {
+            "callback": {
+              "operations": [
+                {
+                  "name": "insertOne",
+                  "object": "collection",
+                  "arguments": {
+                    "session": "session0",
+                    "document": {
+                      "_id": 1
+                    }
+                  },
+                  "result": {
+                    "insertedId": 1
+                  }
+                }
+              ]
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "readConcern": null,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "withTransaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "autocommit": false,
+              "readConcern": null,
+              "startTransaction": null,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "readConcern": {
+                "afterClusterTime": 42
+              },
+              "txnNumber": {
+                "$numberLong": "2"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "withTransaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "2"
+              },
+              "autocommit": false,
+              "readConcern": null,
+              "startTransaction": null,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "readConcern": {
+                "afterClusterTime": 42
+              },
+              "txnNumber": {
+                "$numberLong": "3"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "withTransaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "3"
+              },
+              "autocommit": false,
+              "readConcern": null,
+              "startTransaction": null,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions-convenient-api/commit-transienttransactionerror.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions-convenient-api/commit-transienttransactionerror.json
new file mode 100644
index 0000000000000000000000000000000000000000..18becbe09c6c36105590c71098f483b619cbddfc
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions-convenient-api/commit-transienttransactionerror.json	
@@ -0,0 +1,725 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.0",
+      "topology": [
+        "replicaset"
+      ]
+    },
+    {
+      "minServerVersion": "4.1.8",
+      "topology": [
+        "sharded"
+      ]
+    }
+  ],
+  "database_name": "withTransaction-tests",
+  "collection_name": "test",
+  "data": [],
+  "tests": [
+    {
+      "description": "transaction is retried after commitTransaction TransientTransactionError (LockTimeout)",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 2
+        },
+        "data": {
+          "failCommands": [
+            "commitTransaction"
+          ],
+          "errorCode": 24,
+          "closeConnection": false
+        }
+      },
+      "operations": [
+        {
+          "name": "withTransaction",
+          "object": "session0",
+          "arguments": {
+            "callback": {
+              "operations": [
+                {
+                  "name": "insertOne",
+                  "object": "collection",
+                  "arguments": {
+                    "session": "session0",
+                    "document": {
+                      "_id": 1
+                    }
+                  },
+                  "result": {
+                    "insertedId": 1
+                  }
+                }
+              ]
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "readConcern": null,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "withTransaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "autocommit": false,
+              "readConcern": null,
+              "startTransaction": null,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "readConcern": {
+                "afterClusterTime": 42
+              },
+              "txnNumber": {
+                "$numberLong": "2"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "withTransaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "2"
+              },
+              "autocommit": false,
+              "readConcern": null,
+              "startTransaction": null,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "readConcern": {
+                "afterClusterTime": 42
+              },
+              "txnNumber": {
+                "$numberLong": "3"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "withTransaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "3"
+              },
+              "autocommit": false,
+              "readConcern": null,
+              "startTransaction": null,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "transaction is retried after commitTransaction TransientTransactionError (WriteConflict)",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 2
+        },
+        "data": {
+          "failCommands": [
+            "commitTransaction"
+          ],
+          "errorCode": 112,
+          "closeConnection": false
+        }
+      },
+      "operations": [
+        {
+          "name": "withTransaction",
+          "object": "session0",
+          "arguments": {
+            "callback": {
+              "operations": [
+                {
+                  "name": "insertOne",
+                  "object": "collection",
+                  "arguments": {
+                    "session": "session0",
+                    "document": {
+                      "_id": 1
+                    }
+                  },
+                  "result": {
+                    "insertedId": 1
+                  }
+                }
+              ]
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "readConcern": null,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "withTransaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "autocommit": false,
+              "readConcern": null,
+              "startTransaction": null,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "readConcern": {
+                "afterClusterTime": 42
+              },
+              "txnNumber": {
+                "$numberLong": "2"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "withTransaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "2"
+              },
+              "autocommit": false,
+              "readConcern": null,
+              "startTransaction": null,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "readConcern": {
+                "afterClusterTime": 42
+              },
+              "txnNumber": {
+                "$numberLong": "3"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "withTransaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "3"
+              },
+              "autocommit": false,
+              "readConcern": null,
+              "startTransaction": null,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "transaction is retried after commitTransaction TransientTransactionError (SnapshotUnavailable)",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 2
+        },
+        "data": {
+          "failCommands": [
+            "commitTransaction"
+          ],
+          "errorCode": 246,
+          "closeConnection": false
+        }
+      },
+      "operations": [
+        {
+          "name": "withTransaction",
+          "object": "session0",
+          "arguments": {
+            "callback": {
+              "operations": [
+                {
+                  "name": "insertOne",
+                  "object": "collection",
+                  "arguments": {
+                    "session": "session0",
+                    "document": {
+                      "_id": 1
+                    }
+                  },
+                  "result": {
+                    "insertedId": 1
+                  }
+                }
+              ]
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "readConcern": null,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "withTransaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "autocommit": false,
+              "readConcern": null,
+              "startTransaction": null,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "readConcern": {
+                "afterClusterTime": 42
+              },
+              "txnNumber": {
+                "$numberLong": "2"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "withTransaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "2"
+              },
+              "autocommit": false,
+              "readConcern": null,
+              "startTransaction": null,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "readConcern": {
+                "afterClusterTime": 42
+              },
+              "txnNumber": {
+                "$numberLong": "3"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "withTransaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "3"
+              },
+              "autocommit": false,
+              "readConcern": null,
+              "startTransaction": null,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "transaction is retried after commitTransaction TransientTransactionError (NoSuchTransaction)",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 2
+        },
+        "data": {
+          "failCommands": [
+            "commitTransaction"
+          ],
+          "errorCode": 251,
+          "closeConnection": false
+        }
+      },
+      "operations": [
+        {
+          "name": "withTransaction",
+          "object": "session0",
+          "arguments": {
+            "callback": {
+              "operations": [
+                {
+                  "name": "insertOne",
+                  "object": "collection",
+                  "arguments": {
+                    "session": "session0",
+                    "document": {
+                      "_id": 1
+                    }
+                  },
+                  "result": {
+                    "insertedId": 1
+                  }
+                }
+              ]
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "readConcern": null,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "withTransaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "autocommit": false,
+              "readConcern": null,
+              "startTransaction": null,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "readConcern": {
+                "afterClusterTime": 42
+              },
+              "txnNumber": {
+                "$numberLong": "2"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "withTransaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "2"
+              },
+              "autocommit": false,
+              "readConcern": null,
+              "startTransaction": null,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "readConcern": {
+                "afterClusterTime": 42
+              },
+              "txnNumber": {
+                "$numberLong": "3"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "withTransaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "3"
+              },
+              "autocommit": false,
+              "readConcern": null,
+              "startTransaction": null,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions-convenient-api/commit-writeconcernerror.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions-convenient-api/commit-writeconcernerror.json
new file mode 100644
index 0000000000000000000000000000000000000000..fbad6455465ffe49af8c9a95c7f1a189fed9815e
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions-convenient-api/commit-writeconcernerror.json	
@@ -0,0 +1,602 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.0",
+      "topology": [
+        "replicaset"
+      ]
+    },
+    {
+      "minServerVersion": "4.1.8",
+      "topology": [
+        "sharded"
+      ]
+    }
+  ],
+  "database_name": "withTransaction-tests",
+  "collection_name": "test",
+  "data": [],
+  "tests": [
+    {
+      "description": "commitTransaction is retried after WriteConcernFailed timeout error",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 2
+        },
+        "data": {
+          "failCommands": [
+            "commitTransaction"
+          ],
+          "writeConcernError": {
+            "code": 64,
+            "codeName": "WriteConcernFailed",
+            "errmsg": "waiting for replication timed out",
+            "errInfo": {
+              "wtimeout": true
+            }
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "withTransaction",
+          "object": "session0",
+          "arguments": {
+            "callback": {
+              "operations": [
+                {
+                  "name": "insertOne",
+                  "object": "collection",
+                  "arguments": {
+                    "session": "session0",
+                    "document": {
+                      "_id": 1
+                    }
+                  },
+                  "result": {
+                    "insertedId": 1
+                  }
+                }
+              ]
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "readConcern": null,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "withTransaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "autocommit": false,
+              "readConcern": null,
+              "startTransaction": null,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "autocommit": false,
+              "writeConcern": {
+                "w": "majority",
+                "wtimeout": 10000
+              },
+              "readConcern": null,
+              "startTransaction": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "autocommit": false,
+              "writeConcern": {
+                "w": "majority",
+                "wtimeout": 10000
+              },
+              "readConcern": null,
+              "startTransaction": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "commitTransaction is retried after WriteConcernFailed non-timeout error",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 2
+        },
+        "data": {
+          "failCommands": [
+            "commitTransaction"
+          ],
+          "writeConcernError": {
+            "code": 64,
+            "codeName": "WriteConcernFailed",
+            "errmsg": "multiple errors reported"
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "withTransaction",
+          "object": "session0",
+          "arguments": {
+            "callback": {
+              "operations": [
+                {
+                  "name": "insertOne",
+                  "object": "collection",
+                  "arguments": {
+                    "session": "session0",
+                    "document": {
+                      "_id": 1
+                    }
+                  },
+                  "result": {
+                    "insertedId": 1
+                  }
+                }
+              ]
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "readConcern": null,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "withTransaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "autocommit": false,
+              "readConcern": null,
+              "startTransaction": null,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "autocommit": false,
+              "writeConcern": {
+                "w": "majority",
+                "wtimeout": 10000
+              },
+              "readConcern": null,
+              "startTransaction": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "autocommit": false,
+              "writeConcern": {
+                "w": "majority",
+                "wtimeout": 10000
+              },
+              "readConcern": null,
+              "startTransaction": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "commitTransaction is not retried after UnknownReplWriteConcern error",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "commitTransaction"
+          ],
+          "writeConcernError": {
+            "code": 79,
+            "codeName": "UnknownReplWriteConcern",
+            "errmsg": "No write concern mode named 'foo' found in replica set configuration"
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "withTransaction",
+          "object": "session0",
+          "arguments": {
+            "callback": {
+              "operations": [
+                {
+                  "name": "insertOne",
+                  "object": "collection",
+                  "arguments": {
+                    "session": "session0",
+                    "document": {
+                      "_id": 1
+                    }
+                  },
+                  "result": {
+                    "insertedId": 1
+                  }
+                }
+              ]
+            }
+          },
+          "result": {
+            "errorCodeName": "UnknownReplWriteConcern",
+            "errorLabelsOmit": [
+              "TransientTransactionError",
+              "UnknownTransactionCommitResult"
+            ]
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "readConcern": null,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "withTransaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "autocommit": false,
+              "readConcern": null,
+              "startTransaction": null,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "commitTransaction is not retried after UnsatisfiableWriteConcern error",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "commitTransaction"
+          ],
+          "writeConcernError": {
+            "code": 100,
+            "codeName": "UnsatisfiableWriteConcern",
+            "errmsg": "Not enough data-bearing nodes"
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "withTransaction",
+          "object": "session0",
+          "arguments": {
+            "callback": {
+              "operations": [
+                {
+                  "name": "insertOne",
+                  "object": "collection",
+                  "arguments": {
+                    "session": "session0",
+                    "document": {
+                      "_id": 1
+                    }
+                  },
+                  "result": {
+                    "insertedId": 1
+                  }
+                }
+              ]
+            }
+          },
+          "result": {
+            "errorCodeName": "UnsatisfiableWriteConcern",
+            "errorLabelsOmit": [
+              "TransientTransactionError",
+              "UnknownTransactionCommitResult"
+            ]
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "readConcern": null,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "withTransaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "autocommit": false,
+              "readConcern": null,
+              "startTransaction": null,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "commitTransaction is not retried after MaxTimeMSExpired error",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "commitTransaction"
+          ],
+          "writeConcernError": {
+            "code": 50,
+            "codeName": "MaxTimeMSExpired",
+            "errmsg": "operation exceeded time limit"
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "withTransaction",
+          "object": "session0",
+          "arguments": {
+            "callback": {
+              "operations": [
+                {
+                  "name": "insertOne",
+                  "object": "collection",
+                  "arguments": {
+                    "session": "session0",
+                    "document": {
+                      "_id": 1
+                    }
+                  },
+                  "result": {
+                    "insertedId": 1
+                  }
+                }
+              ]
+            }
+          },
+          "result": {
+            "errorCodeName": "MaxTimeMSExpired",
+            "errorLabelsContain": [
+              "UnknownTransactionCommitResult"
+            ],
+            "errorLabelsOmit": [
+              "TransientTransactionError"
+            ]
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "readConcern": null,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "withTransaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "autocommit": false,
+              "readConcern": null,
+              "startTransaction": null,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions-convenient-api/commit.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions-convenient-api/commit.json
new file mode 100644
index 0000000000000000000000000000000000000000..0a7451db952dc3712aaa39293629694453ec70ed
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions-convenient-api/commit.json	
@@ -0,0 +1,286 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.0",
+      "topology": [
+        "replicaset"
+      ]
+    },
+    {
+      "minServerVersion": "4.1.8",
+      "topology": [
+        "sharded"
+      ]
+    }
+  ],
+  "database_name": "withTransaction-tests",
+  "collection_name": "test",
+  "data": [],
+  "tests": [
+    {
+      "description": "withTransaction commits after callback returns",
+      "useMultipleMongoses": true,
+      "operations": [
+        {
+          "name": "withTransaction",
+          "object": "session0",
+          "arguments": {
+            "callback": {
+              "operations": [
+                {
+                  "name": "insertOne",
+                  "object": "collection",
+                  "arguments": {
+                    "session": "session0",
+                    "document": {
+                      "_id": 1
+                    }
+                  },
+                  "result": {
+                    "insertedId": 1
+                  }
+                },
+                {
+                  "name": "insertOne",
+                  "object": "collection",
+                  "arguments": {
+                    "session": "session0",
+                    "document": {
+                      "_id": 2
+                    }
+                  },
+                  "result": {
+                    "insertedId": 2
+                  }
+                }
+              ]
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "readConcern": null,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "withTransaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 2
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "autocommit": false,
+              "readConcern": null,
+              "startTransaction": null,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "withTransaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "autocommit": false,
+              "readConcern": null,
+              "startTransaction": null,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "withTransaction commits after callback returns (second transaction)",
+      "useMultipleMongoses": true,
+      "operations": [
+        {
+          "name": "withTransaction",
+          "object": "session0",
+          "arguments": {
+            "callback": {
+              "operations": [
+                {
+                  "name": "insertOne",
+                  "object": "collection",
+                  "arguments": {
+                    "session": "session0",
+                    "document": {
+                      "_id": 1
+                    }
+                  },
+                  "result": {
+                    "insertedId": 1
+                  }
+                },
+                {
+                  "name": "commitTransaction",
+                  "object": "session0"
+                },
+                {
+                  "name": "startTransaction",
+                  "object": "session0"
+                },
+                {
+                  "name": "insertOne",
+                  "object": "collection",
+                  "arguments": {
+                    "session": "session0",
+                    "document": {
+                      "_id": 2
+                    }
+                  },
+                  "result": {
+                    "insertedId": 2
+                  }
+                }
+              ]
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "readConcern": null,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "withTransaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "autocommit": false,
+              "readConcern": null,
+              "startTransaction": null,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 2
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "readConcern": {
+                "afterClusterTime": 42
+              },
+              "txnNumber": {
+                "$numberLong": "2"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "withTransaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "2"
+              },
+              "autocommit": false,
+              "readConcern": null,
+              "startTransaction": null,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions-convenient-api/transaction-options.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions-convenient-api/transaction-options.json
new file mode 100644
index 0000000000000000000000000000000000000000..6deff43cf45f6c1df246f04286a7e5df6e28a6c4
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions-convenient-api/transaction-options.json	
@@ -0,0 +1,577 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.0",
+      "topology": [
+        "replicaset"
+      ]
+    },
+    {
+      "minServerVersion": "4.1.8",
+      "topology": [
+        "sharded"
+      ]
+    }
+  ],
+  "database_name": "withTransaction-tests",
+  "collection_name": "test",
+  "data": [],
+  "tests": [
+    {
+      "description": "withTransaction and no transaction options set",
+      "useMultipleMongoses": true,
+      "operations": [
+        {
+          "name": "withTransaction",
+          "object": "session0",
+          "arguments": {
+            "callback": {
+              "operations": [
+                {
+                  "name": "insertOne",
+                  "object": "collection",
+                  "arguments": {
+                    "session": "session0",
+                    "document": {
+                      "_id": 1
+                    }
+                  },
+                  "result": {
+                    "insertedId": 1
+                  }
+                }
+              ]
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "readConcern": null,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "withTransaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "autocommit": false,
+              "readConcern": null,
+              "startTransaction": null,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "withTransaction inherits transaction options from client",
+      "useMultipleMongoses": true,
+      "clientOptions": {
+        "readConcernLevel": "local",
+        "w": 1
+      },
+      "operations": [
+        {
+          "name": "withTransaction",
+          "object": "session0",
+          "arguments": {
+            "callback": {
+              "operations": [
+                {
+                  "name": "insertOne",
+                  "object": "collection",
+                  "arguments": {
+                    "session": "session0",
+                    "document": {
+                      "_id": 1
+                    }
+                  },
+                  "result": {
+                    "insertedId": 1
+                  }
+                }
+              ]
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "readConcern": {
+                "level": "local"
+              },
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "withTransaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "autocommit": false,
+              "writeConcern": {
+                "w": 1
+              },
+              "readConcern": null,
+              "startTransaction": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "withTransaction inherits transaction options from defaultTransactionOptions",
+      "useMultipleMongoses": true,
+      "sessionOptions": {
+        "session0": {
+          "defaultTransactionOptions": {
+            "readConcern": {
+              "level": "majority"
+            },
+            "writeConcern": {
+              "w": 1
+            }
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "withTransaction",
+          "object": "session0",
+          "arguments": {
+            "callback": {
+              "operations": [
+                {
+                  "name": "insertOne",
+                  "object": "collection",
+                  "arguments": {
+                    "session": "session0",
+                    "document": {
+                      "_id": 1
+                    }
+                  },
+                  "result": {
+                    "insertedId": 1
+                  }
+                }
+              ]
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "readConcern": {
+                "level": "majority"
+              },
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "withTransaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "autocommit": false,
+              "writeConcern": {
+                "w": 1
+              },
+              "readConcern": null,
+              "startTransaction": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "withTransaction explicit transaction options",
+      "useMultipleMongoses": true,
+      "operations": [
+        {
+          "name": "withTransaction",
+          "object": "session0",
+          "arguments": {
+            "callback": {
+              "operations": [
+                {
+                  "name": "insertOne",
+                  "object": "collection",
+                  "arguments": {
+                    "session": "session0",
+                    "document": {
+                      "_id": 1
+                    }
+                  },
+                  "result": {
+                    "insertedId": 1
+                  }
+                }
+              ]
+            },
+            "options": {
+              "readConcern": {
+                "level": "majority"
+              },
+              "writeConcern": {
+                "w": 1
+              }
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "readConcern": {
+                "level": "majority"
+              },
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "withTransaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "autocommit": false,
+              "writeConcern": {
+                "w": 1
+              },
+              "readConcern": null,
+              "startTransaction": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "withTransaction explicit transaction options override defaultTransactionOptions",
+      "useMultipleMongoses": true,
+      "sessionOptions": {
+        "session0": {
+          "defaultTransactionOptions": {
+            "readConcern": {
+              "level": "snapshot"
+            },
+            "writeConcern": {
+              "w": "majority"
+            }
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "withTransaction",
+          "object": "session0",
+          "arguments": {
+            "callback": {
+              "operations": [
+                {
+                  "name": "insertOne",
+                  "object": "collection",
+                  "arguments": {
+                    "session": "session0",
+                    "document": {
+                      "_id": 1
+                    }
+                  },
+                  "result": {
+                    "insertedId": 1
+                  }
+                }
+              ]
+            },
+            "options": {
+              "readConcern": {
+                "level": "majority"
+              },
+              "writeConcern": {
+                "w": 1
+              }
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "readConcern": {
+                "level": "majority"
+              },
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "withTransaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "autocommit": false,
+              "writeConcern": {
+                "w": 1
+              },
+              "readConcern": null,
+              "startTransaction": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "withTransaction explicit transaction options override client options",
+      "useMultipleMongoses": true,
+      "clientOptions": {
+        "readConcernLevel": "local",
+        "w": "majority"
+      },
+      "operations": [
+        {
+          "name": "withTransaction",
+          "object": "session0",
+          "arguments": {
+            "callback": {
+              "operations": [
+                {
+                  "name": "insertOne",
+                  "object": "collection",
+                  "arguments": {
+                    "session": "session0",
+                    "document": {
+                      "_id": 1
+                    }
+                  },
+                  "result": {
+                    "insertedId": 1
+                  }
+                }
+              ]
+            },
+            "options": {
+              "readConcern": {
+                "level": "majority"
+              },
+              "writeConcern": {
+                "w": 1
+              }
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "readConcern": {
+                "level": "majority"
+              },
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "withTransaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "autocommit": false,
+              "writeConcern": {
+                "w": 1
+              },
+              "readConcern": null,
+              "startTransaction": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/abort.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/abort.json
new file mode 100644
index 0000000000000000000000000000000000000000..3729a98298577f5467eb760222531302af955642
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/abort.json	
@@ -0,0 +1,621 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.0",
+      "topology": [
+        "replicaset"
+      ]
+    },
+    {
+      "minServerVersion": "4.1.8",
+      "topology": [
+        "sharded"
+      ]
+    }
+  ],
+  "database_name": "transaction-tests",
+  "collection_name": "test",
+  "data": [],
+  "tests": [
+    {
+      "description": "abort",
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "abortTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "abortTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "readConcern": {
+                "afterClusterTime": 42
+              },
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "2"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "abortTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "2"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "abortTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": []
+        }
+      }
+    },
+    {
+      "description": "implicit abort",
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "abortTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "abortTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": []
+        }
+      }
+    },
+    {
+      "description": "two aborts",
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0",
+          "result": {
+            "errorContains": "cannot call abortTransaction twice"
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "abortTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "abortTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": []
+        }
+      }
+    },
+    {
+      "description": "abort without start",
+      "operations": [
+        {
+          "name": "abortTransaction",
+          "object": "session0",
+          "result": {
+            "errorContains": "no transaction started"
+          }
+        }
+      ],
+      "expectations": [],
+      "outcome": {
+        "collection": {
+          "data": []
+        }
+      }
+    },
+    {
+      "description": "abort directly after no-op commit",
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0",
+          "result": {
+            "errorContains": "Cannot call abortTransaction after calling commitTransaction"
+          }
+        }
+      ],
+      "expectations": [],
+      "outcome": {
+        "collection": {
+          "data": []
+        }
+      }
+    },
+    {
+      "description": "abort directly after commit",
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0",
+          "result": {
+            "errorContains": "Cannot call abortTransaction after calling commitTransaction"
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "abort ignores TransactionAborted",
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "errorLabelsOmit": [
+              "TransientTransactionError",
+              "UnknownTransactionCommitResult"
+            ],
+            "errorContains": "E11000"
+          }
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "errorCodeName": "NoSuchTransaction",
+            "errorLabelsContain": [
+              "TransientTransactionError"
+            ],
+            "errorLabelsOmit": [
+              "UnknownTransactionCommitResult"
+            ]
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "abortTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "abortTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": []
+        }
+      }
+    },
+    {
+      "description": "abort does not apply writeConcern",
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0",
+          "arguments": {
+            "options": {
+              "writeConcern": {
+                "w": 10
+              }
+            }
+          }
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": []
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/bulk.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/bulk.json
new file mode 100644
index 0000000000000000000000000000000000000000..8a9793b8b3857bdce2097e0a7fbcda2a6bc30069
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/bulk.json	
@@ -0,0 +1,531 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.0",
+      "topology": [
+        "replicaset"
+      ]
+    },
+    {
+      "minServerVersion": "4.1.8",
+      "topology": [
+        "sharded"
+      ]
+    }
+  ],
+  "database_name": "transaction-tests",
+  "collection_name": "test",
+  "data": [],
+  "tests": [
+    {
+      "description": "bulk",
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "deleteOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "filter": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "deletedCount": 1
+          }
+        },
+        {
+          "name": "bulkWrite",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "requests": [
+              {
+                "name": "insertOne",
+                "arguments": {
+                  "document": {
+                    "_id": 1
+                  }
+                }
+              },
+              {
+                "name": "updateOne",
+                "arguments": {
+                  "filter": {
+                    "_id": 1
+                  },
+                  "update": {
+                    "$set": {
+                      "x": 1
+                    }
+                  }
+                }
+              },
+              {
+                "name": "updateOne",
+                "arguments": {
+                  "filter": {
+                    "_id": 2
+                  },
+                  "update": {
+                    "$set": {
+                      "x": 2
+                    }
+                  },
+                  "upsert": true
+                }
+              },
+              {
+                "name": "insertOne",
+                "arguments": {
+                  "document": {
+                    "_id": 3
+                  }
+                }
+              },
+              {
+                "name": "insertOne",
+                "arguments": {
+                  "document": {
+                    "_id": 4
+                  }
+                }
+              },
+              {
+                "name": "insertOne",
+                "arguments": {
+                  "document": {
+                    "_id": 5
+                  }
+                }
+              },
+              {
+                "name": "insertOne",
+                "arguments": {
+                  "document": {
+                    "_id": 6
+                  }
+                }
+              },
+              {
+                "name": "insertOne",
+                "arguments": {
+                  "document": {
+                    "_id": 7
+                  }
+                }
+              },
+              {
+                "name": "replaceOne",
+                "arguments": {
+                  "filter": {
+                    "_id": 1
+                  },
+                  "replacement": {
+                    "y": 1
+                  }
+                }
+              },
+              {
+                "name": "replaceOne",
+                "arguments": {
+                  "filter": {
+                    "_id": 2
+                  },
+                  "replacement": {
+                    "y": 2
+                  }
+                }
+              },
+              {
+                "name": "deleteOne",
+                "arguments": {
+                  "filter": {
+                    "_id": 3
+                  }
+                }
+              },
+              {
+                "name": "deleteOne",
+                "arguments": {
+                  "filter": {
+                    "_id": 4
+                  }
+                }
+              },
+              {
+                "name": "updateMany",
+                "arguments": {
+                  "filter": {
+                    "_id": {
+                      "$gte": 2
+                    }
+                  },
+                  "update": {
+                    "$set": {
+                      "z": 1
+                    }
+                  }
+                }
+              },
+              {
+                "name": "deleteMany",
+                "arguments": {
+                  "filter": {
+                    "_id": {
+                      "$gte": 6
+                    }
+                  }
+                }
+              }
+            ]
+          },
+          "result": {
+            "deletedCount": 4,
+            "insertedCount": 6,
+            "insertedIds": {
+              "0": 1,
+              "3": 3,
+              "4": 4,
+              "5": 5,
+              "6": 6,
+              "7": 7
+            },
+            "matchedCount": 7,
+            "modifiedCount": 7,
+            "upsertedCount": 1,
+            "upsertedIds": {
+              "2": 2
+            }
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "delete": "test",
+              "deletes": [
+                {
+                  "q": {
+                    "_id": 1
+                  },
+                  "limit": 1
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "delete",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "update": "test",
+              "updates": [
+                {
+                  "q": {
+                    "_id": 1
+                  },
+                  "u": {
+                    "$set": {
+                      "x": 1
+                    }
+                  }
+                },
+                {
+                  "q": {
+                    "_id": 2
+                  },
+                  "u": {
+                    "$set": {
+                      "x": 2
+                    }
+                  },
+                  "upsert": true
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "update",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 3
+                },
+                {
+                  "_id": 4
+                },
+                {
+                  "_id": 5
+                },
+                {
+                  "_id": 6
+                },
+                {
+                  "_id": 7
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "update": "test",
+              "updates": [
+                {
+                  "q": {
+                    "_id": 1
+                  },
+                  "u": {
+                    "y": 1
+                  }
+                },
+                {
+                  "q": {
+                    "_id": 2
+                  },
+                  "u": {
+                    "y": 2
+                  }
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "update",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "delete": "test",
+              "deletes": [
+                {
+                  "q": {
+                    "_id": 3
+                  },
+                  "limit": 1
+                },
+                {
+                  "q": {
+                    "_id": 4
+                  },
+                  "limit": 1
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "delete",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "update": "test",
+              "updates": [
+                {
+                  "q": {
+                    "_id": {
+                      "$gte": 2
+                    }
+                  },
+                  "u": {
+                    "$set": {
+                      "z": 1
+                    }
+                  },
+                  "multi": true
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "update",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "delete": "test",
+              "deletes": [
+                {
+                  "q": {
+                    "_id": {
+                      "$gte": 6
+                    }
+                  },
+                  "limit": 0
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "delete",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "y": 1
+            },
+            {
+              "_id": 2,
+              "y": 2,
+              "z": 1
+            },
+            {
+              "_id": 5,
+              "z": 1
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/causal-consistency.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/causal-consistency.json
new file mode 100644
index 0000000000000000000000000000000000000000..0e81bf2ff2b82be16697e3422141e014b741d180
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/causal-consistency.json	
@@ -0,0 +1,305 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.0",
+      "topology": [
+        "replicaset"
+      ]
+    },
+    {
+      "minServerVersion": "4.1.8",
+      "topology": [
+        "sharded"
+      ]
+    }
+  ],
+  "database_name": "transaction-tests",
+  "collection_name": "test",
+  "data": [
+    {
+      "_id": 1,
+      "count": 0
+    }
+  ],
+  "tests": [
+    {
+      "description": "causal consistency",
+      "clientOptions": {
+        "retryWrites": false
+      },
+      "operations": [
+        {
+          "name": "updateOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "filter": {
+              "_id": 1
+            },
+            "update": {
+              "$inc": {
+                "count": 1
+              }
+            }
+          },
+          "result": {
+            "matchedCount": 1,
+            "modifiedCount": 1,
+            "upsertedCount": 0
+          }
+        },
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "updateOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "filter": {
+              "_id": 1
+            },
+            "update": {
+              "$inc": {
+                "count": 1
+              }
+            }
+          },
+          "result": {
+            "matchedCount": 1,
+            "modifiedCount": 1,
+            "upsertedCount": 0
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "update": "test",
+              "updates": [
+                {
+                  "q": {
+                    "_id": 1
+                  },
+                  "u": {
+                    "$inc": {
+                      "count": 1
+                    }
+                  }
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "readConcern": null,
+              "txnNumber": null,
+              "startTransaction": null,
+              "autocommit": null,
+              "writeConcern": null
+            },
+            "command_name": "update",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "update": "test",
+              "updates": [
+                {
+                  "q": {
+                    "_id": 1
+                  },
+                  "u": {
+                    "$inc": {
+                      "count": 1
+                    }
+                  }
+                }
+              ],
+              "ordered": true,
+              "readConcern": {
+                "afterClusterTime": 42
+              },
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "update",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "count": 2
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "causal consistency disabled",
+      "clientOptions": {
+        "retryWrites": false
+      },
+      "sessionOptions": {
+        "session0": {
+          "causalConsistency": false
+        }
+      },
+      "operations": [
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 2
+            }
+          },
+          "result": {
+            "insertedId": 2
+          }
+        },
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "updateOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "filter": {
+              "_id": 1
+            },
+            "update": {
+              "$inc": {
+                "count": 1
+              }
+            }
+          },
+          "result": {
+            "matchedCount": 1,
+            "modifiedCount": 1,
+            "upsertedCount": 0
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 2
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": null,
+              "autocommit": null,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "update": "test",
+              "updates": [
+                {
+                  "q": {
+                    "_id": 1
+                  },
+                  "u": {
+                    "$inc": {
+                      "count": 1
+                    }
+                  }
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "update",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1,
+              "count": 1
+            },
+            {
+              "_id": 2
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/commit.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/commit.json
new file mode 100644
index 0000000000000000000000000000000000000000..faa39a65f1890b1f11dbb3b46d20eeb2754d8e2f
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/commit.json	
@@ -0,0 +1,925 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.0",
+      "topology": [
+        "replicaset"
+      ]
+    },
+    {
+      "minServerVersion": "4.1.8",
+      "topology": [
+        "sharded"
+      ]
+    }
+  ],
+  "database_name": "transaction-tests",
+  "collection_name": "test",
+  "data": [],
+  "tests": [
+    {
+      "description": "commit",
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 2
+            }
+          },
+          "result": {
+            "insertedId": 2
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 2
+                }
+              ],
+              "ordered": true,
+              "readConcern": {
+                "afterClusterTime": 42
+              },
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "2"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "2"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "rerun commit after empty transaction",
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "2"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "2"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "multiple commits in a row",
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": {
+                "w": "majority",
+                "wtimeout": 10000
+              }
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": {
+                "w": "majority",
+                "wtimeout": 10000
+              }
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "write concern error on commit",
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0",
+          "arguments": {
+            "options": {
+              "writeConcern": {
+                "w": 10
+              }
+            }
+          }
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0",
+          "result": {
+            "errorLabelsOmit": [
+              "TransientTransactionError",
+              "UnknownTransactionCommitResult"
+            ]
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "commit without start",
+      "operations": [
+        {
+          "name": "commitTransaction",
+          "object": "session0",
+          "result": {
+            "errorContains": "no transaction started"
+          }
+        }
+      ],
+      "expectations": [],
+      "outcome": {
+        "collection": {
+          "data": []
+        }
+      }
+    },
+    {
+      "description": "commit after no-op abort",
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0",
+          "result": {
+            "errorContains": "Cannot call commitTransaction after calling abortTransaction"
+          }
+        }
+      ],
+      "expectations": [],
+      "outcome": {
+        "collection": {
+          "data": []
+        }
+      }
+    },
+    {
+      "description": "commit after abort",
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0",
+          "result": {
+            "errorContains": "Cannot call commitTransaction after calling abortTransaction"
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "abortTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "abortTransaction",
+            "database_name": "admin"
+          }
+        }
+      ]
+    },
+    {
+      "description": "multiple commits after empty transaction",
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "abortTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "abortTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "readConcern": {
+                "afterClusterTime": 42
+              },
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "3"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "abortTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "3"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "abortTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": []
+        }
+      }
+    },
+    {
+      "description": "reset session state commit",
+      "clientOptions": {
+        "retryWrites": false
+      },
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 2
+            }
+          },
+          "result": {
+            "insertedId": 2
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0",
+          "result": {
+            "errorContains": "no transaction started"
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 2
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": null,
+              "startTransaction": null,
+              "autocommit": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "reset session state abort",
+      "clientOptions": {
+        "retryWrites": false
+      },
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 2
+            }
+          },
+          "result": {
+            "insertedId": 2
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0",
+          "result": {
+            "errorContains": "no transaction started"
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "abortTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "abortTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 2
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": null,
+              "startTransaction": null,
+              "autocommit": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 2
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/count.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/count.json
new file mode 100644
index 0000000000000000000000000000000000000000..169296416a4f38ab85f1d61c448e4aef7f80f71f
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/count.json	
@@ -0,0 +1,120 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.0.2",
+      "topology": [
+        "replicaset"
+      ]
+    },
+    {
+      "minServerVersion": "4.1.8",
+      "topology": [
+        "sharded"
+      ]
+    }
+  ],
+  "database_name": "transaction-tests",
+  "collection_name": "test",
+  "data": [
+    {
+      "_id": 1
+    },
+    {
+      "_id": 2
+    },
+    {
+      "_id": 3
+    },
+    {
+      "_id": 4
+    }
+  ],
+  "tests": [
+    {
+      "description": "count",
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "count",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "filter": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "errorCodeName": "OperationNotSupportedInTransaction",
+            "errorLabelsOmit": [
+              "TransientTransactionError",
+              "UnknownTransactionCommitResult"
+            ]
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "count": "test",
+              "query": {
+                "_id": 1
+              },
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "count",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "abortTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "abortTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            },
+            {
+              "_id": 3
+            },
+            {
+              "_id": 4
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/create-collection.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/create-collection.json
new file mode 100644
index 0000000000000000000000000000000000000000..9071c59c4192849b7fc19a644514ba95707d5486
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/create-collection.json	
@@ -0,0 +1,204 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.3.4",
+      "topology": [
+        "replicaset",
+        "sharded"
+      ]
+    }
+  ],
+  "database_name": "transaction-tests",
+  "collection_name": "test",
+  "data": [],
+  "tests": [
+    {
+      "description": "explicitly create collection using create command",
+      "operations": [
+        {
+          "name": "dropCollection",
+          "object": "database",
+          "arguments": {
+            "collection": "test"
+          }
+        },
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "createCollection",
+          "object": "database",
+          "arguments": {
+            "session": "session0",
+            "collection": "test"
+          }
+        },
+        {
+          "name": "assertCollectionNotExists",
+          "object": "testRunner",
+          "arguments": {
+            "database": "transaction-tests",
+            "collection": "test"
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "assertCollectionExists",
+          "object": "testRunner",
+          "arguments": {
+            "database": "transaction-tests",
+            "collection": "test"
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "drop": "test",
+              "writeConcern": null
+            },
+            "command_name": "drop",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "create": "test",
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "create",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ]
+    },
+    {
+      "description": "implicitly create collection using insert",
+      "operations": [
+        {
+          "name": "dropCollection",
+          "object": "database",
+          "arguments": {
+            "collection": "test"
+          }
+        },
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "assertCollectionNotExists",
+          "object": "testRunner",
+          "arguments": {
+            "database": "transaction-tests",
+            "collection": "test"
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "assertCollectionExists",
+          "object": "testRunner",
+          "arguments": {
+            "database": "transaction-tests",
+            "collection": "test"
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "drop": "test",
+              "writeConcern": null
+            },
+            "command_name": "drop",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/create-index.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/create-index.json
new file mode 100644
index 0000000000000000000000000000000000000000..2ff09c9288f1056fd08711dad97d04a34e4672ad
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/create-index.json	
@@ -0,0 +1,237 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.3.4",
+      "topology": [
+        "replicaset",
+        "sharded"
+      ]
+    }
+  ],
+  "database_name": "transaction-tests",
+  "collection_name": "test",
+  "data": [],
+  "tests": [
+    {
+      "description": "create index on a non-existing collection",
+      "operations": [
+        {
+          "name": "dropCollection",
+          "object": "database",
+          "arguments": {
+            "collection": "test"
+          }
+        },
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "createIndex",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "name": "t_1",
+            "keys": {
+              "x": 1
+            }
+          }
+        },
+        {
+          "name": "assertIndexNotExists",
+          "object": "testRunner",
+          "arguments": {
+            "database": "transaction-tests",
+            "collection": "test",
+            "index": "t_1"
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "assertIndexExists",
+          "object": "testRunner",
+          "arguments": {
+            "database": "transaction-tests",
+            "collection": "test",
+            "index": "t_1"
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "drop": "test",
+              "writeConcern": null
+            },
+            "command_name": "drop",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "createIndexes": "test",
+              "indexes": [
+                {
+                  "name": "t_1",
+                  "key": {
+                    "x": 1
+                  }
+                }
+              ],
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "createIndexes",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ]
+    },
+    {
+      "description": "create index on a collection created within the same transaction",
+      "operations": [
+        {
+          "name": "dropCollection",
+          "object": "database",
+          "arguments": {
+            "collection": "test"
+          }
+        },
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "createCollection",
+          "object": "database",
+          "arguments": {
+            "session": "session0",
+            "collection": "test"
+          }
+        },
+        {
+          "name": "createIndex",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "name": "t_1",
+            "keys": {
+              "x": 1
+            }
+          }
+        },
+        {
+          "name": "assertIndexNotExists",
+          "object": "testRunner",
+          "arguments": {
+            "database": "transaction-tests",
+            "collection": "test",
+            "index": "t_1"
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "assertIndexExists",
+          "object": "testRunner",
+          "arguments": {
+            "database": "transaction-tests",
+            "collection": "test",
+            "index": "t_1"
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "drop": "test",
+              "writeConcern": null
+            },
+            "command_name": "drop",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "create": "test",
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "create",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "createIndexes": "test",
+              "indexes": [
+                {
+                  "name": "t_1",
+                  "key": {
+                    "x": 1
+                  }
+                }
+              ],
+              "lsid": "session0",
+              "writeConcern": null
+            },
+            "command_name": "createIndexes",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/delete.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/delete.json
new file mode 100644
index 0000000000000000000000000000000000000000..65b83270392bb9d985dc5d269ed1bb23f02ba61c
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/delete.json	
@@ -0,0 +1,327 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.0",
+      "topology": [
+        "replicaset"
+      ]
+    },
+    {
+      "minServerVersion": "4.1.8",
+      "topology": [
+        "sharded"
+      ]
+    }
+  ],
+  "database_name": "transaction-tests",
+  "collection_name": "test",
+  "data": [
+    {
+      "_id": 1
+    },
+    {
+      "_id": 2
+    },
+    {
+      "_id": 3
+    },
+    {
+      "_id": 4
+    },
+    {
+      "_id": 5
+    }
+  ],
+  "tests": [
+    {
+      "description": "delete",
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "deleteOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "filter": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "deletedCount": 1
+          }
+        },
+        {
+          "name": "deleteMany",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "filter": {
+              "_id": {
+                "$lte": 3
+              }
+            }
+          },
+          "result": {
+            "deletedCount": 2
+          }
+        },
+        {
+          "name": "deleteOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "filter": {
+              "_id": 4
+            }
+          },
+          "result": {
+            "deletedCount": 1
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "delete": "test",
+              "deletes": [
+                {
+                  "q": {
+                    "_id": 1
+                  },
+                  "limit": 1
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "delete",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "delete": "test",
+              "deletes": [
+                {
+                  "q": {
+                    "_id": {
+                      "$lte": 3
+                    }
+                  },
+                  "limit": 0
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "delete",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "delete": "test",
+              "deletes": [
+                {
+                  "q": {
+                    "_id": 4
+                  },
+                  "limit": 1
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "delete",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 5
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "collection writeConcern ignored for delete",
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0",
+          "arguments": {
+            "options": {
+              "writeConcern": {
+                "w": "majority"
+              }
+            }
+          }
+        },
+        {
+          "name": "deleteOne",
+          "object": "collection",
+          "collectionOptions": {
+            "writeConcern": {
+              "w": "majority"
+            }
+          },
+          "arguments": {
+            "session": "session0",
+            "filter": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "deletedCount": 1
+          }
+        },
+        {
+          "name": "deleteMany",
+          "object": "collection",
+          "collectionOptions": {
+            "writeConcern": {
+              "w": "majority"
+            }
+          },
+          "arguments": {
+            "session": "session0",
+            "filter": {
+              "_id": {
+                "$lte": 3
+              }
+            }
+          },
+          "result": {
+            "deletedCount": 2
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "delete": "test",
+              "deletes": [
+                {
+                  "q": {
+                    "_id": 1
+                  },
+                  "limit": 1
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "delete",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "delete": "test",
+              "deletes": [
+                {
+                  "q": {
+                    "_id": {
+                      "$lte": 3
+                    }
+                  },
+                  "limit": 0
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "delete",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": {
+                "w": "majority"
+              }
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/error-labels.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/error-labels.json
new file mode 100644
index 0000000000000000000000000000000000000000..2d3eed3ccc333066427114e7290aba9089e171b3
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/error-labels.json	
@@ -0,0 +1,2085 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.0",
+      "topology": [
+        "replicaset"
+      ]
+    },
+    {
+      "minServerVersion": "4.1.8",
+      "topology": [
+        "sharded"
+      ]
+    }
+  ],
+  "database_name": "transaction-tests",
+  "collection_name": "test",
+  "data": [],
+  "tests": [
+    {
+      "description": "DuplicateKey errors do not contain transient label",
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertMany",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "documents": [
+              {
+                "_id": 1
+              },
+              {
+                "_id": 1
+              }
+            ]
+          },
+          "result": {
+            "errorLabelsOmit": [
+              "TransientTransactionError",
+              "UnknownTransactionCommitResult"
+            ],
+            "errorContains": "E11000"
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                },
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "abortTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "abortTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": []
+        }
+      }
+    },
+    {
+      "description": "NotMaster errors contain transient label",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "insert"
+          ],
+          "errorCode": 10107
+        }
+      },
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "errorLabelsContain": [
+              "TransientTransactionError"
+            ],
+            "errorLabelsOmit": [
+              "RetryableWriteError",
+              "UnknownTransactionCommitResult"
+            ]
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "abortTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "abortTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": []
+        }
+      }
+    },
+    {
+      "description": "WriteConflict errors contain transient label",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "insert"
+          ],
+          "errorCode": 112
+        }
+      },
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "errorLabelsContain": [
+              "TransientTransactionError"
+            ],
+            "errorLabelsOmit": [
+              "RetryableWriteError",
+              "UnknownTransactionCommitResult"
+            ]
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "abortTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "abortTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": []
+        }
+      }
+    },
+    {
+      "description": "NoSuchTransaction errors contain transient label",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "insert"
+          ],
+          "errorCode": 251
+        }
+      },
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "errorLabelsContain": [
+              "TransientTransactionError"
+            ],
+            "errorLabelsOmit": [
+              "RetryableWriteError",
+              "UnknownTransactionCommitResult"
+            ]
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "abortTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "abortTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": []
+        }
+      }
+    },
+    {
+      "description": "NoSuchTransaction errors on commit contain transient label",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "commitTransaction"
+          ],
+          "errorCode": 251
+        }
+      },
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0",
+          "result": {
+            "errorLabelsContain": [
+              "TransientTransactionError"
+            ],
+            "errorLabelsOmit": [
+              "RetryableWriteError",
+              "UnknownTransactionCommitResult"
+            ]
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": []
+        }
+      }
+    },
+    {
+      "description": "add TransientTransactionError label to connection errors, but do not add RetryableWriteError label",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 4
+        },
+        "data": {
+          "failCommands": [
+            "insert",
+            "find",
+            "aggregate",
+            "distinct"
+          ],
+          "closeConnection": true
+        }
+      },
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "errorLabelsContain": [
+              "TransientTransactionError"
+            ],
+            "errorLabelsOmit": [
+              "RetryableWriteError",
+              "UnknownTransactionCommitResult"
+            ]
+          }
+        },
+        {
+          "name": "find",
+          "object": "collection",
+          "arguments": {
+            "session": "session0"
+          },
+          "result": {
+            "errorLabelsContain": [
+              "TransientTransactionError"
+            ],
+            "errorLabelsOmit": [
+              "RetryableWriteError",
+              "UnknownTransactionCommitResult"
+            ]
+          }
+        },
+        {
+          "name": "aggregate",
+          "object": "collection",
+          "arguments": {
+            "pipeline": [
+              {
+                "$project": {
+                  "_id": 1
+                }
+              }
+            ],
+            "session": "session0"
+          },
+          "result": {
+            "errorLabelsContain": [
+              "TransientTransactionError"
+            ],
+            "errorLabelsOmit": [
+              "RetryableWriteError",
+              "UnknownTransactionCommitResult"
+            ]
+          }
+        },
+        {
+          "name": "distinct",
+          "object": "collection",
+          "arguments": {
+            "fieldName": "_id",
+            "session": "session0"
+          },
+          "result": {
+            "errorLabelsContain": [
+              "TransientTransactionError"
+            ],
+            "errorLabelsOmit": [
+              "RetryableWriteError",
+              "UnknownTransactionCommitResult"
+            ]
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "test",
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false
+            },
+            "command_name": "find",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test",
+              "pipeline": [
+                {
+                  "$project": {
+                    "_id": 1
+                  }
+                }
+              ],
+              "cursor": {},
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false
+            },
+            "command_name": "aggregate",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "distinct": "test",
+              "key": "_id",
+              "lsid": "session0",
+              "readConcern": null,
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false
+            },
+            "command_name": "distinct",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "abortTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "abortTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": []
+        }
+      }
+    },
+    {
+      "description": "add RetryableWriteError and UnknownTransactionCommitResult labels to connection errors",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 2
+        },
+        "data": {
+          "failCommands": [
+            "commitTransaction"
+          ],
+          "closeConnection": true
+        }
+      },
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0",
+          "result": {
+            "errorLabelsContain": [
+              "RetryableWriteError",
+              "UnknownTransactionCommitResult"
+            ],
+            "errorLabelsOmit": [
+              "TransientTransactionError"
+            ]
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": {
+                "w": "majority",
+                "wtimeout": 10000
+              }
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": {
+                "w": "majority",
+                "wtimeout": 10000
+              }
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "add RetryableWriteError and UnknownTransactionCommitResult labels to retryable commit errors",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 2
+        },
+        "data": {
+          "failCommands": [
+            "commitTransaction"
+          ],
+          "errorCode": 11602,
+          "errorLabels": [
+            "RetryableWriteError"
+          ]
+        }
+      },
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0",
+          "result": {
+            "errorLabelsContain": [
+              "RetryableWriteError",
+              "UnknownTransactionCommitResult"
+            ],
+            "errorLabelsOmit": [
+              "TransientTransactionError"
+            ]
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": {
+                "w": "majority",
+                "wtimeout": 10000
+              }
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": {
+                "w": "majority",
+                "wtimeout": 10000
+              }
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "add RetryableWriteError and UnknownTransactionCommitResult labels to writeConcernError ShutdownInProgress",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 2
+        },
+        "data": {
+          "failCommands": [
+            "commitTransaction"
+          ],
+          "writeConcernError": {
+            "code": 91,
+            "errmsg": "Replication is being shut down",
+            "errorLabels": [
+              "RetryableWriteError"
+            ]
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0",
+          "arguments": {
+            "options": {
+              "writeConcern": {
+                "w": "majority"
+              }
+            }
+          }
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0",
+          "result": {
+            "errorLabelsContain": [
+              "RetryableWriteError",
+              "UnknownTransactionCommitResult"
+            ],
+            "errorLabelsOmit": [
+              "TransientTransactionError"
+            ]
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": {
+                "w": "majority"
+              }
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": {
+                "w": "majority",
+                "wtimeout": 10000
+              }
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": {
+                "w": "majority",
+                "wtimeout": 10000
+              }
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "do not add RetryableWriteError label to writeConcernError ShutdownInProgress that occurs within transaction",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "insert"
+          ],
+          "writeConcernError": {
+            "code": 91,
+            "errmsg": "Replication is being shut down"
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0",
+          "arguments": {
+            "options": {
+              "writeConcern": {
+                "w": "majority"
+              }
+            }
+          }
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "errorLabelsContain": [],
+            "errorLabelsOmit": [
+              "RetryableWriteError",
+              "TransientTransactionError",
+              "UnknownTransactionCommitResult"
+            ]
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "abortTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false
+            },
+            "command_name": "abortTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": []
+        }
+      }
+    },
+    {
+      "description": "add UnknownTransactionCommitResult label to writeConcernError WriteConcernFailed",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "commitTransaction"
+          ],
+          "writeConcernError": {
+            "code": 64,
+            "errmsg": "multiple errors reported"
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0",
+          "arguments": {
+            "options": {
+              "writeConcern": {
+                "w": "majority"
+              }
+            }
+          }
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0",
+          "result": {
+            "errorLabelsContain": [
+              "UnknownTransactionCommitResult"
+            ],
+            "errorLabelsOmit": [
+              "RetryableWriteError",
+              "TransientTransactionError"
+            ]
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": {
+                "w": "majority"
+              }
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": {
+                "w": "majority",
+                "wtimeout": 10000
+              }
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "add UnknownTransactionCommitResult label to writeConcernError WriteConcernFailed with wtimeout",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "commitTransaction"
+          ],
+          "writeConcernError": {
+            "code": 64,
+            "codeName": "WriteConcernFailed",
+            "errmsg": "waiting for replication timed out",
+            "errInfo": {
+              "wtimeout": true
+            }
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0",
+          "arguments": {
+            "options": {
+              "writeConcern": {
+                "w": "majority"
+              }
+            }
+          }
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0",
+          "result": {
+            "errorLabelsContain": [
+              "UnknownTransactionCommitResult"
+            ],
+            "errorLabelsOmit": [
+              "RetryableWriteError",
+              "TransientTransactionError"
+            ]
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": {
+                "w": "majority"
+              }
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": {
+                "w": "majority",
+                "wtimeout": 10000
+              }
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "omit UnknownTransactionCommitResult label from writeConcernError UnsatisfiableWriteConcern",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "commitTransaction"
+          ],
+          "writeConcernError": {
+            "code": 100,
+            "errmsg": "Not enough data-bearing nodes"
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0",
+          "arguments": {
+            "options": {
+              "writeConcern": {
+                "w": "majority"
+              }
+            }
+          }
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0",
+          "result": {
+            "errorLabelsOmit": [
+              "RetryableWriteError",
+              "TransientTransactionError",
+              "UnknownTransactionCommitResult"
+            ]
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": {
+                "w": "majority"
+              }
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "omit UnknownTransactionCommitResult label from writeConcernError UnknownReplWriteConcern",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "commitTransaction"
+          ],
+          "writeConcernError": {
+            "code": 79,
+            "errmsg": "No write concern mode named 'blah' found in replica set configuration"
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0",
+          "arguments": {
+            "options": {
+              "writeConcern": {
+                "w": "majority"
+              }
+            }
+          }
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0",
+          "result": {
+            "errorLabelsOmit": [
+              "RetryableWriteConcern",
+              "TransientTransactionError",
+              "UnknownTransactionCommitResult"
+            ]
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": {
+                "w": "majority"
+              }
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "do not add UnknownTransactionCommitResult label to MaxTimeMSExpired inside transactions",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "aggregate"
+          ],
+          "errorCode": 50
+        }
+      },
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "aggregate",
+          "object": "collection",
+          "arguments": {
+            "pipeline": [
+              {
+                "$project": {
+                  "_id": 1
+                }
+              }
+            ],
+            "maxTimeMS": 60000,
+            "session": "session0"
+          },
+          "result": {
+            "errorLabelsOmit": [
+              "RetryableWriteError",
+              "UnknownTransactionCommitResult",
+              "TransientTransactionError"
+            ]
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test",
+              "pipeline": [
+                {
+                  "$project": {
+                    "_id": 1
+                  }
+                }
+              ],
+              "cursor": {},
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "autocommit": false,
+              "maxTimeMS": 60000
+            },
+            "command_name": "aggregate",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "abortTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "abortTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": []
+        }
+      }
+    },
+    {
+      "description": "add UnknownTransactionCommitResult label to MaxTimeMSExpired",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "commitTransaction"
+          ],
+          "errorCode": 50
+        }
+      },
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0",
+          "arguments": {
+            "options": {
+              "writeConcern": {
+                "w": "majority"
+              },
+              "maxCommitTimeMS": 60000
+            }
+          }
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0",
+          "result": {
+            "errorLabelsContain": [
+              "UnknownTransactionCommitResult"
+            ],
+            "errorLabelsOmit": [
+              "RetryableWriteError",
+              "TransientTransactionError"
+            ]
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": {
+                "w": "majority"
+              },
+              "maxTimeMS": 60000
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": {
+                "w": "majority",
+                "wtimeout": 10000
+              },
+              "maxTimeMS": 60000
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "add UnknownTransactionCommitResult label to writeConcernError MaxTimeMSExpired",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "commitTransaction"
+          ],
+          "writeConcernError": {
+            "code": 50,
+            "errmsg": "operation exceeded time limit"
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0",
+          "arguments": {
+            "options": {
+              "writeConcern": {
+                "w": "majority"
+              },
+              "maxCommitTimeMS": 60000
+            }
+          }
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0",
+          "result": {
+            "errorLabelsContain": [
+              "UnknownTransactionCommitResult"
+            ],
+            "errorLabelsOmit": [
+              "RetryableWriteError",
+              "TransientTransactionError"
+            ]
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": {
+                "w": "majority"
+              },
+              "maxTimeMS": 60000
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": {
+                "w": "majority",
+                "wtimeout": 10000
+              },
+              "maxTimeMS": 60000
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/errors-client.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/errors-client.json
new file mode 100644
index 0000000000000000000000000000000000000000..4bd1c0eb321023da2966c027b41afe6042b8a0ce
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/errors-client.json	
@@ -0,0 +1,94 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.0",
+      "topology": [
+        "replicaset"
+      ]
+    },
+    {
+      "minServerVersion": "4.1.8",
+      "topology": [
+        "sharded"
+      ]
+    }
+  ],
+  "database_name": "transaction-tests",
+  "collection_name": "test",
+  "data": [],
+  "tests": [
+    {
+      "description": "Client side error in command starting transaction",
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": {
+                ".": "."
+              }
+            }
+          },
+          "error": true
+        },
+        {
+          "name": "assertSessionTransactionState",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0",
+            "state": "starting"
+          }
+        }
+      ]
+    },
+    {
+      "description": "Client side error when transaction is in progress",
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 4
+            }
+          },
+          "result": {
+            "insertedId": 4
+          }
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": {
+                ".": "."
+              }
+            }
+          },
+          "error": true
+        },
+        {
+          "name": "assertSessionTransactionState",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0",
+            "state": "in_progress"
+          }
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/errors.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/errors.json
new file mode 100644
index 0000000000000000000000000000000000000000..5fc4905e8c32edac6ab467c0cccd3a26e443766b
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/errors.json	
@@ -0,0 +1,222 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.0",
+      "topology": [
+        "replicaset"
+      ]
+    },
+    {
+      "minServerVersion": "4.1.8",
+      "topology": [
+        "sharded"
+      ]
+    }
+  ],
+  "database_name": "transaction-tests",
+  "collection_name": "test",
+  "data": [],
+  "tests": [
+    {
+      "description": "start insert start",
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "startTransaction",
+          "object": "session0",
+          "result": {
+            "errorContains": "transaction already in progress"
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        }
+      ]
+    },
+    {
+      "description": "start twice",
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "startTransaction",
+          "object": "session0",
+          "result": {
+            "errorContains": "transaction already in progress"
+          }
+        }
+      ]
+    },
+    {
+      "description": "commit and start twice",
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "startTransaction",
+          "object": "session0",
+          "result": {
+            "errorContains": "transaction already in progress"
+          }
+        }
+      ]
+    },
+    {
+      "description": "write conflict commit",
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "startTransaction",
+          "object": "session1"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session1",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "errorCodeName": "WriteConflict",
+            "errorLabelsContain": [
+              "TransientTransactionError"
+            ],
+            "errorLabelsOmit": [
+              "UnknownTransactionCommitResult"
+            ]
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session1",
+          "result": {
+            "errorCodeName": "NoSuchTransaction",
+            "errorLabelsContain": [
+              "TransientTransactionError"
+            ],
+            "errorLabelsOmit": [
+              "UnknownTransactionCommitResult"
+            ]
+          }
+        }
+      ]
+    },
+    {
+      "description": "write conflict abort",
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "startTransaction",
+          "object": "session1"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session1",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "errorCodeName": "WriteConflict",
+            "errorLabelsContain": [
+              "TransientTransactionError"
+            ],
+            "errorLabelsOmit": [
+              "UnknownTransactionCommitResult"
+            ]
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session1"
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/findOneAndDelete.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/findOneAndDelete.json
new file mode 100644
index 0000000000000000000000000000000000000000..d82657a9f533c72813b9b1e9409fb48339e9d699
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/findOneAndDelete.json	
@@ -0,0 +1,221 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.0",
+      "topology": [
+        "replicaset"
+      ]
+    },
+    {
+      "minServerVersion": "4.1.8",
+      "topology": [
+        "sharded"
+      ]
+    }
+  ],
+  "database_name": "transaction-tests",
+  "collection_name": "test",
+  "data": [
+    {
+      "_id": 1
+    },
+    {
+      "_id": 2
+    },
+    {
+      "_id": 3
+    }
+  ],
+  "tests": [
+    {
+      "description": "findOneAndDelete",
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "findOneAndDelete",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "filter": {
+              "_id": 3
+            }
+          },
+          "result": {
+            "_id": 3
+          }
+        },
+        {
+          "name": "findOneAndDelete",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "filter": {
+              "_id": 4
+            }
+          },
+          "result": null
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "findAndModify": "test",
+              "query": {
+                "_id": 3
+              },
+              "remove": true,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "readConcern": null,
+              "writeConcern": null
+            },
+            "command_name": "findAndModify",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "findAndModify": "test",
+              "query": {
+                "_id": 4
+              },
+              "remove": true,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "readConcern": null,
+              "writeConcern": null
+            },
+            "command_name": "findAndModify",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "readConcern": null,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "collection writeConcern ignored for findOneAndDelete",
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0",
+          "arguments": {
+            "options": {
+              "writeConcern": {
+                "w": "majority"
+              }
+            }
+          }
+        },
+        {
+          "name": "findOneAndDelete",
+          "object": "collection",
+          "collectionOptions": {
+            "writeConcern": {
+              "w": "majority"
+            }
+          },
+          "arguments": {
+            "session": "session0",
+            "filter": {
+              "_id": 3
+            }
+          },
+          "result": {
+            "_id": 3
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "findAndModify": "test",
+              "query": {
+                "_id": 3
+              },
+              "remove": true,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "readConcern": null,
+              "writeConcern": null
+            },
+            "command_name": "findAndModify",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "readConcern": null,
+              "writeConcern": {
+                "w": "majority"
+              }
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/findOneAndReplace.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/findOneAndReplace.json
new file mode 100644
index 0000000000000000000000000000000000000000..7a54ca3433e7da2ef1027feb792858114690f90b
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/findOneAndReplace.json	
@@ -0,0 +1,255 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.0",
+      "topology": [
+        "replicaset"
+      ]
+    },
+    {
+      "minServerVersion": "4.1.8",
+      "topology": [
+        "sharded"
+      ]
+    }
+  ],
+  "database_name": "transaction-tests",
+  "collection_name": "test",
+  "data": [
+    {
+      "_id": 1
+    },
+    {
+      "_id": 2
+    },
+    {
+      "_id": 3
+    }
+  ],
+  "tests": [
+    {
+      "description": "findOneAndReplace",
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "findOneAndReplace",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "filter": {
+              "_id": 3
+            },
+            "replacement": {
+              "x": 1
+            },
+            "returnDocument": "Before"
+          },
+          "result": {
+            "_id": 3
+          }
+        },
+        {
+          "name": "findOneAndReplace",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "filter": {
+              "_id": 4
+            },
+            "replacement": {
+              "x": 1
+            },
+            "upsert": true,
+            "returnDocument": "After"
+          },
+          "result": {
+            "_id": 4,
+            "x": 1
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "findAndModify": "test",
+              "query": {
+                "_id": 3
+              },
+              "update": {
+                "x": 1
+              },
+              "new": false,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "readConcern": null,
+              "writeConcern": null
+            },
+            "command_name": "findAndModify",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "findAndModify": "test",
+              "query": {
+                "_id": 4
+              },
+              "update": {
+                "x": 1
+              },
+              "new": true,
+              "upsert": true,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "readConcern": null,
+              "writeConcern": null
+            },
+            "command_name": "findAndModify",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "readConcern": null,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            },
+            {
+              "_id": 3,
+              "x": 1
+            },
+            {
+              "_id": 4,
+              "x": 1
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "collection writeConcern ignored for findOneAndReplace",
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0",
+          "arguments": {
+            "options": {
+              "writeConcern": {
+                "w": "majority"
+              }
+            }
+          }
+        },
+        {
+          "name": "findOneAndReplace",
+          "object": "collection",
+          "collectionOptions": {
+            "writeConcern": {
+              "w": "majority"
+            }
+          },
+          "arguments": {
+            "session": "session0",
+            "filter": {
+              "_id": 3
+            },
+            "replacement": {
+              "x": 1
+            },
+            "returnDocument": "Before"
+          },
+          "result": {
+            "_id": 3
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "findAndModify": "test",
+              "query": {
+                "_id": 3
+              },
+              "update": {
+                "x": 1
+              },
+              "new": false,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "readConcern": null,
+              "writeConcern": null
+            },
+            "command_name": "findAndModify",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "readConcern": null,
+              "writeConcern": {
+                "w": "majority"
+              }
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/findOneAndUpdate.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/findOneAndUpdate.json
new file mode 100644
index 0000000000000000000000000000000000000000..7af54ba808102308048b22b86959a0cb49443393
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/findOneAndUpdate.json	
@@ -0,0 +1,413 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.0",
+      "topology": [
+        "replicaset"
+      ]
+    },
+    {
+      "minServerVersion": "4.1.8",
+      "topology": [
+        "sharded"
+      ]
+    }
+  ],
+  "database_name": "transaction-tests",
+  "collection_name": "test",
+  "data": [
+    {
+      "_id": 1
+    },
+    {
+      "_id": 2
+    },
+    {
+      "_id": 3
+    }
+  ],
+  "tests": [
+    {
+      "description": "findOneAndUpdate",
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "findOneAndUpdate",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "filter": {
+              "_id": 3
+            },
+            "update": {
+              "$inc": {
+                "x": 1
+              }
+            },
+            "returnDocument": "Before"
+          },
+          "result": {
+            "_id": 3
+          }
+        },
+        {
+          "name": "findOneAndUpdate",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "filter": {
+              "_id": 4
+            },
+            "update": {
+              "$inc": {
+                "x": 1
+              }
+            },
+            "upsert": true,
+            "returnDocument": "After"
+          },
+          "result": {
+            "_id": 4,
+            "x": 1
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "findOneAndUpdate",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "filter": {
+              "_id": 3
+            },
+            "update": {
+              "$inc": {
+                "x": 1
+              }
+            },
+            "returnDocument": "Before"
+          },
+          "result": {
+            "_id": 3,
+            "x": 1
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "findOneAndUpdate",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "filter": {
+              "_id": 3
+            },
+            "update": {
+              "$inc": {
+                "x": 1
+              }
+            },
+            "returnDocument": "Before"
+          },
+          "result": {
+            "_id": 3,
+            "x": 2
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "findAndModify": "test",
+              "query": {
+                "_id": 3
+              },
+              "update": {
+                "$inc": {
+                  "x": 1
+                }
+              },
+              "new": false,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "readConcern": null,
+              "writeConcern": null
+            },
+            "command_name": "findAndModify",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "findAndModify": "test",
+              "query": {
+                "_id": 4
+              },
+              "update": {
+                "$inc": {
+                  "x": 1
+                }
+              },
+              "new": true,
+              "upsert": true,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "readConcern": null,
+              "writeConcern": null
+            },
+            "command_name": "findAndModify",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "readConcern": null,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "findAndModify": "test",
+              "query": {
+                "_id": 3
+              },
+              "update": {
+                "$inc": {
+                  "x": 1
+                }
+              },
+              "new": false,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "2"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "readConcern": {
+                "afterClusterTime": 42
+              },
+              "writeConcern": null
+            },
+            "command_name": "findAndModify",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "2"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "readConcern": null,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "findAndModify": "test",
+              "query": {
+                "_id": 3
+              },
+              "update": {
+                "$inc": {
+                  "x": 1
+                }
+              },
+              "new": false,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "3"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "readConcern": {
+                "afterClusterTime": 42
+              },
+              "writeConcern": null
+            },
+            "command_name": "findAndModify",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "abortTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "3"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "readConcern": null,
+              "writeConcern": null
+            },
+            "command_name": "abortTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            },
+            {
+              "_id": 3,
+              "x": 2
+            },
+            {
+              "_id": 4,
+              "x": 1
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "collection writeConcern ignored for findOneAndUpdate",
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0",
+          "arguments": {
+            "options": {
+              "writeConcern": {
+                "w": "majority"
+              }
+            }
+          }
+        },
+        {
+          "name": "findOneAndUpdate",
+          "object": "collection",
+          "collectionOptions": {
+            "writeConcern": {
+              "w": "majority"
+            }
+          },
+          "arguments": {
+            "session": "session0",
+            "filter": {
+              "_id": 3
+            },
+            "update": {
+              "$inc": {
+                "x": 1
+              }
+            },
+            "returnDocument": "Before"
+          },
+          "result": {
+            "_id": 3
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "findAndModify": "test",
+              "query": {
+                "_id": 3
+              },
+              "update": {
+                "$inc": {
+                  "x": 1
+                }
+              },
+              "new": false,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "readConcern": null,
+              "writeConcern": null
+            },
+            "command_name": "findAndModify",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "readConcern": null,
+              "writeConcern": {
+                "w": "majority"
+              }
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/insert.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/insert.json
new file mode 100644
index 0000000000000000000000000000000000000000..f26e7c2a7636548f2506e7da84fc07eca12731b7
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/insert.json	
@@ -0,0 +1,648 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.0",
+      "topology": [
+        "replicaset"
+      ]
+    },
+    {
+      "minServerVersion": "4.1.8",
+      "topology": [
+        "sharded"
+      ]
+    }
+  ],
+  "database_name": "transaction-tests",
+  "collection_name": "test",
+  "data": [],
+  "tests": [
+    {
+      "description": "insert",
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "insertMany",
+          "object": "collection",
+          "arguments": {
+            "documents": [
+              {
+                "_id": 2
+              },
+              {
+                "_id": 3
+              }
+            ],
+            "session": "session0"
+          },
+          "result": {
+            "insertedIds": {
+              "0": 2,
+              "1": 3
+            }
+          }
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 4
+            }
+          },
+          "result": {
+            "insertedId": 4
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 5
+            }
+          },
+          "result": {
+            "insertedId": 5
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 2
+                },
+                {
+                  "_id": 3
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 4
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 5
+                }
+              ],
+              "ordered": true,
+              "readConcern": {
+                "afterClusterTime": 42
+              },
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "2"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "2"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            },
+            {
+              "_id": 3
+            },
+            {
+              "_id": 4
+            },
+            {
+              "_id": 5
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "insert with session1",
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session1"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session1",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "insertMany",
+          "object": "collection",
+          "arguments": {
+            "documents": [
+              {
+                "_id": 2
+              },
+              {
+                "_id": 3
+              }
+            ],
+            "session": "session1"
+          },
+          "result": {
+            "insertedIds": {
+              "0": 2,
+              "1": 3
+            }
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session1"
+        },
+        {
+          "name": "startTransaction",
+          "object": "session1"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session1",
+            "document": {
+              "_id": 4
+            }
+          },
+          "result": {
+            "insertedId": 4
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session1"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session1",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 2
+                },
+                {
+                  "_id": 3
+                }
+              ],
+              "ordered": true,
+              "lsid": "session1",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session1",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 4
+                }
+              ],
+              "ordered": true,
+              "readConcern": {
+                "afterClusterTime": 42
+              },
+              "lsid": "session1",
+              "txnNumber": {
+                "$numberLong": "2"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "abortTransaction": 1,
+              "lsid": "session1",
+              "txnNumber": {
+                "$numberLong": "2"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "abortTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            },
+            {
+              "_id": 3
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "collection writeConcern without transaction",
+      "clientOptions": {
+        "retryWrites": false
+      },
+      "operations": [
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "collectionOptions": {
+            "writeConcern": {
+              "w": "majority"
+            }
+          },
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": null,
+              "startTransaction": null,
+              "autocommit": null,
+              "writeConcern": {
+                "w": "majority"
+              }
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "collection writeConcern ignored for insert",
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0",
+          "arguments": {
+            "options": {
+              "writeConcern": {
+                "w": "majority"
+              }
+            }
+          }
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "collectionOptions": {
+            "writeConcern": {
+              "w": "majority"
+            }
+          },
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "insertMany",
+          "object": "collection",
+          "collectionOptions": {
+            "writeConcern": {
+              "w": "majority"
+            }
+          },
+          "arguments": {
+            "documents": [
+              {
+                "_id": 2
+              },
+              {
+                "_id": 3
+              }
+            ],
+            "session": "session0"
+          },
+          "result": {
+            "insertedIds": {
+              "0": 2,
+              "1": 3
+            }
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 2
+                },
+                {
+                  "_id": 3
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": {
+                "w": "majority"
+              }
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            },
+            {
+              "_id": 3
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/isolation.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/isolation.json
new file mode 100644
index 0000000000000000000000000000000000000000..f16b28a5e6c09d5271c6349e099231c272a7987a
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/isolation.json	
@@ -0,0 +1,225 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.0",
+      "topology": [
+        "replicaset"
+      ]
+    },
+    {
+      "minServerVersion": "4.1.8",
+      "topology": [
+        "sharded"
+      ]
+    }
+  ],
+  "database_name": "transaction-tests",
+  "collection_name": "test",
+  "data": [],
+  "tests": [
+    {
+      "description": "one transaction",
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "find",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "filter": {
+              "_id": 1
+            }
+          },
+          "result": [
+            {
+              "_id": 1
+            }
+          ]
+        },
+        {
+          "name": "find",
+          "object": "collection",
+          "arguments": {
+            "session": "session1",
+            "filter": {
+              "_id": 1
+            }
+          },
+          "result": []
+        },
+        {
+          "name": "find",
+          "object": "collection",
+          "arguments": {
+            "filter": {
+              "_id": 1
+            }
+          },
+          "result": []
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "find",
+          "object": "collection",
+          "arguments": {
+            "session": "session1",
+            "filter": {
+              "_id": 1
+            }
+          },
+          "result": [
+            {
+              "_id": 1
+            }
+          ]
+        },
+        {
+          "name": "find",
+          "object": "collection",
+          "arguments": {
+            "filter": {
+              "_id": 1
+            }
+          },
+          "result": [
+            {
+              "_id": 1
+            }
+          ]
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "two transactions",
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "startTransaction",
+          "object": "session1"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "find",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "filter": {
+              "_id": 1
+            }
+          },
+          "result": [
+            {
+              "_id": 1
+            }
+          ]
+        },
+        {
+          "name": "find",
+          "object": "collection",
+          "arguments": {
+            "session": "session1",
+            "filter": {
+              "_id": 1
+            }
+          },
+          "result": []
+        },
+        {
+          "name": "find",
+          "object": "collection",
+          "arguments": {
+            "filter": {
+              "_id": 1
+            }
+          },
+          "result": []
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "find",
+          "object": "collection",
+          "arguments": {
+            "session": "session1",
+            "filter": {
+              "_id": 1
+            }
+          },
+          "result": []
+        },
+        {
+          "name": "find",
+          "object": "collection",
+          "arguments": {
+            "filter": {
+              "_id": 1
+            }
+          },
+          "result": [
+            {
+              "_id": 1
+            }
+          ]
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session1"
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/mongos-pin-auto.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/mongos-pin-auto.json
new file mode 100644
index 0000000000000000000000000000000000000000..f6ede52687c7f802a6d6eeaa37a74e254ac34876
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/mongos-pin-auto.json	
@@ -0,0 +1,4814 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.1.8",
+      "topology": [
+        "sharded"
+      ]
+    }
+  ],
+  "database_name": "transaction-tests",
+  "collection_name": "test",
+  "data": [
+    {
+      "_id": 1
+    },
+    {
+      "_id": 2
+    }
+  ],
+  "tests": [
+    {
+      "description": "remain pinned after non-transient Interrupted error on insertOne",
+      "useMultipleMongoses": true,
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 3
+            }
+          },
+          "result": {
+            "insertedId": 3
+          }
+        },
+        {
+          "name": "targetedFailPoint",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0",
+            "failPoint": {
+              "configureFailPoint": "failCommand",
+              "mode": {
+                "times": 1
+              },
+              "data": {
+                "failCommands": [
+                  "insert"
+                ],
+                "errorCode": 11601
+              }
+            }
+          }
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 4
+            }
+          },
+          "result": {
+            "errorLabelsOmit": [
+              "TransientTransactionError",
+              "UnknownTransactionCommitResult"
+            ],
+            "errorCodeName": "Interrupted"
+          }
+        },
+        {
+          "name": "assertSessionPinned",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0"
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 3
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 4
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null,
+              "recoveryToken": 42
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            },
+            {
+              "_id": 3
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "unpin after transient error within a transaction",
+      "useMultipleMongoses": true,
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 3
+            }
+          },
+          "result": {
+            "insertedId": 3
+          }
+        },
+        {
+          "name": "targetedFailPoint",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0",
+            "failPoint": {
+              "configureFailPoint": "failCommand",
+              "mode": {
+                "times": 1
+              },
+              "data": {
+                "failCommands": [
+                  "insert"
+                ],
+                "closeConnection": true
+              }
+            }
+          }
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 4
+            }
+          },
+          "result": {
+            "errorLabelsContain": [
+              "TransientTransactionError"
+            ],
+            "errorLabelsOmit": [
+              "UnknownTransactionCommitResult"
+            ]
+          }
+        },
+        {
+          "name": "assertSessionUnpinned",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0"
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 3
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 4
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "abortTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null,
+              "recoveryToken": 42
+            },
+            "command_name": "abortTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "remain pinned after non-transient Interrupted error on insertOne insert",
+      "useMultipleMongoses": true,
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 3
+            }
+          },
+          "result": {
+            "insertedId": 3
+          }
+        },
+        {
+          "name": "targetedFailPoint",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0",
+            "failPoint": {
+              "configureFailPoint": "failCommand",
+              "mode": {
+                "times": 1
+              },
+              "data": {
+                "failCommands": [
+                  "insert"
+                ],
+                "errorCode": 11601
+              }
+            }
+          }
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 4
+            }
+          },
+          "result": {
+            "errorLabelsOmit": [
+              "TransientTransactionError"
+            ]
+          }
+        },
+        {
+          "name": "assertSessionPinned",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0"
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "remain pinned after non-transient Interrupted error on insertMany insert",
+      "useMultipleMongoses": true,
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 3
+            }
+          },
+          "result": {
+            "insertedId": 3
+          }
+        },
+        {
+          "name": "targetedFailPoint",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0",
+            "failPoint": {
+              "configureFailPoint": "failCommand",
+              "mode": {
+                "times": 1
+              },
+              "data": {
+                "failCommands": [
+                  "insert"
+                ],
+                "errorCode": 11601
+              }
+            }
+          }
+        },
+        {
+          "name": "insertMany",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "documents": [
+              {
+                "_id": 4
+              },
+              {
+                "_id": 5
+              }
+            ]
+          },
+          "result": {
+            "errorLabelsOmit": [
+              "TransientTransactionError"
+            ]
+          }
+        },
+        {
+          "name": "assertSessionPinned",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0"
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "remain pinned after non-transient Interrupted error on updateOne update",
+      "useMultipleMongoses": true,
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 3
+            }
+          },
+          "result": {
+            "insertedId": 3
+          }
+        },
+        {
+          "name": "targetedFailPoint",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0",
+            "failPoint": {
+              "configureFailPoint": "failCommand",
+              "mode": {
+                "times": 1
+              },
+              "data": {
+                "failCommands": [
+                  "update"
+                ],
+                "errorCode": 11601
+              }
+            }
+          }
+        },
+        {
+          "name": "updateOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "filter": {
+              "_id": 1
+            },
+            "update": {
+              "$inc": {
+                "x": 1
+              }
+            }
+          },
+          "result": {
+            "errorLabelsOmit": [
+              "TransientTransactionError"
+            ]
+          }
+        },
+        {
+          "name": "assertSessionPinned",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0"
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "remain pinned after non-transient Interrupted error on replaceOne update",
+      "useMultipleMongoses": true,
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 3
+            }
+          },
+          "result": {
+            "insertedId": 3
+          }
+        },
+        {
+          "name": "targetedFailPoint",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0",
+            "failPoint": {
+              "configureFailPoint": "failCommand",
+              "mode": {
+                "times": 1
+              },
+              "data": {
+                "failCommands": [
+                  "update"
+                ],
+                "errorCode": 11601
+              }
+            }
+          }
+        },
+        {
+          "name": "replaceOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "filter": {
+              "_id": 1
+            },
+            "replacement": {
+              "y": 1
+            }
+          },
+          "result": {
+            "errorLabelsOmit": [
+              "TransientTransactionError"
+            ]
+          }
+        },
+        {
+          "name": "assertSessionPinned",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0"
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "remain pinned after non-transient Interrupted error on updateMany update",
+      "useMultipleMongoses": true,
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 3
+            }
+          },
+          "result": {
+            "insertedId": 3
+          }
+        },
+        {
+          "name": "targetedFailPoint",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0",
+            "failPoint": {
+              "configureFailPoint": "failCommand",
+              "mode": {
+                "times": 1
+              },
+              "data": {
+                "failCommands": [
+                  "update"
+                ],
+                "errorCode": 11601
+              }
+            }
+          }
+        },
+        {
+          "name": "updateMany",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "filter": {
+              "_id": {
+                "$gte": 1
+              }
+            },
+            "update": {
+              "$set": {
+                "z": 1
+              }
+            }
+          },
+          "result": {
+            "errorLabelsOmit": [
+              "TransientTransactionError"
+            ]
+          }
+        },
+        {
+          "name": "assertSessionPinned",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0"
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "remain pinned after non-transient Interrupted error on deleteOne delete",
+      "useMultipleMongoses": true,
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 3
+            }
+          },
+          "result": {
+            "insertedId": 3
+          }
+        },
+        {
+          "name": "targetedFailPoint",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0",
+            "failPoint": {
+              "configureFailPoint": "failCommand",
+              "mode": {
+                "times": 1
+              },
+              "data": {
+                "failCommands": [
+                  "delete"
+                ],
+                "errorCode": 11601
+              }
+            }
+          }
+        },
+        {
+          "name": "deleteOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "filter": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "errorLabelsOmit": [
+              "TransientTransactionError"
+            ]
+          }
+        },
+        {
+          "name": "assertSessionPinned",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0"
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "remain pinned after non-transient Interrupted error on deleteMany delete",
+      "useMultipleMongoses": true,
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 3
+            }
+          },
+          "result": {
+            "insertedId": 3
+          }
+        },
+        {
+          "name": "targetedFailPoint",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0",
+            "failPoint": {
+              "configureFailPoint": "failCommand",
+              "mode": {
+                "times": 1
+              },
+              "data": {
+                "failCommands": [
+                  "delete"
+                ],
+                "errorCode": 11601
+              }
+            }
+          }
+        },
+        {
+          "name": "deleteMany",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "filter": {
+              "_id": {
+                "$gte": 1
+              }
+            }
+          },
+          "result": {
+            "errorLabelsOmit": [
+              "TransientTransactionError"
+            ]
+          }
+        },
+        {
+          "name": "assertSessionPinned",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0"
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "remain pinned after non-transient Interrupted error on findOneAndDelete findAndModify",
+      "useMultipleMongoses": true,
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 3
+            }
+          },
+          "result": {
+            "insertedId": 3
+          }
+        },
+        {
+          "name": "targetedFailPoint",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0",
+            "failPoint": {
+              "configureFailPoint": "failCommand",
+              "mode": {
+                "times": 1
+              },
+              "data": {
+                "failCommands": [
+                  "findAndModify"
+                ],
+                "errorCode": 11601
+              }
+            }
+          }
+        },
+        {
+          "name": "findOneAndDelete",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "filter": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "errorLabelsOmit": [
+              "TransientTransactionError"
+            ]
+          }
+        },
+        {
+          "name": "assertSessionPinned",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0"
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "remain pinned after non-transient Interrupted error on findOneAndUpdate findAndModify",
+      "useMultipleMongoses": true,
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 3
+            }
+          },
+          "result": {
+            "insertedId": 3
+          }
+        },
+        {
+          "name": "targetedFailPoint",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0",
+            "failPoint": {
+              "configureFailPoint": "failCommand",
+              "mode": {
+                "times": 1
+              },
+              "data": {
+                "failCommands": [
+                  "findAndModify"
+                ],
+                "errorCode": 11601
+              }
+            }
+          }
+        },
+        {
+          "name": "findOneAndUpdate",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "filter": {
+              "_id": 1
+            },
+            "update": {
+              "$inc": {
+                "x": 1
+              }
+            },
+            "returnDocument": "Before"
+          },
+          "result": {
+            "errorLabelsOmit": [
+              "TransientTransactionError"
+            ]
+          }
+        },
+        {
+          "name": "assertSessionPinned",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0"
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "remain pinned after non-transient Interrupted error on findOneAndReplace findAndModify",
+      "useMultipleMongoses": true,
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 3
+            }
+          },
+          "result": {
+            "insertedId": 3
+          }
+        },
+        {
+          "name": "targetedFailPoint",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0",
+            "failPoint": {
+              "configureFailPoint": "failCommand",
+              "mode": {
+                "times": 1
+              },
+              "data": {
+                "failCommands": [
+                  "findAndModify"
+                ],
+                "errorCode": 11601
+              }
+            }
+          }
+        },
+        {
+          "name": "findOneAndReplace",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "filter": {
+              "_id": 1
+            },
+            "replacement": {
+              "y": 1
+            },
+            "returnDocument": "Before"
+          },
+          "result": {
+            "errorLabelsOmit": [
+              "TransientTransactionError"
+            ]
+          }
+        },
+        {
+          "name": "assertSessionPinned",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0"
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "remain pinned after non-transient Interrupted error on bulkWrite insert",
+      "useMultipleMongoses": true,
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 3
+            }
+          },
+          "result": {
+            "insertedId": 3
+          }
+        },
+        {
+          "name": "targetedFailPoint",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0",
+            "failPoint": {
+              "configureFailPoint": "failCommand",
+              "mode": {
+                "times": 1
+              },
+              "data": {
+                "failCommands": [
+                  "insert"
+                ],
+                "errorCode": 11601
+              }
+            }
+          }
+        },
+        {
+          "name": "bulkWrite",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "requests": [
+              {
+                "name": "insertOne",
+                "arguments": {
+                  "document": {
+                    "_id": 1
+                  }
+                }
+              }
+            ]
+          },
+          "result": {
+            "errorLabelsOmit": [
+              "TransientTransactionError"
+            ]
+          }
+        },
+        {
+          "name": "assertSessionPinned",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0"
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "remain pinned after non-transient Interrupted error on bulkWrite update",
+      "useMultipleMongoses": true,
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 3
+            }
+          },
+          "result": {
+            "insertedId": 3
+          }
+        },
+        {
+          "name": "targetedFailPoint",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0",
+            "failPoint": {
+              "configureFailPoint": "failCommand",
+              "mode": {
+                "times": 1
+              },
+              "data": {
+                "failCommands": [
+                  "update"
+                ],
+                "errorCode": 11601
+              }
+            }
+          }
+        },
+        {
+          "name": "bulkWrite",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "requests": [
+              {
+                "name": "updateOne",
+                "arguments": {
+                  "filter": {
+                    "_id": 1
+                  },
+                  "update": {
+                    "$set": {
+                      "x": 1
+                    }
+                  }
+                }
+              }
+            ]
+          },
+          "result": {
+            "errorLabelsOmit": [
+              "TransientTransactionError"
+            ]
+          }
+        },
+        {
+          "name": "assertSessionPinned",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0"
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "remain pinned after non-transient Interrupted error on bulkWrite delete",
+      "useMultipleMongoses": true,
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 3
+            }
+          },
+          "result": {
+            "insertedId": 3
+          }
+        },
+        {
+          "name": "targetedFailPoint",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0",
+            "failPoint": {
+              "configureFailPoint": "failCommand",
+              "mode": {
+                "times": 1
+              },
+              "data": {
+                "failCommands": [
+                  "delete"
+                ],
+                "errorCode": 11601
+              }
+            }
+          }
+        },
+        {
+          "name": "bulkWrite",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "requests": [
+              {
+                "name": "deleteOne",
+                "arguments": {
+                  "filter": {
+                    "_id": 1
+                  }
+                }
+              }
+            ]
+          },
+          "result": {
+            "errorLabelsOmit": [
+              "TransientTransactionError"
+            ]
+          }
+        },
+        {
+          "name": "assertSessionPinned",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0"
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "remain pinned after non-transient Interrupted error on find find",
+      "useMultipleMongoses": true,
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 3
+            }
+          },
+          "result": {
+            "insertedId": 3
+          }
+        },
+        {
+          "name": "targetedFailPoint",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0",
+            "failPoint": {
+              "configureFailPoint": "failCommand",
+              "mode": {
+                "times": 1
+              },
+              "data": {
+                "failCommands": [
+                  "find"
+                ],
+                "errorCode": 11601
+              }
+            }
+          }
+        },
+        {
+          "name": "find",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "filter": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "errorLabelsOmit": [
+              "TransientTransactionError"
+            ]
+          }
+        },
+        {
+          "name": "assertSessionPinned",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0"
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "remain pinned after non-transient Interrupted error on countDocuments aggregate",
+      "useMultipleMongoses": true,
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 3
+            }
+          },
+          "result": {
+            "insertedId": 3
+          }
+        },
+        {
+          "name": "targetedFailPoint",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0",
+            "failPoint": {
+              "configureFailPoint": "failCommand",
+              "mode": {
+                "times": 1
+              },
+              "data": {
+                "failCommands": [
+                  "aggregate"
+                ],
+                "errorCode": 11601
+              }
+            }
+          }
+        },
+        {
+          "name": "countDocuments",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "filter": {}
+          },
+          "result": {
+            "errorLabelsOmit": [
+              "TransientTransactionError"
+            ]
+          }
+        },
+        {
+          "name": "assertSessionPinned",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0"
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "remain pinned after non-transient Interrupted error on aggregate aggregate",
+      "useMultipleMongoses": true,
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 3
+            }
+          },
+          "result": {
+            "insertedId": 3
+          }
+        },
+        {
+          "name": "targetedFailPoint",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0",
+            "failPoint": {
+              "configureFailPoint": "failCommand",
+              "mode": {
+                "times": 1
+              },
+              "data": {
+                "failCommands": [
+                  "aggregate"
+                ],
+                "errorCode": 11601
+              }
+            }
+          }
+        },
+        {
+          "name": "aggregate",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "pipeline": []
+          },
+          "result": {
+            "errorLabelsOmit": [
+              "TransientTransactionError"
+            ]
+          }
+        },
+        {
+          "name": "assertSessionPinned",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0"
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "remain pinned after non-transient Interrupted error on distinct distinct",
+      "useMultipleMongoses": true,
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 3
+            }
+          },
+          "result": {
+            "insertedId": 3
+          }
+        },
+        {
+          "name": "targetedFailPoint",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0",
+            "failPoint": {
+              "configureFailPoint": "failCommand",
+              "mode": {
+                "times": 1
+              },
+              "data": {
+                "failCommands": [
+                  "distinct"
+                ],
+                "errorCode": 11601
+              }
+            }
+          }
+        },
+        {
+          "name": "distinct",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "fieldName": "_id"
+          },
+          "result": {
+            "errorLabelsOmit": [
+              "TransientTransactionError"
+            ]
+          }
+        },
+        {
+          "name": "assertSessionPinned",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0"
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "remain pinned after non-transient Interrupted error on runCommand insert",
+      "useMultipleMongoses": true,
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 3
+            }
+          },
+          "result": {
+            "insertedId": 3
+          }
+        },
+        {
+          "name": "targetedFailPoint",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0",
+            "failPoint": {
+              "configureFailPoint": "failCommand",
+              "mode": {
+                "times": 1
+              },
+              "data": {
+                "failCommands": [
+                  "insert"
+                ],
+                "errorCode": 11601
+              }
+            }
+          }
+        },
+        {
+          "name": "runCommand",
+          "object": "database",
+          "command_name": "insert",
+          "arguments": {
+            "session": "session0",
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ]
+            }
+          },
+          "result": {
+            "errorLabelsOmit": [
+              "TransientTransactionError"
+            ]
+          }
+        },
+        {
+          "name": "assertSessionPinned",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0"
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "unpin after transient connection error on insertOne insert",
+      "useMultipleMongoses": true,
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 3
+            }
+          },
+          "result": {
+            "insertedId": 3
+          }
+        },
+        {
+          "name": "targetedFailPoint",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0",
+            "failPoint": {
+              "configureFailPoint": "failCommand",
+              "mode": {
+                "times": 1
+              },
+              "data": {
+                "failCommands": [
+                  "insert"
+                ],
+                "closeConnection": true
+              }
+            }
+          }
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 4
+            }
+          },
+          "result": {
+            "errorLabelsContain": [
+              "TransientTransactionError"
+            ]
+          }
+        },
+        {
+          "name": "assertSessionUnpinned",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0"
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "unpin after transient ShutdownInProgress error on insertOne insert",
+      "useMultipleMongoses": true,
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 3
+            }
+          },
+          "result": {
+            "insertedId": 3
+          }
+        },
+        {
+          "name": "targetedFailPoint",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0",
+            "failPoint": {
+              "configureFailPoint": "failCommand",
+              "mode": {
+                "times": 1
+              },
+              "data": {
+                "failCommands": [
+                  "insert"
+                ],
+                "errorCode": 91
+              }
+            }
+          }
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 4
+            }
+          },
+          "result": {
+            "errorLabelsContain": [
+              "TransientTransactionError"
+            ]
+          }
+        },
+        {
+          "name": "assertSessionUnpinned",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0"
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "unpin after transient connection error on insertMany insert",
+      "useMultipleMongoses": true,
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 3
+            }
+          },
+          "result": {
+            "insertedId": 3
+          }
+        },
+        {
+          "name": "targetedFailPoint",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0",
+            "failPoint": {
+              "configureFailPoint": "failCommand",
+              "mode": {
+                "times": 1
+              },
+              "data": {
+                "failCommands": [
+                  "insert"
+                ],
+                "closeConnection": true
+              }
+            }
+          }
+        },
+        {
+          "name": "insertMany",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "documents": [
+              {
+                "_id": 4
+              },
+              {
+                "_id": 5
+              }
+            ]
+          },
+          "result": {
+            "errorLabelsContain": [
+              "TransientTransactionError"
+            ]
+          }
+        },
+        {
+          "name": "assertSessionUnpinned",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0"
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "unpin after transient ShutdownInProgress error on insertMany insert",
+      "useMultipleMongoses": true,
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 3
+            }
+          },
+          "result": {
+            "insertedId": 3
+          }
+        },
+        {
+          "name": "targetedFailPoint",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0",
+            "failPoint": {
+              "configureFailPoint": "failCommand",
+              "mode": {
+                "times": 1
+              },
+              "data": {
+                "failCommands": [
+                  "insert"
+                ],
+                "errorCode": 91
+              }
+            }
+          }
+        },
+        {
+          "name": "insertMany",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "documents": [
+              {
+                "_id": 4
+              },
+              {
+                "_id": 5
+              }
+            ]
+          },
+          "result": {
+            "errorLabelsContain": [
+              "TransientTransactionError"
+            ]
+          }
+        },
+        {
+          "name": "assertSessionUnpinned",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0"
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "unpin after transient connection error on updateOne update",
+      "useMultipleMongoses": true,
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 3
+            }
+          },
+          "result": {
+            "insertedId": 3
+          }
+        },
+        {
+          "name": "targetedFailPoint",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0",
+            "failPoint": {
+              "configureFailPoint": "failCommand",
+              "mode": {
+                "times": 1
+              },
+              "data": {
+                "failCommands": [
+                  "update"
+                ],
+                "closeConnection": true
+              }
+            }
+          }
+        },
+        {
+          "name": "updateOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "filter": {
+              "_id": 1
+            },
+            "update": {
+              "$inc": {
+                "x": 1
+              }
+            }
+          },
+          "result": {
+            "errorLabelsContain": [
+              "TransientTransactionError"
+            ]
+          }
+        },
+        {
+          "name": "assertSessionUnpinned",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0"
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "unpin after transient ShutdownInProgress error on updateOne update",
+      "useMultipleMongoses": true,
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 3
+            }
+          },
+          "result": {
+            "insertedId": 3
+          }
+        },
+        {
+          "name": "targetedFailPoint",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0",
+            "failPoint": {
+              "configureFailPoint": "failCommand",
+              "mode": {
+                "times": 1
+              },
+              "data": {
+                "failCommands": [
+                  "update"
+                ],
+                "errorCode": 91
+              }
+            }
+          }
+        },
+        {
+          "name": "updateOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "filter": {
+              "_id": 1
+            },
+            "update": {
+              "$inc": {
+                "x": 1
+              }
+            }
+          },
+          "result": {
+            "errorLabelsContain": [
+              "TransientTransactionError"
+            ]
+          }
+        },
+        {
+          "name": "assertSessionUnpinned",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0"
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "unpin after transient connection error on replaceOne update",
+      "useMultipleMongoses": true,
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 3
+            }
+          },
+          "result": {
+            "insertedId": 3
+          }
+        },
+        {
+          "name": "targetedFailPoint",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0",
+            "failPoint": {
+              "configureFailPoint": "failCommand",
+              "mode": {
+                "times": 1
+              },
+              "data": {
+                "failCommands": [
+                  "update"
+                ],
+                "closeConnection": true
+              }
+            }
+          }
+        },
+        {
+          "name": "replaceOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "filter": {
+              "_id": 1
+            },
+            "replacement": {
+              "y": 1
+            }
+          },
+          "result": {
+            "errorLabelsContain": [
+              "TransientTransactionError"
+            ]
+          }
+        },
+        {
+          "name": "assertSessionUnpinned",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0"
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "unpin after transient ShutdownInProgress error on replaceOne update",
+      "useMultipleMongoses": true,
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 3
+            }
+          },
+          "result": {
+            "insertedId": 3
+          }
+        },
+        {
+          "name": "targetedFailPoint",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0",
+            "failPoint": {
+              "configureFailPoint": "failCommand",
+              "mode": {
+                "times": 1
+              },
+              "data": {
+                "failCommands": [
+                  "update"
+                ],
+                "errorCode": 91
+              }
+            }
+          }
+        },
+        {
+          "name": "replaceOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "filter": {
+              "_id": 1
+            },
+            "replacement": {
+              "y": 1
+            }
+          },
+          "result": {
+            "errorLabelsContain": [
+              "TransientTransactionError"
+            ]
+          }
+        },
+        {
+          "name": "assertSessionUnpinned",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0"
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "unpin after transient connection error on updateMany update",
+      "useMultipleMongoses": true,
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 3
+            }
+          },
+          "result": {
+            "insertedId": 3
+          }
+        },
+        {
+          "name": "targetedFailPoint",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0",
+            "failPoint": {
+              "configureFailPoint": "failCommand",
+              "mode": {
+                "times": 1
+              },
+              "data": {
+                "failCommands": [
+                  "update"
+                ],
+                "closeConnection": true
+              }
+            }
+          }
+        },
+        {
+          "name": "updateMany",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "filter": {
+              "_id": {
+                "$gte": 1
+              }
+            },
+            "update": {
+              "$set": {
+                "z": 1
+              }
+            }
+          },
+          "result": {
+            "errorLabelsContain": [
+              "TransientTransactionError"
+            ]
+          }
+        },
+        {
+          "name": "assertSessionUnpinned",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0"
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "unpin after transient ShutdownInProgress error on updateMany update",
+      "useMultipleMongoses": true,
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 3
+            }
+          },
+          "result": {
+            "insertedId": 3
+          }
+        },
+        {
+          "name": "targetedFailPoint",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0",
+            "failPoint": {
+              "configureFailPoint": "failCommand",
+              "mode": {
+                "times": 1
+              },
+              "data": {
+                "failCommands": [
+                  "update"
+                ],
+                "errorCode": 91
+              }
+            }
+          }
+        },
+        {
+          "name": "updateMany",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "filter": {
+              "_id": {
+                "$gte": 1
+              }
+            },
+            "update": {
+              "$set": {
+                "z": 1
+              }
+            }
+          },
+          "result": {
+            "errorLabelsContain": [
+              "TransientTransactionError"
+            ]
+          }
+        },
+        {
+          "name": "assertSessionUnpinned",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0"
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "unpin after transient connection error on deleteOne delete",
+      "useMultipleMongoses": true,
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 3
+            }
+          },
+          "result": {
+            "insertedId": 3
+          }
+        },
+        {
+          "name": "targetedFailPoint",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0",
+            "failPoint": {
+              "configureFailPoint": "failCommand",
+              "mode": {
+                "times": 1
+              },
+              "data": {
+                "failCommands": [
+                  "delete"
+                ],
+                "closeConnection": true
+              }
+            }
+          }
+        },
+        {
+          "name": "deleteOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "filter": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "errorLabelsContain": [
+              "TransientTransactionError"
+            ]
+          }
+        },
+        {
+          "name": "assertSessionUnpinned",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0"
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "unpin after transient ShutdownInProgress error on deleteOne delete",
+      "useMultipleMongoses": true,
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 3
+            }
+          },
+          "result": {
+            "insertedId": 3
+          }
+        },
+        {
+          "name": "targetedFailPoint",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0",
+            "failPoint": {
+              "configureFailPoint": "failCommand",
+              "mode": {
+                "times": 1
+              },
+              "data": {
+                "failCommands": [
+                  "delete"
+                ],
+                "errorCode": 91
+              }
+            }
+          }
+        },
+        {
+          "name": "deleteOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "filter": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "errorLabelsContain": [
+              "TransientTransactionError"
+            ]
+          }
+        },
+        {
+          "name": "assertSessionUnpinned",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0"
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "unpin after transient connection error on deleteMany delete",
+      "useMultipleMongoses": true,
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 3
+            }
+          },
+          "result": {
+            "insertedId": 3
+          }
+        },
+        {
+          "name": "targetedFailPoint",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0",
+            "failPoint": {
+              "configureFailPoint": "failCommand",
+              "mode": {
+                "times": 1
+              },
+              "data": {
+                "failCommands": [
+                  "delete"
+                ],
+                "closeConnection": true
+              }
+            }
+          }
+        },
+        {
+          "name": "deleteMany",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "filter": {
+              "_id": {
+                "$gte": 1
+              }
+            }
+          },
+          "result": {
+            "errorLabelsContain": [
+              "TransientTransactionError"
+            ]
+          }
+        },
+        {
+          "name": "assertSessionUnpinned",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0"
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "unpin after transient ShutdownInProgress error on deleteMany delete",
+      "useMultipleMongoses": true,
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 3
+            }
+          },
+          "result": {
+            "insertedId": 3
+          }
+        },
+        {
+          "name": "targetedFailPoint",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0",
+            "failPoint": {
+              "configureFailPoint": "failCommand",
+              "mode": {
+                "times": 1
+              },
+              "data": {
+                "failCommands": [
+                  "delete"
+                ],
+                "errorCode": 91
+              }
+            }
+          }
+        },
+        {
+          "name": "deleteMany",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "filter": {
+              "_id": {
+                "$gte": 1
+              }
+            }
+          },
+          "result": {
+            "errorLabelsContain": [
+              "TransientTransactionError"
+            ]
+          }
+        },
+        {
+          "name": "assertSessionUnpinned",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0"
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "unpin after transient connection error on findOneAndDelete findAndModify",
+      "useMultipleMongoses": true,
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 3
+            }
+          },
+          "result": {
+            "insertedId": 3
+          }
+        },
+        {
+          "name": "targetedFailPoint",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0",
+            "failPoint": {
+              "configureFailPoint": "failCommand",
+              "mode": {
+                "times": 1
+              },
+              "data": {
+                "failCommands": [
+                  "findAndModify"
+                ],
+                "closeConnection": true
+              }
+            }
+          }
+        },
+        {
+          "name": "findOneAndDelete",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "filter": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "errorLabelsContain": [
+              "TransientTransactionError"
+            ]
+          }
+        },
+        {
+          "name": "assertSessionUnpinned",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0"
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "unpin after transient ShutdownInProgress error on findOneAndDelete findAndModify",
+      "useMultipleMongoses": true,
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 3
+            }
+          },
+          "result": {
+            "insertedId": 3
+          }
+        },
+        {
+          "name": "targetedFailPoint",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0",
+            "failPoint": {
+              "configureFailPoint": "failCommand",
+              "mode": {
+                "times": 1
+              },
+              "data": {
+                "failCommands": [
+                  "findAndModify"
+                ],
+                "errorCode": 91
+              }
+            }
+          }
+        },
+        {
+          "name": "findOneAndDelete",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "filter": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "errorLabelsContain": [
+              "TransientTransactionError"
+            ]
+          }
+        },
+        {
+          "name": "assertSessionUnpinned",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0"
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "unpin after transient connection error on findOneAndUpdate findAndModify",
+      "useMultipleMongoses": true,
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 3
+            }
+          },
+          "result": {
+            "insertedId": 3
+          }
+        },
+        {
+          "name": "targetedFailPoint",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0",
+            "failPoint": {
+              "configureFailPoint": "failCommand",
+              "mode": {
+                "times": 1
+              },
+              "data": {
+                "failCommands": [
+                  "findAndModify"
+                ],
+                "closeConnection": true
+              }
+            }
+          }
+        },
+        {
+          "name": "findOneAndUpdate",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "filter": {
+              "_id": 1
+            },
+            "update": {
+              "$inc": {
+                "x": 1
+              }
+            },
+            "returnDocument": "Before"
+          },
+          "result": {
+            "errorLabelsContain": [
+              "TransientTransactionError"
+            ]
+          }
+        },
+        {
+          "name": "assertSessionUnpinned",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0"
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "unpin after transient ShutdownInProgress error on findOneAndUpdate findAndModify",
+      "useMultipleMongoses": true,
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 3
+            }
+          },
+          "result": {
+            "insertedId": 3
+          }
+        },
+        {
+          "name": "targetedFailPoint",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0",
+            "failPoint": {
+              "configureFailPoint": "failCommand",
+              "mode": {
+                "times": 1
+              },
+              "data": {
+                "failCommands": [
+                  "findAndModify"
+                ],
+                "errorCode": 91
+              }
+            }
+          }
+        },
+        {
+          "name": "findOneAndUpdate",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "filter": {
+              "_id": 1
+            },
+            "update": {
+              "$inc": {
+                "x": 1
+              }
+            },
+            "returnDocument": "Before"
+          },
+          "result": {
+            "errorLabelsContain": [
+              "TransientTransactionError"
+            ]
+          }
+        },
+        {
+          "name": "assertSessionUnpinned",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0"
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "unpin after transient connection error on findOneAndReplace findAndModify",
+      "useMultipleMongoses": true,
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 3
+            }
+          },
+          "result": {
+            "insertedId": 3
+          }
+        },
+        {
+          "name": "targetedFailPoint",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0",
+            "failPoint": {
+              "configureFailPoint": "failCommand",
+              "mode": {
+                "times": 1
+              },
+              "data": {
+                "failCommands": [
+                  "findAndModify"
+                ],
+                "closeConnection": true
+              }
+            }
+          }
+        },
+        {
+          "name": "findOneAndReplace",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "filter": {
+              "_id": 1
+            },
+            "replacement": {
+              "y": 1
+            },
+            "returnDocument": "Before"
+          },
+          "result": {
+            "errorLabelsContain": [
+              "TransientTransactionError"
+            ]
+          }
+        },
+        {
+          "name": "assertSessionUnpinned",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0"
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "unpin after transient ShutdownInProgress error on findOneAndReplace findAndModify",
+      "useMultipleMongoses": true,
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 3
+            }
+          },
+          "result": {
+            "insertedId": 3
+          }
+        },
+        {
+          "name": "targetedFailPoint",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0",
+            "failPoint": {
+              "configureFailPoint": "failCommand",
+              "mode": {
+                "times": 1
+              },
+              "data": {
+                "failCommands": [
+                  "findAndModify"
+                ],
+                "errorCode": 91
+              }
+            }
+          }
+        },
+        {
+          "name": "findOneAndReplace",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "filter": {
+              "_id": 1
+            },
+            "replacement": {
+              "y": 1
+            },
+            "returnDocument": "Before"
+          },
+          "result": {
+            "errorLabelsContain": [
+              "TransientTransactionError"
+            ]
+          }
+        },
+        {
+          "name": "assertSessionUnpinned",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0"
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "unpin after transient connection error on bulkWrite insert",
+      "useMultipleMongoses": true,
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 3
+            }
+          },
+          "result": {
+            "insertedId": 3
+          }
+        },
+        {
+          "name": "targetedFailPoint",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0",
+            "failPoint": {
+              "configureFailPoint": "failCommand",
+              "mode": {
+                "times": 1
+              },
+              "data": {
+                "failCommands": [
+                  "insert"
+                ],
+                "closeConnection": true
+              }
+            }
+          }
+        },
+        {
+          "name": "bulkWrite",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "requests": [
+              {
+                "name": "insertOne",
+                "arguments": {
+                  "document": {
+                    "_id": 1
+                  }
+                }
+              }
+            ]
+          },
+          "result": {
+            "errorLabelsContain": [
+              "TransientTransactionError"
+            ]
+          }
+        },
+        {
+          "name": "assertSessionUnpinned",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0"
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "unpin after transient ShutdownInProgress error on bulkWrite insert",
+      "useMultipleMongoses": true,
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 3
+            }
+          },
+          "result": {
+            "insertedId": 3
+          }
+        },
+        {
+          "name": "targetedFailPoint",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0",
+            "failPoint": {
+              "configureFailPoint": "failCommand",
+              "mode": {
+                "times": 1
+              },
+              "data": {
+                "failCommands": [
+                  "insert"
+                ],
+                "errorCode": 91
+              }
+            }
+          }
+        },
+        {
+          "name": "bulkWrite",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "requests": [
+              {
+                "name": "insertOne",
+                "arguments": {
+                  "document": {
+                    "_id": 1
+                  }
+                }
+              }
+            ]
+          },
+          "result": {
+            "errorLabelsContain": [
+              "TransientTransactionError"
+            ]
+          }
+        },
+        {
+          "name": "assertSessionUnpinned",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0"
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "unpin after transient connection error on bulkWrite update",
+      "useMultipleMongoses": true,
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 3
+            }
+          },
+          "result": {
+            "insertedId": 3
+          }
+        },
+        {
+          "name": "targetedFailPoint",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0",
+            "failPoint": {
+              "configureFailPoint": "failCommand",
+              "mode": {
+                "times": 1
+              },
+              "data": {
+                "failCommands": [
+                  "update"
+                ],
+                "closeConnection": true
+              }
+            }
+          }
+        },
+        {
+          "name": "bulkWrite",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "requests": [
+              {
+                "name": "updateOne",
+                "arguments": {
+                  "filter": {
+                    "_id": 1
+                  },
+                  "update": {
+                    "$set": {
+                      "x": 1
+                    }
+                  }
+                }
+              }
+            ]
+          },
+          "result": {
+            "errorLabelsContain": [
+              "TransientTransactionError"
+            ]
+          }
+        },
+        {
+          "name": "assertSessionUnpinned",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0"
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "unpin after transient ShutdownInProgress error on bulkWrite update",
+      "useMultipleMongoses": true,
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 3
+            }
+          },
+          "result": {
+            "insertedId": 3
+          }
+        },
+        {
+          "name": "targetedFailPoint",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0",
+            "failPoint": {
+              "configureFailPoint": "failCommand",
+              "mode": {
+                "times": 1
+              },
+              "data": {
+                "failCommands": [
+                  "update"
+                ],
+                "errorCode": 91
+              }
+            }
+          }
+        },
+        {
+          "name": "bulkWrite",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "requests": [
+              {
+                "name": "updateOne",
+                "arguments": {
+                  "filter": {
+                    "_id": 1
+                  },
+                  "update": {
+                    "$set": {
+                      "x": 1
+                    }
+                  }
+                }
+              }
+            ]
+          },
+          "result": {
+            "errorLabelsContain": [
+              "TransientTransactionError"
+            ]
+          }
+        },
+        {
+          "name": "assertSessionUnpinned",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0"
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "unpin after transient connection error on bulkWrite delete",
+      "useMultipleMongoses": true,
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 3
+            }
+          },
+          "result": {
+            "insertedId": 3
+          }
+        },
+        {
+          "name": "targetedFailPoint",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0",
+            "failPoint": {
+              "configureFailPoint": "failCommand",
+              "mode": {
+                "times": 1
+              },
+              "data": {
+                "failCommands": [
+                  "delete"
+                ],
+                "closeConnection": true
+              }
+            }
+          }
+        },
+        {
+          "name": "bulkWrite",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "requests": [
+              {
+                "name": "deleteOne",
+                "arguments": {
+                  "filter": {
+                    "_id": 1
+                  }
+                }
+              }
+            ]
+          },
+          "result": {
+            "errorLabelsContain": [
+              "TransientTransactionError"
+            ]
+          }
+        },
+        {
+          "name": "assertSessionUnpinned",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0"
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "unpin after transient ShutdownInProgress error on bulkWrite delete",
+      "useMultipleMongoses": true,
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 3
+            }
+          },
+          "result": {
+            "insertedId": 3
+          }
+        },
+        {
+          "name": "targetedFailPoint",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0",
+            "failPoint": {
+              "configureFailPoint": "failCommand",
+              "mode": {
+                "times": 1
+              },
+              "data": {
+                "failCommands": [
+                  "delete"
+                ],
+                "errorCode": 91
+              }
+            }
+          }
+        },
+        {
+          "name": "bulkWrite",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "requests": [
+              {
+                "name": "deleteOne",
+                "arguments": {
+                  "filter": {
+                    "_id": 1
+                  }
+                }
+              }
+            ]
+          },
+          "result": {
+            "errorLabelsContain": [
+              "TransientTransactionError"
+            ]
+          }
+        },
+        {
+          "name": "assertSessionUnpinned",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0"
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "unpin after transient connection error on find find",
+      "useMultipleMongoses": true,
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 3
+            }
+          },
+          "result": {
+            "insertedId": 3
+          }
+        },
+        {
+          "name": "targetedFailPoint",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0",
+            "failPoint": {
+              "configureFailPoint": "failCommand",
+              "mode": {
+                "times": 1
+              },
+              "data": {
+                "failCommands": [
+                  "find"
+                ],
+                "closeConnection": true
+              }
+            }
+          }
+        },
+        {
+          "name": "find",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "filter": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "errorLabelsContain": [
+              "TransientTransactionError"
+            ]
+          }
+        },
+        {
+          "name": "assertSessionUnpinned",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0"
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "unpin after transient ShutdownInProgress error on find find",
+      "useMultipleMongoses": true,
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 3
+            }
+          },
+          "result": {
+            "insertedId": 3
+          }
+        },
+        {
+          "name": "targetedFailPoint",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0",
+            "failPoint": {
+              "configureFailPoint": "failCommand",
+              "mode": {
+                "times": 1
+              },
+              "data": {
+                "failCommands": [
+                  "find"
+                ],
+                "errorCode": 91
+              }
+            }
+          }
+        },
+        {
+          "name": "find",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "filter": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "errorLabelsContain": [
+              "TransientTransactionError"
+            ]
+          }
+        },
+        {
+          "name": "assertSessionUnpinned",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0"
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "unpin after transient connection error on countDocuments aggregate",
+      "useMultipleMongoses": true,
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 3
+            }
+          },
+          "result": {
+            "insertedId": 3
+          }
+        },
+        {
+          "name": "targetedFailPoint",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0",
+            "failPoint": {
+              "configureFailPoint": "failCommand",
+              "mode": {
+                "times": 1
+              },
+              "data": {
+                "failCommands": [
+                  "aggregate"
+                ],
+                "closeConnection": true
+              }
+            }
+          }
+        },
+        {
+          "name": "countDocuments",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "filter": {}
+          },
+          "result": {
+            "errorLabelsContain": [
+              "TransientTransactionError"
+            ]
+          }
+        },
+        {
+          "name": "assertSessionUnpinned",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0"
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "unpin after transient ShutdownInProgress error on countDocuments aggregate",
+      "useMultipleMongoses": true,
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 3
+            }
+          },
+          "result": {
+            "insertedId": 3
+          }
+        },
+        {
+          "name": "targetedFailPoint",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0",
+            "failPoint": {
+              "configureFailPoint": "failCommand",
+              "mode": {
+                "times": 1
+              },
+              "data": {
+                "failCommands": [
+                  "aggregate"
+                ],
+                "errorCode": 91
+              }
+            }
+          }
+        },
+        {
+          "name": "countDocuments",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "filter": {}
+          },
+          "result": {
+            "errorLabelsContain": [
+              "TransientTransactionError"
+            ]
+          }
+        },
+        {
+          "name": "assertSessionUnpinned",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0"
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "unpin after transient connection error on aggregate aggregate",
+      "useMultipleMongoses": true,
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 3
+            }
+          },
+          "result": {
+            "insertedId": 3
+          }
+        },
+        {
+          "name": "targetedFailPoint",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0",
+            "failPoint": {
+              "configureFailPoint": "failCommand",
+              "mode": {
+                "times": 1
+              },
+              "data": {
+                "failCommands": [
+                  "aggregate"
+                ],
+                "closeConnection": true
+              }
+            }
+          }
+        },
+        {
+          "name": "aggregate",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "pipeline": []
+          },
+          "result": {
+            "errorLabelsContain": [
+              "TransientTransactionError"
+            ]
+          }
+        },
+        {
+          "name": "assertSessionUnpinned",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0"
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "unpin after transient ShutdownInProgress error on aggregate aggregate",
+      "useMultipleMongoses": true,
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 3
+            }
+          },
+          "result": {
+            "insertedId": 3
+          }
+        },
+        {
+          "name": "targetedFailPoint",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0",
+            "failPoint": {
+              "configureFailPoint": "failCommand",
+              "mode": {
+                "times": 1
+              },
+              "data": {
+                "failCommands": [
+                  "aggregate"
+                ],
+                "errorCode": 91
+              }
+            }
+          }
+        },
+        {
+          "name": "aggregate",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "pipeline": []
+          },
+          "result": {
+            "errorLabelsContain": [
+              "TransientTransactionError"
+            ]
+          }
+        },
+        {
+          "name": "assertSessionUnpinned",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0"
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "unpin after transient connection error on distinct distinct",
+      "useMultipleMongoses": true,
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 3
+            }
+          },
+          "result": {
+            "insertedId": 3
+          }
+        },
+        {
+          "name": "targetedFailPoint",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0",
+            "failPoint": {
+              "configureFailPoint": "failCommand",
+              "mode": {
+                "times": 1
+              },
+              "data": {
+                "failCommands": [
+                  "distinct"
+                ],
+                "closeConnection": true
+              }
+            }
+          }
+        },
+        {
+          "name": "distinct",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "fieldName": "_id"
+          },
+          "result": {
+            "errorLabelsContain": [
+              "TransientTransactionError"
+            ]
+          }
+        },
+        {
+          "name": "assertSessionUnpinned",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0"
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "unpin after transient ShutdownInProgress error on distinct distinct",
+      "useMultipleMongoses": true,
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 3
+            }
+          },
+          "result": {
+            "insertedId": 3
+          }
+        },
+        {
+          "name": "targetedFailPoint",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0",
+            "failPoint": {
+              "configureFailPoint": "failCommand",
+              "mode": {
+                "times": 1
+              },
+              "data": {
+                "failCommands": [
+                  "distinct"
+                ],
+                "errorCode": 91
+              }
+            }
+          }
+        },
+        {
+          "name": "distinct",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "fieldName": "_id"
+          },
+          "result": {
+            "errorLabelsContain": [
+              "TransientTransactionError"
+            ]
+          }
+        },
+        {
+          "name": "assertSessionUnpinned",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0"
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "unpin after transient connection error on runCommand insert",
+      "useMultipleMongoses": true,
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 3
+            }
+          },
+          "result": {
+            "insertedId": 3
+          }
+        },
+        {
+          "name": "targetedFailPoint",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0",
+            "failPoint": {
+              "configureFailPoint": "failCommand",
+              "mode": {
+                "times": 1
+              },
+              "data": {
+                "failCommands": [
+                  "insert"
+                ],
+                "closeConnection": true
+              }
+            }
+          }
+        },
+        {
+          "name": "runCommand",
+          "object": "database",
+          "command_name": "insert",
+          "arguments": {
+            "session": "session0",
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ]
+            }
+          },
+          "result": {
+            "errorLabelsContain": [
+              "TransientTransactionError"
+            ]
+          }
+        },
+        {
+          "name": "assertSessionUnpinned",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0"
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "unpin after transient ShutdownInProgress error on runCommand insert",
+      "useMultipleMongoses": true,
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 3
+            }
+          },
+          "result": {
+            "insertedId": 3
+          }
+        },
+        {
+          "name": "targetedFailPoint",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0",
+            "failPoint": {
+              "configureFailPoint": "failCommand",
+              "mode": {
+                "times": 1
+              },
+              "data": {
+                "failCommands": [
+                  "insert"
+                ],
+                "errorCode": 91
+              }
+            }
+          }
+        },
+        {
+          "name": "runCommand",
+          "object": "database",
+          "command_name": "insert",
+          "arguments": {
+            "session": "session0",
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ]
+            }
+          },
+          "result": {
+            "errorLabelsContain": [
+              "TransientTransactionError"
+            ]
+          }
+        },
+        {
+          "name": "assertSessionUnpinned",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0"
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/mongos-recovery-token.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/mongos-recovery-token.json
new file mode 100644
index 0000000000000000000000000000000000000000..35ef45a0394075038ab95077a134d8a24bda47d9
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/mongos-recovery-token.json	
@@ -0,0 +1,509 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.1.8",
+      "topology": [
+        "sharded"
+      ]
+    }
+  ],
+  "database_name": "transaction-tests",
+  "collection_name": "test",
+  "data": [],
+  "tests": [
+    {
+      "description": "commitTransaction explicit retries include recoveryToken",
+      "useMultipleMongoses": true,
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null,
+              "recoveryToken": 42
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": {
+                "w": "majority",
+                "wtimeout": 10000
+              },
+              "recoveryToken": 42
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": {
+                "w": "majority",
+                "wtimeout": 10000
+              },
+              "recoveryToken": 42
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "commitTransaction retry succeeds on new mongos",
+      "useMultipleMongoses": true,
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0",
+          "arguments": {
+            "options": {
+              "writeConcern": {
+                "w": "majority"
+              }
+            }
+          }
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "targetedFailPoint",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0",
+            "failPoint": {
+              "configureFailPoint": "failCommand",
+              "mode": {
+                "times": 1
+              },
+              "data": {
+                "failCommands": [
+                  "commitTransaction"
+                ],
+                "writeConcernError": {
+                  "code": 91,
+                  "errmsg": "Replication is being shut down",
+                  "errorLabels": [
+                    "RetryableWriteError"
+                  ]
+                }
+              }
+            }
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": {
+                "w": "majority"
+              },
+              "recoveryToken": 42
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": {
+                "w": "majority",
+                "wtimeout": 10000
+              },
+              "recoveryToken": 42
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "commitTransaction retry fails on new mongos",
+      "useMultipleMongoses": true,
+      "clientOptions": {
+        "heartbeatFrequencyMS": 30000
+      },
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "targetedFailPoint",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0",
+            "failPoint": {
+              "configureFailPoint": "failCommand",
+              "mode": {
+                "times": 7
+              },
+              "data": {
+                "failCommands": [
+                  "commitTransaction",
+                  "isMaster"
+                ],
+                "closeConnection": true
+              }
+            }
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0",
+          "result": {
+            "errorLabelsContain": [
+              "TransientTransactionError"
+            ],
+            "errorLabelsOmit": [
+              "UnknownTransactionCommitResult"
+            ],
+            "errorCodeName": "NoSuchTransaction"
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null,
+              "recoveryToken": 42
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": {
+                "w": "majority",
+                "wtimeout": 10000
+              },
+              "recoveryToken": 42
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": []
+        }
+      }
+    },
+    {
+      "description": "abortTransaction sends recoveryToken",
+      "useMultipleMongoses": true,
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "targetedFailPoint",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0",
+            "failPoint": {
+              "configureFailPoint": "failCommand",
+              "mode": {
+                "times": 1
+              },
+              "data": {
+                "failCommands": [
+                  "abortTransaction"
+                ],
+                "closeConnection": true
+              }
+            }
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "abortTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null,
+              "recoveryToken": 42
+            },
+            "command_name": "abortTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "abortTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null,
+              "recoveryToken": 42
+            },
+            "command_name": "abortTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": []
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/pin-mongos.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/pin-mongos.json
new file mode 100644
index 0000000000000000000000000000000000000000..8e9d049d048cbe2104064c90fdd8d89f63ce6a1c
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/pin-mongos.json	
@@ -0,0 +1,1227 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.1.8",
+      "topology": [
+        "sharded"
+      ]
+    }
+  ],
+  "database_name": "transaction-tests",
+  "collection_name": "test",
+  "data": [
+    {
+      "_id": 1
+    },
+    {
+      "_id": 2
+    }
+  ],
+  "tests": [
+    {
+      "description": "countDocuments",
+      "useMultipleMongoses": true,
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "countDocuments",
+          "object": "collection",
+          "arguments": {
+            "filter": {
+              "_id": 2
+            },
+            "session": "session0"
+          },
+          "result": 1
+        },
+        {
+          "name": "countDocuments",
+          "object": "collection",
+          "arguments": {
+            "filter": {
+              "_id": 2
+            },
+            "session": "session0"
+          },
+          "result": 1
+        },
+        {
+          "name": "countDocuments",
+          "object": "collection",
+          "arguments": {
+            "filter": {
+              "_id": 2
+            },
+            "session": "session0"
+          },
+          "result": 1
+        },
+        {
+          "name": "countDocuments",
+          "object": "collection",
+          "arguments": {
+            "filter": {
+              "_id": 2
+            },
+            "session": "session0"
+          },
+          "result": 1
+        },
+        {
+          "name": "countDocuments",
+          "object": "collection",
+          "arguments": {
+            "filter": {
+              "_id": 2
+            },
+            "session": "session0"
+          },
+          "result": 1
+        },
+        {
+          "name": "countDocuments",
+          "object": "collection",
+          "arguments": {
+            "filter": {
+              "_id": 2
+            },
+            "session": "session0"
+          },
+          "result": 1
+        },
+        {
+          "name": "countDocuments",
+          "object": "collection",
+          "arguments": {
+            "filter": {
+              "_id": 2
+            },
+            "session": "session0"
+          },
+          "result": 1
+        },
+        {
+          "name": "countDocuments",
+          "object": "collection",
+          "arguments": {
+            "filter": {
+              "_id": 2
+            },
+            "session": "session0"
+          },
+          "result": 1
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "distinct",
+      "useMultipleMongoses": true,
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "distinct",
+          "object": "collection",
+          "arguments": {
+            "fieldName": "_id",
+            "session": "session0"
+          },
+          "result": [
+            1,
+            2
+          ]
+        },
+        {
+          "name": "distinct",
+          "object": "collection",
+          "arguments": {
+            "fieldName": "_id",
+            "session": "session0"
+          },
+          "result": [
+            1,
+            2
+          ]
+        },
+        {
+          "name": "distinct",
+          "object": "collection",
+          "arguments": {
+            "fieldName": "_id",
+            "session": "session0"
+          },
+          "result": [
+            1,
+            2
+          ]
+        },
+        {
+          "name": "distinct",
+          "object": "collection",
+          "arguments": {
+            "fieldName": "_id",
+            "session": "session0"
+          },
+          "result": [
+            1,
+            2
+          ]
+        },
+        {
+          "name": "distinct",
+          "object": "collection",
+          "arguments": {
+            "fieldName": "_id",
+            "session": "session0"
+          },
+          "result": [
+            1,
+            2
+          ]
+        },
+        {
+          "name": "distinct",
+          "object": "collection",
+          "arguments": {
+            "fieldName": "_id",
+            "session": "session0"
+          },
+          "result": [
+            1,
+            2
+          ]
+        },
+        {
+          "name": "distinct",
+          "object": "collection",
+          "arguments": {
+            "fieldName": "_id",
+            "session": "session0"
+          },
+          "result": [
+            1,
+            2
+          ]
+        },
+        {
+          "name": "distinct",
+          "object": "collection",
+          "arguments": {
+            "fieldName": "_id",
+            "session": "session0"
+          },
+          "result": [
+            1,
+            2
+          ]
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "find",
+      "useMultipleMongoses": true,
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "find",
+          "object": "collection",
+          "arguments": {
+            "filter": {
+              "_id": 2
+            },
+            "session": "session0"
+          },
+          "result": [
+            {
+              "_id": 2
+            }
+          ]
+        },
+        {
+          "name": "find",
+          "object": "collection",
+          "arguments": {
+            "filter": {
+              "_id": 2
+            },
+            "session": "session0"
+          },
+          "result": [
+            {
+              "_id": 2
+            }
+          ]
+        },
+        {
+          "name": "find",
+          "object": "collection",
+          "arguments": {
+            "filter": {
+              "_id": 2
+            },
+            "session": "session0"
+          },
+          "result": [
+            {
+              "_id": 2
+            }
+          ]
+        },
+        {
+          "name": "find",
+          "object": "collection",
+          "arguments": {
+            "filter": {
+              "_id": 2
+            },
+            "session": "session0"
+          },
+          "result": [
+            {
+              "_id": 2
+            }
+          ]
+        },
+        {
+          "name": "find",
+          "object": "collection",
+          "arguments": {
+            "filter": {
+              "_id": 2
+            },
+            "session": "session0"
+          },
+          "result": [
+            {
+              "_id": 2
+            }
+          ]
+        },
+        {
+          "name": "find",
+          "object": "collection",
+          "arguments": {
+            "filter": {
+              "_id": 2
+            },
+            "session": "session0"
+          },
+          "result": [
+            {
+              "_id": 2
+            }
+          ]
+        },
+        {
+          "name": "find",
+          "object": "collection",
+          "arguments": {
+            "filter": {
+              "_id": 2
+            },
+            "session": "session0"
+          },
+          "result": [
+            {
+              "_id": 2
+            }
+          ]
+        },
+        {
+          "name": "find",
+          "object": "collection",
+          "arguments": {
+            "filter": {
+              "_id": 2
+            },
+            "session": "session0"
+          },
+          "result": [
+            {
+              "_id": 2
+            }
+          ]
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "insertOne",
+      "useMultipleMongoses": true,
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "document": {
+              "_id": 3
+            },
+            "session": "session0"
+          },
+          "result": {
+            "insertedId": 3
+          }
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "document": {
+              "_id": 4
+            },
+            "session": "session0"
+          },
+          "result": {
+            "insertedId": 4
+          }
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "document": {
+              "_id": 5
+            },
+            "session": "session0"
+          },
+          "result": {
+            "insertedId": 5
+          }
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "document": {
+              "_id": 6
+            },
+            "session": "session0"
+          },
+          "result": {
+            "insertedId": 6
+          }
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "document": {
+              "_id": 7
+            },
+            "session": "session0"
+          },
+          "result": {
+            "insertedId": 7
+          }
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "document": {
+              "_id": 8
+            },
+            "session": "session0"
+          },
+          "result": {
+            "insertedId": 8
+          }
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "document": {
+              "_id": 9
+            },
+            "session": "session0"
+          },
+          "result": {
+            "insertedId": 9
+          }
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "document": {
+              "_id": 10
+            },
+            "session": "session0"
+          },
+          "result": {
+            "insertedId": 10
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            },
+            {
+              "_id": 3
+            },
+            {
+              "_id": 4
+            },
+            {
+              "_id": 5
+            },
+            {
+              "_id": 6
+            },
+            {
+              "_id": 7
+            },
+            {
+              "_id": 8
+            },
+            {
+              "_id": 9
+            },
+            {
+              "_id": 10
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "mixed read write operations",
+      "useMultipleMongoses": true,
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "document": {
+              "_id": 3
+            },
+            "session": "session0"
+          },
+          "result": {
+            "insertedId": 3
+          }
+        },
+        {
+          "name": "countDocuments",
+          "object": "collection",
+          "arguments": {
+            "filter": {
+              "_id": 3
+            },
+            "session": "session0"
+          },
+          "result": 1
+        },
+        {
+          "name": "countDocuments",
+          "object": "collection",
+          "arguments": {
+            "filter": {
+              "_id": 3
+            },
+            "session": "session0"
+          },
+          "result": 1
+        },
+        {
+          "name": "countDocuments",
+          "object": "collection",
+          "arguments": {
+            "filter": {
+              "_id": 3
+            },
+            "session": "session0"
+          },
+          "result": 1
+        },
+        {
+          "name": "countDocuments",
+          "object": "collection",
+          "arguments": {
+            "filter": {
+              "_id": 3
+            },
+            "session": "session0"
+          },
+          "result": 1
+        },
+        {
+          "name": "countDocuments",
+          "object": "collection",
+          "arguments": {
+            "filter": {
+              "_id": 3
+            },
+            "session": "session0"
+          },
+          "result": 1
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "document": {
+              "_id": 4
+            },
+            "session": "session0"
+          },
+          "result": {
+            "insertedId": 4
+          }
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "document": {
+              "_id": 5
+            },
+            "session": "session0"
+          },
+          "result": {
+            "insertedId": 5
+          }
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "document": {
+              "_id": 6
+            },
+            "session": "session0"
+          },
+          "result": {
+            "insertedId": 6
+          }
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "document": {
+              "_id": 7
+            },
+            "session": "session0"
+          },
+          "result": {
+            "insertedId": 7
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            },
+            {
+              "_id": 3
+            },
+            {
+              "_id": 4
+            },
+            {
+              "_id": 5
+            },
+            {
+              "_id": 6
+            },
+            {
+              "_id": 7
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "multiple commits",
+      "useMultipleMongoses": true,
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertMany",
+          "object": "collection",
+          "arguments": {
+            "documents": [
+              {
+                "_id": 3
+              },
+              {
+                "_id": 4
+              }
+            ],
+            "session": "session0"
+          },
+          "result": {
+            "insertedIds": {
+              "0": 3,
+              "1": 4
+            }
+          }
+        },
+        {
+          "name": "assertSessionPinned",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0"
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "assertSessionPinned",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0"
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "assertSessionPinned",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            },
+            {
+              "_id": 3
+            },
+            {
+              "_id": 4
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "remain pinned after non-transient error on commit",
+      "useMultipleMongoses": true,
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertMany",
+          "object": "collection",
+          "arguments": {
+            "documents": [
+              {
+                "_id": 3
+              },
+              {
+                "_id": 4
+              }
+            ],
+            "session": "session0"
+          },
+          "result": {
+            "insertedIds": {
+              "0": 3,
+              "1": 4
+            }
+          }
+        },
+        {
+          "name": "assertSessionPinned",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0"
+          }
+        },
+        {
+          "name": "targetedFailPoint",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0",
+            "failPoint": {
+              "configureFailPoint": "failCommand",
+              "mode": {
+                "times": 1
+              },
+              "data": {
+                "failCommands": [
+                  "commitTransaction"
+                ],
+                "errorCode": 51
+              }
+            }
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0",
+          "result": {
+            "errorLabelsOmit": [
+              "TransientTransactionError"
+            ],
+            "errorCode": 51
+          }
+        },
+        {
+          "name": "assertSessionPinned",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0"
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "assertSessionPinned",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            },
+            {
+              "_id": 3
+            },
+            {
+              "_id": 4
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "unpin after transient error within a transaction",
+      "useMultipleMongoses": true,
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 3
+            }
+          },
+          "result": {
+            "insertedId": 3
+          }
+        },
+        {
+          "name": "targetedFailPoint",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0",
+            "failPoint": {
+              "configureFailPoint": "failCommand",
+              "mode": {
+                "times": 1
+              },
+              "data": {
+                "failCommands": [
+                  "insert"
+                ],
+                "closeConnection": true
+              }
+            }
+          }
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 4
+            }
+          },
+          "result": {
+            "errorLabelsContain": [
+              "TransientTransactionError"
+            ],
+            "errorLabelsOmit": [
+              "UnknownTransactionCommitResult"
+            ]
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 3
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 4
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "abortTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null,
+              "recoveryToken": 42
+            },
+            "command_name": "abortTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "unpin after transient error within a transaction and commit",
+      "useMultipleMongoses": true,
+      "clientOptions": {
+        "heartbeatFrequencyMS": 30000
+      },
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 3
+            }
+          },
+          "result": {
+            "insertedId": 3
+          }
+        },
+        {
+          "name": "targetedFailPoint",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0",
+            "failPoint": {
+              "configureFailPoint": "failCommand",
+              "mode": {
+                "times": 7
+              },
+              "data": {
+                "failCommands": [
+                  "insert",
+                  "isMaster"
+                ],
+                "closeConnection": true
+              }
+            }
+          }
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 4
+            }
+          },
+          "result": {
+            "errorLabelsContain": [
+              "TransientTransactionError"
+            ],
+            "errorLabelsOmit": [
+              "UnknownTransactionCommitResult"
+            ]
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0",
+          "result": {
+            "errorLabelsContain": [
+              "TransientTransactionError"
+            ],
+            "errorLabelsOmit": [
+              "UnknownTransactionCommitResult"
+            ],
+            "errorCodeName": "NoSuchTransaction"
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 3
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 4
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null,
+              "recoveryToken": 42
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/read-concern.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/read-concern.json
new file mode 100644
index 0000000000000000000000000000000000000000..dd9243e2f7422a64560161dff376576ab560da79
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/read-concern.json	
@@ -0,0 +1,1628 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.0",
+      "topology": [
+        "replicaset"
+      ]
+    },
+    {
+      "minServerVersion": "4.1.8",
+      "topology": [
+        "sharded"
+      ]
+    }
+  ],
+  "database_name": "transaction-tests",
+  "collection_name": "test",
+  "data": [
+    {
+      "_id": 1
+    },
+    {
+      "_id": 2
+    },
+    {
+      "_id": 3
+    },
+    {
+      "_id": 4
+    }
+  ],
+  "tests": [
+    {
+      "description": "only first countDocuments includes readConcern",
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0",
+          "arguments": {
+            "options": {
+              "readConcern": {
+                "level": "majority"
+              }
+            }
+          }
+        },
+        {
+          "name": "countDocuments",
+          "object": "collection",
+          "collectionOptions": {
+            "readConcern": {
+              "level": "majority"
+            }
+          },
+          "arguments": {
+            "session": "session0",
+            "filter": {
+              "_id": {
+                "$gte": 2
+              }
+            }
+          },
+          "result": 3
+        },
+        {
+          "name": "countDocuments",
+          "object": "collection",
+          "collectionOptions": {
+            "readConcern": {
+              "level": "majority"
+            }
+          },
+          "arguments": {
+            "session": "session0",
+            "filter": {
+              "_id": {
+                "$gte": 2
+              }
+            }
+          },
+          "result": 3
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test",
+              "pipeline": [
+                {
+                  "$match": {
+                    "_id": {
+                      "$gte": 2
+                    }
+                  }
+                },
+                {
+                  "$group": {
+                    "_id": 1,
+                    "n": {
+                      "$sum": 1
+                    }
+                  }
+                }
+              ],
+              "cursor": {},
+              "lsid": "session0",
+              "readConcern": {
+                "level": "majority"
+              },
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false
+            },
+            "command_name": "aggregate",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test",
+              "pipeline": [
+                {
+                  "$match": {
+                    "_id": {
+                      "$gte": 2
+                    }
+                  }
+                },
+                {
+                  "$group": {
+                    "_id": 1,
+                    "n": {
+                      "$sum": 1
+                    }
+                  }
+                }
+              ],
+              "cursor": {},
+              "lsid": "session0",
+              "readConcern": null,
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false
+            },
+            "command_name": "aggregate",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "readConcern": null,
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            },
+            {
+              "_id": 3
+            },
+            {
+              "_id": 4
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "only first find includes readConcern",
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0",
+          "arguments": {
+            "options": {
+              "readConcern": {
+                "level": "majority"
+              }
+            }
+          }
+        },
+        {
+          "name": "find",
+          "object": "collection",
+          "collectionOptions": {
+            "readConcern": {
+              "level": "majority"
+            }
+          },
+          "arguments": {
+            "session": "session0",
+            "batchSize": 3
+          },
+          "result": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            },
+            {
+              "_id": 3
+            },
+            {
+              "_id": 4
+            }
+          ]
+        },
+        {
+          "name": "find",
+          "object": "collection",
+          "collectionOptions": {
+            "readConcern": {
+              "level": "majority"
+            }
+          },
+          "arguments": {
+            "session": "session0",
+            "batchSize": 3
+          },
+          "result": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            },
+            {
+              "_id": 3
+            },
+            {
+              "_id": 4
+            }
+          ]
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "find": "test",
+              "batchSize": 3,
+              "lsid": "session0",
+              "readConcern": {
+                "level": "majority"
+              },
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false
+            },
+            "command_name": "find",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "getMore": {
+                "$numberLong": "42"
+              },
+              "collection": "test",
+              "batchSize": 3,
+              "lsid": "session0",
+              "readConcern": null,
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false
+            },
+            "command_name": "getMore",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "test",
+              "batchSize": 3,
+              "lsid": "session0",
+              "readConcern": null,
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false
+            },
+            "command_name": "find",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "getMore": {
+                "$numberLong": "42"
+              },
+              "collection": "test",
+              "batchSize": 3,
+              "lsid": "session0",
+              "readConcern": null,
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false
+            },
+            "command_name": "getMore",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "readConcern": null,
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            },
+            {
+              "_id": 3
+            },
+            {
+              "_id": 4
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "only first aggregate includes readConcern",
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0",
+          "arguments": {
+            "options": {
+              "readConcern": {
+                "level": "majority"
+              }
+            }
+          }
+        },
+        {
+          "name": "aggregate",
+          "object": "collection",
+          "collectionOptions": {
+            "readConcern": {
+              "level": "majority"
+            }
+          },
+          "arguments": {
+            "pipeline": [
+              {
+                "$project": {
+                  "_id": 1
+                }
+              }
+            ],
+            "batchSize": 3,
+            "session": "session0"
+          },
+          "result": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            },
+            {
+              "_id": 3
+            },
+            {
+              "_id": 4
+            }
+          ]
+        },
+        {
+          "name": "aggregate",
+          "object": "collection",
+          "collectionOptions": {
+            "readConcern": {
+              "level": "majority"
+            }
+          },
+          "arguments": {
+            "pipeline": [
+              {
+                "$project": {
+                  "_id": 1
+                }
+              }
+            ],
+            "batchSize": 3,
+            "session": "session0"
+          },
+          "result": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            },
+            {
+              "_id": 3
+            },
+            {
+              "_id": 4
+            }
+          ]
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test",
+              "pipeline": [
+                {
+                  "$project": {
+                    "_id": 1
+                  }
+                }
+              ],
+              "cursor": {
+                "batchSize": 3
+              },
+              "lsid": "session0",
+              "readConcern": {
+                "level": "majority"
+              },
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false
+            },
+            "command_name": "aggregate",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "getMore": {
+                "$numberLong": "42"
+              },
+              "collection": "test",
+              "batchSize": 3,
+              "lsid": "session0",
+              "readConcern": null,
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false
+            },
+            "command_name": "getMore",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test",
+              "pipeline": [
+                {
+                  "$project": {
+                    "_id": 1
+                  }
+                }
+              ],
+              "cursor": {
+                "batchSize": 3
+              },
+              "lsid": "session0",
+              "readConcern": null,
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false
+            },
+            "command_name": "aggregate",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "getMore": {
+                "$numberLong": "42"
+              },
+              "collection": "test",
+              "batchSize": 3,
+              "lsid": "session0",
+              "readConcern": null,
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false
+            },
+            "command_name": "getMore",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "readConcern": null,
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            },
+            {
+              "_id": 3
+            },
+            {
+              "_id": 4
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "only first distinct includes readConcern",
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0",
+          "arguments": {
+            "options": {
+              "readConcern": {
+                "level": "majority"
+              }
+            }
+          }
+        },
+        {
+          "name": "distinct",
+          "object": "collection",
+          "collectionOptions": {
+            "readConcern": {
+              "level": "majority"
+            }
+          },
+          "arguments": {
+            "session": "session0",
+            "fieldName": "_id"
+          },
+          "result": [
+            1,
+            2,
+            3,
+            4
+          ]
+        },
+        {
+          "name": "distinct",
+          "object": "collection",
+          "collectionOptions": {
+            "readConcern": {
+              "level": "majority"
+            }
+          },
+          "arguments": {
+            "session": "session0",
+            "fieldName": "_id"
+          },
+          "result": [
+            1,
+            2,
+            3,
+            4
+          ]
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "distinct": "test",
+              "key": "_id",
+              "lsid": "session0",
+              "readConcern": {
+                "level": "majority"
+              },
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "distinct",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "distinct": "test",
+              "key": "_id",
+              "lsid": "session0",
+              "readConcern": null,
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "distinct",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "readConcern": null,
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            },
+            {
+              "_id": 3
+            },
+            {
+              "_id": 4
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "only first runCommand includes readConcern",
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0",
+          "arguments": {
+            "options": {
+              "readConcern": {
+                "level": "majority"
+              }
+            }
+          }
+        },
+        {
+          "name": "runCommand",
+          "object": "database",
+          "command_name": "find",
+          "arguments": {
+            "session": "session0",
+            "command": {
+              "find": "test"
+            }
+          }
+        },
+        {
+          "name": "runCommand",
+          "object": "database",
+          "command_name": "find",
+          "arguments": {
+            "session": "session0",
+            "command": {
+              "find": "test"
+            }
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "find": "test",
+              "lsid": "session0",
+              "readConcern": {
+                "level": "majority"
+              },
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "find",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "test",
+              "lsid": "session0",
+              "readConcern": null,
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "find",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "readConcern": null,
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            },
+            {
+              "_id": 3
+            },
+            {
+              "_id": 4
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "countDocuments ignores collection readConcern",
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "countDocuments",
+          "object": "collection",
+          "collectionOptions": {
+            "readConcern": {
+              "level": "majority"
+            }
+          },
+          "arguments": {
+            "session": "session0",
+            "filter": {
+              "_id": {
+                "$gte": 2
+              }
+            }
+          },
+          "result": 3
+        },
+        {
+          "name": "countDocuments",
+          "object": "collection",
+          "collectionOptions": {
+            "readConcern": {
+              "level": "majority"
+            }
+          },
+          "arguments": {
+            "session": "session0",
+            "filter": {
+              "_id": {
+                "$gte": 2
+              }
+            }
+          },
+          "result": 3
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test",
+              "pipeline": [
+                {
+                  "$match": {
+                    "_id": {
+                      "$gte": 2
+                    }
+                  }
+                },
+                {
+                  "$group": {
+                    "_id": 1,
+                    "n": {
+                      "$sum": 1
+                    }
+                  }
+                }
+              ],
+              "cursor": {},
+              "lsid": "session0",
+              "readConcern": null,
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false
+            },
+            "command_name": "aggregate",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test",
+              "pipeline": [
+                {
+                  "$match": {
+                    "_id": {
+                      "$gte": 2
+                    }
+                  }
+                },
+                {
+                  "$group": {
+                    "_id": 1,
+                    "n": {
+                      "$sum": 1
+                    }
+                  }
+                }
+              ],
+              "cursor": {},
+              "lsid": "session0",
+              "readConcern": null,
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false
+            },
+            "command_name": "aggregate",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "readConcern": null,
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            },
+            {
+              "_id": 3
+            },
+            {
+              "_id": 4
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "find ignores collection readConcern",
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "find",
+          "object": "collection",
+          "collectionOptions": {
+            "readConcern": {
+              "level": "majority"
+            }
+          },
+          "arguments": {
+            "session": "session0",
+            "batchSize": 3
+          },
+          "result": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            },
+            {
+              "_id": 3
+            },
+            {
+              "_id": 4
+            }
+          ]
+        },
+        {
+          "name": "find",
+          "object": "collection",
+          "collectionOptions": {
+            "readConcern": {
+              "level": "majority"
+            }
+          },
+          "arguments": {
+            "session": "session0",
+            "batchSize": 3
+          },
+          "result": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            },
+            {
+              "_id": 3
+            },
+            {
+              "_id": 4
+            }
+          ]
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "find": "test",
+              "batchSize": 3,
+              "lsid": "session0",
+              "readConcern": null,
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false
+            },
+            "command_name": "find",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "getMore": {
+                "$numberLong": "42"
+              },
+              "collection": "test",
+              "batchSize": 3,
+              "lsid": "session0",
+              "readConcern": null,
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false
+            },
+            "command_name": "getMore",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "test",
+              "batchSize": 3,
+              "lsid": "session0",
+              "readConcern": null,
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false
+            },
+            "command_name": "find",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "getMore": {
+                "$numberLong": "42"
+              },
+              "collection": "test",
+              "batchSize": 3,
+              "lsid": "session0",
+              "readConcern": null,
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false
+            },
+            "command_name": "getMore",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "readConcern": null,
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            },
+            {
+              "_id": 3
+            },
+            {
+              "_id": 4
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "aggregate ignores collection readConcern",
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "aggregate",
+          "object": "collection",
+          "collectionOptions": {
+            "readConcern": {
+              "level": "majority"
+            }
+          },
+          "arguments": {
+            "pipeline": [
+              {
+                "$project": {
+                  "_id": 1
+                }
+              }
+            ],
+            "batchSize": 3,
+            "session": "session0"
+          },
+          "result": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            },
+            {
+              "_id": 3
+            },
+            {
+              "_id": 4
+            }
+          ]
+        },
+        {
+          "name": "aggregate",
+          "object": "collection",
+          "collectionOptions": {
+            "readConcern": {
+              "level": "majority"
+            }
+          },
+          "arguments": {
+            "pipeline": [
+              {
+                "$project": {
+                  "_id": 1
+                }
+              }
+            ],
+            "batchSize": 3,
+            "session": "session0"
+          },
+          "result": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            },
+            {
+              "_id": 3
+            },
+            {
+              "_id": 4
+            }
+          ]
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test",
+              "pipeline": [
+                {
+                  "$project": {
+                    "_id": 1
+                  }
+                }
+              ],
+              "cursor": {
+                "batchSize": 3
+              },
+              "lsid": "session0",
+              "readConcern": null,
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false
+            },
+            "command_name": "aggregate",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "getMore": {
+                "$numberLong": "42"
+              },
+              "collection": "test",
+              "batchSize": 3,
+              "lsid": "session0",
+              "readConcern": null,
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false
+            },
+            "command_name": "getMore",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test",
+              "pipeline": [
+                {
+                  "$project": {
+                    "_id": 1
+                  }
+                }
+              ],
+              "cursor": {
+                "batchSize": 3
+              },
+              "lsid": "session0",
+              "readConcern": null,
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false
+            },
+            "command_name": "aggregate",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "getMore": {
+                "$numberLong": "42"
+              },
+              "collection": "test",
+              "batchSize": 3,
+              "lsid": "session0",
+              "readConcern": null,
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false
+            },
+            "command_name": "getMore",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "readConcern": null,
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            },
+            {
+              "_id": 3
+            },
+            {
+              "_id": 4
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "distinct ignores collection readConcern",
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "distinct",
+          "object": "collection",
+          "collectionOptions": {
+            "readConcern": {
+              "level": "majority"
+            }
+          },
+          "arguments": {
+            "session": "session0",
+            "fieldName": "_id"
+          },
+          "result": [
+            1,
+            2,
+            3,
+            4
+          ]
+        },
+        {
+          "name": "distinct",
+          "object": "collection",
+          "collectionOptions": {
+            "readConcern": {
+              "level": "majority"
+            }
+          },
+          "arguments": {
+            "session": "session0",
+            "fieldName": "_id"
+          },
+          "result": [
+            1,
+            2,
+            3,
+            4
+          ]
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "distinct": "test",
+              "key": "_id",
+              "lsid": "session0",
+              "readConcern": null,
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "distinct",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "distinct": "test",
+              "key": "_id",
+              "lsid": "session0",
+              "readConcern": null,
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "distinct",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "readConcern": null,
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            },
+            {
+              "_id": 3
+            },
+            {
+              "_id": 4
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "runCommand ignores database readConcern",
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "runCommand",
+          "object": "database",
+          "databaseOptions": {
+            "readConcern": {
+              "level": "majority"
+            }
+          },
+          "command_name": "find",
+          "arguments": {
+            "session": "session0",
+            "command": {
+              "find": "test"
+            }
+          }
+        },
+        {
+          "name": "runCommand",
+          "object": "database",
+          "command_name": "find",
+          "arguments": {
+            "session": "session0",
+            "command": {
+              "find": "test"
+            }
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "find": "test",
+              "lsid": "session0",
+              "readConcern": null,
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "find",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "test",
+              "lsid": "session0",
+              "readConcern": null,
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "find",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "readConcern": null,
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            },
+            {
+              "_id": 3
+            },
+            {
+              "_id": 4
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/read-pref.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/read-pref.json
new file mode 100644
index 0000000000000000000000000000000000000000..bf1f1970eb639ea2734f2404fbba3223e90d4133
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/read-pref.json	
@@ -0,0 +1,720 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.0",
+      "topology": [
+        "replicaset"
+      ]
+    },
+    {
+      "minServerVersion": "4.1.8",
+      "topology": [
+        "sharded"
+      ]
+    }
+  ],
+  "database_name": "transaction-tests",
+  "collection_name": "test",
+  "data": [],
+  "tests": [
+    {
+      "description": "default readPreference",
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertMany",
+          "object": "collection",
+          "arguments": {
+            "documents": [
+              {
+                "_id": 1
+              },
+              {
+                "_id": 2
+              },
+              {
+                "_id": 3
+              },
+              {
+                "_id": 4
+              }
+            ],
+            "session": "session0"
+          },
+          "result": {
+            "insertedIds": {
+              "0": 1,
+              "1": 2,
+              "2": 3,
+              "3": 4
+            }
+          }
+        },
+        {
+          "name": "aggregate",
+          "object": "collection",
+          "collectionOptions": {
+            "readPreference": {
+              "mode": "Secondary"
+            }
+          },
+          "arguments": {
+            "session": "session0",
+            "pipeline": [
+              {
+                "$match": {
+                  "_id": 1
+                }
+              },
+              {
+                "$count": "count"
+              }
+            ]
+          },
+          "result": [
+            {
+              "count": 1
+            }
+          ]
+        },
+        {
+          "name": "find",
+          "object": "collection",
+          "collectionOptions": {
+            "readPreference": {
+              "mode": "Secondary"
+            }
+          },
+          "arguments": {
+            "session": "session0",
+            "batchSize": 3
+          },
+          "result": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            },
+            {
+              "_id": 3
+            },
+            {
+              "_id": 4
+            }
+          ]
+        },
+        {
+          "name": "aggregate",
+          "object": "collection",
+          "collectionOptions": {
+            "readPreference": {
+              "mode": "Secondary"
+            }
+          },
+          "arguments": {
+            "pipeline": [
+              {
+                "$project": {
+                  "_id": 1
+                }
+              }
+            ],
+            "batchSize": 3,
+            "session": "session0"
+          },
+          "result": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            },
+            {
+              "_id": 3
+            },
+            {
+              "_id": 4
+            }
+          ]
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            },
+            {
+              "_id": 3
+            },
+            {
+              "_id": 4
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "primary readPreference",
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0",
+          "arguments": {
+            "options": {
+              "readPreference": {
+                "mode": "Primary"
+              }
+            }
+          }
+        },
+        {
+          "name": "insertMany",
+          "object": "collection",
+          "arguments": {
+            "documents": [
+              {
+                "_id": 1
+              },
+              {
+                "_id": 2
+              },
+              {
+                "_id": 3
+              },
+              {
+                "_id": 4
+              }
+            ],
+            "session": "session0"
+          },
+          "result": {
+            "insertedIds": {
+              "0": 1,
+              "1": 2,
+              "2": 3,
+              "3": 4
+            }
+          }
+        },
+        {
+          "name": "aggregate",
+          "object": "collection",
+          "collectionOptions": {
+            "readPreference": {
+              "mode": "Secondary"
+            }
+          },
+          "arguments": {
+            "session": "session0",
+            "pipeline": [
+              {
+                "$match": {
+                  "_id": 1
+                }
+              },
+              {
+                "$count": "count"
+              }
+            ]
+          },
+          "result": [
+            {
+              "count": 1
+            }
+          ]
+        },
+        {
+          "name": "find",
+          "object": "collection",
+          "collectionOptions": {
+            "readPreference": {
+              "mode": "Secondary"
+            }
+          },
+          "arguments": {
+            "session": "session0",
+            "batchSize": 3
+          },
+          "result": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            },
+            {
+              "_id": 3
+            },
+            {
+              "_id": 4
+            }
+          ]
+        },
+        {
+          "name": "aggregate",
+          "object": "collection",
+          "collectionOptions": {
+            "readPreference": {
+              "mode": "Secondary"
+            }
+          },
+          "arguments": {
+            "pipeline": [
+              {
+                "$project": {
+                  "_id": 1
+                }
+              }
+            ],
+            "batchSize": 3,
+            "session": "session0"
+          },
+          "result": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            },
+            {
+              "_id": 3
+            },
+            {
+              "_id": 4
+            }
+          ]
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            },
+            {
+              "_id": 3
+            },
+            {
+              "_id": 4
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "secondary readPreference",
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0",
+          "arguments": {
+            "options": {
+              "readPreference": {
+                "mode": "Secondary"
+              }
+            }
+          }
+        },
+        {
+          "name": "insertMany",
+          "object": "collection",
+          "arguments": {
+            "documents": [
+              {
+                "_id": 1
+              },
+              {
+                "_id": 2
+              },
+              {
+                "_id": 3
+              },
+              {
+                "_id": 4
+              }
+            ],
+            "session": "session0"
+          },
+          "result": {
+            "insertedIds": {
+              "0": 1,
+              "1": 2,
+              "2": 3,
+              "3": 4
+            }
+          }
+        },
+        {
+          "name": "aggregate",
+          "object": "collection",
+          "collectionOptions": {
+            "readPreference": {
+              "mode": "Primary"
+            }
+          },
+          "arguments": {
+            "session": "session0",
+            "pipeline": [
+              {
+                "$match": {
+                  "_id": 1
+                }
+              },
+              {
+                "$count": "count"
+              }
+            ]
+          },
+          "result": {
+            "errorContains": "read preference in a transaction must be primary"
+          }
+        },
+        {
+          "name": "find",
+          "object": "collection",
+          "collectionOptions": {
+            "readPreference": {
+              "mode": "Primary"
+            }
+          },
+          "arguments": {
+            "session": "session0",
+            "batchSize": 3
+          },
+          "result": {
+            "errorContains": "read preference in a transaction must be primary"
+          }
+        },
+        {
+          "name": "aggregate",
+          "object": "collection",
+          "collectionOptions": {
+            "readPreference": {
+              "mode": "Primary"
+            }
+          },
+          "arguments": {
+            "pipeline": [
+              {
+                "$project": {
+                  "_id": 1
+                }
+              }
+            ],
+            "batchSize": 3,
+            "session": "session0"
+          },
+          "result": {
+            "errorContains": "read preference in a transaction must be primary"
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": []
+        }
+      }
+    },
+    {
+      "description": "primaryPreferred readPreference",
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0",
+          "arguments": {
+            "options": {
+              "readPreference": {
+                "mode": "PrimaryPreferred"
+              }
+            }
+          }
+        },
+        {
+          "name": "insertMany",
+          "object": "collection",
+          "arguments": {
+            "documents": [
+              {
+                "_id": 1
+              },
+              {
+                "_id": 2
+              },
+              {
+                "_id": 3
+              },
+              {
+                "_id": 4
+              }
+            ],
+            "session": "session0"
+          },
+          "result": {
+            "insertedIds": {
+              "0": 1,
+              "1": 2,
+              "2": 3,
+              "3": 4
+            }
+          }
+        },
+        {
+          "name": "aggregate",
+          "object": "collection",
+          "collectionOptions": {
+            "readPreference": {
+              "mode": "Primary"
+            }
+          },
+          "arguments": {
+            "session": "session0",
+            "pipeline": [
+              {
+                "$match": {
+                  "_id": 1
+                }
+              },
+              {
+                "$count": "count"
+              }
+            ]
+          },
+          "result": {
+            "errorContains": "read preference in a transaction must be primary"
+          }
+        },
+        {
+          "name": "find",
+          "object": "collection",
+          "collectionOptions": {
+            "readPreference": {
+              "mode": "Primary"
+            }
+          },
+          "arguments": {
+            "session": "session0",
+            "batchSize": 3
+          },
+          "result": {
+            "errorContains": "read preference in a transaction must be primary"
+          }
+        },
+        {
+          "name": "aggregate",
+          "object": "collection",
+          "collectionOptions": {
+            "readPreference": {
+              "mode": "Primary"
+            }
+          },
+          "arguments": {
+            "pipeline": [
+              {
+                "$project": {
+                  "_id": 1
+                }
+              }
+            ],
+            "batchSize": 3,
+            "session": "session0"
+          },
+          "result": {
+            "errorContains": "read preference in a transaction must be primary"
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": []
+        }
+      }
+    },
+    {
+      "description": "nearest readPreference",
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0",
+          "arguments": {
+            "options": {
+              "readPreference": {
+                "mode": "Nearest"
+              }
+            }
+          }
+        },
+        {
+          "name": "insertMany",
+          "object": "collection",
+          "arguments": {
+            "documents": [
+              {
+                "_id": 1
+              },
+              {
+                "_id": 2
+              },
+              {
+                "_id": 3
+              },
+              {
+                "_id": 4
+              }
+            ],
+            "session": "session0"
+          },
+          "result": {
+            "insertedIds": {
+              "0": 1,
+              "1": 2,
+              "2": 3,
+              "3": 4
+            }
+          }
+        },
+        {
+          "name": "aggregate",
+          "object": "collection",
+          "collectionOptions": {
+            "readPreference": {
+              "mode": "Primary"
+            }
+          },
+          "arguments": {
+            "session": "session0",
+            "pipeline": [
+              {
+                "$match": {
+                  "_id": 1
+                }
+              },
+              {
+                "$count": "count"
+              }
+            ]
+          },
+          "result": {
+            "errorContains": "read preference in a transaction must be primary"
+          }
+        },
+        {
+          "name": "find",
+          "object": "collection",
+          "collectionOptions": {
+            "readPreference": {
+              "mode": "Primary"
+            }
+          },
+          "arguments": {
+            "session": "session0",
+            "batchSize": 3
+          },
+          "result": {
+            "errorContains": "read preference in a transaction must be primary"
+          }
+        },
+        {
+          "name": "aggregate",
+          "object": "collection",
+          "collectionOptions": {
+            "readPreference": {
+              "mode": "Primary"
+            }
+          },
+          "arguments": {
+            "pipeline": [
+              {
+                "$project": {
+                  "_id": 1
+                }
+              }
+            ],
+            "batchSize": 3,
+            "session": "session0"
+          },
+          "result": {
+            "errorContains": "read preference in a transaction must be primary"
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": []
+        }
+      }
+    },
+    {
+      "description": "secondary write only",
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0",
+          "arguments": {
+            "options": {
+              "readPreference": {
+                "mode": "Secondary"
+              }
+            }
+          }
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/reads.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/reads.json
new file mode 100644
index 0000000000000000000000000000000000000000..9fc587f482d3567f8485ddc40ace153aa087de0a
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/reads.json	
@@ -0,0 +1,543 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.0",
+      "topology": [
+        "replicaset"
+      ]
+    },
+    {
+      "minServerVersion": "4.1.8",
+      "topology": [
+        "sharded"
+      ]
+    }
+  ],
+  "database_name": "transaction-tests",
+  "collection_name": "test",
+  "data": [
+    {
+      "_id": 1
+    },
+    {
+      "_id": 2
+    },
+    {
+      "_id": 3
+    },
+    {
+      "_id": 4
+    }
+  ],
+  "tests": [
+    {
+      "description": "collection readConcern without transaction",
+      "operations": [
+        {
+          "name": "find",
+          "object": "collection",
+          "collectionOptions": {
+            "readConcern": {
+              "level": "majority"
+            }
+          },
+          "arguments": {
+            "session": "session0"
+          },
+          "result": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            },
+            {
+              "_id": 3
+            },
+            {
+              "_id": 4
+            }
+          ]
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "find": "test",
+              "readConcern": {
+                "level": "majority"
+              },
+              "lsid": "session0",
+              "txnNumber": null,
+              "startTransaction": null,
+              "autocommit": null
+            },
+            "command_name": "find",
+            "database_name": "transaction-tests"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            },
+            {
+              "_id": 3
+            },
+            {
+              "_id": 4
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "find",
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "find",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "batchSize": 3
+          },
+          "result": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            },
+            {
+              "_id": 3
+            },
+            {
+              "_id": 4
+            }
+          ]
+        },
+        {
+          "name": "find",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "batchSize": 3
+          },
+          "result": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            },
+            {
+              "_id": 3
+            },
+            {
+              "_id": 4
+            }
+          ]
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "find": "test",
+              "batchSize": 3,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false
+            },
+            "command_name": "find",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "getMore": {
+                "$numberLong": "42"
+              },
+              "collection": "test",
+              "batchSize": 3,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false
+            },
+            "command_name": "getMore",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "find": "test",
+              "batchSize": 3,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false
+            },
+            "command_name": "find",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "getMore": {
+                "$numberLong": "42"
+              },
+              "collection": "test",
+              "batchSize": 3,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false
+            },
+            "command_name": "getMore",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            },
+            {
+              "_id": 3
+            },
+            {
+              "_id": 4
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "aggregate",
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "aggregate",
+          "object": "collection",
+          "arguments": {
+            "pipeline": [
+              {
+                "$project": {
+                  "_id": 1
+                }
+              }
+            ],
+            "batchSize": 3,
+            "session": "session0"
+          },
+          "result": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            },
+            {
+              "_id": 3
+            },
+            {
+              "_id": 4
+            }
+          ]
+        },
+        {
+          "name": "aggregate",
+          "object": "collection",
+          "arguments": {
+            "pipeline": [
+              {
+                "$project": {
+                  "_id": 1
+                }
+              }
+            ],
+            "batchSize": 3,
+            "session": "session0"
+          },
+          "result": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            },
+            {
+              "_id": 3
+            },
+            {
+              "_id": 4
+            }
+          ]
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test",
+              "pipeline": [
+                {
+                  "$project": {
+                    "_id": 1
+                  }
+                }
+              ],
+              "cursor": {
+                "batchSize": 3
+              },
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false
+            },
+            "command_name": "aggregate",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "getMore": {
+                "$numberLong": "42"
+              },
+              "collection": "test",
+              "batchSize": 3,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false
+            },
+            "command_name": "getMore",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "aggregate": "test",
+              "pipeline": [
+                {
+                  "$project": {
+                    "_id": 1
+                  }
+                }
+              ],
+              "cursor": {
+                "batchSize": 3
+              },
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false
+            },
+            "command_name": "aggregate",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "getMore": {
+                "$numberLong": "42"
+              },
+              "collection": "test",
+              "batchSize": 3,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false
+            },
+            "command_name": "getMore",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            },
+            {
+              "_id": 3
+            },
+            {
+              "_id": 4
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "distinct",
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "distinct",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "fieldName": "_id"
+          },
+          "result": [
+            1,
+            2,
+            3,
+            4
+          ]
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "distinct": "test",
+              "key": "_id",
+              "lsid": "session0",
+              "readConcern": null,
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "distinct",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "readConcern": null,
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            },
+            {
+              "_id": 3
+            },
+            {
+              "_id": 4
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/retryable-abort-errorLabels.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/retryable-abort-errorLabels.json
new file mode 100644
index 0000000000000000000000000000000000000000..1110ce2c326403fdaef7dbaccbb5d5ba1afdc9b8
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/retryable-abort-errorLabels.json	
@@ -0,0 +1,204 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.3.1",
+      "topology": [
+        "replicaset",
+        "sharded"
+      ]
+    }
+  ],
+  "database_name": "transaction-tests",
+  "collection_name": "test",
+  "data": [],
+  "tests": [
+    {
+      "description": "abortTransaction only retries once with RetryableWriteError from server",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 2
+        },
+        "data": {
+          "failCommands": [
+            "abortTransaction"
+          ],
+          "errorCode": 112,
+          "errorLabels": [
+            "RetryableWriteError"
+          ]
+        }
+      },
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "abortTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "abortTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "abortTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "abortTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": []
+        }
+      }
+    },
+    {
+      "description": "abortTransaction does not retry without RetryableWriteError label",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "abortTransaction"
+          ],
+          "errorCode": 11600,
+          "errorLabels": []
+        }
+      },
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "abortTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "abortTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": []
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/retryable-abort.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/retryable-abort.json
new file mode 100644
index 0000000000000000000000000000000000000000..5a3aaa7bf8cd2dc9cf4f2cff0c65c8b92b006f76
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/retryable-abort.json	
@@ -0,0 +1,2017 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.0",
+      "topology": [
+        "replicaset"
+      ]
+    },
+    {
+      "minServerVersion": "4.1.8",
+      "topology": [
+        "sharded"
+      ]
+    }
+  ],
+  "database_name": "transaction-tests",
+  "collection_name": "test",
+  "data": [],
+  "tests": [
+    {
+      "description": "abortTransaction only performs a single retry",
+      "clientOptions": {
+        "retryWrites": false
+      },
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 2
+        },
+        "data": {
+          "failCommands": [
+            "abortTransaction"
+          ],
+          "closeConnection": true
+        }
+      },
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "abortTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "abortTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "abortTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "abortTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": []
+        }
+      }
+    },
+    {
+      "description": "abortTransaction does not retry after Interrupted",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "abortTransaction"
+          ],
+          "errorCode": 11601,
+          "closeConnection": false
+        }
+      },
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "abortTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "abortTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": []
+        }
+      }
+    },
+    {
+      "description": "abortTransaction does not retry after WriteConcernError Interrupted",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "abortTransaction"
+          ],
+          "writeConcernError": {
+            "code": 11601,
+            "errmsg": "operation was interrupted"
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0",
+          "arguments": {
+            "options": {
+              "writeConcern": {
+                "w": "majority"
+              }
+            }
+          }
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "abortTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": {
+                "w": "majority"
+              }
+            },
+            "command_name": "abortTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": []
+        }
+      }
+    },
+    {
+      "description": "abortTransaction succeeds after connection error",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "abortTransaction"
+          ],
+          "closeConnection": true
+        }
+      },
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "abortTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "abortTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "abortTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "abortTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": []
+        }
+      }
+    },
+    {
+      "description": "abortTransaction succeeds after NotMaster",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "abortTransaction"
+          ],
+          "errorCode": 10107,
+          "errorLabels": [
+            "RetryableWriteError"
+          ],
+          "closeConnection": false
+        }
+      },
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "abortTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "abortTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "abortTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "abortTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": []
+        }
+      }
+    },
+    {
+      "description": "abortTransaction succeeds after NotMasterOrSecondary",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "abortTransaction"
+          ],
+          "errorCode": 13436,
+          "errorLabels": [
+            "RetryableWriteError"
+          ],
+          "closeConnection": false
+        }
+      },
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "abortTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "abortTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "abortTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "abortTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": []
+        }
+      }
+    },
+    {
+      "description": "abortTransaction succeeds after NotMasterNoSlaveOk",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "abortTransaction"
+          ],
+          "errorCode": 13435,
+          "errorLabels": [
+            "RetryableWriteError"
+          ],
+          "closeConnection": false
+        }
+      },
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "abortTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "abortTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "abortTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "abortTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": []
+        }
+      }
+    },
+    {
+      "description": "abortTransaction succeeds after InterruptedDueToReplStateChange",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "abortTransaction"
+          ],
+          "errorCode": 11602,
+          "errorLabels": [
+            "RetryableWriteError"
+          ],
+          "closeConnection": false
+        }
+      },
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "abortTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "abortTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "abortTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "abortTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": []
+        }
+      }
+    },
+    {
+      "description": "abortTransaction succeeds after InterruptedAtShutdown",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "abortTransaction"
+          ],
+          "errorCode": 11600,
+          "errorLabels": [
+            "RetryableWriteError"
+          ],
+          "closeConnection": false
+        }
+      },
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "abortTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "abortTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "abortTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "abortTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": []
+        }
+      }
+    },
+    {
+      "description": "abortTransaction succeeds after PrimarySteppedDown",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "abortTransaction"
+          ],
+          "errorCode": 189,
+          "errorLabels": [
+            "RetryableWriteError"
+          ],
+          "closeConnection": false
+        }
+      },
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "abortTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "abortTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "abortTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "abortTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": []
+        }
+      }
+    },
+    {
+      "description": "abortTransaction succeeds after ShutdownInProgress",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "abortTransaction"
+          ],
+          "errorCode": 91,
+          "errorLabels": [
+            "RetryableWriteError"
+          ],
+          "closeConnection": false
+        }
+      },
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "abortTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "abortTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "abortTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "abortTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": []
+        }
+      }
+    },
+    {
+      "description": "abortTransaction succeeds after HostNotFound",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "abortTransaction"
+          ],
+          "errorCode": 7,
+          "errorLabels": [
+            "RetryableWriteError"
+          ],
+          "closeConnection": false
+        }
+      },
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "abortTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "abortTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "abortTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "abortTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": []
+        }
+      }
+    },
+    {
+      "description": "abortTransaction succeeds after HostUnreachable",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "abortTransaction"
+          ],
+          "errorCode": 6,
+          "errorLabels": [
+            "RetryableWriteError"
+          ],
+          "closeConnection": false
+        }
+      },
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "abortTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "abortTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "abortTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "abortTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": []
+        }
+      }
+    },
+    {
+      "description": "abortTransaction succeeds after SocketException",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "abortTransaction"
+          ],
+          "errorCode": 9001,
+          "errorLabels": [
+            "RetryableWriteError"
+          ],
+          "closeConnection": false
+        }
+      },
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "abortTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "abortTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "abortTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "abortTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": []
+        }
+      }
+    },
+    {
+      "description": "abortTransaction succeeds after NetworkTimeout",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "abortTransaction"
+          ],
+          "errorCode": 89,
+          "errorLabels": [
+            "RetryableWriteError"
+          ],
+          "closeConnection": false
+        }
+      },
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "abortTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "abortTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "abortTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "abortTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": []
+        }
+      }
+    },
+    {
+      "description": "abortTransaction succeeds after WriteConcernError InterruptedAtShutdown",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "abortTransaction"
+          ],
+          "writeConcernError": {
+            "code": 11600,
+            "errorLabels": [
+              "RetryableWriteError"
+            ],
+            "errmsg": "Replication is being shut down"
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0",
+          "arguments": {
+            "options": {
+              "writeConcern": {
+                "w": "majority"
+              }
+            }
+          }
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "abortTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": {
+                "w": "majority"
+              }
+            },
+            "command_name": "abortTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "abortTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": {
+                "w": "majority"
+              }
+            },
+            "command_name": "abortTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": []
+        }
+      }
+    },
+    {
+      "description": "abortTransaction succeeds after WriteConcernError InterruptedDueToReplStateChange",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "abortTransaction"
+          ],
+          "writeConcernError": {
+            "code": 11602,
+            "errorLabels": [
+              "RetryableWriteError"
+            ],
+            "errmsg": "Replication is being shut down"
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0",
+          "arguments": {
+            "options": {
+              "writeConcern": {
+                "w": "majority"
+              }
+            }
+          }
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "abortTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": {
+                "w": "majority"
+              }
+            },
+            "command_name": "abortTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "abortTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": {
+                "w": "majority"
+              }
+            },
+            "command_name": "abortTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": []
+        }
+      }
+    },
+    {
+      "description": "abortTransaction succeeds after WriteConcernError PrimarySteppedDown",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "abortTransaction"
+          ],
+          "writeConcernError": {
+            "code": 189,
+            "errorLabels": [
+              "RetryableWriteError"
+            ],
+            "errmsg": "Replication is being shut down"
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0",
+          "arguments": {
+            "options": {
+              "writeConcern": {
+                "w": "majority"
+              }
+            }
+          }
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "abortTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": {
+                "w": "majority"
+              }
+            },
+            "command_name": "abortTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "abortTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": {
+                "w": "majority"
+              }
+            },
+            "command_name": "abortTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": []
+        }
+      }
+    },
+    {
+      "description": "abortTransaction succeeds after WriteConcernError ShutdownInProgress",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "abortTransaction"
+          ],
+          "writeConcernError": {
+            "code": 91,
+            "errorLabels": [
+              "RetryableWriteError"
+            ],
+            "errmsg": "Replication is being shut down"
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0",
+          "arguments": {
+            "options": {
+              "writeConcern": {
+                "w": "majority"
+              }
+            }
+          }
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "abortTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": {
+                "w": "majority"
+              }
+            },
+            "command_name": "abortTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "abortTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": {
+                "w": "majority"
+              }
+            },
+            "command_name": "abortTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": []
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/retryable-commit-errorLabels.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/retryable-commit-errorLabels.json
new file mode 100644
index 0000000000000000000000000000000000000000..e0818f237bbeadcb7c6586958e08ffd00ef09a3a
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/retryable-commit-errorLabels.json	
@@ -0,0 +1,223 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.3.1",
+      "topology": [
+        "replicaset",
+        "sharded"
+      ]
+    }
+  ],
+  "database_name": "transaction-tests",
+  "collection_name": "test",
+  "data": [],
+  "tests": [
+    {
+      "description": "commitTransaction does not retry error without RetryableWriteError label",
+      "clientOptions": {
+        "retryWrites": false
+      },
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "commitTransaction"
+          ],
+          "errorCode": 11600,
+          "errorLabels": []
+        }
+      },
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0",
+          "result": {
+            "errorLabelsOmit": [
+              "RetryableWriteError",
+              "TransientTransactionError"
+            ]
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": []
+        }
+      }
+    },
+    {
+      "description": "commitTransaction retries once with RetryableWriteError from server",
+      "clientOptions": {
+        "retryWrites": false
+      },
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "commitTransaction"
+          ],
+          "errorCode": 112,
+          "errorLabels": [
+            "RetryableWriteError"
+          ]
+        }
+      },
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": {
+                "w": "majority",
+                "wtimeout": 10000
+              }
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/retryable-commit.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/retryable-commit.json
new file mode 100644
index 0000000000000000000000000000000000000000..4895c6e0c2d9cde538737c9dc04602eafda1d647
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/retryable-commit.json	
@@ -0,0 +1,2336 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.0",
+      "topology": [
+        "replicaset"
+      ]
+    },
+    {
+      "minServerVersion": "4.1.8",
+      "topology": [
+        "sharded"
+      ]
+    }
+  ],
+  "database_name": "transaction-tests",
+  "collection_name": "test",
+  "data": [],
+  "tests": [
+    {
+      "description": "commitTransaction fails after two errors",
+      "clientOptions": {
+        "retryWrites": false
+      },
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 2
+        },
+        "data": {
+          "failCommands": [
+            "commitTransaction"
+          ],
+          "closeConnection": true
+        }
+      },
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0",
+          "result": {
+            "errorLabelsContain": [
+              "RetryableWriteError",
+              "UnknownTransactionCommitResult"
+            ],
+            "errorLabelsOmit": [
+              "TransientTransactionError"
+            ]
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": {
+                "w": "majority",
+                "wtimeout": 10000
+              }
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": {
+                "w": "majority",
+                "wtimeout": 10000
+              }
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "commitTransaction applies majority write concern on retries",
+      "clientOptions": {
+        "retryWrites": false
+      },
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 2
+        },
+        "data": {
+          "failCommands": [
+            "commitTransaction"
+          ],
+          "closeConnection": true
+        }
+      },
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0",
+          "arguments": {
+            "options": {
+              "writeConcern": {
+                "w": 2,
+                "j": true,
+                "wtimeout": 5000
+              }
+            }
+          }
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0",
+          "result": {
+            "errorLabelsContain": [
+              "RetryableWriteError",
+              "UnknownTransactionCommitResult"
+            ],
+            "errorLabelsOmit": [
+              "TransientTransactionError"
+            ]
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": {
+                "w": 2,
+                "j": true,
+                "wtimeout": 5000
+              }
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": {
+                "w": "majority",
+                "j": true,
+                "wtimeout": 5000
+              }
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": {
+                "w": "majority",
+                "j": true,
+                "wtimeout": 5000
+              }
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "commitTransaction fails after Interrupted",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "commitTransaction"
+          ],
+          "errorCode": 11601,
+          "closeConnection": false
+        }
+      },
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0",
+          "result": {
+            "errorCodeName": "Interrupted",
+            "errorLabelsOmit": [
+              "RetryableWriteError",
+              "TransientTransactionError",
+              "UnknownTransactionCommitResult"
+            ]
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": []
+        }
+      }
+    },
+    {
+      "description": "commitTransaction is not retried after UnsatisfiableWriteConcern error",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "commitTransaction"
+          ],
+          "writeConcernError": {
+            "code": 100,
+            "errmsg": "Not enough data-bearing nodes"
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0",
+          "arguments": {
+            "options": {
+              "writeConcern": {
+                "w": "majority"
+              }
+            }
+          }
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0",
+          "result": {
+            "errorLabelsOmit": [
+              "RetryableWriteError",
+              "TransientTransactionError",
+              "UnknownTransactionCommitResult"
+            ]
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": {
+                "w": "majority"
+              }
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "commitTransaction succeeds after connection error",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "commitTransaction"
+          ],
+          "closeConnection": true
+        }
+      },
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": {
+                "w": "majority",
+                "wtimeout": 10000
+              }
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "commitTransaction succeeds after NotMaster",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "commitTransaction"
+          ],
+          "errorCode": 10107,
+          "errorLabels": [
+            "RetryableWriteError"
+          ],
+          "closeConnection": false
+        }
+      },
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": {
+                "w": "majority",
+                "wtimeout": 10000
+              }
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "commitTransaction succeeds after NotMasterOrSecondary",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "commitTransaction"
+          ],
+          "errorCode": 13436,
+          "errorLabels": [
+            "RetryableWriteError"
+          ],
+          "closeConnection": false
+        }
+      },
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": {
+                "w": "majority",
+                "wtimeout": 10000
+              }
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "commitTransaction succeeds after NotMasterNoSlaveOk",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "commitTransaction"
+          ],
+          "errorCode": 13435,
+          "errorLabels": [
+            "RetryableWriteError"
+          ],
+          "closeConnection": false
+        }
+      },
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": {
+                "w": "majority",
+                "wtimeout": 10000
+              }
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "commitTransaction succeeds after InterruptedDueToReplStateChange",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "commitTransaction"
+          ],
+          "errorCode": 11602,
+          "errorLabels": [
+            "RetryableWriteError"
+          ],
+          "closeConnection": false
+        }
+      },
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": {
+                "w": "majority",
+                "wtimeout": 10000
+              }
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "commitTransaction succeeds after InterruptedAtShutdown",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "commitTransaction"
+          ],
+          "errorCode": 11600,
+          "errorLabels": [
+            "RetryableWriteError"
+          ],
+          "closeConnection": false
+        }
+      },
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": {
+                "w": "majority",
+                "wtimeout": 10000
+              }
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "commitTransaction succeeds after PrimarySteppedDown",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "commitTransaction"
+          ],
+          "errorCode": 189,
+          "errorLabels": [
+            "RetryableWriteError"
+          ],
+          "closeConnection": false
+        }
+      },
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": {
+                "w": "majority",
+                "wtimeout": 10000
+              }
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "commitTransaction succeeds after ShutdownInProgress",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "commitTransaction"
+          ],
+          "errorCode": 91,
+          "errorLabels": [
+            "RetryableWriteError"
+          ],
+          "closeConnection": false
+        }
+      },
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": {
+                "w": "majority",
+                "wtimeout": 10000
+              }
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "commitTransaction succeeds after HostNotFound",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "commitTransaction"
+          ],
+          "errorCode": 7,
+          "errorLabels": [
+            "RetryableWriteError"
+          ],
+          "closeConnection": false
+        }
+      },
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": {
+                "w": "majority",
+                "wtimeout": 10000
+              }
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "commitTransaction succeeds after HostUnreachable",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "commitTransaction"
+          ],
+          "errorCode": 6,
+          "errorLabels": [
+            "RetryableWriteError"
+          ],
+          "closeConnection": false
+        }
+      },
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": {
+                "w": "majority",
+                "wtimeout": 10000
+              }
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "commitTransaction succeeds after SocketException",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "commitTransaction"
+          ],
+          "errorCode": 9001,
+          "errorLabels": [
+            "RetryableWriteError"
+          ],
+          "closeConnection": false
+        }
+      },
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": {
+                "w": "majority",
+                "wtimeout": 10000
+              }
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "commitTransaction succeeds after NetworkTimeout",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "commitTransaction"
+          ],
+          "errorCode": 89,
+          "errorLabels": [
+            "RetryableWriteError"
+          ],
+          "closeConnection": false
+        }
+      },
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": {
+                "w": "majority",
+                "wtimeout": 10000
+              }
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "commitTransaction succeeds after WriteConcernError InterruptedAtShutdown",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "commitTransaction"
+          ],
+          "writeConcernError": {
+            "code": 11600,
+            "errorLabels": [
+              "RetryableWriteError"
+            ],
+            "errmsg": "Replication is being shut down"
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0",
+          "arguments": {
+            "options": {
+              "writeConcern": {
+                "w": "majority"
+              }
+            }
+          }
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": {
+                "w": "majority"
+              }
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": {
+                "w": "majority",
+                "wtimeout": 10000
+              }
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "commitTransaction succeeds after WriteConcernError InterruptedDueToReplStateChange",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "commitTransaction"
+          ],
+          "writeConcernError": {
+            "code": 11602,
+            "errorLabels": [
+              "RetryableWriteError"
+            ],
+            "errmsg": "Replication is being shut down"
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0",
+          "arguments": {
+            "options": {
+              "writeConcern": {
+                "w": "majority"
+              }
+            }
+          }
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": {
+                "w": "majority"
+              }
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": {
+                "w": "majority",
+                "wtimeout": 10000
+              }
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "commitTransaction succeeds after WriteConcernError PrimarySteppedDown",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "commitTransaction"
+          ],
+          "writeConcernError": {
+            "code": 189,
+            "errorLabels": [
+              "RetryableWriteError"
+            ],
+            "errmsg": "Replication is being shut down"
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0",
+          "arguments": {
+            "options": {
+              "writeConcern": {
+                "w": "majority"
+              }
+            }
+          }
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": {
+                "w": "majority"
+              }
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": {
+                "w": "majority",
+                "wtimeout": 10000
+              }
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "commitTransaction succeeds after WriteConcernError ShutdownInProgress",
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "commitTransaction"
+          ],
+          "writeConcernError": {
+            "code": 91,
+            "errorLabels": [
+              "RetryableWriteError"
+            ],
+            "errmsg": "Replication is being shut down"
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0",
+          "arguments": {
+            "options": {
+              "writeConcern": {
+                "w": "majority"
+              }
+            }
+          }
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": {
+                "w": "majority"
+              }
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": {
+                "w": "majority",
+                "wtimeout": 10000
+              }
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/retryable-writes.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/retryable-writes.json
new file mode 100644
index 0000000000000000000000000000000000000000..c932893b5bc926f19acee88bbf023d7f465367de
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/retryable-writes.json	
@@ -0,0 +1,343 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.0",
+      "topology": [
+        "replicaset"
+      ]
+    },
+    {
+      "minServerVersion": "4.1.8",
+      "topology": [
+        "sharded"
+      ]
+    }
+  ],
+  "database_name": "transaction-tests",
+  "collection_name": "test",
+  "data": [],
+  "tests": [
+    {
+      "description": "increment txnNumber",
+      "clientOptions": {
+        "retryWrites": true
+      },
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 2
+            }
+          },
+          "result": {
+            "insertedId": 2
+          }
+        },
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 3
+            }
+          },
+          "result": {
+            "insertedId": 3
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertMany",
+          "object": "collection",
+          "arguments": {
+            "documents": [
+              {
+                "_id": 4
+              },
+              {
+                "_id": 5
+              }
+            ],
+            "session": "session0"
+          },
+          "result": {
+            "insertedIds": {
+              "0": 4,
+              "1": 5
+            }
+          }
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 2
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "2"
+              },
+              "startTransaction": null,
+              "autocommit": null,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 3
+                }
+              ],
+              "ordered": true,
+              "readConcern": {
+                "afterClusterTime": 42
+              },
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "3"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "abortTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "3"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "abortTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 4
+                },
+                {
+                  "_id": 5
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "4"
+              },
+              "startTransaction": null,
+              "autocommit": null,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            },
+            {
+              "_id": 4
+            },
+            {
+              "_id": 5
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "writes are not retried",
+      "clientOptions": {
+        "retryWrites": true
+      },
+      "failPoint": {
+        "configureFailPoint": "failCommand",
+        "mode": {
+          "times": 1
+        },
+        "data": {
+          "failCommands": [
+            "insert"
+          ],
+          "closeConnection": true
+        }
+      },
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "errorLabelsContain": [
+              "TransientTransactionError"
+            ]
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "abortTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "abortTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": []
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/run-command.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/run-command.json
new file mode 100644
index 0000000000000000000000000000000000000000..2f2a3a88158e038f582fa3f074b38b352074c027
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/run-command.json	
@@ -0,0 +1,306 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.0",
+      "topology": [
+        "replicaset"
+      ]
+    },
+    {
+      "minServerVersion": "4.1.8",
+      "topology": [
+        "sharded"
+      ]
+    }
+  ],
+  "database_name": "transaction-tests",
+  "collection_name": "test",
+  "data": [],
+  "tests": [
+    {
+      "description": "run command with default read preference",
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "runCommand",
+          "object": "database",
+          "command_name": "insert",
+          "arguments": {
+            "session": "session0",
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ]
+            }
+          },
+          "result": {
+            "n": 1
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ]
+    },
+    {
+      "description": "run command with secondary read preference in client option and primary read preference in transaction options",
+      "clientOptions": {
+        "readPreference": "secondary"
+      },
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0",
+          "arguments": {
+            "options": {
+              "readPreference": {
+                "mode": "Primary"
+              }
+            }
+          }
+        },
+        {
+          "name": "runCommand",
+          "object": "database",
+          "command_name": "insert",
+          "arguments": {
+            "session": "session0",
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ]
+            }
+          },
+          "result": {
+            "n": 1
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ]
+    },
+    {
+      "description": "run command with explicit primary read preference",
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "runCommand",
+          "object": "database",
+          "command_name": "insert",
+          "arguments": {
+            "session": "session0",
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ]
+            },
+            "readPreference": {
+              "mode": "Primary"
+            }
+          },
+          "result": {
+            "n": 1
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ]
+    },
+    {
+      "description": "run command fails with explicit secondary read preference",
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "runCommand",
+          "object": "database",
+          "command_name": "find",
+          "arguments": {
+            "session": "session0",
+            "command": {
+              "find": "test"
+            },
+            "readPreference": {
+              "mode": "Secondary"
+            }
+          },
+          "result": {
+            "errorContains": "read preference in a transaction must be primary"
+          }
+        }
+      ]
+    },
+    {
+      "description": "run command fails with secondary read preference from transaction options",
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0",
+          "arguments": {
+            "options": {
+              "readPreference": {
+                "mode": "Secondary"
+              }
+            }
+          }
+        },
+        {
+          "name": "runCommand",
+          "object": "database",
+          "command_name": "find",
+          "arguments": {
+            "session": "session0",
+            "command": {
+              "find": "test"
+            }
+          },
+          "result": {
+            "errorContains": "read preference in a transaction must be primary"
+          }
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/transaction-options-repl.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/transaction-options-repl.json
new file mode 100644
index 0000000000000000000000000000000000000000..33324debb8a32a02ce5797445972986337b5f529
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/transaction-options-repl.json	
@@ -0,0 +1,181 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.0",
+      "topology": [
+        "replicaset"
+      ]
+    }
+  ],
+  "database_name": "transaction-tests",
+  "collection_name": "test",
+  "data": [],
+  "tests": [
+    {
+      "description": "readConcern snapshot in startTransaction options",
+      "sessionOptions": {
+        "session0": {
+          "defaultTransactionOptions": {
+            "readConcern": {
+              "level": "majority"
+            }
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0",
+          "arguments": {
+            "options": {
+              "readConcern": {
+                "level": "snapshot"
+              }
+            }
+          }
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "startTransaction",
+          "object": "session0",
+          "arguments": {
+            "options": {
+              "readConcern": {
+                "level": "snapshot"
+              }
+            }
+          }
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 2
+            }
+          },
+          "result": {
+            "insertedId": 2
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "readConcern": {
+                "level": "snapshot"
+              },
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "readConcern": null,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 2
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "2"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "readConcern": {
+                "level": "snapshot",
+                "afterClusterTime": 42
+              },
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "abortTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "2"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "readConcern": null,
+              "writeConcern": null
+            },
+            "command_name": "abortTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/transaction-options.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/transaction-options.json
new file mode 100644
index 0000000000000000000000000000000000000000..25d245dca5692e7b733e1f0643dd1e0e4e6966e7
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/transaction-options.json	
@@ -0,0 +1,1404 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.0",
+      "topology": [
+        "replicaset"
+      ]
+    },
+    {
+      "minServerVersion": "4.1.8",
+      "topology": [
+        "sharded"
+      ]
+    }
+  ],
+  "database_name": "transaction-tests",
+  "collection_name": "test",
+  "data": [],
+  "tests": [
+    {
+      "description": "no transaction options set",
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 2
+            }
+          },
+          "result": {
+            "insertedId": 2
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "readConcern": null,
+              "writeConcern": null,
+              "maxTimeMS": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "readConcern": null,
+              "writeConcern": null,
+              "maxTimeMS": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 2
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "2"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "readConcern": {
+                "afterClusterTime": 42
+              },
+              "writeConcern": null,
+              "maxTimeMS": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "abortTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "2"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "readConcern": null,
+              "writeConcern": null,
+              "maxTimeMS": null
+            },
+            "command_name": "abortTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "transaction options inherited from client",
+      "clientOptions": {
+        "w": 1,
+        "readConcernLevel": "local"
+      },
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 2
+            }
+          },
+          "result": {
+            "insertedId": 2
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "readConcern": {
+                "level": "local"
+              },
+              "writeConcern": null,
+              "maxTimeMS": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "readConcern": null,
+              "writeConcern": {
+                "w": 1
+              },
+              "maxTimeMS": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 2
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "2"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "readConcern": {
+                "level": "local",
+                "afterClusterTime": 42
+              },
+              "writeConcern": null,
+              "maxTimeMS": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "abortTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "2"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "readConcern": null,
+              "writeConcern": {
+                "w": 1
+              },
+              "maxTimeMS": null
+            },
+            "command_name": "abortTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "transaction options inherited from defaultTransactionOptions",
+      "sessionOptions": {
+        "session0": {
+          "defaultTransactionOptions": {
+            "readConcern": {
+              "level": "majority"
+            },
+            "writeConcern": {
+              "w": 1
+            },
+            "maxCommitTimeMS": 60000
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 2
+            }
+          },
+          "result": {
+            "insertedId": 2
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "readConcern": {
+                "level": "majority"
+              },
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "readConcern": null,
+              "writeConcern": {
+                "w": 1
+              },
+              "maxTimeMS": 60000
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 2
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "2"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "readConcern": {
+                "level": "majority",
+                "afterClusterTime": 42
+              },
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "abortTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "2"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "readConcern": null,
+              "writeConcern": {
+                "w": 1
+              }
+            },
+            "command_name": "abortTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "startTransaction options override defaults",
+      "clientOptions": {
+        "readConcernLevel": "local",
+        "w": 1
+      },
+      "sessionOptions": {
+        "session0": {
+          "defaultTransactionOptions": {
+            "readConcern": {
+              "level": "snapshot"
+            },
+            "writeConcern": {
+              "w": 1
+            },
+            "maxCommitTimeMS": 30000
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0",
+          "arguments": {
+            "options": {
+              "readConcern": {
+                "level": "majority"
+              },
+              "writeConcern": {
+                "w": "majority"
+              },
+              "maxCommitTimeMS": 60000
+            }
+          }
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "startTransaction",
+          "object": "session0",
+          "arguments": {
+            "options": {
+              "readConcern": {
+                "level": "majority"
+              },
+              "writeConcern": {
+                "w": "majority"
+              }
+            }
+          }
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 2
+            }
+          },
+          "result": {
+            "insertedId": 2
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "readConcern": {
+                "level": "majority"
+              },
+              "writeConcern": null,
+              "maxTimeMS": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "readConcern": null,
+              "writeConcern": {
+                "w": "majority"
+              },
+              "maxTimeMS": 60000
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 2
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "2"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "readConcern": {
+                "level": "majority",
+                "afterClusterTime": 42
+              },
+              "writeConcern": null,
+              "maxTimeMS": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "abortTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "2"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "readConcern": null,
+              "writeConcern": {
+                "w": "majority"
+              },
+              "maxTimeMS": null
+            },
+            "command_name": "abortTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "defaultTransactionOptions override client options",
+      "clientOptions": {
+        "readConcernLevel": "local",
+        "w": 1
+      },
+      "sessionOptions": {
+        "session0": {
+          "defaultTransactionOptions": {
+            "readConcern": {
+              "level": "majority"
+            },
+            "writeConcern": {
+              "w": "majority"
+            },
+            "maxCommitTimeMS": 60000
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 2
+            }
+          },
+          "result": {
+            "insertedId": 2
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "readConcern": {
+                "level": "majority"
+              },
+              "writeConcern": null,
+              "maxTimeMS": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "readConcern": null,
+              "writeConcern": {
+                "w": "majority"
+              },
+              "maxTimeMS": 60000
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 2
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "2"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "readConcern": {
+                "level": "majority",
+                "afterClusterTime": 42
+              },
+              "writeConcern": null,
+              "maxTimeMS": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "abortTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "2"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "readConcern": null,
+              "writeConcern": {
+                "w": "majority"
+              },
+              "maxTimeMS": null
+            },
+            "command_name": "abortTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "readConcern local in defaultTransactionOptions",
+      "clientOptions": {
+        "w": 1
+      },
+      "sessionOptions": {
+        "session0": {
+          "defaultTransactionOptions": {
+            "readConcern": {
+              "level": "local"
+            }
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 2
+            }
+          },
+          "result": {
+            "insertedId": 2
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "readConcern": {
+                "level": "local"
+              },
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "readConcern": null,
+              "writeConcern": {
+                "w": 1
+              }
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 2
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "2"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "readConcern": {
+                "level": "local",
+                "afterClusterTime": 42
+              },
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "abortTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "2"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "readConcern": null,
+              "writeConcern": {
+                "w": 1
+              }
+            },
+            "command_name": "abortTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "client writeConcern ignored for bulk",
+      "clientOptions": {
+        "w": "majority"
+      },
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0",
+          "arguments": {
+            "options": {
+              "writeConcern": {
+                "w": 1
+              }
+            }
+          }
+        },
+        {
+          "name": "bulkWrite",
+          "object": "collection",
+          "arguments": {
+            "requests": [
+              {
+                "name": "insertOne",
+                "arguments": {
+                  "document": {
+                    "_id": 1
+                  }
+                }
+              }
+            ],
+            "session": "session0"
+          },
+          "result": {
+            "deletedCount": 0,
+            "insertedCount": 1,
+            "insertedIds": {
+              "0": 1
+            },
+            "matchedCount": 0,
+            "modifiedCount": 0,
+            "upsertedCount": 0,
+            "upsertedIds": {}
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": {
+                "w": 1
+              }
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "readPreference inherited from client",
+      "clientOptions": {
+        "readPreference": "secondary"
+      },
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "find",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "filter": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "errorContains": "read preference in a transaction must be primary"
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "readConcern": null,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "readConcern": null,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "readPreference inherited from defaultTransactionOptions",
+      "clientOptions": {
+        "readPreference": "primary"
+      },
+      "sessionOptions": {
+        "session0": {
+          "defaultTransactionOptions": {
+            "readPreference": {
+              "mode": "Secondary"
+            }
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "find",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "filter": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "errorContains": "read preference in a transaction must be primary"
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "readConcern": null,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "readConcern": null,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "startTransaction overrides readPreference",
+      "clientOptions": {
+        "readPreference": "primary"
+      },
+      "sessionOptions": {
+        "session0": {
+          "defaultTransactionOptions": {
+            "readPreference": {
+              "mode": "Primary"
+            }
+          }
+        }
+      },
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0",
+          "arguments": {
+            "options": {
+              "readPreference": {
+                "mode": "Secondary"
+              }
+            }
+          }
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "find",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "filter": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "errorContains": "read preference in a transaction must be primary"
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "readConcern": null,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "readConcern": null,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/update.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/update.json
new file mode 100644
index 0000000000000000000000000000000000000000..e33bf5b8106a86cfd3a19e88dda6c1201619d7df
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/update.json	
@@ -0,0 +1,442 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.0",
+      "topology": [
+        "replicaset"
+      ]
+    },
+    {
+      "minServerVersion": "4.1.8",
+      "topology": [
+        "sharded"
+      ]
+    }
+  ],
+  "database_name": "transaction-tests",
+  "collection_name": "test",
+  "data": [
+    {
+      "_id": 1
+    },
+    {
+      "_id": 2
+    },
+    {
+      "_id": 3
+    }
+  ],
+  "tests": [
+    {
+      "description": "update",
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "updateOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "filter": {
+              "_id": 4
+            },
+            "update": {
+              "$inc": {
+                "x": 1
+              }
+            },
+            "upsert": true
+          },
+          "result": {
+            "matchedCount": 0,
+            "modifiedCount": 0,
+            "upsertedCount": 1,
+            "upsertedId": 4
+          }
+        },
+        {
+          "name": "replaceOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "filter": {
+              "x": 1
+            },
+            "replacement": {
+              "y": 1
+            }
+          },
+          "result": {
+            "matchedCount": 1,
+            "modifiedCount": 1,
+            "upsertedCount": 0
+          }
+        },
+        {
+          "name": "updateMany",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "filter": {
+              "_id": {
+                "$gte": 3
+              }
+            },
+            "update": {
+              "$set": {
+                "z": 1
+              }
+            }
+          },
+          "result": {
+            "matchedCount": 2,
+            "modifiedCount": 2,
+            "upsertedCount": 0
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "update": "test",
+              "updates": [
+                {
+                  "q": {
+                    "_id": 4
+                  },
+                  "u": {
+                    "$inc": {
+                      "x": 1
+                    }
+                  },
+                  "upsert": true
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "update",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "update": "test",
+              "updates": [
+                {
+                  "q": {
+                    "x": 1
+                  },
+                  "u": {
+                    "y": 1
+                  }
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "update",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "update": "test",
+              "updates": [
+                {
+                  "q": {
+                    "_id": {
+                      "$gte": 3
+                    }
+                  },
+                  "u": {
+                    "$set": {
+                      "z": 1
+                    }
+                  },
+                  "multi": true
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "update",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            },
+            {
+              "_id": 3,
+              "z": 1
+            },
+            {
+              "_id": 4,
+              "y": 1,
+              "z": 1
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "collections writeConcern ignored for update",
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0",
+          "arguments": {
+            "options": {
+              "writeConcern": {
+                "w": "majority"
+              }
+            }
+          }
+        },
+        {
+          "name": "updateOne",
+          "object": "collection",
+          "collectionOptions": {
+            "writeConcern": {
+              "w": "majority"
+            }
+          },
+          "arguments": {
+            "session": "session0",
+            "filter": {
+              "_id": 4
+            },
+            "update": {
+              "$inc": {
+                "x": 1
+              }
+            },
+            "upsert": true
+          },
+          "result": {
+            "matchedCount": 0,
+            "modifiedCount": 0,
+            "upsertedCount": 1,
+            "upsertedId": 4
+          }
+        },
+        {
+          "name": "replaceOne",
+          "object": "collection",
+          "collectionOptions": {
+            "writeConcern": {
+              "w": "majority"
+            }
+          },
+          "arguments": {
+            "session": "session0",
+            "filter": {
+              "x": 1
+            },
+            "replacement": {
+              "y": 1
+            }
+          },
+          "result": {
+            "matchedCount": 1,
+            "modifiedCount": 1,
+            "upsertedCount": 0
+          }
+        },
+        {
+          "name": "updateMany",
+          "object": "collection",
+          "collectionOptions": {
+            "writeConcern": {
+              "w": "majority"
+            }
+          },
+          "arguments": {
+            "session": "session0",
+            "filter": {
+              "_id": {
+                "$gte": 3
+              }
+            },
+            "update": {
+              "$set": {
+                "z": 1
+              }
+            }
+          },
+          "result": {
+            "matchedCount": 2,
+            "modifiedCount": 2,
+            "upsertedCount": 0
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "update": "test",
+              "updates": [
+                {
+                  "q": {
+                    "_id": 4
+                  },
+                  "u": {
+                    "$inc": {
+                      "x": 1
+                    }
+                  },
+                  "upsert": true
+                }
+              ],
+              "ordered": true,
+              "readConcern": null,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "update",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "update": "test",
+              "updates": [
+                {
+                  "q": {
+                    "x": 1
+                  },
+                  "u": {
+                    "y": 1
+                  }
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "update",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "update": "test",
+              "updates": [
+                {
+                  "q": {
+                    "_id": {
+                      "$gte": 3
+                    }
+                  },
+                  "u": {
+                    "$set": {
+                      "z": 1
+                    }
+                  },
+                  "multi": true
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "update",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": {
+                "w": "majority"
+              }
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/write-concern.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/write-concern.json
new file mode 100644
index 0000000000000000000000000000000000000000..84b1ea3650e5b6a349cde15ddbb05d6cff41adfc
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/SpecTests/transactions/write-concern.json	
@@ -0,0 +1,1278 @@
+{
+  "runOn": [
+    {
+      "minServerVersion": "4.0",
+      "topology": [
+        "replicaset"
+      ]
+    },
+    {
+      "minServerVersion": "4.1.8",
+      "topology": [
+        "sharded"
+      ]
+    }
+  ],
+  "database_name": "transaction-tests",
+  "collection_name": "test",
+  "data": [
+    {
+      "_id": 0
+    }
+  ],
+  "tests": [
+    {
+      "description": "commit with majority",
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0",
+          "arguments": {
+            "options": {
+              "writeConcern": {
+                "w": "majority"
+              }
+            }
+          }
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "readConcern": null,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": {
+                "w": "majority"
+              }
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 0
+            },
+            {
+              "_id": 1
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "commit with default",
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "readConcern": null,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 0
+            },
+            {
+              "_id": 1
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "abort with majority",
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0",
+          "arguments": {
+            "options": {
+              "writeConcern": {
+                "w": "majority"
+              }
+            }
+          }
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "readConcern": null,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "abortTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": {
+                "w": "majority"
+              }
+            },
+            "command_name": "abortTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 0
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "abort with default",
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "readConcern": null,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "abortTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "abortTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 0
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "start with unacknowledged write concern",
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0",
+          "arguments": {
+            "options": {
+              "writeConcern": {
+                "w": 0
+              }
+            }
+          },
+          "result": {
+            "errorContains": "transactions do not support unacknowledged write concern"
+          }
+        }
+      ]
+    },
+    {
+      "description": "start with implicit unacknowledged write concern",
+      "clientOptions": {
+        "w": 0
+      },
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0",
+          "result": {
+            "errorContains": "transactions do not support unacknowledged write concern"
+          }
+        }
+      ]
+    },
+    {
+      "description": "unacknowledged write concern coll insertOne",
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection",
+          "collectionOptions": {
+            "writeConcern": {
+              "w": 0
+            }
+          },
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 1
+            }
+          },
+          "result": {
+            "insertedId": 1
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "readConcern": null,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 0
+            },
+            {
+              "_id": 1
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "unacknowledged write concern coll insertMany",
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertMany",
+          "object": "collection",
+          "collectionOptions": {
+            "writeConcern": {
+              "w": 0
+            }
+          },
+          "arguments": {
+            "session": "session0",
+            "documents": [
+              {
+                "_id": 1
+              },
+              {
+                "_id": 2
+              }
+            ]
+          },
+          "result": {
+            "insertedIds": {
+              "0": 1,
+              "1": 2
+            }
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                },
+                {
+                  "_id": 2
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "readConcern": null,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 0
+            },
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "unacknowledged write concern coll bulkWrite",
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "bulkWrite",
+          "object": "collection",
+          "collectionOptions": {
+            "writeConcern": {
+              "w": 0
+            }
+          },
+          "arguments": {
+            "session": "session0",
+            "requests": [
+              {
+                "name": "insertOne",
+                "arguments": {
+                  "document": {
+                    "_id": 1
+                  }
+                }
+              }
+            ]
+          },
+          "result": {
+            "deletedCount": 0,
+            "insertedCount": 1,
+            "insertedIds": {
+              "0": 1
+            },
+            "matchedCount": 0,
+            "modifiedCount": 0,
+            "upsertedCount": 0,
+            "upsertedIds": {}
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "insert": "test",
+              "documents": [
+                {
+                  "_id": 1
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "readConcern": null,
+              "writeConcern": null
+            },
+            "command_name": "insert",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 0
+            },
+            {
+              "_id": 1
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "unacknowledged write concern coll deleteOne",
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "deleteOne",
+          "object": "collection",
+          "collectionOptions": {
+            "writeConcern": {
+              "w": 0
+            }
+          },
+          "arguments": {
+            "session": "session0",
+            "filter": {
+              "_id": 0
+            }
+          },
+          "result": {
+            "deletedCount": 1
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "delete": "test",
+              "deletes": [
+                {
+                  "q": {
+                    "_id": 0
+                  },
+                  "limit": 1
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "readConcern": null,
+              "writeConcern": null
+            },
+            "command_name": "delete",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": []
+        }
+      }
+    },
+    {
+      "description": "unacknowledged write concern coll deleteMany",
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "deleteMany",
+          "object": "collection",
+          "collectionOptions": {
+            "writeConcern": {
+              "w": 0
+            }
+          },
+          "arguments": {
+            "session": "session0",
+            "filter": {
+              "_id": 0
+            }
+          },
+          "result": {
+            "deletedCount": 1
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "delete": "test",
+              "deletes": [
+                {
+                  "q": {
+                    "_id": 0
+                  },
+                  "limit": 0
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "readConcern": null,
+              "writeConcern": null
+            },
+            "command_name": "delete",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": []
+        }
+      }
+    },
+    {
+      "description": "unacknowledged write concern coll updateOne",
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "updateOne",
+          "object": "collection",
+          "collectionOptions": {
+            "writeConcern": {
+              "w": 0
+            }
+          },
+          "arguments": {
+            "session": "session0",
+            "filter": {
+              "_id": 0
+            },
+            "update": {
+              "$inc": {
+                "x": 1
+              }
+            },
+            "upsert": true
+          },
+          "result": {
+            "matchedCount": 1,
+            "modifiedCount": 1,
+            "upsertedCount": 0
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "update": "test",
+              "updates": [
+                {
+                  "q": {
+                    "_id": 0
+                  },
+                  "u": {
+                    "$inc": {
+                      "x": 1
+                    }
+                  },
+                  "upsert": true
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "readConcern": null,
+              "writeConcern": null
+            },
+            "command_name": "update",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 0,
+              "x": 1
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "unacknowledged write concern coll updateMany",
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "updateMany",
+          "object": "collection",
+          "collectionOptions": {
+            "writeConcern": {
+              "w": 0
+            }
+          },
+          "arguments": {
+            "session": "session0",
+            "filter": {
+              "_id": 0
+            },
+            "update": {
+              "$inc": {
+                "x": 1
+              }
+            },
+            "upsert": true
+          },
+          "result": {
+            "matchedCount": 1,
+            "modifiedCount": 1,
+            "upsertedCount": 0
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "update": "test",
+              "updates": [
+                {
+                  "q": {
+                    "_id": 0
+                  },
+                  "u": {
+                    "$inc": {
+                      "x": 1
+                    }
+                  },
+                  "multi": true,
+                  "upsert": true
+                }
+              ],
+              "ordered": true,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "readConcern": null,
+              "writeConcern": null
+            },
+            "command_name": "update",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 0,
+              "x": 1
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "unacknowledged write concern coll findOneAndDelete",
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "findOneAndDelete",
+          "object": "collection",
+          "collectionOptions": {
+            "writeConcern": {
+              "w": 0
+            }
+          },
+          "arguments": {
+            "session": "session0",
+            "filter": {
+              "_id": 0
+            }
+          },
+          "result": {
+            "_id": 0
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "findAndModify": "test",
+              "query": {
+                "_id": 0
+              },
+              "remove": true,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "readConcern": null,
+              "writeConcern": null
+            },
+            "command_name": "findAndModify",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": []
+        }
+      }
+    },
+    {
+      "description": "unacknowledged write concern coll findOneAndReplace",
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "findOneAndReplace",
+          "object": "collection",
+          "collectionOptions": {
+            "writeConcern": {
+              "w": 0
+            }
+          },
+          "arguments": {
+            "session": "session0",
+            "filter": {
+              "_id": 0
+            },
+            "replacement": {
+              "x": 1
+            },
+            "returnDocument": "Before"
+          },
+          "result": {
+            "_id": 0
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "findAndModify": "test",
+              "query": {
+                "_id": 0
+              },
+              "update": {
+                "x": 1
+              },
+              "new": false,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "readConcern": null,
+              "writeConcern": null
+            },
+            "command_name": "findAndModify",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 0,
+              "x": 1
+            }
+          ]
+        }
+      }
+    },
+    {
+      "description": "unacknowledged write concern coll findOneAndUpdate",
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "findOneAndUpdate",
+          "object": "collection",
+          "collectionOptions": {
+            "writeConcern": {
+              "w": 0
+            }
+          },
+          "arguments": {
+            "session": "session0",
+            "filter": {
+              "_id": 0
+            },
+            "update": {
+              "$inc": {
+                "x": 1
+              }
+            },
+            "returnDocument": "Before"
+          },
+          "result": {
+            "_id": 0
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectations": [
+        {
+          "command_started_event": {
+            "command": {
+              "findAndModify": "test",
+              "query": {
+                "_id": 0
+              },
+              "update": {
+                "$inc": {
+                  "x": 1
+                }
+              },
+              "new": false,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": true,
+              "autocommit": false,
+              "readConcern": null,
+              "writeConcern": null
+            },
+            "command_name": "findAndModify",
+            "database_name": "transaction-tests"
+          }
+        },
+        {
+          "command_started_event": {
+            "command": {
+              "commitTransaction": 1,
+              "lsid": "session0",
+              "txnNumber": {
+                "$numberLong": "1"
+              },
+              "startTransaction": null,
+              "autocommit": false,
+              "writeConcern": null
+            },
+            "command_name": "commitTransaction",
+            "database_name": "admin"
+          }
+        }
+      ],
+      "outcome": {
+        "collection": {
+          "data": [
+            {
+              "_id": 0,
+              "x": 1
+            }
+          ]
+        }
+      }
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/TestCase.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/TestCase.php
new file mode 100644
index 0000000000000000000000000000000000000000..16e50da1e898d2d07cd63fded2e86389229aa548
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/TestCase.php	
@@ -0,0 +1,348 @@
+<?php
+
+namespace MongoDB\Tests;
+
+use InvalidArgumentException;
+use MongoDB\Driver\ReadConcern;
+use MongoDB\Driver\ReadPreference;
+use MongoDB\Driver\WriteConcern;
+use MongoDB\Model\BSONArray;
+use MongoDB\Model\BSONDocument;
+use PHPUnit\Framework\TestCase as BaseTestCase;
+use ReflectionClass;
+use stdClass;
+use Traversable;
+use function array_map;
+use function array_merge;
+use function array_values;
+use function call_user_func;
+use function getenv;
+use function hash;
+use function is_array;
+use function is_object;
+use function is_string;
+use function iterator_to_array;
+use function MongoDB\BSON\fromPHP;
+use function MongoDB\BSON\toJSON;
+use function restore_error_handler;
+use function set_error_handler;
+use function sprintf;
+use const E_USER_DEPRECATED;
+
+abstract class TestCase extends BaseTestCase
+{
+    /**
+     * Return the connection URI.
+     *
+     * @return string
+     */
+    public static function getUri()
+    {
+        return getenv('MONGODB_URI') ?: 'mongodb://127.0.0.1:27017';
+    }
+
+    /**
+     * Asserts that a document has expected values for some fields.
+     *
+     * Only fields in the expected document will be checked. The actual document
+     * may contain additional fields.
+     *
+     * @param array|object $expectedDocument
+     * @param array|object $actualDocument
+     */
+    public function assertMatchesDocument($expectedDocument, $actualDocument)
+    {
+        $normalizedExpectedDocument = $this->normalizeBSON($expectedDocument);
+        $normalizedActualDocument = $this->normalizeBSON($actualDocument);
+
+        $extraKeys = [];
+
+        /* Avoid unsetting fields while we're iterating on the ArrayObject to
+         * work around https://bugs.php.net/bug.php?id=70246 */
+        foreach ($normalizedActualDocument as $key => $value) {
+            if (! $normalizedExpectedDocument->offsetExists($key)) {
+                $extraKeys[] = $key;
+            }
+        }
+
+        foreach ($extraKeys as $key) {
+            $normalizedActualDocument->offsetUnset($key);
+        }
+
+        $this->assertEquals(
+            toJSON(fromPHP($normalizedExpectedDocument)),
+            toJSON(fromPHP($normalizedActualDocument))
+        );
+    }
+
+    /**
+     * Asserts that a document has expected values for all fields.
+     *
+     * The actual document will be compared directly with the expected document
+     * and may not contain extra fields.
+     *
+     * @param array|object $expectedDocument
+     * @param array|object $actualDocument
+     */
+    public function assertSameDocument($expectedDocument, $actualDocument)
+    {
+        $this->assertEquals(
+            toJSON(fromPHP($this->normalizeBSON($expectedDocument))),
+            toJSON(fromPHP($this->normalizeBSON($actualDocument)))
+        );
+    }
+
+    public function assertSameDocuments(array $expectedDocuments, $actualDocuments)
+    {
+        if ($actualDocuments instanceof Traversable) {
+            $actualDocuments = iterator_to_array($actualDocuments);
+        }
+
+        if (! is_array($actualDocuments)) {
+            throw new InvalidArgumentException('$actualDocuments is not an array or Traversable');
+        }
+
+        $normalizeRootDocuments = function ($document) {
+            return toJSON(fromPHP($this->normalizeBSON($document)));
+        };
+
+        $this->assertEquals(
+            array_map($normalizeRootDocuments, $expectedDocuments),
+            array_map($normalizeRootDocuments, $actualDocuments)
+        );
+    }
+
+    /**
+     * Compatibility method as PHPUnit 9 no longer includes this method.
+     */
+    public function dataDescription() : string
+    {
+        $dataName = $this->dataName();
+
+        return is_string($dataName) ? $dataName : '';
+    }
+
+    public function provideInvalidArrayValues()
+    {
+        return $this->wrapValuesForDataProvider($this->getInvalidArrayValues());
+    }
+
+    public function provideInvalidDocumentValues()
+    {
+        return $this->wrapValuesForDataProvider($this->getInvalidDocumentValues());
+    }
+
+    protected function assertDeprecated(callable $execution)
+    {
+        $errors = [];
+
+        set_error_handler(function ($errno, $errstr) use (&$errors) {
+            $errors[] = $errstr;
+        }, E_USER_DEPRECATED);
+
+        try {
+            call_user_func($execution);
+        } finally {
+            restore_error_handler();
+        }
+
+        $this->assertCount(1, $errors);
+    }
+
+    /**
+     * Return the test collection name.
+     *
+     * @return string
+     */
+    protected function getCollectionName()
+    {
+        $class = new ReflectionClass($this);
+
+        return sprintf('%s.%s', $class->getShortName(), hash('crc32b', $this->getName()));
+    }
+
+    /**
+     * Return the test database name.
+     *
+     * @return string
+     */
+    protected function getDatabaseName()
+    {
+        return getenv('MONGODB_DATABASE') ?: 'phplib_test';
+    }
+
+    /**
+     * Return a list of invalid array values.
+     *
+     * @param boolean $includeNull
+     *
+     * @return array
+     */
+    protected function getInvalidArrayValues($includeNull = false)
+    {
+        return array_merge([123, 3.14, 'foo', true, new stdClass()], $includeNull ? [null] : []);
+    }
+
+    /**
+     * Return a list of invalid boolean values.
+     *
+     * @param boolean $includeNull
+     *
+     * @return array
+     */
+    protected function getInvalidBooleanValues($includeNull = false)
+    {
+        return array_merge([123, 3.14, 'foo', [], new stdClass()], $includeNull ? [null] : []);
+    }
+
+    /**
+     * Return a list of invalid document values.
+     *
+     * @param boolean $includeNull
+     *
+     * @return array
+     */
+    protected function getInvalidDocumentValues($includeNull = false)
+    {
+        return array_merge([123, 3.14, 'foo', true], $includeNull ? [null] : []);
+    }
+
+    /**
+     * Return a list of invalid integer values.
+     *
+     * @param boolean $includeNull
+     *
+     * @return array
+     */
+    protected function getInvalidIntegerValues($includeNull = false)
+    {
+        return array_merge([3.14, 'foo', true, [], new stdClass()], $includeNull ? [null] : []);
+    }
+
+    /**
+     * Return a list of invalid ReadPreference values.
+     *
+     * @param boolean $includeNull
+     *
+     * @return array
+     */
+    protected function getInvalidReadConcernValues($includeNull = false)
+    {
+        return array_merge([123, 3.14, 'foo', true, [], new stdClass(), new ReadPreference(ReadPreference::RP_PRIMARY), new WriteConcern(1)], $includeNull ? [null] : []);
+    }
+
+    /**
+     * Return a list of invalid ReadPreference values.
+     *
+     * @param boolean $includeNull
+     *
+     * @return array
+     */
+    protected function getInvalidReadPreferenceValues($includeNull = false)
+    {
+        return array_merge([123, 3.14, 'foo', true, [], new stdClass(), new ReadConcern(), new WriteConcern(1)], $includeNull ? [null] : []);
+    }
+
+    /**
+     * Return a list of invalid Session values.
+     *
+     * @param boolean $includeNull
+     *
+     * @return array
+     */
+    protected function getInvalidSessionValues($includeNull = false)
+    {
+        return array_merge([123, 3.14, 'foo', true, [], new stdClass(), new ReadConcern(), new ReadPreference(ReadPreference::RP_PRIMARY), new WriteConcern(1)], $includeNull ? [null] : []);
+    }
+
+    /**
+     * Return a list of invalid string values.
+     *
+     * @param boolean $includeNull
+     *
+     * @return array
+     */
+    protected function getInvalidStringValues($includeNull = false)
+    {
+        return array_merge([123, 3.14, true, [], new stdClass()], $includeNull ? [null] : []);
+    }
+
+    /**
+     * Return a list of invalid WriteConcern values.
+     *
+     * @param boolean $includeNull
+     *
+     * @return array
+     */
+    protected function getInvalidWriteConcernValues($includeNull = false)
+    {
+        return array_merge([123, 3.14, 'foo', true, [], new stdClass(), new ReadConcern(), new ReadPreference(ReadPreference::RP_PRIMARY)], $includeNull ? [null] : []);
+    }
+
+    /**
+     * Return the test namespace.
+     *
+     * @return string
+     */
+    protected function getNamespace()
+    {
+         return sprintf('%s.%s', $this->getDatabaseName(), $this->getCollectionName());
+    }
+
+    /**
+     * Wrap a list of values for use as a single-argument data provider.
+     *
+     * @param array $values List of values
+     * @return array
+     */
+    protected function wrapValuesForDataProvider(array $values)
+    {
+        return array_map(function ($value) {
+            return [$value];
+        }, $values);
+    }
+
+    /**
+     * Normalizes a BSON document or array for use with assertEquals().
+     *
+     * The argument will be converted to a BSONArray or BSONDocument based on
+     * its type and keys. Document fields will be sorted alphabetically. Each
+     * value within the array or document will then be normalized recursively.
+     *
+     * @param array|object $bson
+     * @return BSONDocument|BSONArray
+     * @throws InvalidArgumentException if $bson is not an array or object
+     */
+    private function normalizeBSON($bson)
+    {
+        if (! is_array($bson) && ! is_object($bson)) {
+            throw new InvalidArgumentException('$bson is not an array or object');
+        }
+
+        if ($bson instanceof BSONArray || (is_array($bson) && $bson === array_values($bson))) {
+            if (! $bson instanceof BSONArray) {
+                $bson = new BSONArray($bson);
+            }
+        } else {
+            if (! $bson instanceof BSONDocument) {
+                $bson = new BSONDocument((array) $bson);
+            }
+
+            $bson->ksort();
+        }
+
+        foreach ($bson as $key => $value) {
+            if ($value instanceof BSONArray || (is_array($value) && $value === array_values($value))) {
+                $bson[$key] = $this->normalizeBSON($value);
+                continue;
+            }
+
+            if ($value instanceof stdClass || $value instanceof BSONDocument || is_array($value)) {
+                $bson[$key] = $this->normalizeBSON($value);
+                continue;
+            }
+        }
+
+        return $bson;
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/CollectionData.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/CollectionData.php
new file mode 100644
index 0000000000000000000000000000000000000000..c81615a9ff8629663661448eafc10440854229cf
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/CollectionData.php	
@@ -0,0 +1,91 @@
+<?php
+
+namespace MongoDB\Tests\UnifiedSpecTests;
+
+use ArrayIterator;
+use IteratorIterator;
+use MongoDB\Client;
+use MongoDB\Driver\ReadConcern;
+use MongoDB\Driver\ReadPreference;
+use MongoDB\Driver\WriteConcern;
+use MongoDB\Tests\UnifiedSpecTests\Constraint\Matches;
+use MultipleIterator;
+use stdClass;
+use function PHPUnit\Framework\assertContainsOnly;
+use function PHPUnit\Framework\assertIsArray;
+use function PHPUnit\Framework\assertIsString;
+use function PHPUnit\Framework\assertNotNull;
+use function PHPUnit\Framework\assertThat;
+use function sprintf;
+
+class CollectionData
+{
+    /** @var string */
+    private $collectionName;
+
+    /** @var string */
+    private $databaseName;
+
+    /** @var array */
+    private $documents;
+
+    public function __construct(stdClass $o)
+    {
+        assertIsString($o->collectionName);
+        $this->collectionName = $o->collectionName;
+
+        assertIsString($o->databaseName);
+        $this->databaseName = $o->databaseName;
+
+        assertIsArray($o->documents);
+        assertContainsOnly('object', $o->documents);
+        $this->documents = $o->documents;
+    }
+
+    public function prepareInitialData(Client $client)
+    {
+        $database = $client->selectDatabase(
+            $this->databaseName,
+            ['writeConcern' => new WriteConcern(WriteConcern::MAJORITY)]
+        );
+
+        $database->dropCollection($this->collectionName);
+
+        if (empty($this->documents)) {
+            $database->createCollection($this->collectionName);
+
+            return;
+        }
+
+        $database->selectCollection($this->collectionName)->insertMany($this->documents);
+    }
+
+    public function assertOutcome(Client $client)
+    {
+        $collection = $client->selectCollection(
+            $this->databaseName,
+            $this->collectionName,
+            [
+                'readConcern' => new ReadConcern(ReadConcern::LOCAL),
+                'readPreference' => new ReadPreference(ReadPreference::PRIMARY),
+            ]
+        );
+
+        $cursor = $collection->find([], ['sort' => ['_id' => 1]]);
+
+        $mi = new MultipleIterator(MultipleIterator::MIT_NEED_ANY);
+        $mi->attachIterator(new ArrayIterator($this->documents));
+        $mi->attachIterator(new IteratorIterator($cursor));
+
+        foreach ($mi as $i => $documents) {
+            list($expectedDocument, $actualDocument) = $documents;
+            assertNotNull($expectedDocument);
+            assertNotNull($actualDocument);
+
+            /* Prohibit extra root keys and disable operators to enforce exact
+             * matching of documents. Key order variation is still allowed. */
+            $constraint = new Matches($expectedDocument, null, false, false);
+            assertThat($actualDocument, $constraint, sprintf('documents[%d] match', $i));
+        }
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/Constraint/IsBsonType.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/Constraint/IsBsonType.php
new file mode 100644
index 0000000000000000000000000000000000000000..76dbe42780970726608679a6094309cf53236f47
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/Constraint/IsBsonType.php	
@@ -0,0 +1,210 @@
+<?php
+
+namespace MongoDB\Tests\UnifiedSpecTests\Constraint;
+
+use LogicException;
+use MongoDB\BSON\BinaryInterface;
+use MongoDB\BSON\DBPointer;
+use MongoDB\BSON\Decimal128Interface;
+use MongoDB\BSON\Int64;
+use MongoDB\BSON\JavascriptInterface;
+use MongoDB\BSON\MaxKeyInterface;
+use MongoDB\BSON\MinKeyInterface;
+use MongoDB\BSON\ObjectIdInterface;
+use MongoDB\BSON\RegexInterface;
+use MongoDB\BSON\Serializable;
+use MongoDB\BSON\Symbol;
+use MongoDB\BSON\TimestampInterface;
+use MongoDB\BSON\Type;
+use MongoDB\BSON\Undefined;
+use MongoDB\BSON\UTCDateTimeInterface;
+use MongoDB\Model\BSONArray;
+use MongoDB\Model\BSONDocument;
+use PHPUnit\Framework\Constraint\Constraint;
+use PHPUnit\Framework\Constraint\LogicalOr;
+use RuntimeException;
+use Symfony\Bridge\PhpUnit\ConstraintTrait;
+use function array_keys;
+use function array_map;
+use function count;
+use function in_array;
+use function is_array;
+use function is_bool;
+use function is_float;
+use function is_int;
+use function is_object;
+use function is_string;
+use function range;
+use function sprintf;
+use const PHP_INT_SIZE;
+
+final class IsBsonType extends Constraint
+{
+    use ConstraintTrait;
+
+    /** @var array */
+    private static $types = [
+        'double',
+        'string',
+        'object',
+        'array',
+        'binData',
+        'undefined',
+        'objectId',
+        'bool',
+        'date',
+        'null',
+        'regex',
+        'dbPointer',
+        'javascript',
+        'symbol',
+        'javascriptWithScope',
+        'int',
+        'timestamp',
+        'long',
+        'decimal',
+        'minKey',
+        'maxKey',
+    ];
+
+    /** @var string */
+    private $type;
+
+    public function __construct(string $type)
+    {
+        if (! in_array($type, self::$types)) {
+            throw new RuntimeException(sprintf('Type specified for %s <%s> is not a valid type', self::class, $type));
+        }
+
+        $this->type = $type;
+    }
+
+    public static function any() : LogicalOr
+    {
+        return self::anyOf(...self::$types);
+    }
+
+    public static function anyOf(string ...$types) : Constraint
+    {
+        if (count($types) === 1) {
+            return new self(...$types);
+        }
+
+        return LogicalOr::fromConstraints(...array_map(function ($type) {
+            return new self($type);
+        }, $types));
+    }
+
+    private function doMatches($other) : bool
+    {
+        switch ($this->type) {
+            case 'double':
+                return is_float($other);
+            case 'string':
+                return is_string($other);
+            case 'object':
+                return self::isObject($other);
+            case 'array':
+                return self::isArray($other);
+            case 'binData':
+                return $other instanceof BinaryInterface;
+            case 'undefined':
+                return $other instanceof Undefined;
+            case 'objectId':
+                return $other instanceof ObjectIdInterface;
+            case 'bool':
+                return is_bool($other);
+            case 'date':
+                return $other instanceof UTCDateTimeInterface;
+            case 'null':
+                return $other === null;
+            case 'regex':
+                return $other instanceof RegexInterface;
+            case 'dbPointer':
+                return $other instanceof DBPointer;
+            case 'javascript':
+                return $other instanceof JavascriptInterface && $other->getScope() === null;
+            case 'symbol':
+                return $other instanceof Symbol;
+            case 'javascriptWithScope':
+                return $other instanceof JavascriptInterface && $other->getScope() !== null;
+            case 'int':
+                return is_int($other);
+            case 'timestamp':
+                return $other instanceof TimestampInterface;
+            case 'long':
+                if (PHP_INT_SIZE == 4) {
+                    return $other instanceof Int64;
+                }
+
+                return is_int($other);
+            case 'decimal':
+                return $other instanceof Decimal128Interface;
+            case 'minKey':
+                return $other instanceof MinKeyInterface;
+            case 'maxKey':
+                return $other instanceof MaxKeyInterface;
+            default:
+                // This should already have been caught in the constructor
+                throw new LogicException('Unsupported type: ' . $this->type);
+        }
+    }
+
+    private function doToString() : string
+    {
+        return sprintf('is of BSON type "%s"', $this->type);
+    }
+
+    private static function isArray($other) : bool
+    {
+        if ($other instanceof BSONArray) {
+            return true;
+        }
+
+        // Serializable can produce an array or object, so recurse on its output
+        if ($other instanceof Serializable) {
+            return self::isArray($other->bsonSerialize());
+        }
+
+        if (! is_array($other)) {
+            return false;
+        }
+
+        // Empty and indexed arrays serialize as BSON arrays
+        return self::isArrayEmptyOrIndexed($other);
+    }
+
+    private static function isObject($other) : bool
+    {
+        if ($other instanceof BSONDocument) {
+            return true;
+        }
+
+        // Serializable can produce an array or object, so recurse on its output
+        if ($other instanceof Serializable) {
+            return self::isObject($other->bsonSerialize());
+        }
+
+        // Non-empty, associative arrays serialize as BSON objects
+        if (is_array($other)) {
+            return ! self::isArrayEmptyOrIndexed($other);
+        }
+
+        if (! is_object($other)) {
+            return false;
+        }
+
+        /* Serializable has already been handled, so any remaining instances of
+         * Type will not serialize as BSON objects */
+        return ! $other instanceof Type;
+    }
+
+    private static function isArrayEmptyOrIndexed(array $a) : bool
+    {
+        if (empty($a)) {
+            return true;
+        }
+
+        return array_keys($a) === range(0, count($a) - 1);
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/Constraint/IsBsonTypeTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/Constraint/IsBsonTypeTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..302e63c3b161ee895cba4ab2dfed79791ea7ac33
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/Constraint/IsBsonTypeTest.php	
@@ -0,0 +1,177 @@
+<?php
+
+namespace MongoDB\Tests\UnifiedSpecTests\Constraint;
+
+use MongoDB\BSON\Binary;
+use MongoDB\BSON\Decimal128;
+use MongoDB\BSON\Javascript;
+use MongoDB\BSON\MaxKey;
+use MongoDB\BSON\MinKey;
+use MongoDB\BSON\ObjectId;
+use MongoDB\BSON\Regex;
+use MongoDB\BSON\Serializable;
+use MongoDB\BSON\Timestamp;
+use MongoDB\BSON\UTCDateTime;
+use MongoDB\Model\BSONArray;
+use MongoDB\Model\BSONDocument;
+use MongoDB\Tests\TestCase;
+use PHPUnit\Framework\Constraint\Constraint;
+use PHPUnit\Framework\ExpectationFailedException;
+use stdClass;
+use function fopen;
+use function MongoDB\BSON\fromJSON;
+use function MongoDB\BSON\toPHP;
+use function unserialize;
+use const PHP_INT_SIZE;
+
+class IsBsonTypeTest extends TestCase
+{
+    /**
+     * @dataProvider provideTypes
+     */
+    public function testConstraint($type, $value)
+    {
+        $this->assertResult(true, new IsBsonType($type), $value, $this->dataName() . ' is ' . $type);
+    }
+
+    public function provideTypes()
+    {
+        $undefined = toPHP(fromJSON('{ "undefined": {"$undefined": true} }'));
+        $symbol = toPHP(fromJSON('{ "symbol": {"$symbol": "test"} }'));
+        $dbPointer = toPHP(fromJSON('{ "dbPointer": {"$dbPointer": {"$ref": "phongo.test", "$id" : { "$oid" : "5a2e78accd485d55b405ac12" }  }} }'));
+
+        return [
+            'double' => ['double', 1.4],
+            'string' => ['string', 'foo'],
+            // Note: additional tests in testTypeObject
+            'object(stdClass)' => ['object', new stdClass()],
+            'object(BSONDocument)' => ['object', new BSONDocument()],
+            // Note: additional tests tests in testTypeArray
+            'array(indexed array)' => ['array', ['foo']],
+            'array(BSONArray)' => ['array', new BSONArray()],
+            'binData' => ['binData', new Binary('', 0)],
+            'undefined' => ['undefined', $undefined->undefined],
+            'objectId' => ['objectId', new ObjectId()],
+            'bool' => ['bool', true],
+            'date' => ['date', new UTCDateTime()],
+            'null' => ['null', null],
+            'regex' => ['regex', new Regex('.*')],
+            'dbPointer' => ['dbPointer', $dbPointer->dbPointer],
+            'javascript' => ['javascript', new Javascript('foo = 1;')],
+            'symbol' => ['symbol', $symbol->symbol],
+            'javascriptWithScope' => ['javascriptWithScope', new Javascript('foo = 1;', ['x' => 1])],
+            'int' => ['int', 1],
+            'timestamp' => ['timestamp', new Timestamp(0, 0)],
+            'long' => ['long', PHP_INT_SIZE == 4 ? unserialize('C:18:"MongoDB\BSON\Int64":38:{a:1:{s:7:"integer";s:10:"4294967296";}}') : 4294967296],
+            'decimal' => ['decimal', new Decimal128('18446744073709551616')],
+            'minKey' => ['minKey', new MinKey()],
+            'maxKey' => ['maxKey', new MaxKey()],
+        ];
+    }
+
+    /**
+     * @dataProvider provideTypes
+     */
+    public function testAny($type, $value)
+    {
+        $this->assertResult(true, IsBsonType::any(), $value, $this->dataName() . ' is a BSON type');
+    }
+
+    public function testAnyExcludesStream()
+    {
+        $this->assertResult(false, IsBsonType::any(), fopen('php://temp', 'w+b'), 'stream is not a BSON type');
+    }
+
+    public function testAnyOf()
+    {
+        $c = IsBsonType::anyOf('double', 'int');
+
+        $this->assertResult(true, $c, 1, 'int is double or int');
+        $this->assertResult(true, $c, 1.4, 'int is double or int');
+        $this->assertResult(false, $c, 'foo', 'string is not double or int');
+    }
+
+    public function testErrorMessage()
+    {
+        $c = new IsBsonType('string');
+
+        try {
+            $c->evaluate(1);
+            $this->fail('Expected a comparison failure');
+        } catch (ExpectationFailedException $e) {
+            $this->assertStringMatchesFormat('Failed asserting that %s is of BSON type "string".', $e->getMessage());
+        }
+    }
+
+    public function testTypeArray()
+    {
+        $c = new IsBsonType('array');
+
+        $this->assertResult(true, $c, [], 'empty array is array');
+        $this->assertResult(true, $c, ['foo'], 'indexed array is array');
+        $this->assertResult(true, $c, new BSONArray(), 'BSONArray is array');
+        $this->assertResult(true, $c, new SerializableArray(), 'SerializableArray is array');
+
+        $this->assertResult(false, $c, 1, 'integer is not array');
+        $this->assertResult(false, $c, ['x' => 1], 'associative array is not array');
+        $this->assertResult(false, $c, new BSONDocument(), 'BSONDocument is not array');
+        $this->assertResult(false, $c, new SerializableObject(), 'SerializableObject is not array');
+    }
+
+    public function testTypeObject()
+    {
+        $c = new IsBsonType('object');
+
+        $this->assertResult(true, $c, new stdClass(), 'stdClass is object');
+        $this->assertResult(true, $c, new BSONDocument(), 'BSONDocument is object');
+        $this->assertResult(true, $c, ['x' => 1], 'associative array is object');
+        $this->assertResult(true, $c, new SerializableObject(), 'SerializableObject is object');
+
+        $this->assertResult(false, $c, 1, 'integer is not object');
+        $this->assertResult(false, $c, [], 'empty array is not object');
+        $this->assertResult(false, $c, ['foo'], 'indexed array is not object');
+        $this->assertResult(false, $c, new BSONArray(), 'BSONArray is not object');
+        $this->assertResult(false, $c, new SerializableArray(), 'SerializableArray is not object');
+        $this->assertResult(false, $c, new ObjectId(), 'Type other than Serializable is not object');
+    }
+
+    public function testTypeJavascript()
+    {
+        $c = new IsBsonType('javascript');
+
+        $this->assertResult(false, $c, 1, 'integer is not javascript');
+        $this->assertResult(false, $c, new Javascript('foo = 1;', ['x' => 1]), 'javascriptWithScope is not javascript');
+    }
+
+    public function testTypeJavascriptWithScope()
+    {
+        $c = new IsBsonType('javascriptWithScope');
+
+        $this->assertResult(false, $c, 1, 'integer is not javascriptWithScope');
+        $this->assertResult(false, $c, new Javascript('foo = 1;'), 'javascript is not javascriptWithScope');
+    }
+
+    private function assertResult($expected, Constraint $constraint, $value, string $message = '')
+    {
+        $this->assertSame($expected, $constraint->evaluate($value, '', true), $message);
+    }
+}
+
+// phpcs:disable PSR1.Classes.ClassDeclaration.MultipleClasses
+// phpcs:disable Squiz.Classes.ClassFileName.NoMatch
+class SerializableArray implements Serializable
+{
+    public function bsonSerialize()
+    {
+        return ['foo'];
+    }
+}
+
+class SerializableObject implements Serializable
+{
+    public function bsonSerialize()
+    {
+        return ['x' => 1];
+    }
+}
+// phpcs:enable
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/Constraint/Matches.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/Constraint/Matches.php
new file mode 100644
index 0000000000000000000000000000000000000000..78bd504c4f0310b0301777433736b0351acb54c6
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/Constraint/Matches.php	
@@ -0,0 +1,453 @@
+<?php
+
+namespace MongoDB\Tests\UnifiedSpecTests\Constraint;
+
+use LogicException;
+use MongoDB\BSON\Serializable;
+use MongoDB\BSON\Type;
+use MongoDB\Model\BSONArray;
+use MongoDB\Model\BSONDocument;
+use MongoDB\Tests\UnifiedSpecTests\EntityMap;
+use PHPUnit\Framework\Constraint\Constraint;
+use PHPUnit\Framework\ExpectationFailedException;
+use RuntimeException;
+use SebastianBergmann\Comparator\ComparisonFailure;
+use SebastianBergmann\Comparator\Factory;
+use Symfony\Bridge\PhpUnit\ConstraintTrait;
+use function array_keys;
+use function count;
+use function get_debug_type;
+use function hex2bin;
+use function implode;
+use function is_array;
+use function is_float;
+use function is_int;
+use function is_object;
+use function PHPUnit\Framework\assertIsBool;
+use function PHPUnit\Framework\assertIsString;
+use function PHPUnit\Framework\assertMatchesRegularExpression;
+use function PHPUnit\Framework\assertNotNull;
+use function PHPUnit\Framework\assertThat;
+use function PHPUnit\Framework\containsOnly;
+use function PHPUnit\Framework\isInstanceOf;
+use function PHPUnit\Framework\isType;
+use function PHPUnit\Framework\logicalAnd;
+use function PHPUnit\Framework\logicalOr;
+use function range;
+use function sprintf;
+use function strpos;
+use const PHP_INT_SIZE;
+
+/**
+ * Constraint that checks if one value matches another.
+ *
+ * The expected value is passed in the constructor. An EntityMap may be supplied
+ * for resolving operators (e.g. $$matchesEntity). Behavior for allowing extra
+ * keys in root documents and processing operators is also configurable.
+ */
+class Matches extends Constraint
+{
+    use ConstraintTrait;
+
+    /** @var EntityMap */
+    private $entityMap;
+
+    /** @var mixed */
+    private $value;
+
+    /** @var bool */
+    private $allowExtraRootKeys;
+
+    /** @var bool */
+    private $allowOperators;
+
+    /** @var ComparisonFailure|null */
+    private $lastFailure;
+
+    public function __construct($value, EntityMap $entityMap = null, $allowExtraRootKeys = true, $allowOperators = true)
+    {
+        $this->value = self::prepare($value);
+        $this->entityMap = $entityMap;
+        $this->allowExtraRootKeys = $allowExtraRootKeys;
+        $this->allowOperators = $allowOperators;
+        $this->comparatorFactory = Factory::getInstance();
+    }
+
+    private function doEvaluate($other, $description = '', $returnResult = false)
+    {
+        $other = self::prepare($other);
+        $success = false;
+        $this->lastFailure = null;
+
+        try {
+            $this->assertMatches($this->value, $other);
+            $success = true;
+        } catch (ExpectationFailedException $e) {
+            /* Rethrow internal assertion failures (e.g. operator type checks,
+             * EntityMap errors), which are logical errors in the code/test. */
+            throw $e;
+        } catch (RuntimeException $e) {
+            /* This will generally catch internal errors from failAt(), which
+             * include a key path to pinpoint the failure. */
+            $this->lastFailure = new ComparisonFailure(
+                $this->value,
+                $other,
+                /* TODO: Improve the exporter to canonicalize documents by
+                 * sorting keys and remove spl_object_hash from output. */
+                $this->exporter()->export($this->value),
+                $this->exporter()->export($other),
+                false,
+                $e->getMessage()
+            );
+        }
+
+        if ($returnResult) {
+            return $success;
+        }
+
+        if (! $success) {
+            $this->fail($other, $description, $this->lastFailure);
+        }
+    }
+
+    private function assertEquals($expected, $actual, string $keyPath)
+    {
+        $expectedType = get_debug_type($expected);
+        $actualType = get_debug_type($actual);
+
+        /* Early check to work around ObjectComparator printing the entire value
+         * for a failed type comparison. Avoid doing this if either value is
+         * numeric to allow for flexible numeric comparisons (e.g. 1 == 1.0). */
+        if ($expectedType !== $actualType && ! (self::isNumeric($expected) || self::isNumeric($actual))) {
+            self::failAt(sprintf('%s is not expected type "%s"', $actualType, $expectedType), $keyPath);
+        }
+
+        try {
+            $this->comparatorFactory->getComparatorFor($expected, $actual)->assertEquals($expected, $actual);
+        } catch (ComparisonFailure $e) {
+            /* Disregard other ComparisonFailure fields, as evaluate() only uses
+             * the message when creating its own ComparisonFailure. */
+            self::failAt($e->getMessage(), $keyPath);
+        }
+    }
+
+    private function assertMatches($expected, $actual, string $keyPath = '')
+    {
+        if ($expected instanceof BSONArray) {
+            $this->assertMatchesArray($expected, $actual, $keyPath);
+
+            return;
+        }
+
+        if ($expected instanceof BSONDocument) {
+            $this->assertMatchesDocument($expected, $actual, $keyPath);
+
+            return;
+        }
+
+        $this->assertEquals($expected, $actual, $keyPath);
+    }
+
+    private function assertMatchesArray(BSONArray $expected, $actual, string $keyPath)
+    {
+        if (! $actual instanceof BSONArray) {
+            $actualType = get_debug_type($actual);
+            self::failAt(sprintf('%s is not instance of expected class "%s"', $actualType, BSONArray::class), $keyPath);
+        }
+
+        if (count($expected) !== count($actual)) {
+            self::failAt(sprintf('$actual count is %d, expected %d', count($actual), count($expected)), $keyPath);
+        }
+
+        foreach ($expected as $key => $expectedValue) {
+            $this->assertMatches(
+                $expectedValue,
+                $actual[$key],
+                (empty($keyPath) ? $key : $keyPath . '.' . $key)
+            );
+        }
+    }
+
+    private function assertMatchesDocument(BSONDocument $expected, $actual, string $keyPath)
+    {
+        if ($this->allowOperators && self::isOperator($expected)) {
+            $this->assertMatchesOperator($expected, $actual, $keyPath);
+
+            return;
+        }
+
+        if (! $actual instanceof BSONDocument) {
+            $actualType = get_debug_type($actual);
+            self::failAt(sprintf('%s is not instance of expected class "%s"', $actualType, BSONDocument::class), $keyPath);
+        }
+
+        foreach ($expected as $key => $expectedValue) {
+            $actualKeyExists = $actual->offsetExists($key);
+
+            if ($this->allowOperators && $expectedValue instanceof BSONDocument && self::isOperator($expectedValue)) {
+                $operatorName = self::getOperatorName($expectedValue);
+
+                if ($operatorName === '$$exists') {
+                    assertIsBool($expectedValue['$$exists'], '$$exists requires bool');
+
+                    if ($expectedValue['$$exists'] && ! $actualKeyExists) {
+                        self::failAt(sprintf('$actual does not have expected key "%s"', $key), $keyPath);
+                    }
+
+                    if (! $expectedValue['$$exists'] && $actualKeyExists) {
+                        self::failAt(sprintf('$actual has unexpected key "%s"', $key), $keyPath);
+                    }
+
+                    continue;
+                }
+
+                if ($operatorName === '$$unsetOrMatches') {
+                    if (! $actualKeyExists) {
+                        continue;
+                    }
+
+                    $expectedValue = $expectedValue['$$unsetOrMatches'];
+                }
+            }
+
+            if (! $actualKeyExists) {
+                self::failAt(sprintf('$actual does not have expected key "%s"', $key), $keyPath);
+            }
+
+            $this->assertMatches(
+                $expectedValue,
+                $actual[$key],
+                (empty($keyPath) ? $key : $keyPath . '.' . $key)
+            );
+        }
+
+        // Ignore extra keys in root documents
+        if ($this->allowExtraRootKeys && empty($keyPath)) {
+            return;
+        }
+
+        foreach ($actual as $key => $_) {
+            if (! $expected->offsetExists($key)) {
+                self::failAt(sprintf('$actual has unexpected key "%s"', $key), $keyPath);
+            }
+        }
+    }
+
+    private function assertMatchesOperator(BSONDocument $operator, $actual, string $keyPath)
+    {
+        $name = self::getOperatorName($operator);
+
+        if ($name === '$$type') {
+            assertThat(
+                $operator['$$type'],
+                logicalOr(isType('string'), logicalAnd(isInstanceOf(BSONArray::class), containsOnly('string'))),
+                '$$type requires string or string[]'
+            );
+
+            $constraint = IsBsonType::anyOf(...(array) $operator['$$type']);
+
+            if (! $constraint->evaluate($actual, '', true)) {
+                self::failAt(sprintf('%s is not an expected BSON type: %s', $this->exporter()->shortenedExport($actual), implode(', ', $types)), $keyPath);
+            }
+
+            return;
+        }
+
+        if ($name === '$$matchesEntity') {
+            assertNotNull($this->entityMap, '$$matchesEntity requires EntityMap');
+            assertIsString($operator['$$matchesEntity'], '$$matchesEntity requires string');
+
+            /* TODO: Consider including the entity ID in any error message to
+             * assist with diagnosing errors. Also consider disabling operators
+             * within this match, since entities are unlikely to use them. */
+            $this->assertMatches(
+                self::prepare($this->entityMap[$operator['$$matchesEntity']]),
+                $actual,
+                $keyPath
+            );
+
+            return;
+        }
+
+        if ($name === '$$matchesHexBytes') {
+            assertIsString($operator['$$matchesHexBytes'], '$$matchesHexBytes requires string');
+            assertMatchesRegularExpression('/^([0-9a-fA-F]{2})*$/', $operator['$$matchesHexBytes'], '$$matchesHexBytes requires pairs of hex chars');
+            assertIsString($actual);
+
+            if ($actual !== hex2bin($operator['$$matchesHexBytes'])) {
+                self::failAt(sprintf('%s does not match expected hex bytes: %s', $this->exporter()->shortenedExport($actual), $operator['$$matchesHexBytes']), $keyPath);
+            }
+
+            return;
+        }
+
+        if ($name === '$$unsetOrMatches') {
+            /* If the operator is used at the top level, consider null values
+             * for $actual to be unset. If the operator is nested, this check is
+             * done later during document iteration. */
+            if ($keyPath === '' && $actual === null) {
+                return;
+            }
+
+            $this->assertMatches(
+                self::prepare($operator['$$unsetOrMatches']),
+                $actual,
+                $keyPath
+            );
+
+            return;
+        }
+
+        if ($name === '$$sessionLsid') {
+            assertNotNull($this->entityMap, '$$sessionLsid requires EntityMap');
+            assertIsString($operator['$$sessionLsid'], '$$sessionLsid requires string');
+            $lsid = $this->entityMap->getLogicalSessionId($operator['$$sessionLsid']);
+
+            $this->assertEquals(self::prepare($lsid), $actual, $keyPath);
+
+            return;
+        }
+
+        throw new LogicException('unsupported operator: ' . $name);
+    }
+
+    /** @see ConstraintTrait */
+    private function doAdditionalFailureDescription($other)
+    {
+        if ($this->lastFailure === null) {
+            return '';
+        }
+
+        return $this->lastFailure->getMessage();
+    }
+
+    /** @see ConstraintTrait */
+    private function doFailureDescription($other)
+    {
+        return 'expected value matches actual value';
+    }
+
+    /** @see ConstraintTrait */
+    private function doMatches($other)
+    {
+        $other = self::prepare($other);
+
+        try {
+            $this->assertMatches($this->value, $other);
+        } catch (RuntimeException $e) {
+            return false;
+        }
+
+        return true;
+    }
+
+    /** @see ConstraintTrait */
+    private function doToString()
+    {
+        return 'matches ' . $this->exporter()->export($this->value);
+    }
+
+    private static function failAt(string $message, string $keyPath)
+    {
+        $prefix = empty($keyPath) ? '' : sprintf('Field path "%s": ', $keyPath);
+
+        throw new RuntimeException($prefix . $message);
+    }
+
+    private static function getOperatorName(BSONDocument $document) : string
+    {
+        foreach ($document as $key => $_) {
+            if (strpos((string) $key, '$$') === 0) {
+                return $key;
+            }
+        }
+
+        throw new LogicException('should not reach this point');
+    }
+
+    private static function isNumeric($value)
+    {
+        return is_int($value) || is_float($value) || $value instanceof Int64;
+    }
+
+    private static function isOperator(BSONDocument $document) : bool
+    {
+        if (count($document) !== 1) {
+            return false;
+        }
+
+        foreach ($document as $key => $_) {
+            return strpos((string) $key, '$$') === 0;
+        }
+
+        throw new LogicException('should not reach this point');
+    }
+
+    /**
+     * Prepare a value for comparison.
+     *
+     * If the value is an array or object, it will be converted to a BSONArray
+     * or BSONDocument. If $value is an array and $isRoot is true, it will be
+     * converted to a BSONDocument; otherwise, it will be converted to a
+     * BSONArray or BSONDocument based on its keys. Each value within an array
+     * or document will then be prepared recursively.
+     *
+     * @param mixed $bson
+     * @return mixed
+     */
+    private static function prepare($bson)
+    {
+        if (! is_array($bson) && ! is_object($bson)) {
+            return $bson;
+        }
+
+        /* Convert Int64 objects to integers on 64-bit platforms for
+         * compatibility reasons. */
+        if ($bson instanceof Int64 && PHP_INT_SIZE != 4) {
+            return (int) ((string) $bson);
+        }
+
+        /* TODO: Convert Int64 objects to integers on 32-bit platforms if they
+         * can be expressed as such. This is necessary to handle flexible
+         * numeric comparisons if the server returns 32-bit value as a 64-bit
+         * integer (e.g. cursor ID). */
+
+        // Serializable can produce an array or object, so recurse on its output
+        if ($bson instanceof Serializable) {
+            return self::prepare($bson->bsonSerialize());
+        }
+
+        /* Serializable has already been handled, so any remaining instances of
+         * Type will not serialize as BSON arrays or objects */
+        if ($bson instanceof Type) {
+            return $bson;
+        }
+
+        if (is_array($bson) && self::isArrayEmptyOrIndexed($bson)) {
+            $bson = new BSONArray($bson);
+        }
+
+        if (! $bson instanceof BSONArray && ! $bson instanceof BSONDocument) {
+            /* If $bson is an object, any numeric keys may become inaccessible.
+             * We can work around this by casting back to an array. */
+            $bson = new BSONDocument((array) $bson);
+        }
+
+        foreach ($bson as $key => $value) {
+            if (is_array($value) || is_object($value)) {
+                $bson[$key] = self::prepare($value);
+            }
+        }
+
+        return $bson;
+    }
+
+    private static function isArrayEmptyOrIndexed(array $a) : bool
+    {
+        if (empty($a)) {
+            return true;
+        }
+
+        return array_keys($a) === range(0, count($a) - 1);
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/Constraint/MatchesTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/Constraint/MatchesTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..39789401116e882a5cb769ac3fc6b32a54c452a8
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/Constraint/MatchesTest.php	
@@ -0,0 +1,291 @@
+<?php
+
+namespace MongoDB\Tests\UnifiedSpecTests\Constraint;
+
+use MongoDB\BSON\Binary;
+use MongoDB\Tests\FunctionalTestCase;
+use MongoDB\Tests\UnifiedSpecTests\EntityMap;
+use PHPUnit\Framework\ExpectationFailedException;
+use stdClass;
+use function hex2bin;
+use function preg_quote;
+use function version_compare;
+
+class MatchesTest extends FunctionalTestCase
+{
+    public function testMatchesDocument()
+    {
+        $c = new Matches(['x' => 1, 'y' => ['a' => 1, 'b' => 2]]);
+        $this->assertResult(false, $c, ['x' => 1, 'y' => 2], 'Incorrect value');
+        $this->assertResult(true, $c, ['x' => 1, 'y' => ['a' => 1, 'b' => 2]], 'Exact match');
+        $this->assertResult(true, $c, ['x' => 1, 'y' => ['a' => 1, 'b' => 2], 'z' => 3], 'Extra keys in root are permitted');
+        $this->assertResult(false, $c, ['x' => 1, 'y' => ['a' => 1, 'b' => 2, 'c' => 3]], 'Extra keys in embedded are not permitted');
+        $this->assertResult(true, $c, ['y' => ['b' => 2, 'a' => 1], 'x' => 1], 'Root and embedded key order is not significant');
+    }
+
+    public function testDoNotAllowExtraRootKeys()
+    {
+        $c = new Matches(['x' => 1], null, false);
+        $this->assertResult(false, $c, ['x' => 1, 'y' => 1], 'Extra keys in root are prohibited');
+    }
+
+    public function testDoNotAllowOperators()
+    {
+        $c = new Matches(['x' => ['$$exists' => true]], null, true, false);
+        $this->assertResult(false, $c, ['x' => 1], 'Operators are not processed');
+        $this->assertResult(true, $c, ['x' => ['$$exists' => true]], 'Operators are not processed but compared as-is');
+    }
+
+    public function testOperatorExists()
+    {
+        $c = new Matches(['x' => ['$$exists' => true]]);
+        $this->assertResult(true, $c, ['x' => '1'], 'root-level key exists');
+        $this->assertResult(false, $c, new stdClass(), 'root-level key missing');
+        $this->assertResult(true, $c, ['x' => '1', 'y' => 1], 'root-level key exists (extra key)');
+        $this->assertResult(false, $c, ['y' => 1], 'root-level key missing (extra key)');
+
+        $c = new Matches(['x' => ['$$exists' => false]]);
+        $this->assertResult(false, $c, ['x' => '1'], 'root-level key exists');
+        $this->assertResult(true, $c, new stdClass(), 'root-level key missing');
+        $this->assertResult(false, $c, ['x' => '1', 'y' => 1], 'root-level key exists (extra key)');
+        $this->assertResult(true, $c, ['y' => 1], 'root-level key missing (extra key)');
+
+        $c = new Matches(['x' => ['y' => ['$$exists' => true]]]);
+        $this->assertResult(true, $c, ['x' => ['y' => '1']], 'embedded key exists');
+        $this->assertResult(false, $c, ['x' => new stdClass()], 'embedded key missing');
+
+        $c = new Matches(['x' => ['y' => ['$$exists' => false]]]);
+        $this->assertResult(false, $c, ['x' => ['y' => 1]], 'embedded key exists');
+        $this->assertResult(true, $c, ['x' => new stdClass()], 'embedded key missing');
+    }
+
+    public function testOperatorType()
+    {
+        $c = new Matches(['x' => ['$$type' => 'string']]);
+        $this->assertResult(true, $c, ['x' => 'foo'], 'string matches string type');
+        $this->assertResult(false, $c, ['x' => 1], 'integer does not match string type');
+
+        $c = new Matches(['x' => ['$$type' => ['string', 'bool']]]);
+        $this->assertResult(true, $c, ['x' => 'foo'], 'string matches [string,bool] type');
+        $this->assertResult(true, $c, ['x' => true], 'bool matches [string,bool] type');
+        $this->assertResult(false, $c, ['x' => 1], 'integer does not match [string,bool] type');
+    }
+
+    public function testOperatorMatchesEntity()
+    {
+        $entityMap = new EntityMap();
+        $entityMap->set('integer', 1);
+        $entityMap->set('object', ['y' => 1]);
+
+        $c = new Matches(['x' => ['$$matchesEntity' => 'integer']], $entityMap);
+        $this->assertResult(true, $c, ['x' => 1], 'value matches integer entity (embedded)');
+        $this->assertResult(false, $c, ['x' => 2], 'value does not match integer entity (embedded)');
+        $this->assertResult(false, $c, ['x' => ['y' => 1]], 'value does not match integer entity (embedded)');
+
+        $c = new Matches(['x' => ['$$matchesEntity' => 'object']], $entityMap);
+        $this->assertResult(true, $c, ['x' => ['y' => 1]], 'value matches object entity (embedded)');
+        $this->assertResult(false, $c, ['x' => 1], 'value does not match object entity (embedded)');
+        $this->assertResult(false, $c, ['x' => ['y' => 1, 'z' => 2]], 'value does not match object entity (embedded)');
+
+        $c = new Matches(['$$matchesEntity' => 'object'], $entityMap);
+        $this->assertResult(true, $c, ['y' => 1], 'value matches object entity (root-level)');
+        $this->assertResult(true, $c, ['x' => 2, 'y' => 1], 'value matches object entity (root-level)');
+        $this->assertResult(false, $c, ['x' => ['y' => 1, 'z' => 2]], 'value does not match object entity (root-level)');
+    }
+
+    public function testOperatorMatchesHexBytes()
+    {
+        $c = new Matches(['$$matchesHexBytes' => 'DEADBEEF']);
+        $this->assertResult(true, $c, hex2bin('DEADBEEF'), 'value matches hex bytes (root-level)');
+        $this->assertResult(false, $c, hex2bin('90ABCDEF'), 'value does not match hex bytes (root-level)');
+
+        $c = new Matches(['x' => ['$$matchesHexBytes' => '90ABCDEF']]);
+        $this->assertResult(true, $c, ['x' => hex2bin('90ABCDEF')], 'value matches hex bytes (embedded)');
+        $this->assertResult(false, $c, ['x' => hex2bin('DEADBEEF')], 'value does not match hex bytes (embedded)');
+    }
+
+    public function testOperatorUnsetOrMatches()
+    {
+        $c = new Matches(['$$unsetOrMatches' => ['x' => 1]]);
+        $this->assertResult(true, $c, null, 'null value is considered unset (root-level)');
+        $this->assertResult(true, $c, ['x' => 1], 'value matches (root-level)');
+        $this->assertResult(true, $c, ['x' => 1, 'y' => 1], 'value matches (root-level)');
+        $this->assertResult(false, $c, ['x' => 2], 'value does not match (root-level)');
+
+        $c = new Matches(['x' => ['$$unsetOrMatches' => ['y' => 1]]]);
+        $this->assertResult(true, $c, new stdClass(), 'missing value is considered unset (embedded)');
+        $this->assertResult(false, $c, ['x' => null], 'null value is not considered unset (embedded)');
+        $this->assertResult(true, $c, ['x' => ['y' => 1]], 'value matches (embedded)');
+        $this->assertResult(false, $c, ['x' => ['y' => 1, 'z' => 2]], 'value does not match (embedded)');
+    }
+
+    public function testOperatorSessionLsid()
+    {
+        if (version_compare($this->getFeatureCompatibilityVersion(), '3.6', '<')) {
+            $this->markTestSkipped('startSession() is only supported on FCV 3.6 or higher');
+        }
+
+        $session = $this->manager->startSession();
+
+        $entityMap = new EntityMap();
+        $entityMap->set('session', $session);
+
+        $lsidWithWrongId = ['id' => new Binary('0123456789ABCDEF', Binary::TYPE_UUID)];
+        $lsidWithExtraField = (array) $session->getLogicalSessionId() + ['y' => 1];
+
+        $c = new Matches(['$$sessionLsid' => 'session'], $entityMap);
+        $this->assertResult(true, $c, $session->getLogicalSessionId(), 'session LSID matches (root-level)');
+        $this->assertResult(false, $c, $lsidWithWrongId, 'session LSID does not match (root-level)');
+        $this->assertResult(false, $c, $lsidWithExtraField, 'session LSID does not match (root-level)');
+        $this->assertResult(false, $c, 1, 'session LSID does not match (root-level)');
+
+        $c = new Matches(['x' => ['$$sessionLsid' => 'session']], $entityMap);
+        $this->assertResult(true, $c, ['x' => $session->getLogicalSessionId()], 'session LSID matches (embedded)');
+        $this->assertResult(false, $c, ['x' => $lsidWithWrongId], 'session LSID does not match (embedded)');
+        $this->assertResult(false, $c, ['x' => $lsidWithExtraField], 'session LSID does not match (embedded)');
+        $this->assertResult(false, $c, ['x' => 1], 'session LSID does not match (embedded)');
+    }
+
+    /**
+     * @dataProvider errorMessageProvider
+     */
+    public function testErrorMessages($expectedMessageRegex, Matches $constraint, $actualValue)
+    {
+        try {
+            $constraint->evaluate($actualValue);
+            $this->fail('Expected a comparison failure');
+        } catch (ExpectationFailedException $e) {
+            $this->assertStringContainsString('Failed asserting that expected value matches actual value.', $e->getMessage());
+            $this->assertMatchesRegularExpression($expectedMessageRegex, $e->getMessage());
+        }
+    }
+
+    public function errorMessageProvider()
+    {
+        return [
+            'assertEquals: type check (root-level)' => [
+                '#bool(ean)? is not expected type "string"#',
+                new Matches('foo'),
+                true,
+            ],
+            'assertEquals: type check (embedded)' => [
+                '#Field path "x": bool(ean)? is not expected type "string"#',
+                new Matches(['x' => 'foo']),
+                ['x' => true],
+            ],
+            'assertEquals: comparison failure (root-level)' => [
+                '#' . preg_quote('Failed asserting that two strings are equal.', '#') . '#',
+                new Matches('foo'),
+                'bar',
+            ],
+            'assertEquals: comparison failure (embedded)' => [
+                '#' . preg_quote('Field path "x": Failed asserting that two strings are equal.', '#') . '#',
+                new Matches(['x' => 'foo']),
+                ['x' => 'bar'],
+            ],
+            'assertMatchesArray: type check (root-level)' => [
+                '#' . preg_quote('MongoDB\Model\BSONDocument is not instance of expected class "MongoDB\Model\BSONArray"', '#') . '#',
+                new Matches([1, 2, 3]),
+                ['x' => 1],
+            ],
+            'assertMatchesArray: type check (embedded)' => [
+                '#Field path "x": int(eger)? is not instance of expected class "MongoDB\\\\Model\\\\BSONArray"#',
+                new Matches(['x' => [1, 2, 3]]),
+                ['x' => 1],
+            ],
+            'assertMatchesArray: count check (root-level)' => [
+                '#' . preg_quote('$actual count is 2, expected 3', '#') . '#',
+                new Matches(['x' => [1, 2, 3]]),
+                ['x' => [1, 2]],
+            ],
+            'assertMatchesArray: count check (embedded)' => [
+                '#' . preg_quote('Field path "x": $actual count is 2, expected 3', '#') . '#',
+                new Matches(['x' => [1, 2, 3]]),
+                ['x' => [1, 2]],
+            ],
+            'assertMatchesDocument: type check (root-level)' => [
+                '#int(eger)? is not instance of expected class "MongoDB\\\\Model\\\\BSONDocument"#',
+                new Matches(['x' => 1]),
+                1,
+            ],
+            'assertMatchesDocument: type check (embedded)' => [
+                '#Field path "x": int(eger)? is not instance of expected class "MongoDB\\\\Model\\\\BSONDocument"#',
+                new Matches(['x' => ['y' => 1]]),
+                ['x' => 1],
+            ],
+            'assertMatchesDocument: expected key missing (root-level)' => [
+                '#' . preg_quote('$actual does not have expected key "x"', '#') . '#',
+                new Matches(['x' => 1]),
+                new stdClass(),
+            ],
+            'assertMatchesDocument: expected key missing (embedded)' => [
+                '#' . preg_quote('Field path "x": $actual does not have expected key "y"', '#') . '#',
+                new Matches(['x' => ['y' => 1]]),
+                ['x' => new stdClass()],
+            ],
+            'assertMatchesDocument: unexpected key present (embedded)' => [
+                '#' . preg_quote('Field path "x": $actual has unexpected key "y', '#') . '#',
+                new Matches(['x' => new stdClass()]),
+                ['x' => ['y' => 1]],
+            ],
+        ];
+    }
+
+    /**
+     * @dataProvider operatorErrorMessageProvider
+     */
+    public function testOperatorSyntaxValidation($expectedMessage, Matches $constraint)
+    {
+        $this->expectException(ExpectationFailedException::class);
+        $this->expectExceptionMessage($expectedMessage);
+
+        $constraint->evaluate(['x' => 1], '', true);
+    }
+
+    public function operatorErrorMessageProvider()
+    {
+        return [
+            '$$exists type' => [
+                '$$exists requires bool',
+                new Matches(['x' => ['$$exists' => 1]]),
+            ],
+            '$$type type (string)' => [
+                '$$type requires string or string[]',
+                new Matches(['x' => ['$$type' => 1]]),
+            ],
+            '$$type type (string[])' => [
+                '$$type requires string or string[]',
+                new Matches(['x' => ['$$type' => [1]]]),
+            ],
+            '$$matchesEntity requires EntityMap' => [
+                '$$matchesEntity requires EntityMap',
+                new Matches(['x' => ['$$matchesEntity' => 'foo']]),
+            ],
+            '$$matchesEntity type' => [
+                '$$matchesEntity requires string',
+                new Matches(['x' => ['$$matchesEntity' => 1]], new EntityMap()),
+            ],
+            '$$matchesHexBytes type' => [
+                '$$matchesHexBytes requires string',
+                new Matches(['$$matchesHexBytes' => 1]),
+            ],
+            '$$matchesHexBytes string format' => [
+                '$$matchesHexBytes requires pairs of hex chars',
+                new Matches(['$$matchesHexBytes' => 'f00']),
+            ],
+            '$$sessionLsid requires EntityMap' => [
+                '$$sessionLsid requires EntityMap',
+                new Matches(['x' => ['$$sessionLsid' => 'foo']]),
+            ],
+            '$$sessionLsid type' => [
+                '$$sessionLsid requires string',
+                new Matches(['x' => ['$$sessionLsid' => 1]], new EntityMap()),
+            ],
+        ];
+    }
+
+    private function assertResult($expected, Matches $constraint, $value, string $message = '')
+    {
+        $this->assertSame($expected, $constraint->evaluate($value, '', true), $message);
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/Context.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/Context.php
new file mode 100644
index 0000000000000000000000000000000000000000..b62a5a73323af557a37e436fd5dc4eb45cf849bc
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/Context.php	
@@ -0,0 +1,452 @@
+<?php
+
+namespace MongoDB\Tests\UnifiedSpecTests;
+
+use LogicException;
+use MongoDB\Client;
+use MongoDB\Driver\Manager;
+use MongoDB\Driver\ReadPreference;
+use MongoDB\Driver\Server;
+use stdClass;
+use function array_key_exists;
+use function array_map;
+use function count;
+use function current;
+use function explode;
+use function implode;
+use function in_array;
+use function key;
+use function parse_url;
+use function PHPUnit\Framework\assertArrayHasKey;
+use function PHPUnit\Framework\assertCount;
+use function PHPUnit\Framework\assertIsArray;
+use function PHPUnit\Framework\assertIsBool;
+use function PHPUnit\Framework\assertIsInt;
+use function PHPUnit\Framework\assertIsObject;
+use function PHPUnit\Framework\assertIsString;
+use function PHPUnit\Framework\assertNotEmpty;
+use function PHPUnit\Framework\assertNotFalse;
+use function PHPUnit\Framework\assertStringContainsString;
+use function PHPUnit\Framework\assertStringStartsWith;
+use function strlen;
+use function strpos;
+use function substr_replace;
+use const PHP_URL_HOST;
+
+/**
+ * Execution context for spec tests.
+ *
+ * This object tracks state that would be difficult to store on the test itself
+ * due to the design of PHPUnit's data providers and setUp/tearDown methods.
+ */
+final class Context
+{
+    /** @var string */
+    private $activeClient;
+
+    /** @var string[] */
+    private $dirtySessions = [];
+
+    /** @var EntityMap */
+    private $entityMap;
+
+    /** @var EventObserver[] */
+    private $eventObserversByClient = [];
+
+    /** @var Client */
+    private $internalClient;
+
+    /** @var string */
+    private $uri;
+
+    public function __construct(Client $internalClient, string $uri)
+    {
+        $this->entityMap = new EntityMap();
+        $this->internalClient = $internalClient;
+        $this->uri = $uri;
+    }
+
+    /**
+     * Create entities for "createEntities".
+     *
+     * @param array $createEntities
+     */
+    public function createEntities(array $entities)
+    {
+        foreach ($entities as $entity) {
+            assertIsObject($entity);
+            $entity = (array) $entity;
+            assertCount(1, $entity);
+
+            $type = key($entity);
+            $def = current($entity);
+            assertIsObject($def);
+
+            $id = $def->id ?? null;
+            assertIsString($id);
+
+            switch ($type) {
+                case 'client':
+                    $this->createClient($id, $def);
+                    break;
+
+                case 'database':
+                    $this->createDatabase($id, $def);
+                    break;
+
+                case 'collection':
+                    $this->createCollection($id, $def);
+                    break;
+
+                case 'session':
+                    $this->createSession($id, $def);
+                    break;
+
+                case 'bucket':
+                    $this->createBucket($id, $def);
+                    break;
+
+                default:
+                    throw new LogicException('Unsupported entity type: ' . $type);
+            }
+        }
+    }
+
+    public function getEntityMap() : EntityMap
+    {
+        return $this->entityMap;
+    }
+
+    public function getInternalClient() : Client
+    {
+        return $this->internalClient;
+    }
+
+    public function isDirtySession(string $sessionId) : bool
+    {
+        return in_array($sessionId, $this->dirtySessions);
+    }
+
+    public function markDirtySession(string $sessionId)
+    {
+        if ($this->isDirtySession($sessionId)) {
+            return;
+        }
+
+        $this->dirtySessions[] = $sessionId;
+    }
+
+    public function isActiveClient(string $clientId) : bool
+    {
+        return $this->activeClient === $clientId;
+    }
+
+    public function setActiveClient(string $clientId = null)
+    {
+        $this->activeClient = $clientId;
+    }
+
+    public function assertExpectedEventsForClients(array $expectedEventsForClients)
+    {
+        assertNotEmpty($expectedEventsForClients);
+
+        foreach ($expectedEventsForClients as $expectedEventsForClient) {
+            assertIsObject($expectedEventsForClient);
+            Util::assertHasOnlyKeys($expectedEventsForClient, ['client', 'events']);
+
+            $client = $expectedEventsForClient->client ?? null;
+            $expectedEvents = $expectedEventsForClient->events ?? null;
+
+            assertIsString($client);
+            assertArrayHasKey($client, $this->eventObserversByClient);
+            assertIsArray($expectedEvents);
+
+            $this->eventObserversByClient[$client]->assert($expectedEvents);
+        }
+    }
+
+    public function startEventObservers()
+    {
+        foreach ($this->eventObserversByClient as $eventObserver) {
+            $eventObserver->start();
+        }
+    }
+
+    public function stopEventObservers()
+    {
+        foreach ($this->eventObserversByClient as $eventObserver) {
+            $eventObserver->stop();
+        }
+    }
+
+    public function getEventObserverForClient(string $id) : EventObserver
+    {
+        assertArrayHasKey($id, $this->eventObserversByClient);
+
+        return $this->eventObserversByClient[$id];
+    }
+
+    /** @param string|array $readPreferenceTags */
+    private function convertReadPreferenceTags($readPreferenceTags) : array
+    {
+        return array_map(
+            static function (string $readPreferenceTagSet) : array {
+                $tags = explode(',', $readPreferenceTagSet);
+
+                return array_map(
+                    static function (string $tag) : array {
+                        list($key, $value) = explode(':', $tag);
+
+                        return [$key => $value];
+                    },
+                    $tags
+                );
+            },
+            (array) $readPreferenceTags
+        );
+    }
+
+    private function createClient(string $id, stdClass $o)
+    {
+        Util::assertHasOnlyKeys($o, ['id', 'uriOptions', 'useMultipleMongoses', 'observeEvents', 'ignoreCommandMonitoringEvents']);
+
+        $useMultipleMongoses = $o->useMultipleMongoses ?? null;
+        $observeEvents = $o->observeEvents ?? null;
+        $ignoreCommandMonitoringEvents = $o->ignoreCommandMonitoringEvents ?? [];
+
+        $uri = $this->uri;
+
+        if (isset($useMultipleMongoses)) {
+            assertIsBool($useMultipleMongoses);
+
+            if ($useMultipleMongoses) {
+                self::requireMultipleMongoses($uri);
+            } else {
+                $uri = self::removeMultipleMongoses($uri);
+            }
+        }
+
+        $uriOptions = [];
+
+        if (isset($o->uriOptions)) {
+            assertIsObject($o->uriOptions);
+            $uriOptions = (array) $o->uriOptions;
+
+            if (! empty($uriOptions['readPreferenceTags'])) {
+                /* readPreferenceTags may take the following form:
+                 *
+                 * 1. A string containing multiple tags: "dc:ny,rack:1".
+                 *    Expected result: [["dc" => "ny", "rack" => "1"]]
+                 * 2. An array containing multiple strings as above: ["dc:ny,rack:1", "dc:la"].
+                 *    Expected result: [["dc" => "ny", "rack" => "1"], ["dc" => "la"]]
+                 */
+                $uriOptions['readPreferenceTags'] = $this->convertReadPreferenceTags($uriOptions['readPreferenceTags']);
+            }
+        }
+
+        if (isset($observeEvents)) {
+            assertIsArray($observeEvents);
+            assertIsArray($ignoreCommandMonitoringEvents);
+
+            $this->eventObserversByClient[$id] = new EventObserver($observeEvents, $ignoreCommandMonitoringEvents, $id, $this);
+        }
+
+        /* TODO: Remove this once PHPC-1645 is implemented. Each client needs
+         * its own libmongoc client to facilitate txnNumber assertions. */
+        static $i = 0;
+        $driverOptions = isset($observeEvents) ? ['i' => $i++] : [];
+
+        $this->entityMap->set($id, new Client($uri, $uriOptions, $driverOptions));
+    }
+
+    private function createCollection(string $id, stdClass $o)
+    {
+        Util::assertHasOnlyKeys($o, ['id', 'database', 'collectionName', 'collectionOptions']);
+
+        $collectionName = $o->collectionName ?? null;
+        $databaseId = $o->database ?? null;
+
+        assertIsString($collectionName);
+        assertIsString($databaseId);
+
+        $database = $this->entityMap->getDatabase($databaseId);
+
+        $options = [];
+
+        if (isset($o->collectionOptions)) {
+            assertIsObject($o->collectionOptions);
+            $options = self::prepareCollectionOrDatabaseOptions((array) $o->collectionOptions);
+        }
+
+        $this->entityMap->set($id, $database->selectCollection($o->collectionName, $options), $databaseId);
+    }
+
+    private function createDatabase(string $id, stdClass $o)
+    {
+        Util::assertHasOnlyKeys($o, ['id', 'client', 'databaseName', 'databaseOptions']);
+
+        $databaseName = $o->databaseName ?? null;
+        $clientId = $o->client ?? null;
+
+        assertIsString($databaseName);
+        assertIsString($clientId);
+
+        $client = $this->entityMap->getClient($clientId);
+
+        $options = [];
+
+        if (isset($o->databaseOptions)) {
+            assertIsObject($o->databaseOptions);
+            $options = self::prepareCollectionOrDatabaseOptions((array) $o->databaseOptions);
+        }
+
+        $this->entityMap->set($id, $client->selectDatabase($databaseName, $options), $clientId);
+    }
+
+    private function createSession(string $id, stdClass $o)
+    {
+        Util::assertHasOnlyKeys($o, ['id', 'client', 'sessionOptions']);
+
+        $clientId = $o->client ?? null;
+        assertIsString($clientId);
+        $client = $this->entityMap->getClient($clientId);
+
+        $options = [];
+
+        if (isset($o->sessionOptions)) {
+            assertIsObject($o->sessionOptions);
+            $options = self::prepareSessionOptions((array) $o->sessionOptions);
+        }
+
+        $this->entityMap->set($id, $client->startSession($options), $clientId);
+    }
+
+    private function createBucket(string $id, stdClass $o)
+    {
+        Util::assertHasOnlyKeys($o, ['id', 'database', 'bucketOptions']);
+
+        $databaseId = $o->database ?? null;
+        assertIsString($databaseId);
+        $database = $this->entityMap->getDatabase($databaseId);
+
+        $options = [];
+
+        if (isset($o->bucketOptions)) {
+            assertIsObject($o->bucketOptions);
+            $options = self::prepareBucketOptions((array) $o->bucketOptions);
+        }
+
+        $this->entityMap->set($id, $database->selectGridFSBucket($options), $databaseId);
+    }
+
+    private static function prepareCollectionOrDatabaseOptions(array $options) : array
+    {
+        Util::assertHasOnlyKeys($options, ['readConcern', 'readPreference', 'writeConcern']);
+
+        return Util::prepareCommonOptions($options);
+    }
+
+    private static function prepareBucketOptions(array $options) : array
+    {
+        Util::assertHasOnlyKeys($options, ['bucketName', 'chunkSizeBytes', 'disableMD5', 'readConcern', 'readPreference', 'writeConcern']);
+
+        if (array_key_exists('bucketName', $options)) {
+            assertIsString($options['bucketName']);
+        }
+
+        if (array_key_exists('chunkSizeBytes', $options)) {
+            assertIsInt($options['chunkSizeBytes']);
+        }
+
+        if (array_key_exists('disableMD5', $options)) {
+            assertIsBool($options['disableMD5']);
+        }
+
+        return Util::prepareCommonOptions($options);
+    }
+
+    private static function prepareSessionOptions(array $options) : array
+    {
+        Util::assertHasOnlyKeys($options, ['causalConsistency', 'defaultTransactionOptions']);
+
+        if (array_key_exists('causalConsistency', $options)) {
+            assertIsBool($options['causalConsistency']);
+        }
+
+        if (array_key_exists('defaultTransactionOptions', $options)) {
+            assertIsObject($options['defaultTransactionOptions']);
+            $options['defaultTransactionOptions'] = self::prepareDefaultTransactionOptions((array) $options['defaultTransactionOptions']);
+        }
+
+        return $options;
+    }
+
+    private static function prepareDefaultTransactionOptions(array $options) : array
+    {
+        Util::assertHasOnlyKeys($options, ['maxCommitTimeMS', 'readConcern', 'readPreference', 'writeConcern']);
+
+        if (array_key_exists('maxCommitTimeMS', $options)) {
+            assertIsInt($options['maxCommitTimeMS']);
+        }
+
+        return Util::prepareCommonOptions($options);
+    }
+
+    /**
+     * Removes mongos hosts beyond the first if the URI refers to a sharded
+     * cluster. Otherwise, the URI is returned as-is.
+     */
+    private static function removeMultipleMongoses(string $uri) : string
+    {
+        assertStringStartsWith('mongodb://', $uri);
+
+        $manager = new Manager($uri);
+
+        // Nothing to do if the URI does not refer to a sharded cluster
+        if ($manager->selectServer(new ReadPreference(ReadPreference::PRIMARY))->getType() !== Server::TYPE_MONGOS) {
+            return $uri;
+        }
+
+        $parts = parse_url($uri);
+
+        assertIsArray($parts);
+
+        $hosts = explode(',', $parts['host']);
+
+        // Nothing to do if the URI already has a single mongos host
+        if (count($hosts) === 1) {
+            return $uri;
+        }
+
+        // Re-append port to last host
+        if (isset($parts['port'])) {
+            $hosts[count($hosts) - 1] .= ':' . $parts['port'];
+        }
+
+        $singleHost = $hosts[0];
+        $multipleHosts = implode(',', $hosts);
+
+        $pos = strpos($uri, $multipleHosts);
+
+        assertNotFalse($pos);
+
+        return substr_replace($uri, $singleHost, $pos, strlen($multipleHosts));
+    }
+
+    /**
+     * Requires multiple mongos hosts if the URI refers to a sharded cluster.
+     */
+    private static function requireMultipleMongoses(string $uri)
+    {
+        assertStringStartsWith('mongodb://', $uri);
+
+        $manager = new Manager($uri);
+
+        // Nothing to do if the URI does not refer to a sharded cluster
+        if ($manager->selectServer(new ReadPreference(ReadPreference::PRIMARY))->getType() !== Server::TYPE_MONGOS) {
+            return;
+        }
+
+        assertStringContainsString(',', parse_url($uri, PHP_URL_HOST));
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/DirtySessionObserver.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/DirtySessionObserver.php
new file mode 100644
index 0000000000000000000000000000000000000000..e69f7e534852ceb57090dea9d16dd11b04da9734
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/DirtySessionObserver.php	
@@ -0,0 +1,83 @@
+<?php
+
+namespace MongoDB\Tests\UnifiedSpecTests;
+
+use MongoDB\Driver\Exception\ConnectionException;
+use MongoDB\Driver\Monitoring\CommandFailedEvent;
+use MongoDB\Driver\Monitoring\CommandStartedEvent;
+use MongoDB\Driver\Monitoring\CommandSubscriber;
+use MongoDB\Driver\Monitoring\CommandSucceededEvent;
+use stdClass;
+use function in_array;
+use function MongoDB\Driver\Monitoring\addSubscriber;
+use function MongoDB\Driver\Monitoring\removeSubscriber;
+
+/**
+ * Observes whether a session is used in an command that encounters a network
+ * error. This is primarily used to infer whether a sesson will be marked dirty
+ * in libmongoc.
+ *
+ * TODO: Remove this once CDRIVER-3780 and PHPLIB-528 are implemented.
+ */
+class DirtySessionObserver implements CommandSubscriber
+{
+    /** @var stdClass */
+    private $lsid;
+
+    /** @var array */
+    private $requestIds = [];
+
+    /** @var bool */
+    private $observedNetworkError = false;
+
+    public function __construct(stdClass $lsid)
+    {
+        $this->lsid = $lsid;
+    }
+
+    /**
+     * @see https://www.php.net/manual/en/mongodb-driver-monitoring-commandsubscriber.commandfailed.php
+     */
+    public function commandFailed(CommandFailedEvent $event)
+    {
+        if (! in_array($event->getRequestId(), $this->requestIds)) {
+            return;
+        }
+
+        if ($event->getError() instanceof ConnectionException) {
+            $this->observedNetworkError = true;
+        }
+    }
+
+    /**
+     * @see https://www.php.net/manual/en/mongodb-driver-monitoring-commandsubscriber.commandstarted.php
+     */
+    public function commandStarted(CommandStartedEvent $event)
+    {
+        if ($this->lsid == ($event->getCommand()->lsid ?? null)) {
+            $this->requestIds[] = $event->getRequestId();
+        }
+    }
+
+    /**
+     * @see https://www.php.net/manual/en/mongodb-driver-monitoring-commandsubscriber.commandsucceeded.php
+     */
+    public function commandSucceeded(CommandSucceededEvent $event)
+    {
+    }
+
+    public function observedNetworkError() : bool
+    {
+        return $this->observedNetworkError;
+    }
+
+    public function start()
+    {
+        addSubscriber($this);
+    }
+
+    public function stop()
+    {
+        removeSubscriber($this);
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/EntityMap.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/EntityMap.php
new file mode 100644
index 0000000000000000000000000000000000000000..f86715c96e73f78855d9f9b9063e52faff305635
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/EntityMap.php	
@@ -0,0 +1,179 @@
+<?php
+
+namespace MongoDB\Tests\UnifiedSpecTests;
+
+use ArrayAccess;
+use MongoDB\ChangeStream;
+use MongoDB\Client;
+use MongoDB\Collection;
+use MongoDB\Database;
+use MongoDB\Driver\Session;
+use MongoDB\GridFS\Bucket;
+use MongoDB\Tests\UnifiedSpecTests\Constraint\IsBsonType;
+use PHPUnit\Framework\Assert;
+use PHPUnit\Framework\Constraint\Constraint;
+use stdClass;
+use function array_key_exists;
+use function PHPUnit\Framework\assertArrayHasKey;
+use function PHPUnit\Framework\assertArrayNotHasKey;
+use function PHPUnit\Framework\assertIsString;
+use function PHPUnit\Framework\assertThat;
+use function PHPUnit\Framework\isInstanceOf;
+use function PHPUnit\Framework\logicalOr;
+use function sprintf;
+
+class EntityMap implements ArrayAccess
+{
+    /** @var array */
+    private $map = [];
+
+    /**
+     * Track lsids so they can be accessed after Session::getLogicalSessionId()
+     * has been called.
+     *
+     * @var stdClass[]
+     */
+    private $lsidsBySession = [];
+
+    /** @var Constraint */
+    private static $isSupportedType;
+
+    public function __destruct()
+    {
+        /* TODO: Determine if this is actually necessary. References to session
+         * entities should not persist between tests.
+         *
+         * Note: This does not appear to trigger after a test due to cyclic
+         * references (see comment in UnifiedSpecTest.php). */
+        foreach ($this->map as $entity) {
+            if ($entity->value instanceof Session) {
+                $entity->value->endSession();
+            }
+        }
+    }
+
+    /**
+     * @see http://php.net/arrayaccess.offsetexists
+     */
+    public function offsetExists($id)
+    {
+        assertIsString($id);
+
+        return array_key_exists($id, $this->map);
+    }
+
+    /**
+     * @see http://php.net/arrayaccess.offsetget
+     */
+    public function offsetGet($id)
+    {
+        assertIsString($id);
+        assertArrayHasKey($id, $this->map, sprintf('No entity is defined for "%s"', $id));
+
+        return $this->map[$id]->value;
+    }
+
+    /**
+     * @see http://php.net/arrayaccess.offsetset
+     */
+    public function offsetSet($id, $value)
+    {
+        Assert::fail('Entities can only be set via register()');
+    }
+
+    /**
+     * @see http://php.net/arrayaccess.offsetunset
+     */
+    public function offsetUnset($id)
+    {
+        Assert::fail('Entities cannot be removed from the map');
+    }
+
+    public function set(string $id, $value, string $parentId = null)
+    {
+        assertArrayNotHasKey($id, $this->map, sprintf('Entity already exists for "%s" and cannot be replaced', $id));
+        assertThat($value, self::isSupportedType());
+
+        if ($value instanceof Session) {
+            $this->lsidsBySession[$id] = $value->getLogicalSessionId();
+        }
+
+        $parent = $parentId === null ? null : $this->map[$parentId];
+
+        $this->map[$id] = new class ($id, $value, $parent) {
+            /** @var string */
+            public $id;
+            /** @var mixed */
+            public $value;
+            /** @var self */
+            public $parent;
+
+            public function __construct(string $id, $value, self $parent = null)
+            {
+                $this->id = $id;
+                $this->value = $value;
+                $this->parent = $parent;
+            }
+
+            public function getRoot() : self
+            {
+                $root = $this;
+
+                while ($root->parent !== null) {
+                    $root = $root->parent;
+                }
+
+                return $root;
+            }
+        };
+    }
+
+    public function getClient(string $clientId) : Client
+    {
+        return $this[$clientId];
+    }
+
+    public function getCollection(string $collectionId) : Collection
+    {
+        return $this[$collectionId];
+    }
+
+    public function getDatabase(string $databaseId) : Database
+    {
+        return $this[$databaseId];
+    }
+
+    public function getSession(string $sessionId) : Session
+    {
+        return $this[$sessionId];
+    }
+
+    public function getLogicalSessionId(string $sessionId) : stdClass
+    {
+        return $this->lsidsBySession[$sessionId];
+    }
+
+    public function getRootClientIdOf(string $id)
+    {
+        $root = $this->map[$id]->getRoot();
+
+        return $root->value instanceof Client ? $root->id : null;
+    }
+
+    private static function isSupportedType() : Constraint
+    {
+        if (self::$isSupportedType === null) {
+            self::$isSupportedType = logicalOr(
+                isInstanceOf(Client::class),
+                isInstanceOf(Database::class),
+                isInstanceOf(Collection::class),
+                isInstanceOf(Session::class),
+                isInstanceOf(Bucket::class),
+                isInstanceOf(ChangeStream::class),
+                IsBsonType::any()
+            );
+        }
+
+        return self::$isSupportedType;
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/EventObserver.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/EventObserver.php
new file mode 100644
index 0000000000000000000000000000000000000000..b4c58d307dcf60a87215c2f5abcbb24370a5cc94
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/EventObserver.php	
@@ -0,0 +1,263 @@
+<?php
+
+namespace MongoDB\Tests\UnifiedSpecTests;
+
+use ArrayIterator;
+use MongoDB\Driver\Monitoring\CommandFailedEvent;
+use MongoDB\Driver\Monitoring\CommandStartedEvent;
+use MongoDB\Driver\Monitoring\CommandSubscriber;
+use MongoDB\Driver\Monitoring\CommandSucceededEvent;
+use MongoDB\Tests\UnifiedSpecTests\Constraint\Matches;
+use MultipleIterator;
+use PHPUnit\Framework\Assert;
+use stdClass;
+use function array_fill_keys;
+use function array_reverse;
+use function count;
+use function current;
+use function get_class;
+use function is_object;
+use function key;
+use function MongoDB\Driver\Monitoring\addSubscriber;
+use function MongoDB\Driver\Monitoring\removeSubscriber;
+use function PHPUnit\Framework\assertArrayHasKey;
+use function PHPUnit\Framework\assertCount;
+use function PHPUnit\Framework\assertInstanceOf;
+use function PHPUnit\Framework\assertIsObject;
+use function PHPUnit\Framework\assertIsString;
+use function PHPUnit\Framework\assertNotEmpty;
+use function PHPUnit\Framework\assertObjectHasAttribute;
+use function PHPUnit\Framework\assertSame;
+use function PHPUnit\Framework\assertThat;
+use function sprintf;
+
+class EventObserver implements CommandSubscriber
+{
+    /** @var array */
+    private static $defaultIgnoreCommands = [
+        // failPoint and targetedFailPoint operations
+        'configureFailPoint',
+        // See: https://github.com/mongodb/specifications/blob/master/source/command-monitoring/command-monitoring.rst#security
+        'authenticate',
+        'saslStart',
+        'saslContinue',
+        'getnonce',
+        'createUser',
+        'updateUser',
+        'copydbgetnonce',
+        'copydbsaslstart',
+        'copydb',
+        'isMaster',
+    ];
+
+    /** @var array */
+    private static $supportedEvents = [
+        'commandStartedEvent' => CommandStartedEvent::class,
+        'commandSucceededEvent' => CommandSucceededEvent::class,
+        'commandFailedEvent' => CommandFailedEvent::class,
+    ];
+
+    /** @var array */
+    private $actualEvents = [];
+
+    /** @var string */
+    private $clientId;
+
+    /** @var Context */
+    private $context;
+
+    /** @var array */
+    private $ignoreCommands = [];
+
+    /** @var array */
+    private $observeEvents = [];
+
+    public function __construct(array $observeEvents, array $ignoreCommands, string $clientId, Context $context)
+    {
+        assertNotEmpty($observeEvents);
+
+        foreach ($observeEvents as $event) {
+            assertIsString($event);
+            assertArrayHasKey($event, self::$supportedEvents);
+            $this->observeEvents[self::$supportedEvents[$event]] = 1;
+        }
+
+        $this->ignoreCommands = array_fill_keys(self::$defaultIgnoreCommands, 1);
+
+        foreach ($ignoreCommands as $command) {
+            assertIsString($command);
+            $this->ignoreCommands[$command] = 1;
+        }
+
+        $this->clientId = $clientId;
+        $this->context = $context;
+    }
+
+    /**
+     * @see https://www.php.net/manual/en/mongodb-driver-monitoring-commandsubscriber.commandfailed.php
+     */
+    public function commandFailed(CommandFailedEvent $event)
+    {
+        $this->handleEvent($event);
+    }
+
+    /**
+     * @see https://www.php.net/manual/en/mongodb-driver-monitoring-commandsubscriber.commandstarted.php
+     */
+    public function commandStarted(CommandStartedEvent $event)
+    {
+        $this->handleEvent($event);
+    }
+
+    /**
+     * @see https://www.php.net/manual/en/mongodb-driver-monitoring-commandsubscriber.commandsucceeded.php
+     */
+    public function commandSucceeded(CommandSucceededEvent $event)
+    {
+        $this->handleEvent($event);
+    }
+
+    public function start()
+    {
+        addSubscriber($this);
+    }
+
+    public function stop()
+    {
+        removeSubscriber($this);
+    }
+
+    public function getLsidsOnLastTwoCommands() : array
+    {
+        $lsids = [];
+
+        foreach (array_reverse($this->actualEvents) as $event) {
+            if (! $event instanceof CommandStartedEvent) {
+                continue;
+            }
+
+            $command = $event->getCommand();
+            assertObjectHasAttribute('lsid', $command);
+            $lsids[] = $command->lsid;
+
+            if (count($lsids) === 2) {
+                return $lsids;
+            }
+        }
+
+        Assert::fail('Not enough CommandStartedEvents observed');
+    }
+
+    public function assert(array $expectedEvents)
+    {
+        assertCount(count($expectedEvents), $this->actualEvents);
+
+        $mi = new MultipleIterator(MultipleIterator::MIT_NEED_ANY);
+        $mi->attachIterator(new ArrayIterator($expectedEvents));
+        $mi->attachIterator(new ArrayIterator($this->actualEvents));
+
+        foreach ($mi as $keys => $events) {
+            list($expectedEvent, $actualEvent) = $events;
+
+            assertIsObject($expectedEvent);
+            $expectedEvent = (array) $expectedEvent;
+            assertCount(1, $expectedEvent);
+
+            $type = key($expectedEvent);
+            assertArrayHasKey($type, self::$supportedEvents);
+            $data = current($expectedEvent);
+            assertIsObject($data);
+
+            // Message is used for actual event assertions (not test structure)
+            $message = sprintf('%s event[%d]', $this->clientId, $keys[0]);
+
+            assertInstanceOf(self::$supportedEvents[$type], $actualEvent, $message . ': type matches');
+            $this->assertEvent($actualEvent, $data, $message);
+        }
+    }
+
+    private function assertEvent($actual, stdClass $expected, string $message)
+    {
+        assertIsObject($actual);
+
+        switch (get_class($actual)) {
+            case CommandStartedEvent::class:
+                return $this->assertCommandStartedEvent($actual, $expected, $message);
+            case CommandSucceededEvent::class:
+                return $this->assertCommandSucceededEvent($actual, $expected, $message);
+            case CommandFailedEvent::class:
+                return $this->assertCommandFailedEvent($actual, $expected, $message);
+            default:
+                Assert::fail($message . ': Unsupported event type: ' . get_class($actual));
+        }
+    }
+
+    private function assertCommandStartedEvent(CommandStartedEvent $actual, stdClass $expected, string $message)
+    {
+        Util::assertHasOnlyKeys($expected, ['command', 'commandName', 'databaseName']);
+
+        if (isset($expected->command)) {
+            assertIsObject($expected->command);
+            $constraint = new Matches($expected->command, $this->context->getEntityMap());
+            assertThat($actual->getCommand(), $constraint, $message . ': command matches');
+        }
+
+        if (isset($expected->commandName)) {
+            assertIsString($expected->commandName);
+            assertSame($actual->getCommandName(), $expected->commandName, $message . ': commandName matches');
+        }
+
+        if (isset($expected->databaseName)) {
+            assertIsString($expected->databaseName);
+            assertSame($actual->getDatabaseName(), $expected->databaseName, $message . ': databaseName matches');
+        }
+    }
+
+    private function assertCommandSucceededEvent(CommandSucceededEvent $actual, stdClass $expected, string $message)
+    {
+        Util::assertHasOnlyKeys($expected, ['reply', 'commandName']);
+
+        if (isset($expected->reply)) {
+            assertIsObject($expected->reply);
+            $constraint = new Matches($expected->reply, $this->context->getEntityMap());
+            assertThat($actual->getReply(), $constraint, $message . ': reply matches');
+        }
+
+        if (isset($expected->commandName)) {
+            assertIsString($expected->commandName);
+            assertSame($actual->getCommandName(), $expected->commandName, $message . ': commandName matches');
+        }
+    }
+
+    private function assertCommandFailedEvent(CommandFailedEvent $actual, stdClass $expected, string $message)
+    {
+        Util::assertHasOnlyKeys($expected, ['commandName']);
+
+        if (isset($expected->commandName)) {
+            assertIsString($expected->commandName);
+            assertSame($actual->getCommandName(), $expected->commandName, $message . ': commandName matches');
+        }
+    }
+
+    /** @param CommandStartedEvent|CommandSucceededEvent|CommandFailedEvent $event */
+    private function handleEvent($event)
+    {
+        if (! $this->context->isActiveClient($this->clientId)) {
+            return;
+        }
+
+        if (! is_object($event)) {
+            return;
+        }
+
+        if (! isset($this->observeEvents[get_class($event)])) {
+            return;
+        }
+
+        if (isset($this->ignoreCommands[$event->getCommandName()])) {
+            return;
+        }
+
+        $this->actualEvents[] = $event;
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/ExpectedError.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/ExpectedError.php
new file mode 100644
index 0000000000000000000000000000000000000000..d5c5c322e42ce381fed59f496c44fa912a86ff89
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/ExpectedError.php	
@@ -0,0 +1,195 @@
+<?php
+
+namespace MongoDB\Tests\UnifiedSpecTests;
+
+use MongoDB\Driver\Exception\BulkWriteException;
+use MongoDB\Driver\Exception\CommandException;
+use MongoDB\Driver\Exception\ExecutionTimeoutException;
+use MongoDB\Driver\Exception\RuntimeException;
+use MongoDB\Driver\Exception\ServerException;
+use PHPUnit\Framework\Assert;
+use stdClass;
+use Throwable;
+use function get_class;
+use function PHPUnit\Framework\assertArrayHasKey;
+use function PHPUnit\Framework\assertContainsOnly;
+use function PHPUnit\Framework\assertFalse;
+use function PHPUnit\Framework\assertInstanceOf;
+use function PHPUnit\Framework\assertIsArray;
+use function PHPUnit\Framework\assertIsBool;
+use function PHPUnit\Framework\assertIsInt;
+use function PHPUnit\Framework\assertIsString;
+use function PHPUnit\Framework\assertNotNull;
+use function PHPUnit\Framework\assertNull;
+use function PHPUnit\Framework\assertObjectHasAttribute;
+use function PHPUnit\Framework\assertSame;
+use function PHPUnit\Framework\assertStringContainsStringIgnoringCase;
+use function PHPUnit\Framework\assertTrue;
+use function property_exists;
+use function sprintf;
+
+final class ExpectedError
+{
+    /**
+     * @see https://github.com/mongodb/mongo/blob/master/src/mongo/base/error_codes.err
+     * @var array
+     */
+    private static $codeNameMap = [
+        'Interrupted' => 11601,
+        'MaxTimeMSExpired' => 50,
+        'NoSuchTransaction' => 251,
+        'OperationNotSupportedInTransaction' => 263,
+        'WriteConflict' => 112,
+    ];
+
+    /** @var bool */
+    private $isError = false;
+
+    /** @var bool|null */
+    private $isClientError;
+
+    /** @var string|null */
+    private $messageContains;
+
+    /** @var int|null */
+    private $code;
+
+    /** @var string|null */
+    private $codeName;
+
+    /** @var array */
+    private $includedLabels = [];
+
+    /** @var array */
+    private $excludedLabels = [];
+
+    /** @var ExpectedResult|null */
+    private $expectedResult;
+
+    public function __construct(stdClass $o = null, EntityMap $entityMap)
+    {
+        if ($o === null) {
+            return;
+        }
+
+        $this->isError = true;
+
+        if (isset($o->isError)) {
+            assertTrue($o->isError);
+        }
+
+        if (isset($o->isClientError)) {
+            assertIsBool($o->isClientError);
+            $this->isClientError = $o->isClientError;
+        }
+
+        if (isset($o->errorContains)) {
+            assertIsString($o->errorContains);
+            $this->messageContains = $o->errorContains;
+        }
+
+        if (isset($o->errorCode)) {
+            assertIsInt($o->errorCode);
+            $this->code = $o->errorCode;
+        }
+
+        if (isset($o->errorCodeName)) {
+            assertIsString($o->errorCodeName);
+            $this->codeName = $o->errorCodeName;
+        }
+
+        if (isset($o->errorLabelsContain)) {
+            assertIsArray($o->errorLabelsContain);
+            assertContainsOnly('string', $o->errorLabelsContain);
+            $this->includedLabels = $o->errorLabelsContain;
+        }
+
+        if (isset($o->errorLabelsOmit)) {
+            assertIsArray($o->errorLabelsOmit);
+            assertContainsOnly('string', $o->errorLabelsOmit);
+            $this->excludedLabels = $o->errorLabelsOmit;
+        }
+
+        if (property_exists($o, 'expectResult')) {
+            $this->expectedResult = new ExpectedResult($o, $entityMap);
+        }
+    }
+
+    /**
+     * Assert the outcome of an operation.
+     *
+     * @param Throwable|null $e Exception (if any) from executing an operation
+     */
+    public function assert(Throwable $e = null)
+    {
+        if (! $this->isError && $e !== null) {
+            Assert::fail(sprintf("Operation threw unexpected %s: %s\n%s", get_class($e), $e->getMessage(), $e->getTraceAsString()));
+        }
+
+        if (! $this->isError) {
+            assertNull($e);
+
+            return;
+        }
+
+        assertNotNull($e);
+
+        if (isset($this->messageContains)) {
+            assertStringContainsStringIgnoringCase($this->messageContains, $e->getMessage());
+        }
+
+        if (isset($this->code)) {
+            assertInstanceOf(ServerException::class, $e);
+            assertSame($this->code, $e->getCode());
+        }
+
+        if (isset($this->codeName)) {
+            assertInstanceOf(ServerException::class, $e);
+            $this->assertCodeName($e);
+        }
+
+        if (! empty($this->excludedLabels) || ! empty($this->includedLabels)) {
+            assertInstanceOf(RuntimeException::class, $e);
+
+            foreach ($this->excludedLabels as $label) {
+                assertFalse($e->hasErrorLabel($label), 'Exception should not have error label: ' . $label);
+            }
+
+            foreach ($this->includedLabels as $label) {
+                assertTrue($e->hasErrorLabel($label), 'Exception should have error label: ' . $label);
+            }
+        }
+
+        if (isset($this->expectedResult)) {
+            assertInstanceOf(BulkWriteException::class, $e);
+            $this->expectedResult->assert($e->getWriteResult());
+        }
+    }
+
+    private function assertCodeName(ServerException $e)
+    {
+        /* BulkWriteException and ExecutionTimeoutException do not expose
+         * codeName. Work around this by translating it to a numeric code.
+         *
+         * TODO: Remove this once PHPC-1386 is resolved. */
+        if ($e instanceof BulkWriteException || $e instanceof ExecutionTimeoutException) {
+            assertArrayHasKey($this->codeName, self::$codeNameMap);
+            assertSame(self::$codeNameMap[$this->codeName], $e->getCode());
+
+            return;
+        }
+
+        assertInstanceOf(CommandException::class, $e);
+        $result = $e->getResultDocument();
+
+        if (isset($result->writeConcernError)) {
+            assertObjectHasAttribute('codeName', $result->writeConcernError);
+            assertSame($this->codeName, $result->writeConcernError->codeName);
+
+            return;
+        }
+
+        assertObjectHasAttribute('codeName', $result);
+        assertSame($this->codeName, $result->codeName);
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/ExpectedResult.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/ExpectedResult.php
new file mode 100644
index 0000000000000000000000000000000000000000..f51da2e1c86d5843cc8197143ae3f73b6f253a33
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/ExpectedResult.php	
@@ -0,0 +1,123 @@
+<?php
+
+namespace MongoDB\Tests\UnifiedSpecTests;
+
+use MongoDB\BulkWriteResult;
+use MongoDB\DeleteResult;
+use MongoDB\Driver\WriteResult;
+use MongoDB\InsertManyResult;
+use MongoDB\InsertOneResult;
+use MongoDB\Tests\UnifiedSpecTests\Constraint\Matches;
+use MongoDB\UpdateResult;
+use stdClass;
+use function is_object;
+use function PHPUnit\Framework\assertThat;
+use function property_exists;
+
+final class ExpectedResult
+{
+    /** @var Matches */
+    private $constraint;
+
+    /** @var EntityMap */
+    private $entityMap;
+
+    /**
+     * ID of the entity yielding the result. This is mainly used to associate
+     * entities with a root client for collation of observed events.
+     *
+     * @var ?string
+     */
+    private $yieldingEntityId;
+
+    public function __construct(stdClass $o, EntityMap $entityMap, string $yieldingEntityId = null)
+    {
+        if (property_exists($o, 'expectResult')) {
+            $this->constraint = new Matches($o->expectResult, $entityMap);
+        }
+
+        $this->entityMap = $entityMap;
+        $this->yieldingEntityId = $yieldingEntityId;
+    }
+
+    public function assert($actual, string $saveResultAsEntity = null)
+    {
+        if ($this->constraint === null && $saveResultAsEntity === null) {
+            return;
+        }
+
+        $actual = self::prepare($actual);
+
+        if ($this->constraint !== null) {
+            assertThat($actual, $this->constraint);
+        }
+
+        if ($saveResultAsEntity !== null) {
+            $this->entityMap->set($saveResultAsEntity, $actual, $this->yieldingEntityId);
+        }
+    }
+
+    private static function prepare($value)
+    {
+        if (! is_object($value)) {
+            return $value;
+        }
+
+        if ($value instanceof BulkWriteResult ||
+            $value instanceof WriteResult ||
+            $value instanceof DeleteResult ||
+            $value instanceof InsertOneResult ||
+            $value instanceof InsertManyResult ||
+            $value instanceof UpdateResult) {
+            return self::prepareWriteResult($value);
+        }
+
+        return $value;
+    }
+
+    private static function prepareWriteResult($value)
+    {
+        $result = ['acknowledged' => $value->isAcknowledged()];
+
+        if (! $result['acknowledged']) {
+            return $result;
+        }
+
+        if ($value instanceof BulkWriteResult || $value instanceof WriteResult) {
+            $result['deletedCount'] = $value->getDeletedCount();
+            $result['insertedCount'] = $value->getInsertedCount();
+            $result['matchedCount'] = $value->getMatchedCount();
+            $result['modifiedCount'] = $value->getModifiedCount();
+            $result['upsertedCount'] = $value->getUpsertedCount();
+            $result['upsertedIds'] = (object) $value->getUpsertedIds();
+        }
+
+        // WriteResult does not provide insertedIds (see: PHPLIB-428)
+        if ($value instanceof BulkWriteResult) {
+            $result['insertedIds'] = (object) $value->getInsertedIds();
+        }
+
+        if ($value instanceof DeleteResult) {
+            $result['deletedCount'] = $value->getDeletedCount();
+        }
+
+        if ($value instanceof InsertManyResult) {
+            $result['insertedCount'] = $value->getInsertedCount();
+            $result['insertedIds'] = (object) $value->getInsertedIds();
+        }
+
+        if ($value instanceof InsertOneResult) {
+            $result['insertedCount'] = $value->getInsertedCount();
+            $result['insertedId'] = $value->getInsertedId();
+        }
+
+        if ($value instanceof UpdateResult) {
+            $result['matchedCount'] = $value->getMatchedCount();
+            $result['modifiedCount'] = $value->getModifiedCount();
+            $result['upsertedCount'] = $value->getUpsertedCount();
+            $result['upsertedId'] = $value->getUpsertedId();
+        }
+
+        return $result;
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/FailPointObserver.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/FailPointObserver.php
new file mode 100644
index 0000000000000000000000000000000000000000..f7794f7fc5cf5468c8a9c199f002f8c11b933ba4
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/FailPointObserver.php	
@@ -0,0 +1,69 @@
+<?php
+
+namespace MongoDB\Tests\UnifiedSpecTests;
+
+use MongoDB\Driver\Monitoring\CommandFailedEvent;
+use MongoDB\Driver\Monitoring\CommandStartedEvent;
+use MongoDB\Driver\Monitoring\CommandSubscriber;
+use MongoDB\Driver\Monitoring\CommandSucceededEvent;
+use MongoDB\Operation\DatabaseCommand;
+use function MongoDB\Driver\Monitoring\addSubscriber;
+use function MongoDB\Driver\Monitoring\removeSubscriber;
+
+class FailPointObserver implements CommandSubscriber
+{
+    /** @var array */
+    private $failPointsAndServers = [];
+
+    /**
+     * @see https://www.php.net/manual/en/mongodb-driver-monitoring-commandsubscriber.commandfailed.php
+     */
+    public function commandFailed(CommandFailedEvent $event)
+    {
+    }
+
+    /**
+     * @see https://www.php.net/manual/en/mongodb-driver-monitoring-commandsubscriber.commandstarted.php
+     */
+    public function commandStarted(CommandStartedEvent $event)
+    {
+        $command = $event->getCommand();
+
+        if (! isset($command->configureFailPoint)) {
+            return;
+        }
+
+        if (isset($command->mode) && $command->mode === 'off') {
+            return;
+        }
+
+        $this->failPointsAndServers[] = [$command->configureFailPoint, $event->getServer()];
+    }
+
+    /**
+     * @see https://www.php.net/manual/en/mongodb-driver-monitoring-commandsubscriber.commandsucceeded.php
+     */
+    public function commandSucceeded(CommandSucceededEvent $event)
+    {
+    }
+
+    public function disableFailPoints()
+    {
+        foreach ($this->failPointsAndServers as list($failPoint, $server)) {
+            $operation = new DatabaseCommand('admin', ['configureFailPoint' => $failPoint, 'mode' => 'off']);
+            $operation->execute($server);
+        }
+
+        $this->failPointsAndServers = [];
+    }
+
+    public function start()
+    {
+        addSubscriber($this);
+    }
+
+    public function stop()
+    {
+        removeSubscriber($this);
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/Operation.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/Operation.php
new file mode 100644
index 0000000000000000000000000000000000000000..be9b86664c2b57d4843d67de8be1665d5810e095
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/Operation.php	
@@ -0,0 +1,659 @@
+<?php
+
+namespace MongoDB\Tests\UnifiedSpecTests;
+
+use MongoDB\ChangeStream;
+use MongoDB\Client;
+use MongoDB\Collection;
+use MongoDB\Database;
+use MongoDB\Driver\Server;
+use MongoDB\Driver\Session;
+use MongoDB\GridFS\Bucket;
+use MongoDB\Model\IndexInfo;
+use MongoDB\Operation\DatabaseCommand;
+use MongoDB\Operation\FindOneAndReplace;
+use MongoDB\Operation\FindOneAndUpdate;
+use PHPUnit\Framework\Assert;
+use PHPUnit\Framework\AssertionFailedError;
+use stdClass;
+use Throwable;
+use Traversable;
+use function array_diff_key;
+use function array_key_exists;
+use function array_map;
+use function current;
+use function fopen;
+use function fwrite;
+use function get_class;
+use function hex2bin;
+use function iterator_to_array;
+use function key;
+use function MongoDB\with_transaction;
+use function PHPUnit\Framework\assertContains;
+use function PHPUnit\Framework\assertCount;
+use function PHPUnit\Framework\assertEquals;
+use function PHPUnit\Framework\assertFalse;
+use function PHPUnit\Framework\assertInstanceOf;
+use function PHPUnit\Framework\assertIsArray;
+use function PHPUnit\Framework\assertIsObject;
+use function PHPUnit\Framework\assertIsString;
+use function PHPUnit\Framework\assertMatchesRegularExpression;
+use function PHPUnit\Framework\assertNotContains;
+use function PHPUnit\Framework\assertNotEquals;
+use function PHPUnit\Framework\assertNotNull;
+use function PHPUnit\Framework\assertNull;
+use function PHPUnit\Framework\assertObjectHasAttribute;
+use function PHPUnit\Framework\assertSame;
+use function PHPUnit\Framework\assertThat;
+use function PHPUnit\Framework\assertTrue;
+use function PHPUnit\Framework\equalTo;
+use function PHPUnit\Framework\logicalOr;
+use function property_exists;
+use function rewind;
+use function stream_get_contents;
+use function strtolower;
+
+final class Operation
+{
+    const OBJECT_TEST_RUNNER = 'testRunner';
+
+    /** @var bool */
+    private $isTestRunnerOperation;
+
+    /** @var string */
+    private $name;
+
+    /** @var ?string */
+    private $object;
+
+    /** @var array */
+    private $arguments = [];
+
+    /** @var Context */
+    private $context;
+
+    /** @var EntityMap */
+    private $entityMap;
+
+    /** @var ExpectedError */
+    private $expectedError;
+
+    /** @var ExpectedResult */
+    private $expectedResult;
+
+    /** @var string */
+    private $saveResultAsEntity;
+
+    public function __construct(stdClass $o, Context $context)
+    {
+        $this->context =$context;
+        $this->entityMap = $context->getEntityMap();
+
+        assertIsString($o->name);
+        $this->name = $o->name;
+
+        assertIsString($o->object);
+        $this->isTestRunnerOperation = $o->object === self::OBJECT_TEST_RUNNER;
+        $this->object = $this->isTestRunnerOperation ? null : $o->object;
+
+        if (isset($o->arguments)) {
+            assertIsObject($o->arguments);
+            $this->arguments = (array) $o->arguments;
+        }
+
+        if (isset($o->expectError) && (property_exists($o, 'expectResult') || isset($o->saveResultAsEntity))) {
+            Assert::fail('expectError is mutually exclusive with expectResult and saveResultAsEntity');
+        }
+
+        $this->expectError = new ExpectedError($o->expectError ?? null, $this->entityMap);
+        $this->expectResult = new ExpectedResult($o, $this->entityMap, $this->object);
+
+        if (isset($o->saveResultAsEntity)) {
+            assertIsString($o->saveResultAsEntity);
+            $this->saveResultAsEntity = $o->saveResultAsEntity;
+        }
+    }
+
+    /**
+     * Execute the operation and assert its outcome.
+     */
+    public function assert(bool $rethrowExceptions = false)
+    {
+        $error = null;
+        $result = null;
+        $saveResultAsEntity = null;
+
+        if (isset($this->arguments['session'])) {
+            $dirtySessionObserver = new DirtySessionObserver($this->entityMap->getLogicalSessionId($this->arguments['session']));
+            $dirtySessionObserver->start();
+        }
+
+        try {
+            $result = $this->execute();
+            $saveResultAsEntity = $this->saveResultAsEntity;
+        } catch (Throwable $e) {
+            /* Note: we must be selective about what PHPUnit exceptions to pass
+             * through, as PHPUnit's Warning exception must be considered for
+             * expectError in GridFS tests (see: PHPLIB-592).
+             *
+             * TODO: Consider adding operation details (e.g. operations[] index)
+             * to the exception message. Alternatively, throw a new exception
+             * and include this as the previous, since PHPUnit will render the
+             * chain when reporting a test failure. */
+            if ($e instanceof AssertionFailedError) {
+                throw $e;
+            }
+
+            $error = $e;
+        }
+
+        if (isset($dirtySessionObserver)) {
+            $dirtySessionObserver->stop();
+
+            if ($dirtySessionObserver->observedNetworkError()) {
+                $this->context->markDirtySession($this->arguments['session']);
+            }
+        }
+
+        $this->expectError->assert($error);
+        $this->expectResult->assert($result, $saveResultAsEntity);
+
+        // Rethrowing is primarily used for withTransaction callbacks
+        if ($error && $rethrowExceptions) {
+            throw $error;
+        }
+    }
+
+    private function execute()
+    {
+        $this->context->setActiveClient(null);
+
+        if ($this->isTestRunnerOperation) {
+            return $this->executeForTestRunner();
+        }
+
+        $object = $this->entityMap[$this->object];
+        assertIsObject($object);
+
+        $this->context->setActiveClient($this->entityMap->getRootClientIdOf($this->object));
+
+        switch (get_class($object)) {
+            case Client::class:
+                $result = $this->executeForClient($object);
+                break;
+            case Database::class:
+                $result = $this->executeForDatabase($object);
+                break;
+            case Collection::class:
+                $result = $this->executeForCollection($object);
+                break;
+            case ChangeStream::class:
+                $result = $this->executeForChangeStream($object);
+                break;
+            case Session::class:
+                $result = $this->executeForSession($object);
+                break;
+            case Bucket::class:
+                $result = $this->executeForBucket($object);
+                break;
+            default:
+                Assert::fail('Unsupported entity type: ' . get_class($object));
+        }
+
+        if ($result instanceof Traversable && ! $result instanceof ChangeStream) {
+            return iterator_to_array($result);
+        }
+
+        return $result;
+    }
+
+    private function executeForChangeStream(ChangeStream $changeStream)
+    {
+        $args = $this->prepareArguments();
+
+        switch ($this->name) {
+            case 'iterateUntilDocumentOrError':
+                /* Note: the first iteration should use rewind, otherwise we may
+                 * miss a document from the initial batch (possible if using a
+                 * resume token). We can infer this from a null key; however,
+                 * if a test ever calls this operation consecutively to expect
+                 * multiple errors from the same ChangeStream we will need a
+                 * different approach (e.g. examining internal hasAdvanced
+                 * property on the ChangeStream). */
+                if ($changeStream->key() === null) {
+                    $changeStream->rewind();
+
+                    if ($changeStream->valid()) {
+                        return $changeStream->current();
+                    }
+                }
+
+                do {
+                    $changeStream->next();
+                } while (! $changeStream->valid());
+
+                return $changeStream->current();
+            default:
+                Assert::fail('Unsupported client operation: ' . $this->name);
+        }
+    }
+
+    private function executeForClient(Client $client)
+    {
+        $args = $this->prepareArguments();
+
+        switch ($this->name) {
+            case 'createChangeStream':
+                $changeStream = $client->watch(
+                    $args['pipeline'] ?? [],
+                    array_diff_key($args, ['pipeline' => 1])
+                );
+                $changeStream->rewind();
+
+                return $changeStream;
+            case 'listDatabaseNames':
+                return $client->listDatabaseNames($args);
+            case 'listDatabases':
+                return $client->listDatabases($args);
+            default:
+                Assert::fail('Unsupported client operation: ' . $this->name);
+        }
+    }
+
+    private function executeForCollection(Collection $collection)
+    {
+        $args = $this->prepareArguments();
+
+        switch ($this->name) {
+            case 'aggregate':
+                return $collection->aggregate(
+                    $args['pipeline'],
+                    array_diff_key($args, ['pipeline' => 1])
+                );
+            case 'bulkWrite':
+                return $collection->bulkWrite(
+                    array_map('self::prepareBulkWriteRequest', $args['requests']),
+                    array_diff_key($args, ['requests' => 1])
+                );
+            case 'createChangeStream':
+                $changeStream = $collection->watch(
+                    $args['pipeline'] ?? [],
+                    array_diff_key($args, ['pipeline' => 1])
+                );
+                $changeStream->rewind();
+
+                return $changeStream;
+            case 'createIndex':
+                return $collection->createIndex(
+                    $args['keys'],
+                    array_diff_key($args, ['keys' => 1])
+                );
+            case 'dropIndex':
+                return $collection->dropIndex(
+                    $args['name'],
+                    array_diff_key($args, ['name' => 1])
+                );
+            case 'count':
+            case 'countDocuments':
+            case 'find':
+                return $collection->{$this->name}(
+                    $args['filter'] ?? [],
+                    array_diff_key($args, ['filter' => 1])
+                );
+            case 'estimatedDocumentCount':
+                return $collection->estimatedDocumentCount($args);
+            case 'deleteMany':
+            case 'deleteOne':
+            case 'findOneAndDelete':
+                return $collection->{$this->name}(
+                    $args['filter'],
+                    array_diff_key($args, ['filter' => 1])
+                );
+            case 'distinct':
+                if (isset($args['session']) && $args['session']->isInTransaction()) {
+                    // Transaction, but sharded cluster?
+                    $collection->distinct('foo');
+                }
+
+                return $collection->distinct(
+                    $args['fieldName'],
+                    $args['filter'] ?? [],
+                    array_diff_key($args, ['fieldName' => 1, 'filter' => 1])
+                );
+            case 'drop':
+                return $collection->drop($args);
+            case 'findOne':
+                return $collection->findOne($args['filter'], array_diff_key($args, ['filter' => 1]));
+            case 'findOneAndReplace':
+                if (isset($args['returnDocument'])) {
+                    $args['returnDocument'] = strtolower($args['returnDocument']);
+                    assertThat($args['returnDocument'], logicalOr(equalTo('after'), equalTo('before')));
+
+                    $args['returnDocument'] = 'after' === $args['returnDocument']
+                        ? FindOneAndReplace::RETURN_DOCUMENT_AFTER
+                        : FindOneAndReplace::RETURN_DOCUMENT_BEFORE;
+                }
+                // Fall through
+
+            case 'replaceOne':
+                return $collection->{$this->name}(
+                    $args['filter'],
+                    $args['replacement'],
+                    array_diff_key($args, ['filter' => 1, 'replacement' => 1])
+                );
+            case 'findOneAndUpdate':
+                if (isset($args['returnDocument'])) {
+                    $args['returnDocument'] = strtolower($args['returnDocument']);
+                    assertThat($args['returnDocument'], logicalOr(equalTo('after'), equalTo('before')));
+
+                    $args['returnDocument'] = 'after' === $args['returnDocument']
+                        ? FindOneAndUpdate::RETURN_DOCUMENT_AFTER
+                        : FindOneAndUpdate::RETURN_DOCUMENT_BEFORE;
+                }
+                // Fall through
+
+            case 'updateMany':
+            case 'updateOne':
+                return $collection->{$this->name}(
+                    $args['filter'],
+                    $args['update'],
+                    array_diff_key($args, ['filter' => 1, 'update' => 1])
+                );
+            case 'insertMany':
+                // Merge nested and top-level options (see: SPEC-1158)
+                $options = isset($args['options']) ? (array) $args['options'] : [];
+                $options += array_diff_key($args, ['documents' => 1]);
+
+                return $collection->insertMany(
+                    $args['documents'],
+                    $options
+                );
+            case 'insertOne':
+                return $collection->insertOne(
+                    $args['document'],
+                    array_diff_key($args, ['document' => 1])
+                );
+            case 'listIndexes':
+                return $collection->listIndexes($args);
+            case 'mapReduce':
+                return $collection->mapReduce(
+                    $args['map'],
+                    $args['reduce'],
+                    $args['out'],
+                    array_diff_key($args, ['map' => 1, 'reduce' => 1, 'out' => 1])
+                );
+            default:
+                Assert::fail('Unsupported collection operation: ' . $this->name);
+        }
+    }
+
+    private function executeForDatabase(Database $database)
+    {
+        $args = $this->prepareArguments();
+
+        switch ($this->name) {
+            case 'aggregate':
+                return $database->aggregate(
+                    $args['pipeline'],
+                    array_diff_key($args, ['pipeline' => 1])
+                );
+            case 'createChangeStream':
+                $changeStream = $database->watch(
+                    $args['pipeline'] ?? [],
+                    array_diff_key($args, ['pipeline' => 1])
+                );
+                $changeStream->rewind();
+
+                return $changeStream;
+            case 'createCollection':
+                return $database->createCollection(
+                    $args['collection'],
+                    array_diff_key($args, ['collection' => 1])
+                );
+            case 'dropCollection':
+                return $database->dropCollection(
+                    $args['collection'],
+                    array_diff_key($args, ['collection' => 1])
+                );
+            case 'listCollectionNames':
+                return $database->listCollectionNames($args);
+            case 'listCollections':
+                return $database->listCollections($args);
+            case 'runCommand':
+                return $database->command(
+                    $args['command'],
+                    array_diff_key($args, ['command' => 1])
+                )->toArray()[0];
+            default:
+                Assert::fail('Unsupported database operation: ' . $this->name);
+        }
+    }
+
+    private function executeForSession(Session $session)
+    {
+        $args = $this->prepareArguments();
+
+        switch ($this->name) {
+            case 'abortTransaction':
+                return $session->abortTransaction();
+            case 'commitTransaction':
+                return $session->commitTransaction();
+            case 'endSession':
+                return $session->endSession();
+            case 'startTransaction':
+                return $session->startTransaction($args);
+            case 'withTransaction':
+                assertIsArray($args['callback']);
+
+                $operations = array_map(function ($o) {
+                    assertIsObject($o);
+
+                    return new Operation($o, $this->context);
+                }, $args['callback']);
+
+                $callback = function () use ($operations) {
+                    foreach ($operations as $operation) {
+                        $operation->assert(true); // rethrow exceptions
+                    }
+                };
+
+                return with_transaction($session, $callback, array_diff_key($args, ['callback' => 1]));
+            default:
+                Assert::fail('Unsupported session operation: ' . $this->name);
+        }
+    }
+
+    private function executeForBucket(Bucket $bucket)
+    {
+        $args = $this->prepareArguments();
+
+        switch ($this->name) {
+            case 'delete':
+                return $bucket->delete($args['id']);
+            case 'downloadByName':
+                return stream_get_contents($bucket->openDownloadStream(
+                    $args['filename'],
+                    array_diff_key($args, ['filename' => 1])
+                ));
+            case 'download':
+                return stream_get_contents($bucket->openDownloadStream($args['id']));
+            case 'uploadWithId':
+                $args['_id'] = $args['id'];
+                unset($args['id']);
+
+                // Fall through
+
+            case 'upload':
+                $args = self::prepareUploadArguments($args);
+
+                return $bucket->uploadFromStream(
+                    $args['filename'],
+                    $args['source'],
+                    array_diff_key($args, ['filename' => 1, 'source' => 1])
+                );
+            default:
+                Assert::fail('Unsupported bucket operation: ' . $this->name);
+        }
+    }
+
+    private function executeForTestRunner()
+    {
+        $args = $this->prepareArguments();
+
+        if (array_key_exists('client', $args)) {
+            assertIsString($args['client']);
+            $args['client'] = $this->entityMap->getClient($args['client']);
+        }
+
+        switch ($this->name) {
+            case 'assertCollectionExists':
+                assertIsString($args['databaseName']);
+                assertIsString($args['collectionName']);
+                $database = $this->context->getInternalClient()->selectDatabase($args['databaseName']);
+                assertContains($args['collectionName'], $database->listCollectionNames());
+                break;
+            case 'assertCollectionNotExists':
+                assertIsString($args['databaseName']);
+                assertIsString($args['collectionName']);
+                $database = $this->context->getInternalClient()->selectDatabase($args['databaseName']);
+                assertNotContains($args['collectionName'], $database->listCollectionNames());
+                break;
+            case 'assertIndexExists':
+                assertIsString($args['databaseName']);
+                assertIsString($args['collectionName']);
+                assertIsString($args['indexName']);
+                assertContains($args['indexName'], $this->getIndexNames($args['databaseName'], $args['collectionName']));
+                break;
+            case 'assertIndexNotExists':
+                assertIsString($args['databaseName']);
+                assertIsString($args['collectionName']);
+                assertIsString($args['indexName']);
+                assertNotContains($args['indexName'], $this->getIndexNames($args['databaseName'], $args['collectionName']));
+                break;
+            case 'assertSameLsidOnLastTwoCommands':
+                $eventObserver = $this->context->getEventObserverForClient($this->arguments['client']);
+                assertEquals(...$eventObserver->getLsidsOnLastTwoCommands());
+                break;
+            case 'assertDifferentLsidOnLastTwoCommands':
+                $eventObserver = $this->context->getEventObserverForClient($this->arguments['client']);
+                assertNotEquals(...$eventObserver->getLsidsOnLastTwoCommands());
+                break;
+            case 'assertSessionDirty':
+                assertTrue($this->context->isDirtySession($this->arguments['session']));
+                break;
+            case 'assertSessionNotDirty':
+                assertFalse($this->context->isDirtySession($this->arguments['session']));
+                break;
+            case 'assertSessionPinned':
+                assertInstanceOf(Session::class, $args['session']);
+                assertInstanceOf(Server::class, $args['session']->getServer());
+                break;
+            case 'assertSessionTransactionState':
+                assertInstanceOf(Session::class, $args['session']);
+                assertSame($this->arguments['state'], $args['session']->getTransactionState());
+                break;
+            case 'assertSessionUnpinned':
+                assertInstanceOf(Session::class, $args['session']);
+                assertNull($args['session']->getServer());
+                break;
+            case 'failPoint':
+                assertInstanceOf(stdClass::class, $args['failPoint']);
+                $args['client']->selectDatabase('admin')->command($args['failPoint']);
+                break;
+            case 'targetedFailPoint':
+                assertInstanceOf(Session::class, $args['session']);
+                assertInstanceOf(stdClass::class, $args['failPoint']);
+                assertNotNull($args['session']->getServer(), 'Session is pinned');
+                $operation = new DatabaseCommand('admin', $args['failPoint']);
+                $operation->execute($args['session']->getServer());
+                break;
+            default:
+                Assert::fail('Unsupported test runner operation: ' . $this->name);
+        }
+    }
+
+    private function getIndexNames(string $databaseName, string $collectionName) : array
+    {
+        return array_map(
+            function (IndexInfo $indexInfo) {
+                return $indexInfo->getName();
+            },
+            iterator_to_array($this->context->getInternalClient()->selectCollection($databaseName, $collectionName)->listIndexes())
+        );
+    }
+
+    private function prepareArguments() : array
+    {
+        $args = $this->arguments;
+
+        if (array_key_exists('session', $args)) {
+            assertIsString($args['session']);
+            $args['session'] = $this->entityMap->getSession($args['session']);
+        }
+
+        // Prepare readConcern, readPreference, and writeConcern
+        return Util::prepareCommonOptions($args);
+    }
+
+    private static function prepareBulkWriteRequest(stdClass $request) : array
+    {
+        $request = (array) $request;
+        assertCount(1, $request);
+
+        $type = key($request);
+        $args = current($request);
+        assertIsObject($args);
+        $args = (array) $args;
+
+        switch ($type) {
+            case 'deleteMany':
+            case 'deleteOne':
+                return [
+                    $type => [
+                        $args['filter'],
+                        array_diff_key($args, ['filter' => 1]),
+                    ],
+                ];
+            case 'insertOne':
+                return [ 'insertOne' => [ $args['document']]];
+            case 'replaceOne':
+                return [
+                    'replaceOne' => [
+                        $args['filter'],
+                        $args['replacement'],
+                        array_diff_key($args, ['filter' => 1, 'replacement' => 1]),
+                    ],
+                ];
+            case 'updateMany':
+            case 'updateOne':
+                return [
+                    $type => [
+                        $args['filter'],
+                        $args['update'],
+                        array_diff_key($args, ['filter' => 1, 'update' => 1]),
+                    ],
+                ];
+            default:
+                Assert::fail('Unsupported bulk write request: ' . $type);
+        }
+    }
+
+    private static function prepareUploadArguments(array $args) : array
+    {
+        $source = $args['source'] ?? null;
+        assertIsObject($source);
+        assertObjectHasAttribute('$$hexBytes', $source);
+        Util::assertHasOnlyKeys($source, ['$$hexBytes']);
+        $hexBytes = $source->{'$$hexBytes'};
+        assertIsString($hexBytes);
+        assertMatchesRegularExpression('/^([0-9a-fA-F]{2})*$/', $hexBytes);
+
+        $stream = fopen('php://temp', 'w+b');
+        fwrite($stream, hex2bin($hexBytes));
+        rewind($stream);
+
+        $args['source'] = $stream;
+
+        return $args;
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/RunOnRequirement.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/RunOnRequirement.php
new file mode 100644
index 0000000000000000000000000000000000000000..909d3c1ab451736ca96b6e0892a6d1d5ddc60895
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/RunOnRequirement.php	
@@ -0,0 +1,78 @@
+<?php
+
+namespace MongoDB\Tests\UnifiedSpecTests;
+
+use stdClass;
+use function in_array;
+use function PHPUnit\Framework\assertContainsOnly;
+use function PHPUnit\Framework\assertIsArray;
+use function PHPUnit\Framework\assertIsString;
+use function PHPUnit\Framework\assertMatchesRegularExpression;
+use function version_compare;
+
+class RunOnRequirement
+{
+    const TOPOLOGY_SINGLE = 'single';
+    const TOPOLOGY_REPLICASET = 'replicaset';
+    const TOPOLOGY_SHARDED = 'sharded';
+    const TOPOLOGY_SHARDED_REPLICASET = 'sharded-replicaset';
+
+    const VERSION_PATTERN = '/^[0-9]+(\\.[0-9]+){1,2}$/';
+
+    /** @var string */
+    private $minServerVersion;
+
+    /** @var string */
+    private $maxServerVersion;
+
+    /** @var array */
+    private $topologies;
+
+    public function __construct(stdClass $o)
+    {
+        if (isset($o->minServerVersion)) {
+            assertIsString($o->minServerVersion);
+            assertMatchesRegularExpression(self::VERSION_PATTERN, $o->minServerVersion);
+            $this->minServerVersion = $o->minServerVersion;
+        }
+
+        if (isset($o->maxServerVersion)) {
+            assertIsString($o->maxServerVersion);
+            assertMatchesRegularExpression(self::VERSION_PATTERN, $o->maxServerVersion);
+            $this->maxServerVersion = $o->maxServerVersion;
+        }
+
+        if (isset($o->topologies)) {
+            assertIsArray($o->topologies);
+            assertContainsOnly('string', $o->topologies);
+            $this->topologies = $o->topologies;
+        }
+    }
+
+    public function isSatisfied(string $serverVersion, string $topology) : bool
+    {
+        if (isset($this->minServerVersion) && version_compare($serverVersion, $this->minServerVersion, '<')) {
+            return false;
+        }
+
+        if (isset($this->maxServerVersion) && version_compare($serverVersion, $this->maxServerVersion, '>')) {
+            return false;
+        }
+
+        if (isset($this->topologies)) {
+            if (in_array($topology, $this->topologies)) {
+                return true;
+            }
+
+            /* Ensure "sharded-replicaset" is also accepted for topologies that
+             * only include "sharded" (agnostic about the shard topology) */
+            if ($topology === self::TOPOLOGY_SHARDED_REPLICASET && in_array(self::TOPOLOGY_SHARDED, $this->topologies)) {
+                return true;
+            }
+
+            return false;
+        }
+
+        return true;
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/UnifiedSpecTest.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/UnifiedSpecTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..5090692fead78be8a00513a4d0df176b2ea21ab8
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/UnifiedSpecTest.php	
@@ -0,0 +1,389 @@
+<?php
+
+namespace MongoDB\Tests\UnifiedSpecTests;
+
+use MongoDB\Client;
+use MongoDB\Collection;
+use MongoDB\Driver\Exception\ServerException;
+use MongoDB\Driver\ReadPreference;
+use MongoDB\Driver\Server;
+use MongoDB\Operation\DatabaseCommand;
+use MongoDB\Tests\FunctionalTestCase;
+use stdClass;
+use Symfony\Bridge\PhpUnit\SetUpTearDownTrait;
+use Throwable;
+use function file_get_contents;
+use function gc_collect_cycles;
+use function glob;
+use function MongoDB\BSON\fromJSON;
+use function MongoDB\BSON\toPHP;
+use function PHPUnit\Framework\assertTrue;
+use function sprintf;
+use function version_compare;
+
+/**
+ * Unified spec test runner.
+ *
+ * @see https://github.com/mongodb/specifications/pull/846
+ */
+class UnifiedSpecTest extends FunctionalTestCase
+{
+    use SetUpTearDownTrait;
+
+    const SERVER_ERROR_INTERRUPTED = 11601;
+
+    const MIN_SCHEMA_VERSION = '1.0';
+    const MAX_SCHEMA_VERSION = '1.1';
+
+    const TOPOLOGY_SINGLE = 'single';
+    const TOPOLOGY_REPLICASET = 'replicaset';
+    const TOPOLOGY_SHARDED = 'sharded';
+    const TOPOLOGY_SHARDED_REPLICASET = 'sharded-replicaset';
+
+    /** @var MongoDB\Client */
+    private static $internalClient;
+
+    /** @var FailPointObserver */
+    private $failPointObserver;
+
+    private static function doSetUpBeforeClass()
+    {
+        parent::setUpBeforeClass();
+
+        /* Provide internal client unmodified URI, since it may need to execute
+         * commands on multiple mongoses (e.g. killAllSessions) */
+        self::$internalClient = new Client(static::getUri(true));
+        self::killAllSessions();
+    }
+
+    private function doSetUp()
+    {
+        parent::setUp();
+
+        /* The transactions spec advises calling killAllSessions only at the
+         * start of the test suite and after failed tests; however, the "unpin
+         * after transient error within a transaction" pinning test causes the
+         * subsequent transaction test to block. */
+        self::killAllSessions();
+
+        $this->failPointObserver = new FailPointObserver();
+        $this->failPointObserver->start();
+    }
+
+    private function doTearDown()
+    {
+        if ($this->hasFailed()) {
+            self::killAllSessions();
+        }
+
+        $this->failPointObserver->stop();
+        $this->failPointObserver->disableFailPoints();
+
+        /* Manually invoking garbage collection since each test is prone to
+         * create cycles (perhaps due to EntityMap), which can leak and prevent
+         * sessions from being released back into the pool. */
+        gc_collect_cycles();
+
+        parent::tearDown();
+    }
+
+    /**
+     * @dataProvider providePassingTests
+     */
+    public function testPassingTests(stdClass $test, string $schemaVersion, array $runOnRequirements = null, array $createEntities = null, array $initialData = null)
+    {
+        if (! $this->isSchemaVersionSupported($schemaVersion)) {
+            $this->markTestIncomplete(sprintf('Test format schema version "%s" is not supported', $schemaVersion));
+        }
+
+        if (isset($runOnRequirements)) {
+            $this->checkRunOnRequirements($runOnRequirements);
+        }
+
+        if (isset($test->skipReason)) {
+            $this->assertIsString($test->skipReason);
+            $this->markTestSkipped($test->skipReason);
+        }
+
+        if (isset($test->runOnRequirements)) {
+            $this->assertIsArray($test->runOnRequirements);
+            $this->checkRunOnRequirements($test->runOnRequirements);
+        }
+
+        if (isset($initialData)) {
+            $this->prepareInitialData($initialData);
+        }
+
+        // Give Context unmodified URI so it can enforce useMultipleMongoses
+        $context = new Context(self::$internalClient, static::getUri(true));
+
+        if (isset($createEntities)) {
+            $context->createEntities($createEntities);
+        }
+
+        $this->assertIsArray($test->operations);
+        $this->preventStaleDbVersionError($test->operations, $context);
+
+        $context->startEventObservers();
+
+        foreach ($test->operations as $o) {
+            $operation = new Operation($o, $context);
+            $operation->assert();
+        }
+
+        $context->stopEventObservers();
+
+        if (isset($test->expectEvents)) {
+            $this->assertIsArray($test->expectEvents);
+            $context->assertExpectedEventsForClients($test->expectEvents);
+        }
+
+        if (isset($test->outcome)) {
+            $this->assertIsArray($test->outcome);
+            $this->assertOutcome($test->outcome);
+        }
+    }
+
+    public function providePassingTests()
+    {
+        return $this->provideTests(__DIR__ . '/valid-pass');
+    }
+
+    /**
+     * @dataProvider provideFailingTests
+     */
+    public function testFailingTests(...$args)
+    {
+        // Cannot use expectException(), as it ignores PHPUnit Exceptions
+        $failed = false;
+
+        try {
+            $this->testCase(...$args);
+        } catch (Throwable $e) {
+            $failed = true;
+        }
+
+        assertTrue($failed, 'Expected test to throw an exception');
+    }
+
+    public function provideFailingTests()
+    {
+        return $this->provideTests(__DIR__ . '/valid-fail');
+    }
+
+    private function provideTests(string $dir)
+    {
+        $testArgs = [];
+
+        foreach (glob($dir . '/*.json') as $filename) {
+            /* Decode the file through the driver's extended JSON parser to
+             * ensure proper handling of special types. */
+            $json = toPHP(fromJSON(file_get_contents($filename)));
+
+            $description = $json->description;
+            $schemaVersion = $json->schemaVersion;
+            $runOnRequirements = $json->runOnRequirements ?? null;
+            $createEntities = $json->createEntities ?? null;
+            $initialData = $json->initialData ?? null;
+            $tests = $json->tests;
+
+            /* Assertions in data providers do not count towards test assertions
+             * but failures will interrupt the test suite with a warning. */
+            $message = 'Invalid test file: ' . $filename;
+            $this->assertIsString($description, $message);
+            $this->assertIsString($schemaVersion, $message);
+            $this->assertIsArray($tests, $message);
+
+            foreach ($json->tests as $test) {
+                $this->assertIsObject($test, $message);
+                $this->assertIsString($test->description, $message);
+
+                $name = $description . ': ' . $test->description;
+                $testArgs[$name] = [$test, $schemaVersion, $runOnRequirements, $createEntities, $initialData];
+            }
+        }
+
+        return $testArgs;
+    }
+
+    /**
+     * Checks server version and topology requirements.
+     *
+     * @param array $runOnRequirements
+     * @throws SkippedTest unless one or more runOnRequirements are met
+     */
+    private function checkRunOnRequirements(array $runOnRequirements)
+    {
+        $this->assertNotEmpty($runOnRequirements);
+        $this->assertContainsOnly('object', $runOnRequirements);
+
+        $serverVersion = $this->getCachedServerVersion();
+        $topology = $this->getCachedTopology();
+
+        foreach ($runOnRequirements as $o) {
+            $runOnRequirement = new RunOnRequirement($o);
+            if ($runOnRequirement->isSatisfied($serverVersion, $topology)) {
+                return;
+            }
+        }
+
+        $this->markTestSkipped(sprintf('Server version "%s" and topology "%s" do not meet test requirements', $serverVersion, $topology));
+    }
+
+    /**
+     * Return the server version (cached for subsequent calls).
+     *
+     * @return string
+     */
+    private function getCachedServerVersion()
+    {
+        static $cachedServerVersion;
+
+        if (isset($cachedServerVersion)) {
+            return $cachedServerVersion;
+        }
+
+        $cachedServerVersion = $this->getServerVersion();
+
+        return $cachedServerVersion;
+    }
+
+    /**
+     * Return the topology type (cached for subsequent calls).
+     *
+     * @return string
+     * @throws UnexpectedValueException if topology is neither single nor RS nor sharded
+     */
+    private function getCachedTopology()
+    {
+        static $cachedTopology = null;
+
+        if (isset($cachedTopology)) {
+            return $cachedTopology;
+        }
+
+        switch ($this->getPrimaryServer()->getType()) {
+            case Server::TYPE_STANDALONE:
+                $cachedTopology = RunOnRequirement::TOPOLOGY_SINGLE;
+                break;
+
+            case Server::TYPE_RS_PRIMARY:
+                $cachedTopology = RunOnRequirement::TOPOLOGY_REPLICASET;
+                break;
+
+            case Server::TYPE_MONGOS:
+                $cachedTopology = $this->isShardedClusterUsingReplicasets()
+                    ? RunOnRequirement::TOPOLOGY_SHARDED_REPLICASET
+                    : RunOnRequirement::TOPOLOGY_SHARDED;
+                break;
+
+            default:
+                throw new UnexpectedValueException('Toplogy is neither single nor RS nor sharded');
+        }
+
+        return $cachedTopology;
+    }
+
+    /**
+     * Checks is a test format schema version is supported.
+     *
+     * @param string $schemaVersion
+     * @return boolean
+     */
+    private function isSchemaVersionSupported($schemaVersion)
+    {
+        return version_compare($schemaVersion, self::MIN_SCHEMA_VERSION, '>=') && version_compare($schemaVersion, self::MAX_SCHEMA_VERSION, '<');
+    }
+
+    /**
+     * Kill all sessions on the cluster.
+     *
+     * This will clean up any open transactions that may remain from a
+     * previously failed test. For sharded clusters, this command will be run
+     * on all mongos nodes.
+     */
+    private static function killAllSessions()
+    {
+        $manager = self::$internalClient->getManager();
+        $primary = $manager->selectServer(new ReadPreference(ReadPreference::PRIMARY));
+        $servers = $primary->getType() === Server::TYPE_MONGOS ? $manager->getServers() : [$primary];
+
+        foreach ($servers as $server) {
+            try {
+                // Skip servers that do not support sessions
+                if (! isset($server->getInfo()['logicalSessionTimeoutMinutes'])) {
+                    continue;
+                }
+
+                $command = new DatabaseCommand('admin', ['killAllSessions' => []]);
+                $command->execute($server);
+            } catch (ServerException $e) {
+                // Interrupted error is safe to ignore (see: SERVER-38335)
+                if ($e->getCode() != self::SERVER_ERROR_INTERRUPTED) {
+                    throw $e;
+                }
+            }
+        }
+    }
+
+    private function assertOutcome(array $outcome)
+    {
+        $this->assertNotEmpty($outcome);
+        $this->assertContainsOnly('object', $outcome);
+
+        foreach ($outcome as $data) {
+            $collectionData = new CollectionData($data);
+            $collectionData->assertOutcome(self::$internalClient);
+        }
+    }
+
+    private function prepareInitialData(array $initialData)
+    {
+        $this->assertNotEmpty($initialData);
+        $this->assertContainsOnly('object', $initialData);
+
+        foreach ($initialData as $data) {
+            $collectionData = new CollectionData($data);
+            $collectionData->prepareInitialData(self::$internalClient);
+        }
+    }
+
+    /**
+     * Work around potential error executing distinct on sharded clusters.
+     *
+     * @see https://github.com/mongodb/specifications/tree/master/source/transactions/tests#why-do-tests-that-run-distinct-sometimes-fail-with-staledbversionts.
+     */
+    private function preventStaleDbVersionError(array $operations, Context $context)
+    {
+        if (! $this->isShardedCluster()) {
+            return;
+        }
+
+        $hasStartTransaction = false;
+        $hasDistinct = false;
+        $collection = null;
+
+        foreach ($operations as $operation) {
+            switch ($operation->name) {
+                case 'distinct':
+                    $hasDistinct = true;
+                    $collection = $context->getEntityMap()[$operation->object];
+                    break;
+
+                case 'startTransaction':
+                    $hasStartTransaction = true;
+                    break;
+
+                default:
+                    continue 2;
+            }
+
+            if ($hasStartTransaction && $hasDistinct) {
+                $this->assertInstanceOf(Collection::class, $collection);
+                $collection->distinct('foo');
+
+                return;
+            }
+        }
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/Util.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/Util.php
new file mode 100644
index 0000000000000000000000000000000000000000..3e57f78ff4e44f0c2629893c0f8ab54f19ca2f82
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/Util.php	
@@ -0,0 +1,116 @@
+<?php
+
+namespace MongoDB\Tests\UnifiedSpecTests;
+
+use MongoDB\Driver\ReadConcern;
+use MongoDB\Driver\ReadPreference;
+use MongoDB\Driver\WriteConcern;
+use stdClass;
+use function array_diff_key;
+use function array_fill_keys;
+use function array_key_exists;
+use function array_keys;
+use function implode;
+use function PHPUnit\Framework\assertContains;
+use function PHPUnit\Framework\assertEmpty;
+use function PHPUnit\Framework\assertIsArray;
+use function PHPUnit\Framework\assertIsBool;
+use function PHPUnit\Framework\assertIsInt;
+use function PHPUnit\Framework\assertIsObject;
+use function PHPUnit\Framework\assertIsString;
+use function PHPUnit\Framework\assertThat;
+use function PHPUnit\Framework\isInstanceOf;
+use function PHPUnit\Framework\isType;
+use function PHPUnit\Framework\logicalOr;
+
+final class Util
+{
+    public static function assertHasOnlyKeys($arrayOrObject, array $keys)
+    {
+        assertThat($arrayOrObject, logicalOr(isType('array'), isInstanceOf(stdClass::class)));
+        $diff = array_diff_key((array) $arrayOrObject, array_fill_keys($keys, 1));
+        assertEmpty($diff, 'Unsupported keys: ' . implode(',', array_keys($diff)));
+    }
+
+    public static function createReadConcern(stdClass $o) : ReadConcern
+    {
+        self::assertHasOnlyKeys($o, ['level']);
+
+        $level = $o->level ?? null;
+        assertIsString($level);
+
+        return new ReadConcern($level);
+    }
+
+    public static function createReadPreference(stdClass $o) : ReadPreference
+    {
+        self::assertHasOnlyKeys($o, ['mode', 'tagSets', 'maxStalenessSeconds', 'hedge']);
+
+        $mode = $o->mode ?? null;
+        $tagSets = $o->tagSets ?? null;
+        $maxStalenessSeconds = $o->maxStalenessSeconds ?? null;
+        $hedge = $o->hedge ?? null;
+
+        assertIsString($mode);
+
+        if (isset($tagSets)) {
+            assertIsArray($tagSets);
+            assertContains('object', $tagSets);
+        }
+
+        $options = [];
+
+        if (isset($maxStalenessSeconds)) {
+            assertIsInt($maxStalenessSeconds);
+            $options['maxStalenessSeconds'] = $maxStalenessSeconds;
+        }
+
+        if (isset($hedge)) {
+            assertIsObject($hedge);
+            $options['hedge'] = $hedge;
+        }
+
+        return new ReadPreference($mode, $tagSets, $options);
+    }
+
+    public static function createWriteConcern(stdClass $o) : WriteConcern
+    {
+        self::assertHasOnlyKeys($o, ['w', 'wtimeoutMS', 'journal']);
+
+        $w = $o->w ?? -2; /* MONGOC_WRITE_CONCERN_W_DEFAULT */
+        $wtimeoutMS = $o->wtimeoutMS ?? 0;
+        $journal = $o->journal ?? null;
+
+        assertThat($w, logicalOr(isType('int'), isType('string')));
+        assertIsInt($wtimeoutMS);
+
+        $args = [$w, $wtimeoutMS];
+
+        if (isset($journal)) {
+            assertIsBool($journal);
+            $args[] = $journal;
+        }
+
+        return new WriteConcern(...$args);
+    }
+
+    public static function prepareCommonOptions(array $options) : array
+    {
+        if (array_key_exists('readConcern', $options)) {
+            assertIsObject($options['readConcern']);
+            $options['readConcern'] = self::createReadConcern($options['readConcern']);
+        }
+
+        if (array_key_exists('readPreference', $options)) {
+            assertIsObject($options['readPreference']);
+            $options['readPreference'] = self::createReadPreference($options['readPreference']);
+        }
+
+        if (array_key_exists('writeConcern', $options)) {
+            assertIsObject($options['writeConcern']);
+            $options['writeConcern'] = self::createWriteConcern($options['writeConcern']);
+        }
+
+        return $options;
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/valid-fail/entity-bucket-database-undefined.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/valid-fail/entity-bucket-database-undefined.json
new file mode 100644
index 0000000000000000000000000000000000000000..7f7f1978c38b7f91f84e619ee5559d08bb244ab2
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/valid-fail/entity-bucket-database-undefined.json	
@@ -0,0 +1,18 @@
+{
+  "description": "entity-bucket-database-undefined",
+  "schemaVersion": "1.0",
+  "createEntities": [
+    {
+      "bucket": {
+        "id": "bucket0",
+        "database": "foo"
+      }
+    }
+  ],
+  "tests": [
+    {
+      "description": "foo",
+      "operations": []
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/valid-fail/entity-collection-database-undefined.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/valid-fail/entity-collection-database-undefined.json
new file mode 100644
index 0000000000000000000000000000000000000000..20b0733e340da52734dcf681df048c5b4c21c116
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/valid-fail/entity-collection-database-undefined.json	
@@ -0,0 +1,19 @@
+{
+  "description": "entity-collection-database-undefined",
+  "schemaVersion": "1.0",
+  "createEntities": [
+    {
+      "collection": {
+        "id": "collection0",
+        "database": "foo",
+        "collectionName": "foo"
+      }
+    }
+  ],
+  "tests": [
+    {
+      "description": "foo",
+      "operations": []
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/valid-fail/entity-database-client-undefined.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/valid-fail/entity-database-client-undefined.json
new file mode 100644
index 0000000000000000000000000000000000000000..0f8110e6d3798b5e5813bc9af4f9fb30e619296b
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/valid-fail/entity-database-client-undefined.json	
@@ -0,0 +1,19 @@
+{
+  "description": "entity-database-client-undefined",
+  "schemaVersion": "1.0",
+  "createEntities": [
+    {
+      "database": {
+        "id": "database0",
+        "client": "foo",
+        "databaseName": "foo"
+      }
+    }
+  ],
+  "tests": [
+    {
+      "description": "foo",
+      "operations": []
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/valid-fail/entity-session-client-undefined.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/valid-fail/entity-session-client-undefined.json
new file mode 100644
index 0000000000000000000000000000000000000000..260356436a8345d65b7285bf7e458906bc3edcba
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/valid-fail/entity-session-client-undefined.json	
@@ -0,0 +1,18 @@
+{
+  "description": "entity-session-client-undefined",
+  "schemaVersion": "1.0",
+  "createEntities": [
+    {
+      "session": {
+        "id": "session0",
+        "client": "foo"
+      }
+    }
+  ],
+  "tests": [
+    {
+      "description": "foo",
+      "operations": []
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/valid-fail/returnDocument-enum-invalid.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/valid-fail/returnDocument-enum-invalid.json
new file mode 100644
index 0000000000000000000000000000000000000000..ea425fb5681a6abb2f7aaed5d825a10da44ebd70
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/valid-fail/returnDocument-enum-invalid.json	
@@ -0,0 +1,66 @@
+{
+  "description": "returnDocument-enum-invalid",
+  "schemaVersion": "1.0",
+  "createEntities": [
+    {
+      "client": {
+        "id": "client0"
+      }
+    },
+    {
+      "database": {
+        "id": "database0",
+        "client": "client0",
+        "databaseName": "test"
+      }
+    },
+    {
+      "collection": {
+        "id": "collection0",
+        "database": "database0",
+        "collectionName": "coll"
+      }
+    }
+  ],
+  "tests": [
+    {
+      "description": "FindOneAndReplace returnDocument invalid enum value",
+      "operations": [
+        {
+          "name": "findOneAndReplace",
+          "object": "collection0",
+          "arguments": {
+            "filter": {
+              "_id": 1
+            },
+            "replacement": {
+              "_id": 1,
+              "x": 111
+            },
+            "returnDocument": "invalid"
+          }
+        }
+      ]
+    },
+    {
+      "description": "FindOneAndUpdate returnDocument invalid enum value",
+      "operations": [
+        {
+          "name": "findOneAndUpdate",
+          "object": "collection0",
+          "arguments": {
+            "filter": {
+              "_id": 1
+            },
+            "update": {
+              "$inc": {
+                "x": 1
+              }
+            },
+            "returnDocument": "invalid"
+          }
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/valid-fail/schemaVersion-unsupported.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/valid-fail/schemaVersion-unsupported.json
new file mode 100644
index 0000000000000000000000000000000000000000..ceb55329179eb1dbd66c39bc10096aef73175684
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/valid-fail/schemaVersion-unsupported.json	
@@ -0,0 +1,10 @@
+{
+  "description": "schemaVersion-unsupported",
+  "schemaVersion": "0.1",
+  "tests": [
+    {
+      "description": "foo",
+      "operations": []
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/valid-pass/poc-change-streams.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/valid-pass/poc-change-streams.json
new file mode 100644
index 0000000000000000000000000000000000000000..dc6e332e3ede9e21f160d2454362adbd69a6bb5b
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/valid-pass/poc-change-streams.json	
@@ -0,0 +1,410 @@
+{
+  "description": "poc-change-streams",
+  "schemaVersion": "1.0",
+  "createEntities": [
+    {
+      "client": {
+        "id": "client0",
+        "useMultipleMongoses": false,
+        "observeEvents": [
+          "commandStartedEvent"
+        ],
+        "ignoreCommandMonitoringEvents": [
+          "getMore",
+          "killCursors"
+        ]
+      }
+    },
+    {
+      "database": {
+        "id": "database0",
+        "client": "client0",
+        "databaseName": "change-stream-tests"
+      }
+    },
+    {
+      "collection": {
+        "id": "collection0",
+        "database": "database0",
+        "collectionName": "test"
+      }
+    },
+    {
+      "client": {
+        "id": "client1",
+        "useMultipleMongoses": false
+      }
+    },
+    {
+      "database": {
+        "id": "database1",
+        "client": "client1",
+        "databaseName": "change-stream-tests"
+      }
+    },
+    {
+      "database": {
+        "id": "database2",
+        "client": "client1",
+        "databaseName": "change-stream-tests-2"
+      }
+    },
+    {
+      "collection": {
+        "id": "collection1",
+        "database": "database1",
+        "collectionName": "test"
+      }
+    },
+    {
+      "collection": {
+        "id": "collection2",
+        "database": "database1",
+        "collectionName": "test2"
+      }
+    },
+    {
+      "collection": {
+        "id": "collection3",
+        "database": "database2",
+        "collectionName": "test"
+      }
+    }
+  ],
+  "initialData": [
+    {
+      "collectionName": "test",
+      "databaseName": "change-stream-tests",
+      "documents": []
+    },
+    {
+      "collectionName": "test2",
+      "databaseName": "change-stream-tests",
+      "documents": []
+    },
+    {
+      "collectionName": "test",
+      "databaseName": "change-stream-tests-2",
+      "documents": []
+    }
+  ],
+  "tests": [
+    {
+      "description": "Executing a watch helper on a MongoClient results in notifications for changes to all collections in all databases in the cluster.",
+      "runOnRequirements": [
+        {
+          "minServerVersion": "3.8.0",
+          "topologies": [
+            "replicaset"
+          ]
+        }
+      ],
+      "operations": [
+        {
+          "name": "createChangeStream",
+          "object": "client0",
+          "saveResultAsEntity": "changeStream0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection2",
+          "arguments": {
+            "document": {
+              "x": 1
+            }
+          }
+        },
+        {
+          "name": "insertOne",
+          "object": "collection3",
+          "arguments": {
+            "document": {
+              "y": 1
+            }
+          }
+        },
+        {
+          "name": "insertOne",
+          "object": "collection1",
+          "arguments": {
+            "document": {
+              "z": 1
+            }
+          }
+        },
+        {
+          "name": "iterateUntilDocumentOrError",
+          "object": "changeStream0",
+          "expectResult": {
+            "operationType": "insert",
+            "ns": {
+              "db": "change-stream-tests",
+              "coll": "test2"
+            },
+            "fullDocument": {
+              "_id": {
+                "$$type": "objectId"
+              },
+              "x": 1
+            }
+          }
+        },
+        {
+          "name": "iterateUntilDocumentOrError",
+          "object": "changeStream0",
+          "expectResult": {
+            "operationType": "insert",
+            "ns": {
+              "db": "change-stream-tests-2",
+              "coll": "test"
+            },
+            "fullDocument": {
+              "_id": {
+                "$$type": "objectId"
+              },
+              "y": 1
+            }
+          }
+        },
+        {
+          "name": "iterateUntilDocumentOrError",
+          "object": "changeStream0",
+          "expectResult": {
+            "operationType": "insert",
+            "ns": {
+              "db": "change-stream-tests",
+              "coll": "test"
+            },
+            "fullDocument": {
+              "_id": {
+                "$$type": "objectId"
+              },
+              "z": 1
+            }
+          }
+        }
+      ],
+      "expectEvents": [
+        {
+          "client": "client0",
+          "events": [
+            {
+              "commandStartedEvent": {
+                "command": {
+                  "aggregate": 1,
+                  "cursor": {},
+                  "pipeline": [
+                    {
+                      "$changeStream": {
+                        "allChangesForCluster": true,
+                        "fullDocument": {
+                          "$$unsetOrMatches": "default"
+                        }
+                      }
+                    }
+                  ]
+                },
+                "commandName": "aggregate",
+                "databaseName": "admin"
+              }
+            }
+          ]
+        }
+      ]
+    },
+    {
+      "description": "Test consecutive resume",
+      "runOnRequirements": [
+        {
+          "minServerVersion": "4.1.7",
+          "topologies": [
+            "replicaset"
+          ]
+        }
+      ],
+      "operations": [
+        {
+          "name": "failPoint",
+          "object": "testRunner",
+          "arguments": {
+            "client": "client0",
+            "failPoint": {
+              "configureFailPoint": "failCommand",
+              "mode": {
+                "times": 2
+              },
+              "data": {
+                "failCommands": [
+                  "getMore"
+                ],
+                "closeConnection": true
+              }
+            }
+          }
+        },
+        {
+          "name": "createChangeStream",
+          "object": "collection0",
+          "arguments": {
+            "batchSize": 1
+          },
+          "saveResultAsEntity": "changeStream0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection1",
+          "arguments": {
+            "document": {
+              "x": 1
+            }
+          }
+        },
+        {
+          "name": "insertOne",
+          "object": "collection1",
+          "arguments": {
+            "document": {
+              "x": 2
+            }
+          }
+        },
+        {
+          "name": "insertOne",
+          "object": "collection1",
+          "arguments": {
+            "document": {
+              "x": 3
+            }
+          }
+        },
+        {
+          "name": "iterateUntilDocumentOrError",
+          "object": "changeStream0",
+          "expectResult": {
+            "operationType": "insert",
+            "ns": {
+              "db": "change-stream-tests",
+              "coll": "test"
+            },
+            "fullDocument": {
+              "_id": {
+                "$$type": "objectId"
+              },
+              "x": 1
+            }
+          }
+        },
+        {
+          "name": "iterateUntilDocumentOrError",
+          "object": "changeStream0",
+          "expectResult": {
+            "operationType": "insert",
+            "ns": {
+              "db": "change-stream-tests",
+              "coll": "test"
+            },
+            "fullDocument": {
+              "_id": {
+                "$$type": "objectId"
+              },
+              "x": 2
+            }
+          }
+        },
+        {
+          "name": "iterateUntilDocumentOrError",
+          "object": "changeStream0",
+          "expectResult": {
+            "operationType": "insert",
+            "ns": {
+              "db": "change-stream-tests",
+              "coll": "test"
+            },
+            "fullDocument": {
+              "_id": {
+                "$$type": "objectId"
+              },
+              "x": 3
+            }
+          }
+        }
+      ],
+      "expectEvents": [
+        {
+          "client": "client0",
+          "events": [
+            {
+              "commandStartedEvent": {
+                "command": {
+                  "aggregate": "test",
+                  "cursor": {
+                    "batchSize": 1
+                  },
+                  "pipeline": [
+                    {
+                      "$changeStream": {
+                        "fullDocument": {
+                          "$$unsetOrMatches": "default"
+                        }
+                      }
+                    }
+                  ]
+                },
+                "commandName": "aggregate",
+                "databaseName": "change-stream-tests"
+              }
+            },
+            {
+              "commandStartedEvent": {
+                "command": {
+                  "aggregate": "test",
+                  "cursor": {
+                    "batchSize": 1
+                  },
+                  "pipeline": [
+                    {
+                      "$changeStream": {
+                        "fullDocument": {
+                          "$$unsetOrMatches": "default"
+                        },
+                        "resumeAfter": {
+                          "$$exists": true
+                        }
+                      }
+                    }
+                  ]
+                },
+                "commandName": "aggregate",
+                "databaseName": "change-stream-tests"
+              }
+            },
+            {
+              "commandStartedEvent": {
+                "command": {
+                  "aggregate": "test",
+                  "cursor": {
+                    "batchSize": 1
+                  },
+                  "pipeline": [
+                    {
+                      "$changeStream": {
+                        "fullDocument": {
+                          "$$unsetOrMatches": "default"
+                        },
+                        "resumeAfter": {
+                          "$$exists": true
+                        }
+                      }
+                    }
+                  ]
+                },
+                "commandName": "aggregate",
+                "databaseName": "change-stream-tests"
+              }
+            }
+          ]
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/valid-pass/poc-command-monitoring.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/valid-pass/poc-command-monitoring.json
new file mode 100644
index 0000000000000000000000000000000000000000..499396e0baa937c3620b6ab3afc225589102d839
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/valid-pass/poc-command-monitoring.json	
@@ -0,0 +1,222 @@
+{
+  "description": "poc-command-monitoring",
+  "schemaVersion": "1.0",
+  "createEntities": [
+    {
+      "client": {
+        "id": "client0",
+        "observeEvents": [
+          "commandStartedEvent",
+          "commandSucceededEvent",
+          "commandFailedEvent"
+        ]
+      }
+    },
+    {
+      "database": {
+        "id": "database0",
+        "client": "client0",
+        "databaseName": "command-monitoring-tests"
+      }
+    },
+    {
+      "collection": {
+        "id": "collection0",
+        "database": "database0",
+        "collectionName": "test"
+      }
+    }
+  ],
+  "initialData": [
+    {
+      "collectionName": "test",
+      "databaseName": "command-monitoring-tests",
+      "documents": [
+        {
+          "_id": 1,
+          "x": 11
+        },
+        {
+          "_id": 2,
+          "x": 22
+        },
+        {
+          "_id": 3,
+          "x": 33
+        },
+        {
+          "_id": 4,
+          "x": 44
+        },
+        {
+          "_id": 5,
+          "x": 55
+        }
+      ]
+    }
+  ],
+  "tests": [
+    {
+      "description": "A successful find event with a getmore and the server kills the cursor",
+      "runOnRequirements": [
+        {
+          "minServerVersion": "3.1",
+          "topologies": [
+            "single",
+            "replicaset"
+          ]
+        }
+      ],
+      "operations": [
+        {
+          "name": "find",
+          "object": "collection0",
+          "arguments": {
+            "filter": {
+              "_id": {
+                "$gte": 1
+              }
+            },
+            "sort": {
+              "_id": 1
+            },
+            "batchSize": 3,
+            "limit": 4
+          }
+        }
+      ],
+      "expectEvents": [
+        {
+          "client": "client0",
+          "events": [
+            {
+              "commandStartedEvent": {
+                "command": {
+                  "find": "test",
+                  "filter": {
+                    "_id": {
+                      "$gte": 1
+                    }
+                  },
+                  "sort": {
+                    "_id": 1
+                  },
+                  "batchSize": 3,
+                  "limit": 4
+                },
+                "commandName": "find",
+                "databaseName": "command-monitoring-tests"
+              }
+            },
+            {
+              "commandSucceededEvent": {
+                "reply": {
+                  "ok": 1,
+                  "cursor": {
+                    "id": {
+                      "$$type": [
+                        "int",
+                        "long"
+                      ]
+                    },
+                    "ns": "command-monitoring-tests.test",
+                    "firstBatch": [
+                      {
+                        "_id": 1,
+                        "x": 11
+                      },
+                      {
+                        "_id": 2,
+                        "x": 22
+                      },
+                      {
+                        "_id": 3,
+                        "x": 33
+                      }
+                    ]
+                  }
+                },
+                "commandName": "find"
+              }
+            },
+            {
+              "commandStartedEvent": {
+                "command": {
+                  "getMore": {
+                    "$$type": [
+                      "int",
+                      "long"
+                    ]
+                  },
+                  "collection": "test",
+                  "batchSize": 1
+                },
+                "commandName": "getMore",
+                "databaseName": "command-monitoring-tests"
+              }
+            },
+            {
+              "commandSucceededEvent": {
+                "reply": {
+                  "ok": 1,
+                  "cursor": {
+                    "id": 0,
+                    "ns": "command-monitoring-tests.test",
+                    "nextBatch": [
+                      {
+                        "_id": 4,
+                        "x": 44
+                      }
+                    ]
+                  }
+                },
+                "commandName": "getMore"
+              }
+            }
+          ]
+        }
+      ]
+    },
+    {
+      "description": "A failed find event",
+      "operations": [
+        {
+          "name": "find",
+          "object": "collection0",
+          "arguments": {
+            "filter": {
+              "$or": true
+            }
+          },
+          "expectError": {
+            "isError": true
+          }
+        }
+      ],
+      "expectEvents": [
+        {
+          "client": "client0",
+          "events": [
+            {
+              "commandStartedEvent": {
+                "command": {
+                  "find": "test",
+                  "filter": {
+                    "$or": true
+                  }
+                },
+                "commandName": "find",
+                "databaseName": "command-monitoring-tests"
+              }
+            },
+            {
+              "commandFailedEvent": {
+                "commandName": "find"
+              }
+            }
+          ]
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/valid-pass/poc-crud.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/valid-pass/poc-crud.json
new file mode 100644
index 0000000000000000000000000000000000000000..2ed86d6150d896ed54be14c2c1f1da3d0dd277d3
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/valid-pass/poc-crud.json	
@@ -0,0 +1,446 @@
+{
+  "description": "poc-crud",
+  "schemaVersion": "1.0",
+  "createEntities": [
+    {
+      "client": {
+        "id": "client0",
+        "observeEvents": [
+          "commandStartedEvent"
+        ]
+      }
+    },
+    {
+      "database": {
+        "id": "database0",
+        "client": "client0",
+        "databaseName": "crud-tests"
+      }
+    },
+    {
+      "database": {
+        "id": "database1",
+        "client": "client0",
+        "databaseName": "admin"
+      }
+    },
+    {
+      "collection": {
+        "id": "collection0",
+        "database": "database0",
+        "collectionName": "coll0"
+      }
+    },
+    {
+      "collection": {
+        "id": "collection1",
+        "database": "database0",
+        "collectionName": "coll1"
+      }
+    },
+    {
+      "collection": {
+        "id": "collection2",
+        "database": "database0",
+        "collectionName": "coll2",
+        "collectionOptions": {
+          "readConcern": {
+            "level": "majority"
+          }
+        }
+      }
+    }
+  ],
+  "initialData": [
+    {
+      "collectionName": "coll0",
+      "databaseName": "crud-tests",
+      "documents": [
+        {
+          "_id": 1,
+          "x": 11
+        },
+        {
+          "_id": 2,
+          "x": 22
+        }
+      ]
+    },
+    {
+      "collectionName": "coll1",
+      "databaseName": "crud-tests",
+      "documents": [
+        {
+          "_id": 1,
+          "x": 11
+        }
+      ]
+    },
+    {
+      "collectionName": "coll2",
+      "databaseName": "crud-tests",
+      "documents": [
+        {
+          "_id": 1,
+          "x": 11
+        },
+        {
+          "_id": 2,
+          "x": 22
+        },
+        {
+          "_id": 3,
+          "x": 33
+        }
+      ]
+    },
+    {
+      "collectionName": "aggregate_out",
+      "databaseName": "crud-tests",
+      "documents": []
+    }
+  ],
+  "tests": [
+    {
+      "description": "BulkWrite with mixed ordered operations",
+      "operations": [
+        {
+          "name": "bulkWrite",
+          "object": "collection0",
+          "arguments": {
+            "requests": [
+              {
+                "insertOne": {
+                  "document": {
+                    "_id": 3,
+                    "x": 33
+                  }
+                }
+              },
+              {
+                "updateOne": {
+                  "filter": {
+                    "_id": 2
+                  },
+                  "update": {
+                    "$inc": {
+                      "x": 1
+                    }
+                  }
+                }
+              },
+              {
+                "updateMany": {
+                  "filter": {
+                    "_id": {
+                      "$gt": 1
+                    }
+                  },
+                  "update": {
+                    "$inc": {
+                      "x": 1
+                    }
+                  }
+                }
+              },
+              {
+                "insertOne": {
+                  "document": {
+                    "_id": 4,
+                    "x": 44
+                  }
+                }
+              },
+              {
+                "deleteMany": {
+                  "filter": {
+                    "x": {
+                      "$nin": [
+                        24,
+                        34
+                      ]
+                    }
+                  }
+                }
+              },
+              {
+                "replaceOne": {
+                  "filter": {
+                    "_id": 4
+                  },
+                  "replacement": {
+                    "_id": 4,
+                    "x": 44
+                  },
+                  "upsert": true
+                }
+              }
+            ],
+            "ordered": true
+          },
+          "expectResult": {
+            "deletedCount": 2,
+            "insertedCount": 2,
+            "insertedIds": {
+              "$$unsetOrMatches": {
+                "0": 3,
+                "3": 4
+              }
+            },
+            "matchedCount": 3,
+            "modifiedCount": 3,
+            "upsertedCount": 1,
+            "upsertedIds": {
+              "5": 4
+            }
+          }
+        }
+      ],
+      "outcome": [
+        {
+          "collectionName": "coll0",
+          "databaseName": "crud-tests",
+          "documents": [
+            {
+              "_id": 2,
+              "x": 24
+            },
+            {
+              "_id": 3,
+              "x": 34
+            },
+            {
+              "_id": 4,
+              "x": 44
+            }
+          ]
+        }
+      ]
+    },
+    {
+      "description": "InsertMany continue-on-error behavior with unordered (duplicate key in requests)",
+      "operations": [
+        {
+          "name": "insertMany",
+          "object": "collection1",
+          "arguments": {
+            "documents": [
+              {
+                "_id": 2,
+                "x": 22
+              },
+              {
+                "_id": 2,
+                "x": 22
+              },
+              {
+                "_id": 3,
+                "x": 33
+              }
+            ],
+            "ordered": false
+          },
+          "expectError": {
+            "expectResult": {
+              "deletedCount": 0,
+              "insertedCount": 2,
+              "matchedCount": 0,
+              "modifiedCount": 0,
+              "upsertedCount": 0,
+              "upsertedIds": {}
+            }
+          }
+        }
+      ],
+      "outcome": [
+        {
+          "collectionName": "coll1",
+          "databaseName": "crud-tests",
+          "documents": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      ]
+    },
+    {
+      "description": "ReplaceOne prohibits atomic modifiers",
+      "operations": [
+        {
+          "name": "replaceOne",
+          "object": "collection1",
+          "arguments": {
+            "filter": {
+              "_id": 1
+            },
+            "replacement": {
+              "$set": {
+                "x": 22
+              }
+            }
+          },
+          "expectError": {
+            "isClientError": true
+          }
+        }
+      ],
+      "expectEvents": [
+        {
+          "client": "client0",
+          "events": []
+        }
+      ],
+      "outcome": [
+        {
+          "collectionName": "coll1",
+          "databaseName": "crud-tests",
+          "documents": [
+            {
+              "_id": 1,
+              "x": 11
+            }
+          ]
+        }
+      ]
+    },
+    {
+      "description": "readConcern majority with out stage",
+      "runOnRequirements": [
+        {
+          "minServerVersion": "4.1.0",
+          "topologies": [
+            "replicaset",
+            "sharded-replicaset"
+          ]
+        }
+      ],
+      "operations": [
+        {
+          "name": "aggregate",
+          "object": "collection2",
+          "arguments": {
+            "pipeline": [
+              {
+                "$sort": {
+                  "x": 1
+                }
+              },
+              {
+                "$match": {
+                  "_id": {
+                    "$gt": 1
+                  }
+                }
+              },
+              {
+                "$out": "aggregate_out"
+              }
+            ]
+          }
+        }
+      ],
+      "expectEvents": [
+        {
+          "client": "client0",
+          "events": [
+            {
+              "commandStartedEvent": {
+                "command": {
+                  "aggregate": "coll2",
+                  "pipeline": [
+                    {
+                      "$sort": {
+                        "x": 1
+                      }
+                    },
+                    {
+                      "$match": {
+                        "_id": {
+                          "$gt": 1
+                        }
+                      }
+                    },
+                    {
+                      "$out": "aggregate_out"
+                    }
+                  ],
+                  "readConcern": {
+                    "level": "majority"
+                  }
+                },
+                "commandName": "aggregate",
+                "databaseName": "crud-tests"
+              }
+            }
+          ]
+        }
+      ],
+      "outcome": [
+        {
+          "collectionName": "aggregate_out",
+          "databaseName": "crud-tests",
+          "documents": [
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      ]
+    },
+    {
+      "description": "Aggregate with $listLocalSessions",
+      "runOnRequirements": [
+        {
+          "minServerVersion": "3.6.0"
+        }
+      ],
+      "operations": [
+        {
+          "name": "aggregate",
+          "object": "database1",
+          "arguments": {
+            "pipeline": [
+              {
+                "$listLocalSessions": {}
+              },
+              {
+                "$limit": 1
+              },
+              {
+                "$addFields": {
+                  "dummy": "dummy field"
+                }
+              },
+              {
+                "$project": {
+                  "_id": 0,
+                  "dummy": 1
+                }
+              }
+            ]
+          },
+          "expectResult": [
+            {
+              "dummy": "dummy field"
+            }
+          ]
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/valid-pass/poc-gridfs.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/valid-pass/poc-gridfs.json
new file mode 100644
index 0000000000000000000000000000000000000000..c04ed89a7cf6ba2e52da55ce9c44360f10ce1767
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/valid-pass/poc-gridfs.json	
@@ -0,0 +1,299 @@
+{
+  "description": "poc-gridfs",
+  "schemaVersion": "1.0",
+  "createEntities": [
+    {
+      "client": {
+        "id": "client0"
+      }
+    },
+    {
+      "database": {
+        "id": "database0",
+        "client": "client0",
+        "databaseName": "gridfs-tests"
+      }
+    },
+    {
+      "bucket": {
+        "id": "bucket0",
+        "database": "database0"
+      }
+    },
+    {
+      "collection": {
+        "id": "bucket0_files_collection",
+        "database": "database0",
+        "collectionName": "fs.files"
+      }
+    },
+    {
+      "collection": {
+        "id": "bucket0_chunks_collection",
+        "database": "database0",
+        "collectionName": "fs.chunks"
+      }
+    }
+  ],
+  "initialData": [
+    {
+      "collectionName": "fs.files",
+      "databaseName": "gridfs-tests",
+      "documents": [
+        {
+          "_id": {
+            "$oid": "000000000000000000000005"
+          },
+          "length": 10,
+          "chunkSize": 4,
+          "uploadDate": {
+            "$date": "1970-01-01T00:00:00.000Z"
+          },
+          "md5": "57d83cd477bfb1ccd975ab33d827a92b",
+          "filename": "length-10",
+          "contentType": "application/octet-stream",
+          "aliases": [],
+          "metadata": {}
+        }
+      ]
+    },
+    {
+      "collectionName": "fs.chunks",
+      "databaseName": "gridfs-tests",
+      "documents": [
+        {
+          "_id": {
+            "$oid": "000000000000000000000005"
+          },
+          "files_id": {
+            "$oid": "000000000000000000000005"
+          },
+          "n": 0,
+          "data": {
+            "$binary": {
+              "base64": "ESIzRA==",
+              "subType": "00"
+            }
+          }
+        },
+        {
+          "_id": {
+            "$oid": "000000000000000000000006"
+          },
+          "files_id": {
+            "$oid": "000000000000000000000005"
+          },
+          "n": 1,
+          "data": {
+            "$binary": {
+              "base64": "VWZ3iA==",
+              "subType": "00"
+            }
+          }
+        },
+        {
+          "_id": {
+            "$oid": "000000000000000000000007"
+          },
+          "files_id": {
+            "$oid": "000000000000000000000005"
+          },
+          "n": 2,
+          "data": {
+            "$binary": {
+              "base64": "mao=",
+              "subType": "00"
+            }
+          }
+        }
+      ]
+    }
+  ],
+  "tests": [
+    {
+      "description": "Delete when length is 10",
+      "operations": [
+        {
+          "name": "delete",
+          "object": "bucket0",
+          "arguments": {
+            "id": {
+              "$oid": "000000000000000000000005"
+            }
+          }
+        }
+      ],
+      "outcome": [
+        {
+          "collectionName": "fs.files",
+          "databaseName": "gridfs-tests",
+          "documents": []
+        },
+        {
+          "collectionName": "fs.chunks",
+          "databaseName": "gridfs-tests",
+          "documents": []
+        }
+      ]
+    },
+    {
+      "description": "Download when there are three chunks",
+      "operations": [
+        {
+          "name": "download",
+          "object": "bucket0",
+          "arguments": {
+            "id": {
+              "$oid": "000000000000000000000005"
+            }
+          },
+          "expectResult": {
+            "$$matchesHexBytes": "112233445566778899aa"
+          }
+        }
+      ]
+    },
+    {
+      "description": "Download when files entry does not exist",
+      "operations": [
+        {
+          "name": "download",
+          "object": "bucket0",
+          "arguments": {
+            "id": {
+              "$oid": "000000000000000000000000"
+            }
+          },
+          "expectError": {
+            "isError": true
+          }
+        }
+      ]
+    },
+    {
+      "description": "Download when an intermediate chunk is missing",
+      "operations": [
+        {
+          "name": "deleteOne",
+          "object": "bucket0_chunks_collection",
+          "arguments": {
+            "filter": {
+              "files_id": {
+                "$oid": "000000000000000000000005"
+              },
+              "n": 1
+            }
+          },
+          "expectResult": {
+            "deletedCount": 1
+          }
+        },
+        {
+          "name": "download",
+          "object": "bucket0",
+          "arguments": {
+            "id": {
+              "$oid": "000000000000000000000005"
+            }
+          },
+          "expectError": {
+            "isError": true
+          }
+        }
+      ]
+    },
+    {
+      "description": "Upload when length is 5",
+      "operations": [
+        {
+          "name": "upload",
+          "object": "bucket0",
+          "arguments": {
+            "filename": "filename",
+            "source": {
+              "$$hexBytes": "1122334455"
+            },
+            "chunkSizeBytes": 4
+          },
+          "expectResult": {
+            "$$type": "objectId"
+          },
+          "saveResultAsEntity": "oid0"
+        },
+        {
+          "name": "find",
+          "object": "bucket0_files_collection",
+          "arguments": {
+            "filter": {},
+            "sort": {
+              "uploadDate": -1
+            },
+            "limit": 1
+          },
+          "expectResult": [
+            {
+              "_id": {
+                "$$matchesEntity": "oid0"
+              },
+              "length": 5,
+              "chunkSize": 4,
+              "uploadDate": {
+                "$$type": "date"
+              },
+              "md5": "283d4fea5dded59cf837d3047328f5af",
+              "filename": "filename"
+            }
+          ]
+        },
+        {
+          "name": "find",
+          "object": "bucket0_chunks_collection",
+          "arguments": {
+            "filter": {
+              "_id": {
+                "$gt": {
+                  "$oid": "000000000000000000000007"
+                }
+              }
+            },
+            "sort": {
+              "n": 1
+            }
+          },
+          "expectResult": [
+            {
+              "_id": {
+                "$$type": "objectId"
+              },
+              "files_id": {
+                "$$matchesEntity": "oid0"
+              },
+              "n": 0,
+              "data": {
+                "$binary": {
+                  "base64": "ESIzRA==",
+                  "subType": "00"
+                }
+              }
+            },
+            {
+              "_id": {
+                "$$type": "objectId"
+              },
+              "files_id": {
+                "$$matchesEntity": "oid0"
+              },
+              "n": 1,
+              "data": {
+                "$binary": {
+                  "base64": "VQ==",
+                  "subType": "00"
+                }
+              }
+            }
+          ]
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/valid-pass/poc-retryable-reads.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/valid-pass/poc-retryable-reads.json
new file mode 100644
index 0000000000000000000000000000000000000000..2b65d501a7840b29606482f2733dfa2cc420b79b
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/valid-pass/poc-retryable-reads.json	
@@ -0,0 +1,433 @@
+{
+  "description": "poc-retryable-reads",
+  "schemaVersion": "1.0",
+  "runOnRequirements": [
+    {
+      "minServerVersion": "4.0",
+      "topologies": [
+        "single",
+        "replicaset"
+      ]
+    },
+    {
+      "minServerVersion": "4.1.7",
+      "topologies": [
+        "sharded"
+      ]
+    }
+  ],
+  "createEntities": [
+    {
+      "client": {
+        "id": "client0",
+        "useMultipleMongoses": false,
+        "observeEvents": [
+          "commandStartedEvent"
+        ]
+      }
+    },
+    {
+      "client": {
+        "id": "client1",
+        "uriOptions": {
+          "retryReads": false
+        },
+        "useMultipleMongoses": false,
+        "observeEvents": [
+          "commandStartedEvent"
+        ]
+      }
+    },
+    {
+      "database": {
+        "id": "database0",
+        "client": "client0",
+        "databaseName": "retryable-reads-tests"
+      }
+    },
+    {
+      "database": {
+        "id": "database1",
+        "client": "client1",
+        "databaseName": "retryable-reads-tests"
+      }
+    },
+    {
+      "collection": {
+        "id": "collection0",
+        "database": "database0",
+        "collectionName": "coll"
+      }
+    },
+    {
+      "collection": {
+        "id": "collection1",
+        "database": "database1",
+        "collectionName": "coll"
+      }
+    }
+  ],
+  "initialData": [
+    {
+      "collectionName": "coll",
+      "databaseName": "retryable-reads-tests",
+      "documents": [
+        {
+          "_id": 1,
+          "x": 11
+        },
+        {
+          "_id": 2,
+          "x": 22
+        },
+        {
+          "_id": 3,
+          "x": 33
+        }
+      ]
+    }
+  ],
+  "tests": [
+    {
+      "description": "Aggregate succeeds after InterruptedAtShutdown",
+      "operations": [
+        {
+          "name": "failPoint",
+          "object": "testRunner",
+          "arguments": {
+            "client": "client0",
+            "failPoint": {
+              "configureFailPoint": "failCommand",
+              "mode": {
+                "times": 1
+              },
+              "data": {
+                "failCommands": [
+                  "aggregate"
+                ],
+                "errorCode": 11600
+              }
+            }
+          }
+        },
+        {
+          "name": "aggregate",
+          "object": "collection0",
+          "arguments": {
+            "pipeline": [
+              {
+                "$match": {
+                  "_id": {
+                    "$gt": 1
+                  }
+                }
+              },
+              {
+                "$sort": {
+                  "x": 1
+                }
+              }
+            ]
+          },
+          "expectResult": [
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      ],
+      "expectEvents": [
+        {
+          "client": "client0",
+          "events": [
+            {
+              "commandStartedEvent": {
+                "command": {
+                  "aggregate": "coll",
+                  "pipeline": [
+                    {
+                      "$match": {
+                        "_id": {
+                          "$gt": 1
+                        }
+                      }
+                    },
+                    {
+                      "$sort": {
+                        "x": 1
+                      }
+                    }
+                  ]
+                },
+                "databaseName": "retryable-reads-tests"
+              }
+            },
+            {
+              "commandStartedEvent": {
+                "command": {
+                  "aggregate": "coll",
+                  "pipeline": [
+                    {
+                      "$match": {
+                        "_id": {
+                          "$gt": 1
+                        }
+                      }
+                    },
+                    {
+                      "$sort": {
+                        "x": 1
+                      }
+                    }
+                  ]
+                },
+                "databaseName": "retryable-reads-tests"
+              }
+            }
+          ]
+        }
+      ]
+    },
+    {
+      "description": "Find succeeds on second attempt",
+      "operations": [
+        {
+          "name": "failPoint",
+          "object": "testRunner",
+          "arguments": {
+            "client": "client0",
+            "failPoint": {
+              "configureFailPoint": "failCommand",
+              "mode": {
+                "times": 1
+              },
+              "data": {
+                "failCommands": [
+                  "find"
+                ],
+                "closeConnection": true
+              }
+            }
+          }
+        },
+        {
+          "name": "find",
+          "object": "collection0",
+          "arguments": {
+            "filter": {},
+            "sort": {
+              "_id": 1
+            },
+            "limit": 2
+          },
+          "expectResult": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      ],
+      "expectEvents": [
+        {
+          "client": "client0",
+          "events": [
+            {
+              "commandStartedEvent": {
+                "command": {
+                  "find": "coll",
+                  "filter": {},
+                  "sort": {
+                    "_id": 1
+                  },
+                  "limit": 2
+                },
+                "databaseName": "retryable-reads-tests"
+              }
+            },
+            {
+              "commandStartedEvent": {
+                "command": {
+                  "find": "coll",
+                  "filter": {},
+                  "sort": {
+                    "_id": 1
+                  },
+                  "limit": 2
+                },
+                "databaseName": "retryable-reads-tests"
+              }
+            }
+          ]
+        }
+      ]
+    },
+    {
+      "description": "Find fails on first attempt",
+      "operations": [
+        {
+          "name": "failPoint",
+          "object": "testRunner",
+          "arguments": {
+            "client": "client0",
+            "failPoint": {
+              "configureFailPoint": "failCommand",
+              "mode": {
+                "times": 1
+              },
+              "data": {
+                "failCommands": [
+                  "find"
+                ],
+                "closeConnection": true
+              }
+            }
+          }
+        },
+        {
+          "name": "find",
+          "object": "collection1",
+          "arguments": {
+            "filter": {}
+          },
+          "expectError": {
+            "isError": true
+          }
+        }
+      ],
+      "expectEvents": [
+        {
+          "client": "client1",
+          "events": [
+            {
+              "commandStartedEvent": {
+                "command": {
+                  "find": "coll",
+                  "filter": {}
+                },
+                "databaseName": "retryable-reads-tests"
+              }
+            }
+          ]
+        }
+      ]
+    },
+    {
+      "description": "Find fails on second attempt",
+      "operations": [
+        {
+          "name": "failPoint",
+          "object": "testRunner",
+          "arguments": {
+            "client": "client0",
+            "failPoint": {
+              "configureFailPoint": "failCommand",
+              "mode": {
+                "times": 2
+              },
+              "data": {
+                "failCommands": [
+                  "find"
+                ],
+                "closeConnection": true
+              }
+            }
+          }
+        },
+        {
+          "name": "find",
+          "object": "collection0",
+          "arguments": {
+            "filter": {}
+          },
+          "expectError": {
+            "isError": true
+          }
+        }
+      ],
+      "expectEvents": [
+        {
+          "client": "client0",
+          "events": [
+            {
+              "commandStartedEvent": {
+                "command": {
+                  "find": "coll",
+                  "filter": {}
+                },
+                "databaseName": "retryable-reads-tests"
+              }
+            },
+            {
+              "commandStartedEvent": {
+                "command": {
+                  "find": "coll",
+                  "filter": {}
+                },
+                "databaseName": "retryable-reads-tests"
+              }
+            }
+          ]
+        }
+      ]
+    },
+    {
+      "description": "ListDatabases succeeds on second attempt",
+      "operations": [
+        {
+          "name": "failPoint",
+          "object": "testRunner",
+          "arguments": {
+            "client": "client0",
+            "failPoint": {
+              "configureFailPoint": "failCommand",
+              "mode": {
+                "times": 1
+              },
+              "data": {
+                "failCommands": [
+                  "listDatabases"
+                ],
+                "closeConnection": true
+              }
+            }
+          }
+        },
+        {
+          "name": "listDatabases",
+          "object": "client0"
+        }
+      ],
+      "expectEvents": [
+        {
+          "client": "client0",
+          "events": [
+            {
+              "commandStartedEvent": {
+                "command": {
+                  "listDatabases": 1
+                }
+              }
+            },
+            {
+              "commandStartedEvent": {
+                "command": {
+                  "listDatabases": 1
+                }
+              }
+            }
+          ]
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/valid-pass/poc-retryable-writes.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/valid-pass/poc-retryable-writes.json
new file mode 100644
index 0000000000000000000000000000000000000000..e64ce1bceefcfdabb3d69145eca14635099804e2
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/valid-pass/poc-retryable-writes.json	
@@ -0,0 +1,481 @@
+{
+  "description": "poc-retryable-writes",
+  "schemaVersion": "1.0",
+  "runOnRequirements": [
+    {
+      "minServerVersion": "3.6",
+      "topologies": [
+        "replicaset"
+      ]
+    }
+  ],
+  "createEntities": [
+    {
+      "client": {
+        "id": "client0",
+        "useMultipleMongoses": false,
+        "observeEvents": [
+          "commandStartedEvent"
+        ]
+      }
+    },
+    {
+      "client": {
+        "id": "client1",
+        "uriOptions": {
+          "retryWrites": false
+        },
+        "useMultipleMongoses": false,
+        "observeEvents": [
+          "commandStartedEvent"
+        ]
+      }
+    },
+    {
+      "database": {
+        "id": "database0",
+        "client": "client0",
+        "databaseName": "retryable-writes-tests"
+      }
+    },
+    {
+      "database": {
+        "id": "database1",
+        "client": "client1",
+        "databaseName": "retryable-writes-tests"
+      }
+    },
+    {
+      "collection": {
+        "id": "collection0",
+        "database": "database0",
+        "collectionName": "coll"
+      }
+    },
+    {
+      "collection": {
+        "id": "collection1",
+        "database": "database1",
+        "collectionName": "coll"
+      }
+    }
+  ],
+  "initialData": [
+    {
+      "collectionName": "coll",
+      "databaseName": "retryable-writes-tests",
+      "documents": [
+        {
+          "_id": 1,
+          "x": 11
+        },
+        {
+          "_id": 2,
+          "x": 22
+        }
+      ]
+    }
+  ],
+  "tests": [
+    {
+      "description": "FindOneAndUpdate is committed on first attempt",
+      "operations": [
+        {
+          "name": "failPoint",
+          "object": "testRunner",
+          "arguments": {
+            "client": "client0",
+            "failPoint": {
+              "configureFailPoint": "onPrimaryTransactionalWrite",
+              "mode": {
+                "times": 1
+              }
+            }
+          }
+        },
+        {
+          "name": "findOneAndUpdate",
+          "object": "collection0",
+          "arguments": {
+            "filter": {
+              "_id": 1
+            },
+            "update": {
+              "$inc": {
+                "x": 1
+              }
+            },
+            "returnDocument": "Before"
+          },
+          "expectResult": {
+            "_id": 1,
+            "x": 11
+          }
+        }
+      ],
+      "outcome": [
+        {
+          "collectionName": "coll",
+          "databaseName": "retryable-writes-tests",
+          "documents": [
+            {
+              "_id": 1,
+              "x": 12
+            },
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      ]
+    },
+    {
+      "description": "FindOneAndUpdate is not committed on first attempt",
+      "operations": [
+        {
+          "name": "failPoint",
+          "object": "testRunner",
+          "arguments": {
+            "client": "client0",
+            "failPoint": {
+              "configureFailPoint": "onPrimaryTransactionalWrite",
+              "mode": {
+                "times": 1
+              },
+              "data": {
+                "failBeforeCommitExceptionCode": 1
+              }
+            }
+          }
+        },
+        {
+          "name": "findOneAndUpdate",
+          "object": "collection0",
+          "arguments": {
+            "filter": {
+              "_id": 1
+            },
+            "update": {
+              "$inc": {
+                "x": 1
+              }
+            },
+            "returnDocument": "Before"
+          },
+          "expectResult": {
+            "_id": 1,
+            "x": 11
+          }
+        }
+      ],
+      "outcome": [
+        {
+          "collectionName": "coll",
+          "databaseName": "retryable-writes-tests",
+          "documents": [
+            {
+              "_id": 1,
+              "x": 12
+            },
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      ]
+    },
+    {
+      "description": "FindOneAndUpdate is never committed",
+      "operations": [
+        {
+          "name": "failPoint",
+          "object": "testRunner",
+          "arguments": {
+            "client": "client0",
+            "failPoint": {
+              "configureFailPoint": "onPrimaryTransactionalWrite",
+              "mode": {
+                "times": 2
+              },
+              "data": {
+                "failBeforeCommitExceptionCode": 1
+              }
+            }
+          }
+        },
+        {
+          "name": "findOneAndUpdate",
+          "object": "collection0",
+          "arguments": {
+            "filter": {
+              "_id": 1
+            },
+            "update": {
+              "$inc": {
+                "x": 1
+              }
+            },
+            "returnDocument": "Before"
+          },
+          "expectError": {
+            "isError": true
+          }
+        }
+      ],
+      "outcome": [
+        {
+          "collectionName": "coll",
+          "databaseName": "retryable-writes-tests",
+          "documents": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      ]
+    },
+    {
+      "description": "InsertMany succeeds after PrimarySteppedDown",
+      "runOnRequirements": [
+        {
+          "minServerVersion": "4.0",
+          "topologies": [
+            "replicaset"
+          ]
+        },
+        {
+          "minServerVersion": "4.1.7",
+          "topologies": [
+            "sharded-replicaset"
+          ]
+        }
+      ],
+      "operations": [
+        {
+          "name": "failPoint",
+          "object": "testRunner",
+          "arguments": {
+            "client": "client0",
+            "failPoint": {
+              "configureFailPoint": "failCommand",
+              "mode": {
+                "times": 1
+              },
+              "data": {
+                "failCommands": [
+                  "insert"
+                ],
+                "errorCode": 189,
+                "errorLabels": [
+                  "RetryableWriteError"
+                ]
+              }
+            }
+          }
+        },
+        {
+          "name": "insertMany",
+          "object": "collection0",
+          "arguments": {
+            "documents": [
+              {
+                "_id": 3,
+                "x": 33
+              },
+              {
+                "_id": 4,
+                "x": 44
+              }
+            ],
+            "ordered": true
+          },
+          "expectResult": {
+            "insertedCount": 2,
+            "insertedIds": {
+              "$$unsetOrMatches": {
+                "0": 3,
+                "1": 4
+              }
+            }
+          }
+        }
+      ],
+      "outcome": [
+        {
+          "collectionName": "coll",
+          "databaseName": "retryable-writes-tests",
+          "documents": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            },
+            {
+              "_id": 4,
+              "x": 44
+            }
+          ]
+        }
+      ]
+    },
+    {
+      "description": "InsertOne fails after connection failure when retryWrites option is false",
+      "runOnRequirements": [
+        {
+          "minServerVersion": "4.0",
+          "topologies": [
+            "replicaset"
+          ]
+        },
+        {
+          "minServerVersion": "4.1.7",
+          "topologies": [
+            "sharded-replicaset"
+          ]
+        }
+      ],
+      "operations": [
+        {
+          "name": "failPoint",
+          "object": "testRunner",
+          "arguments": {
+            "client": "client1",
+            "failPoint": {
+              "configureFailPoint": "failCommand",
+              "mode": {
+                "times": 1
+              },
+              "data": {
+                "failCommands": [
+                  "insert"
+                ],
+                "closeConnection": true
+              }
+            }
+          }
+        },
+        {
+          "name": "insertOne",
+          "object": "collection1",
+          "arguments": {
+            "document": {
+              "_id": 3,
+              "x": 33
+            }
+          },
+          "expectError": {
+            "errorLabelsOmit": [
+              "RetryableWriteError"
+            ]
+          }
+        }
+      ],
+      "outcome": [
+        {
+          "collectionName": "coll",
+          "databaseName": "retryable-writes-tests",
+          "documents": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            }
+          ]
+        }
+      ]
+    },
+    {
+      "description": "InsertOne fails after multiple retryable writeConcernErrors",
+      "runOnRequirements": [
+        {
+          "minServerVersion": "4.0",
+          "topologies": [
+            "replicaset"
+          ]
+        },
+        {
+          "minServerVersion": "4.1.7",
+          "topologies": [
+            "sharded-replicaset"
+          ]
+        }
+      ],
+      "operations": [
+        {
+          "name": "failPoint",
+          "object": "testRunner",
+          "arguments": {
+            "client": "client0",
+            "failPoint": {
+              "configureFailPoint": "failCommand",
+              "mode": {
+                "times": 2
+              },
+              "data": {
+                "failCommands": [
+                  "insert"
+                ],
+                "writeConcernError": {
+                  "code": 91,
+                  "errmsg": "Replication is being shut down"
+                }
+              }
+            }
+          }
+        },
+        {
+          "name": "insertOne",
+          "object": "collection0",
+          "arguments": {
+            "document": {
+              "_id": 3,
+              "x": 33
+            }
+          },
+          "expectError": {
+            "errorLabelsContain": [
+              "RetryableWriteError"
+            ]
+          }
+        }
+      ],
+      "outcome": [
+        {
+          "collectionName": "coll",
+          "databaseName": "retryable-writes-tests",
+          "documents": [
+            {
+              "_id": 1,
+              "x": 11
+            },
+            {
+              "_id": 2,
+              "x": 22
+            },
+            {
+              "_id": 3,
+              "x": 33
+            }
+          ]
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/valid-pass/poc-sessions.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/valid-pass/poc-sessions.json
new file mode 100644
index 0000000000000000000000000000000000000000..75f3489428680ebca9c0a8f5cf2afa08046c9fb2
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/valid-pass/poc-sessions.json	
@@ -0,0 +1,466 @@
+{
+  "description": "poc-sessions",
+  "schemaVersion": "1.0",
+  "runOnRequirements": [
+    {
+      "minServerVersion": "3.6.0"
+    }
+  ],
+  "createEntities": [
+    {
+      "client": {
+        "id": "client0",
+        "useMultipleMongoses": false,
+        "observeEvents": [
+          "commandStartedEvent"
+        ]
+      }
+    },
+    {
+      "database": {
+        "id": "database0",
+        "client": "client0",
+        "databaseName": "session-tests"
+      }
+    },
+    {
+      "collection": {
+        "id": "collection0",
+        "database": "database0",
+        "collectionName": "test"
+      }
+    },
+    {
+      "session": {
+        "id": "session0",
+        "client": "client0"
+      }
+    }
+  ],
+  "initialData": [
+    {
+      "collectionName": "test",
+      "databaseName": "session-tests",
+      "documents": [
+        {
+          "_id": 1
+        }
+      ]
+    }
+  ],
+  "tests": [
+    {
+      "description": "Server supports explicit sessions",
+      "operations": [
+        {
+          "name": "assertSessionNotDirty",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0"
+          }
+        },
+        {
+          "name": "insertOne",
+          "object": "collection0",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 2
+            }
+          },
+          "expectResult": {
+            "$$unsetOrMatches": {
+              "insertedId": {
+                "$$unsetOrMatches": 2
+              }
+            }
+          }
+        },
+        {
+          "name": "assertSessionNotDirty",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0"
+          }
+        },
+        {
+          "name": "endSession",
+          "object": "session0"
+        },
+        {
+          "name": "find",
+          "object": "collection0",
+          "arguments": {
+            "filter": {
+              "_id": -1
+            }
+          },
+          "expectResult": []
+        },
+        {
+          "name": "assertSameLsidOnLastTwoCommands",
+          "object": "testRunner",
+          "arguments": {
+            "client": "client0"
+          }
+        }
+      ],
+      "expectEvents": [
+        {
+          "client": "client0",
+          "events": [
+            {
+              "commandStartedEvent": {
+                "command": {
+                  "insert": "test",
+                  "documents": [
+                    {
+                      "_id": 2
+                    }
+                  ],
+                  "ordered": true,
+                  "lsid": {
+                    "$$sessionLsid": "session0"
+                  }
+                },
+                "commandName": "insert",
+                "databaseName": "session-tests"
+              }
+            },
+            {
+              "commandStartedEvent": {
+                "command": {
+                  "find": "test",
+                  "filter": {
+                    "_id": -1
+                  },
+                  "lsid": {
+                    "$$sessionLsid": "session0"
+                  }
+                },
+                "commandName": "find",
+                "databaseName": "session-tests"
+              }
+            }
+          ]
+        }
+      ],
+      "outcome": [
+        {
+          "collectionName": "test",
+          "databaseName": "session-tests",
+          "documents": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            }
+          ]
+        }
+      ]
+    },
+    {
+      "description": "Server supports implicit sessions",
+      "operations": [
+        {
+          "name": "insertOne",
+          "object": "collection0",
+          "arguments": {
+            "document": {
+              "_id": 2
+            }
+          },
+          "expectResult": {
+            "$$unsetOrMatches": {
+              "insertedId": {
+                "$$unsetOrMatches": 2
+              }
+            }
+          }
+        },
+        {
+          "name": "find",
+          "object": "collection0",
+          "arguments": {
+            "filter": {
+              "_id": -1
+            }
+          },
+          "expectResult": []
+        },
+        {
+          "name": "assertSameLsidOnLastTwoCommands",
+          "object": "testRunner",
+          "arguments": {
+            "client": "client0"
+          }
+        }
+      ],
+      "expectEvents": [
+        {
+          "client": "client0",
+          "events": [
+            {
+              "commandStartedEvent": {
+                "command": {
+                  "insert": "test",
+                  "documents": [
+                    {
+                      "_id": 2
+                    }
+                  ],
+                  "ordered": true,
+                  "lsid": {
+                    "$$type": "object"
+                  }
+                },
+                "commandName": "insert",
+                "databaseName": "session-tests"
+              }
+            },
+            {
+              "commandStartedEvent": {
+                "command": {
+                  "find": "test",
+                  "filter": {
+                    "_id": -1
+                  },
+                  "lsid": {
+                    "$$type": "object"
+                  }
+                },
+                "commandName": "find",
+                "databaseName": "session-tests"
+              }
+            }
+          ]
+        }
+      ],
+      "outcome": [
+        {
+          "collectionName": "test",
+          "databaseName": "session-tests",
+          "documents": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            }
+          ]
+        }
+      ]
+    },
+    {
+      "description": "Dirty explicit session is discarded",
+      "runOnRequirements": [
+        {
+          "minServerVersion": "4.0",
+          "topologies": [
+            "replicaset"
+          ]
+        },
+        {
+          "minServerVersion": "4.1.8",
+          "topologies": [
+            "sharded-replicaset"
+          ]
+        }
+      ],
+      "operations": [
+        {
+          "name": "failPoint",
+          "object": "testRunner",
+          "arguments": {
+            "client": "client0",
+            "failPoint": {
+              "configureFailPoint": "failCommand",
+              "mode": {
+                "times": 1
+              },
+              "data": {
+                "failCommands": [
+                  "insert"
+                ],
+                "closeConnection": true
+              }
+            }
+          }
+        },
+        {
+          "name": "assertSessionNotDirty",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0"
+          }
+        },
+        {
+          "name": "insertOne",
+          "object": "collection0",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 2
+            }
+          },
+          "expectResult": {
+            "$$unsetOrMatches": {
+              "insertedId": {
+                "$$unsetOrMatches": 2
+              }
+            }
+          }
+        },
+        {
+          "name": "assertSessionDirty",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0"
+          }
+        },
+        {
+          "name": "insertOne",
+          "object": "collection0",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 3
+            }
+          },
+          "expectResult": {
+            "$$unsetOrMatches": {
+              "insertedId": {
+                "$$unsetOrMatches": 3
+              }
+            }
+          }
+        },
+        {
+          "name": "assertSessionDirty",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0"
+          }
+        },
+        {
+          "name": "endSession",
+          "object": "session0"
+        },
+        {
+          "name": "find",
+          "object": "collection0",
+          "arguments": {
+            "filter": {
+              "_id": -1
+            }
+          },
+          "expectResult": []
+        },
+        {
+          "name": "assertDifferentLsidOnLastTwoCommands",
+          "object": "testRunner",
+          "arguments": {
+            "client": "client0"
+          }
+        }
+      ],
+      "expectEvents": [
+        {
+          "client": "client0",
+          "events": [
+            {
+              "commandStartedEvent": {
+                "command": {
+                  "insert": "test",
+                  "documents": [
+                    {
+                      "_id": 2
+                    }
+                  ],
+                  "ordered": true,
+                  "lsid": {
+                    "$$sessionLsid": "session0"
+                  },
+                  "txnNumber": 1
+                },
+                "commandName": "insert",
+                "databaseName": "session-tests"
+              }
+            },
+            {
+              "commandStartedEvent": {
+                "command": {
+                  "insert": "test",
+                  "documents": [
+                    {
+                      "_id": 2
+                    }
+                  ],
+                  "ordered": true,
+                  "lsid": {
+                    "$$sessionLsid": "session0"
+                  },
+                  "txnNumber": 1
+                },
+                "commandName": "insert",
+                "databaseName": "session-tests"
+              }
+            },
+            {
+              "commandStartedEvent": {
+                "command": {
+                  "insert": "test",
+                  "documents": [
+                    {
+                      "_id": 3
+                    }
+                  ],
+                  "ordered": true,
+                  "lsid": {
+                    "$$sessionLsid": "session0"
+                  },
+                  "txnNumber": 2
+                },
+                "commandName": "insert",
+                "databaseName": "session-tests"
+              }
+            },
+            {
+              "commandStartedEvent": {
+                "command": {
+                  "find": "test",
+                  "filter": {
+                    "_id": -1
+                  },
+                  "lsid": {
+                    "$$type": "object"
+                  }
+                },
+                "commandName": "find",
+                "databaseName": "session-tests"
+              }
+            }
+          ]
+        }
+      ],
+      "outcome": [
+        {
+          "collectionName": "test",
+          "databaseName": "session-tests",
+          "documents": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            },
+            {
+              "_id": 3
+            }
+          ]
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/valid-pass/poc-transactions-convenient-api.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/valid-pass/poc-transactions-convenient-api.json
new file mode 100644
index 0000000000000000000000000000000000000000..820ed659276acf39cf660ad0fd6f003ddb7a1417
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/valid-pass/poc-transactions-convenient-api.json	
@@ -0,0 +1,505 @@
+{
+  "description": "poc-transactions-convenient-api",
+  "schemaVersion": "1.0",
+  "runOnRequirements": [
+    {
+      "minServerVersion": "4.0",
+      "topologies": [
+        "replicaset"
+      ]
+    },
+    {
+      "minServerVersion": "4.1.8",
+      "topologies": [
+        "sharded-replicaset"
+      ]
+    }
+  ],
+  "createEntities": [
+    {
+      "client": {
+        "id": "client0",
+        "useMultipleMongoses": true,
+        "observeEvents": [
+          "commandStartedEvent"
+        ]
+      }
+    },
+    {
+      "client": {
+        "id": "client1",
+        "uriOptions": {
+          "readConcernLevel": "local",
+          "w": 1
+        },
+        "useMultipleMongoses": true,
+        "observeEvents": [
+          "commandStartedEvent"
+        ]
+      }
+    },
+    {
+      "database": {
+        "id": "database0",
+        "client": "client0",
+        "databaseName": "transaction-tests"
+      }
+    },
+    {
+      "database": {
+        "id": "database1",
+        "client": "client1",
+        "databaseName": "transaction-tests"
+      }
+    },
+    {
+      "collection": {
+        "id": "collection0",
+        "database": "database0",
+        "collectionName": "test"
+      }
+    },
+    {
+      "collection": {
+        "id": "collection1",
+        "database": "database1",
+        "collectionName": "test"
+      }
+    },
+    {
+      "session": {
+        "id": "session0",
+        "client": "client0"
+      }
+    },
+    {
+      "session": {
+        "id": "session1",
+        "client": "client1"
+      }
+    },
+    {
+      "session": {
+        "id": "session2",
+        "client": "client0",
+        "sessionOptions": {
+          "defaultTransactionOptions": {
+            "readConcern": {
+              "level": "majority"
+            },
+            "writeConcern": {
+              "w": 1
+            }
+          }
+        }
+      }
+    }
+  ],
+  "initialData": [
+    {
+      "collectionName": "test",
+      "databaseName": "transaction-tests",
+      "documents": []
+    }
+  ],
+  "tests": [
+    {
+      "description": "withTransaction and no transaction options set",
+      "operations": [
+        {
+          "name": "withTransaction",
+          "object": "session0",
+          "arguments": {
+            "callback": [
+              {
+                "name": "insertOne",
+                "object": "collection0",
+                "arguments": {
+                  "session": "session0",
+                  "document": {
+                    "_id": 1
+                  }
+                },
+                "expectResult": {
+                  "$$unsetOrMatches": {
+                    "insertedId": {
+                      "$$unsetOrMatches": 1
+                    }
+                  }
+                }
+              }
+            ]
+          }
+        }
+      ],
+      "expectEvents": [
+        {
+          "client": "client0",
+          "events": [
+            {
+              "commandStartedEvent": {
+                "command": {
+                  "insert": "test",
+                  "documents": [
+                    {
+                      "_id": 1
+                    }
+                  ],
+                  "ordered": true,
+                  "lsid": {
+                    "$$sessionLsid": "session0"
+                  },
+                  "txnNumber": 1,
+                  "startTransaction": true,
+                  "autocommit": false,
+                  "readConcern": {
+                    "$$exists": false
+                  },
+                  "writeConcern": {
+                    "$$exists": false
+                  }
+                },
+                "commandName": "insert",
+                "databaseName": "transaction-tests"
+              }
+            },
+            {
+              "commandStartedEvent": {
+                "command": {
+                  "commitTransaction": 1,
+                  "lsid": {
+                    "$$sessionLsid": "session0"
+                  },
+                  "txnNumber": 1,
+                  "autocommit": false,
+                  "readConcern": {
+                    "$$exists": false
+                  },
+                  "startTransaction": {
+                    "$$exists": false
+                  },
+                  "writeConcern": {
+                    "$$exists": false
+                  }
+                },
+                "commandName": "commitTransaction",
+                "databaseName": "admin"
+              }
+            }
+          ]
+        }
+      ],
+      "outcome": [
+        {
+          "collectionName": "test",
+          "databaseName": "transaction-tests",
+          "documents": [
+            {
+              "_id": 1
+            }
+          ]
+        }
+      ]
+    },
+    {
+      "description": "withTransaction inherits transaction options from client",
+      "operations": [
+        {
+          "name": "withTransaction",
+          "object": "session1",
+          "arguments": {
+            "callback": [
+              {
+                "name": "insertOne",
+                "object": "collection1",
+                "arguments": {
+                  "session": "session1",
+                  "document": {
+                    "_id": 1
+                  }
+                },
+                "expectResult": {
+                  "$$unsetOrMatches": {
+                    "insertedId": {
+                      "$$unsetOrMatches": 1
+                    }
+                  }
+                }
+              }
+            ]
+          }
+        }
+      ],
+      "expectEvents": [
+        {
+          "client": "client1",
+          "events": [
+            {
+              "commandStartedEvent": {
+                "command": {
+                  "insert": "test",
+                  "documents": [
+                    {
+                      "_id": 1
+                    }
+                  ],
+                  "ordered": true,
+                  "lsid": {
+                    "$$sessionLsid": "session1"
+                  },
+                  "txnNumber": 1,
+                  "startTransaction": true,
+                  "autocommit": false,
+                  "readConcern": {
+                    "level": "local"
+                  },
+                  "writeConcern": {
+                    "$$exists": false
+                  }
+                },
+                "commandName": "insert",
+                "databaseName": "transaction-tests"
+              }
+            },
+            {
+              "commandStartedEvent": {
+                "command": {
+                  "commitTransaction": 1,
+                  "lsid": {
+                    "$$sessionLsid": "session1"
+                  },
+                  "txnNumber": 1,
+                  "autocommit": false,
+                  "writeConcern": {
+                    "w": 1
+                  },
+                  "readConcern": {
+                    "$$exists": false
+                  },
+                  "startTransaction": {
+                    "$$exists": false
+                  }
+                },
+                "commandName": "commitTransaction",
+                "databaseName": "admin"
+              }
+            }
+          ]
+        }
+      ],
+      "outcome": [
+        {
+          "collectionName": "test",
+          "databaseName": "transaction-tests",
+          "documents": [
+            {
+              "_id": 1
+            }
+          ]
+        }
+      ]
+    },
+    {
+      "description": "withTransaction inherits transaction options from defaultTransactionOptions",
+      "operations": [
+        {
+          "name": "withTransaction",
+          "object": "session2",
+          "arguments": {
+            "callback": [
+              {
+                "name": "insertOne",
+                "object": "collection0",
+                "arguments": {
+                  "session": "session2",
+                  "document": {
+                    "_id": 1
+                  }
+                },
+                "expectResult": {
+                  "$$unsetOrMatches": {
+                    "insertedId": {
+                      "$$unsetOrMatches": 1
+                    }
+                  }
+                }
+              }
+            ]
+          }
+        }
+      ],
+      "expectEvents": [
+        {
+          "client": "client0",
+          "events": [
+            {
+              "commandStartedEvent": {
+                "command": {
+                  "insert": "test",
+                  "documents": [
+                    {
+                      "_id": 1
+                    }
+                  ],
+                  "ordered": true,
+                  "lsid": {
+                    "$$sessionLsid": "session2"
+                  },
+                  "txnNumber": 1,
+                  "startTransaction": true,
+                  "autocommit": false,
+                  "readConcern": {
+                    "level": "majority"
+                  },
+                  "writeConcern": {
+                    "$$exists": false
+                  }
+                },
+                "commandName": "insert",
+                "databaseName": "transaction-tests"
+              }
+            },
+            {
+              "commandStartedEvent": {
+                "command": {
+                  "commitTransaction": 1,
+                  "lsid": {
+                    "$$sessionLsid": "session2"
+                  },
+                  "txnNumber": 1,
+                  "autocommit": false,
+                  "writeConcern": {
+                    "w": 1
+                  },
+                  "readConcern": {
+                    "$$exists": false
+                  },
+                  "startTransaction": {
+                    "$$exists": false
+                  }
+                },
+                "commandName": "commitTransaction",
+                "databaseName": "admin"
+              }
+            }
+          ]
+        }
+      ],
+      "outcome": [
+        {
+          "collectionName": "test",
+          "databaseName": "transaction-tests",
+          "documents": [
+            {
+              "_id": 1
+            }
+          ]
+        }
+      ]
+    },
+    {
+      "description": "withTransaction explicit transaction options",
+      "operations": [
+        {
+          "name": "withTransaction",
+          "object": "session0",
+          "arguments": {
+            "callback": [
+              {
+                "name": "insertOne",
+                "object": "collection0",
+                "arguments": {
+                  "session": "session0",
+                  "document": {
+                    "_id": 1
+                  }
+                },
+                "expectResult": {
+                  "$$unsetOrMatches": {
+                    "insertedId": {
+                      "$$unsetOrMatches": 1
+                    }
+                  }
+                }
+              }
+            ],
+            "readConcern": {
+              "level": "majority"
+            },
+            "writeConcern": {
+              "w": 1
+            }
+          }
+        }
+      ],
+      "expectEvents": [
+        {
+          "client": "client0",
+          "events": [
+            {
+              "commandStartedEvent": {
+                "command": {
+                  "insert": "test",
+                  "documents": [
+                    {
+                      "_id": 1
+                    }
+                  ],
+                  "ordered": true,
+                  "lsid": {
+                    "$$sessionLsid": "session0"
+                  },
+                  "txnNumber": 1,
+                  "startTransaction": true,
+                  "autocommit": false,
+                  "readConcern": {
+                    "level": "majority"
+                  },
+                  "writeConcern": {
+                    "$$exists": false
+                  }
+                },
+                "commandName": "insert",
+                "databaseName": "transaction-tests"
+              }
+            },
+            {
+              "commandStartedEvent": {
+                "command": {
+                  "commitTransaction": 1,
+                  "lsid": {
+                    "$$sessionLsid": "session0"
+                  },
+                  "txnNumber": 1,
+                  "autocommit": false,
+                  "writeConcern": {
+                    "w": 1
+                  },
+                  "readConcern": {
+                    "$$exists": false
+                  },
+                  "startTransaction": {
+                    "$$exists": false
+                  }
+                },
+                "commandName": "commitTransaction",
+                "databaseName": "admin"
+              }
+            }
+          ]
+        }
+      ],
+      "outcome": [
+        {
+          "collectionName": "test",
+          "databaseName": "transaction-tests",
+          "documents": [
+            {
+              "_id": 1
+            }
+          ]
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/valid-pass/poc-transactions-mongos-pin-auto.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/valid-pass/poc-transactions-mongos-pin-auto.json
new file mode 100644
index 0000000000000000000000000000000000000000..a0b297d59a56a0a9f496184be70b884618296990
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/valid-pass/poc-transactions-mongos-pin-auto.json	
@@ -0,0 +1,409 @@
+{
+  "description": "poc-transactions-mongos-pin-auto",
+  "schemaVersion": "1.0",
+  "runOnRequirements": [
+    {
+      "minServerVersion": "4.1.8",
+      "topologies": [
+        "sharded-replicaset"
+      ]
+    }
+  ],
+  "createEntities": [
+    {
+      "client": {
+        "id": "client0",
+        "useMultipleMongoses": true,
+        "observeEvents": [
+          "commandStartedEvent"
+        ]
+      }
+    },
+    {
+      "database": {
+        "id": "database0",
+        "client": "client0",
+        "databaseName": "transaction-tests"
+      }
+    },
+    {
+      "collection": {
+        "id": "collection0",
+        "database": "database0",
+        "collectionName": "test"
+      }
+    },
+    {
+      "session": {
+        "id": "session0",
+        "client": "client0"
+      }
+    }
+  ],
+  "initialData": [
+    {
+      "collectionName": "test",
+      "databaseName": "transaction-tests",
+      "documents": [
+        {
+          "_id": 1
+        },
+        {
+          "_id": 2
+        }
+      ]
+    }
+  ],
+  "tests": [
+    {
+      "description": "remain pinned after non-transient Interrupted error on insertOne",
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection0",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 3
+            }
+          },
+          "expectResult": {
+            "$$unsetOrMatches": {
+              "insertedId": {
+                "$$unsetOrMatches": 3
+              }
+            }
+          }
+        },
+        {
+          "name": "targetedFailPoint",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0",
+            "failPoint": {
+              "configureFailPoint": "failCommand",
+              "mode": {
+                "times": 1
+              },
+              "data": {
+                "failCommands": [
+                  "insert"
+                ],
+                "errorCode": 11601
+              }
+            }
+          }
+        },
+        {
+          "name": "insertOne",
+          "object": "collection0",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 4
+            }
+          },
+          "expectError": {
+            "errorLabelsOmit": [
+              "TransientTransactionError",
+              "UnknownTransactionCommitResult"
+            ],
+            "errorCodeName": "Interrupted"
+          }
+        },
+        {
+          "name": "assertSessionPinned",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0"
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectEvents": [
+        {
+          "client": "client0",
+          "events": [
+            {
+              "commandStartedEvent": {
+                "command": {
+                  "insert": "test",
+                  "documents": [
+                    {
+                      "_id": 3
+                    }
+                  ],
+                  "ordered": true,
+                  "readConcern": {
+                    "$$exists": false
+                  },
+                  "lsid": {
+                    "$$sessionLsid": "session0"
+                  },
+                  "txnNumber": 1,
+                  "startTransaction": true,
+                  "autocommit": false,
+                  "writeConcern": {
+                    "$$exists": false
+                  }
+                },
+                "commandName": "insert",
+                "databaseName": "transaction-tests"
+              }
+            },
+            {
+              "commandStartedEvent": {
+                "command": {
+                  "insert": "test",
+                  "documents": [
+                    {
+                      "_id": 4
+                    }
+                  ],
+                  "ordered": true,
+                  "readConcern": {
+                    "$$exists": false
+                  },
+                  "lsid": {
+                    "$$sessionLsid": "session0"
+                  },
+                  "txnNumber": 1,
+                  "startTransaction": {
+                    "$$exists": false
+                  },
+                  "autocommit": false,
+                  "writeConcern": {
+                    "$$exists": false
+                  }
+                },
+                "commandName": "insert",
+                "databaseName": "transaction-tests"
+              }
+            },
+            {
+              "commandStartedEvent": {
+                "command": {
+                  "commitTransaction": 1,
+                  "lsid": {
+                    "$$sessionLsid": "session0"
+                  },
+                  "txnNumber": 1,
+                  "startTransaction": {
+                    "$$exists": false
+                  },
+                  "autocommit": false,
+                  "writeConcern": {
+                    "$$exists": false
+                  },
+                  "recoveryToken": {
+                    "$$type": "object"
+                  }
+                },
+                "commandName": "commitTransaction",
+                "databaseName": "admin"
+              }
+            }
+          ]
+        }
+      ],
+      "outcome": [
+        {
+          "collectionName": "test",
+          "databaseName": "transaction-tests",
+          "documents": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            },
+            {
+              "_id": 3
+            }
+          ]
+        }
+      ]
+    },
+    {
+      "description": "unpin after transient error within a transaction",
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection0",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 3
+            }
+          },
+          "expectResult": {
+            "$$unsetOrMatches": {
+              "insertedId": {
+                "$$unsetOrMatches": 3
+              }
+            }
+          }
+        },
+        {
+          "name": "targetedFailPoint",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0",
+            "failPoint": {
+              "configureFailPoint": "failCommand",
+              "mode": {
+                "times": 1
+              },
+              "data": {
+                "failCommands": [
+                  "insert"
+                ],
+                "closeConnection": true
+              }
+            }
+          }
+        },
+        {
+          "name": "insertOne",
+          "object": "collection0",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": 4
+            }
+          },
+          "expectError": {
+            "errorLabelsContain": [
+              "TransientTransactionError"
+            ],
+            "errorLabelsOmit": [
+              "UnknownTransactionCommitResult"
+            ]
+          }
+        },
+        {
+          "name": "assertSessionUnpinned",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0"
+          }
+        },
+        {
+          "name": "abortTransaction",
+          "object": "session0"
+        }
+      ],
+      "expectEvents": [
+        {
+          "client": "client0",
+          "events": [
+            {
+              "commandStartedEvent": {
+                "command": {
+                  "insert": "test",
+                  "documents": [
+                    {
+                      "_id": 3
+                    }
+                  ],
+                  "ordered": true,
+                  "readConcern": {
+                    "$$exists": false
+                  },
+                  "lsid": {
+                    "$$sessionLsid": "session0"
+                  },
+                  "txnNumber": 1,
+                  "startTransaction": true,
+                  "autocommit": false,
+                  "writeConcern": {
+                    "$$exists": false
+                  }
+                },
+                "commandName": "insert",
+                "databaseName": "transaction-tests"
+              }
+            },
+            {
+              "commandStartedEvent": {
+                "command": {
+                  "insert": "test",
+                  "documents": [
+                    {
+                      "_id": 4
+                    }
+                  ],
+                  "ordered": true,
+                  "readConcern": {
+                    "$$exists": false
+                  },
+                  "lsid": {
+                    "$$sessionLsid": "session0"
+                  },
+                  "txnNumber": 1,
+                  "startTransaction": {
+                    "$$exists": false
+                  },
+                  "autocommit": false,
+                  "writeConcern": {
+                    "$$exists": false
+                  }
+                },
+                "commandName": "insert",
+                "databaseName": "transaction-tests"
+              }
+            },
+            {
+              "commandStartedEvent": {
+                "command": {
+                  "abortTransaction": 1,
+                  "lsid": {
+                    "$$sessionLsid": "session0"
+                  },
+                  "txnNumber": 1,
+                  "startTransaction": {
+                    "$$exists": false
+                  },
+                  "autocommit": false,
+                  "writeConcern": {
+                    "$$exists": false
+                  },
+                  "recoveryToken": {
+                    "$$type": "object"
+                  }
+                },
+                "commandName": "abortTransaction",
+                "databaseName": "admin"
+              }
+            }
+          ]
+        }
+      ],
+      "outcome": [
+        {
+          "collectionName": "test",
+          "databaseName": "transaction-tests",
+          "documents": [
+            {
+              "_id": 1
+            },
+            {
+              "_id": 2
+            }
+          ]
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/valid-pass/poc-transactions.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/valid-pass/poc-transactions.json
new file mode 100644
index 0000000000000000000000000000000000000000..62528f9ce1a9935b440632211359b2850ef02575
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/UnifiedSpecTests/valid-pass/poc-transactions.json	
@@ -0,0 +1,322 @@
+{
+  "description": "poc-transactions",
+  "schemaVersion": "1.0",
+  "runOnRequirements": [
+    {
+      "minServerVersion": "4.0",
+      "topologies": [
+        "replicaset"
+      ]
+    },
+    {
+      "minServerVersion": "4.1.8",
+      "topologies": [
+        "sharded-replicaset"
+      ]
+    }
+  ],
+  "createEntities": [
+    {
+      "client": {
+        "id": "client0",
+        "observeEvents": [
+          "commandStartedEvent"
+        ]
+      }
+    },
+    {
+      "database": {
+        "id": "database0",
+        "client": "client0",
+        "databaseName": "transaction-tests"
+      }
+    },
+    {
+      "collection": {
+        "id": "collection0",
+        "database": "database0",
+        "collectionName": "test"
+      }
+    },
+    {
+      "session": {
+        "id": "session0",
+        "client": "client0"
+      }
+    }
+  ],
+  "initialData": [
+    {
+      "collectionName": "test",
+      "databaseName": "transaction-tests",
+      "documents": []
+    }
+  ],
+  "tests": [
+    {
+      "description": "Client side error in command starting transaction",
+      "operations": [
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "insertOne",
+          "object": "collection0",
+          "arguments": {
+            "session": "session0",
+            "document": {
+              "_id": {
+                ".": "."
+              }
+            }
+          },
+          "expectError": {
+            "isClientError": true
+          }
+        },
+        {
+          "name": "assertSessionTransactionState",
+          "object": "testRunner",
+          "arguments": {
+            "session": "session0",
+            "state": "starting"
+          }
+        }
+      ]
+    },
+    {
+      "description": "explicitly create collection using create command",
+      "runOnRequirements": [
+        {
+          "minServerVersion": "4.3.4",
+          "topologies": [
+            "replicaset",
+            "sharded-replicaset"
+          ]
+        }
+      ],
+      "operations": [
+        {
+          "name": "dropCollection",
+          "object": "database0",
+          "arguments": {
+            "collection": "test"
+          }
+        },
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "createCollection",
+          "object": "database0",
+          "arguments": {
+            "session": "session0",
+            "collection": "test"
+          }
+        },
+        {
+          "name": "assertCollectionNotExists",
+          "object": "testRunner",
+          "arguments": {
+            "databaseName": "transaction-tests",
+            "collectionName": "test"
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "assertCollectionExists",
+          "object": "testRunner",
+          "arguments": {
+            "databaseName": "transaction-tests",
+            "collectionName": "test"
+          }
+        }
+      ],
+      "expectEvents": [
+        {
+          "client": "client0",
+          "events": [
+            {
+              "commandStartedEvent": {
+                "command": {
+                  "drop": "test",
+                  "writeConcern": {
+                    "$$exists": false
+                  }
+                },
+                "commandName": "drop",
+                "databaseName": "transaction-tests"
+              }
+            },
+            {
+              "commandStartedEvent": {
+                "command": {
+                  "create": "test",
+                  "lsid": {
+                    "$$sessionLsid": "session0"
+                  },
+                  "txnNumber": 1,
+                  "startTransaction": true,
+                  "autocommit": false,
+                  "writeConcern": {
+                    "$$exists": false
+                  }
+                },
+                "commandName": "create",
+                "databaseName": "transaction-tests"
+              }
+            },
+            {
+              "commandStartedEvent": {
+                "command": {
+                  "commitTransaction": 1,
+                  "lsid": {
+                    "$$sessionLsid": "session0"
+                  },
+                  "txnNumber": 1,
+                  "startTransaction": {
+                    "$$exists": false
+                  },
+                  "autocommit": false,
+                  "writeConcern": {
+                    "$$exists": false
+                  }
+                },
+                "commandName": "commitTransaction",
+                "databaseName": "admin"
+              }
+            }
+          ]
+        }
+      ]
+    },
+    {
+      "description": "create index on a non-existing collection",
+      "runOnRequirements": [
+        {
+          "minServerVersion": "4.3.4",
+          "topologies": [
+            "replicaset",
+            "sharded-replicaset"
+          ]
+        }
+      ],
+      "operations": [
+        {
+          "name": "dropCollection",
+          "object": "database0",
+          "arguments": {
+            "collection": "test"
+          }
+        },
+        {
+          "name": "startTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "createIndex",
+          "object": "collection0",
+          "arguments": {
+            "session": "session0",
+            "name": "x_1",
+            "keys": {
+              "x": 1
+            }
+          }
+        },
+        {
+          "name": "assertIndexNotExists",
+          "object": "testRunner",
+          "arguments": {
+            "databaseName": "transaction-tests",
+            "collectionName": "test",
+            "indexName": "x_1"
+          }
+        },
+        {
+          "name": "commitTransaction",
+          "object": "session0"
+        },
+        {
+          "name": "assertIndexExists",
+          "object": "testRunner",
+          "arguments": {
+            "databaseName": "transaction-tests",
+            "collectionName": "test",
+            "indexName": "x_1"
+          }
+        }
+      ],
+      "expectEvents": [
+        {
+          "client": "client0",
+          "events": [
+            {
+              "commandStartedEvent": {
+                "command": {
+                  "drop": "test",
+                  "writeConcern": {
+                    "$$exists": false
+                  }
+                },
+                "commandName": "drop",
+                "databaseName": "transaction-tests"
+              }
+            },
+            {
+              "commandStartedEvent": {
+                "command": {
+                  "createIndexes": "test",
+                  "indexes": [
+                    {
+                      "name": "x_1",
+                      "key": {
+                        "x": 1
+                      }
+                    }
+                  ],
+                  "lsid": {
+                    "$$sessionLsid": "session0"
+                  },
+                  "txnNumber": 1,
+                  "startTransaction": true,
+                  "autocommit": false,
+                  "writeConcern": {
+                    "$$exists": false
+                  }
+                },
+                "commandName": "createIndexes",
+                "databaseName": "transaction-tests"
+              }
+            },
+            {
+              "commandStartedEvent": {
+                "command": {
+                  "commitTransaction": 1,
+                  "lsid": {
+                    "$$sessionLsid": "session0"
+                  },
+                  "txnNumber": 1,
+                  "startTransaction": {
+                    "$$exists": false
+                  },
+                  "autocommit": false,
+                  "writeConcern": {
+                    "$$exists": false
+                  }
+                },
+                "commandName": "commitTransaction",
+                "databaseName": "admin"
+              }
+            }
+          ]
+        }
+      ]
+    }
+  ]
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/bootstrap.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/bootstrap.php
new file mode 100644
index 0000000000000000000000000000000000000000..31649c7046fa5c0613b46d4183e3b6be3f94914e
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/mongodb/mongodb/tests/bootstrap.php	
@@ -0,0 +1,23 @@
+<?php
+
+if (file_exists(__DIR__ . '/../vendor/autoload.php')) {
+    // Dependencies were installed with Composer and this is the main project
+    $loader = require_once __DIR__ . '/../vendor/autoload.php';
+} elseif (file_exists(__DIR__ . '/../../../../autoload.php')) {
+    // We're installed as a dependency in another project's `vendor` directory
+    $loader = require_once __DIR__ . '/../../../../autoload.php';
+} else {
+    throw new Exception('Can\'t find autoload.php. Did you install dependencies with Composer?');
+}
+
+if (! class_exists(PHPUnit\Framework\Error\Warning::class)) {
+    class_alias(PHPUnit_Framework_Error_Warning::class, PHPUnit\Framework\Error\Warning::class);
+}
+
+if (! class_exists(PHPUnit\Framework\Constraint\Constraint::class)) {
+    class_alias(PHPUnit_Framework_Constraint::class, PHPUnit\Framework\Constraint\Constraint::class);
+}
+
+if (! class_exists(PHPUnit\Framework\ExpectationFailedException::class)) {
+    class_alias(PHPUnit_Framework_ExpectationFailedException::class, PHPUnit\Framework\ExpectationFailedException::class);
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/symfony/polyfill-php80/LICENSE b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/symfony/polyfill-php80/LICENSE
new file mode 100644
index 0000000000000000000000000000000000000000..5593b1d84f74a170e02b3e58408dc189ea838434
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/symfony/polyfill-php80/LICENSE	
@@ -0,0 +1,19 @@
+Copyright (c) 2020 Fabien Potencier
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/symfony/polyfill-php80/Php80.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/symfony/polyfill-php80/Php80.php
new file mode 100644
index 0000000000000000000000000000000000000000..5fef5118420d305d59bffc58c005bb97978d6c9e
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/symfony/polyfill-php80/Php80.php	
@@ -0,0 +1,105 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Polyfill\Php80;
+
+/**
+ * @author Ion Bazan <ion.bazan@gmail.com>
+ * @author Nico Oelgart <nicoswd@gmail.com>
+ * @author Nicolas Grekas <p@tchwork.com>
+ *
+ * @internal
+ */
+final class Php80
+{
+    public static function fdiv(float $dividend, float $divisor): float
+    {
+        return @($dividend / $divisor);
+    }
+
+    public static function get_debug_type($value): string
+    {
+        switch (true) {
+            case null === $value: return 'null';
+            case \is_bool($value): return 'bool';
+            case \is_string($value): return 'string';
+            case \is_array($value): return 'array';
+            case \is_int($value): return 'int';
+            case \is_float($value): return 'float';
+            case \is_object($value): break;
+            case $value instanceof \__PHP_Incomplete_Class: return '__PHP_Incomplete_Class';
+            default:
+                if (null === $type = @get_resource_type($value)) {
+                    return 'unknown';
+                }
+
+                if ('Unknown' === $type) {
+                    $type = 'closed';
+                }
+
+                return "resource ($type)";
+        }
+
+        $class = \get_class($value);
+
+        if (false === strpos($class, '@')) {
+            return $class;
+        }
+
+        return (get_parent_class($class) ?: key(class_implements($class)) ?: 'class').'@anonymous';
+    }
+
+    public static function get_resource_id($res): int
+    {
+        if (!\is_resource($res) && null === @get_resource_type($res)) {
+            throw new \TypeError(sprintf('Argument 1 passed to get_resource_id() must be of the type resource, %s given', get_debug_type($res)));
+        }
+
+        return (int) $res;
+    }
+
+    public static function preg_last_error_msg(): string
+    {
+        switch (preg_last_error()) {
+            case \PREG_INTERNAL_ERROR:
+                return 'Internal error';
+            case \PREG_BAD_UTF8_ERROR:
+                return 'Malformed UTF-8 characters, possibly incorrectly encoded';
+            case \PREG_BAD_UTF8_OFFSET_ERROR:
+                return 'The offset did not correspond to the beginning of a valid UTF-8 code point';
+            case \PREG_BACKTRACK_LIMIT_ERROR:
+                return 'Backtrack limit exhausted';
+            case \PREG_RECURSION_LIMIT_ERROR:
+                return 'Recursion limit exhausted';
+            case \PREG_JIT_STACKLIMIT_ERROR:
+                return 'JIT stack limit exhausted';
+            case \PREG_NO_ERROR:
+                return 'No error';
+            default:
+                return 'Unknown error';
+        }
+    }
+
+    public static function str_contains(string $haystack, string $needle): bool
+    {
+        return '' === $needle || false !== strpos($haystack, $needle);
+    }
+
+    public static function str_starts_with(string $haystack, string $needle): bool
+    {
+        return 0 === strncmp($haystack, $needle, \strlen($needle));
+    }
+
+    public static function str_ends_with(string $haystack, string $needle): bool
+    {
+        return '' === $needle || ('' !== $haystack && 0 === substr_compare($haystack, $needle, -\strlen($needle)));
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/symfony/polyfill-php80/README.md b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/symfony/polyfill-php80/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..eaa3050abc11f9852eed71f79dccaa3688f67854
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/symfony/polyfill-php80/README.md	
@@ -0,0 +1,24 @@
+Symfony Polyfill / Php80
+========================
+
+This component provides features added to PHP 8.0 core:
+
+- `Stringable` interface
+- [`fdiv`](https://php.net/fdiv)
+- `ValueError` class
+- `UnhandledMatchError` class
+- `FILTER_VALIDATE_BOOL` constant
+- [`get_debug_type`](https://php.net/get_debug_type)
+- [`preg_last_error_msg`](https://php.net/preg_last_error_msg)
+- [`str_contains`](https://php.net/str_contains)
+- [`str_starts_with`](https://php.net/str_starts_with)
+- [`str_ends_with`](https://php.net/str_ends_with)
+- [`get_resource_id`](https://php.net/get_resource_id)
+
+More information can be found in the
+[main Polyfill README](https://github.com/symfony/polyfill/blob/master/README.md).
+
+License
+=======
+
+This library is released under the [MIT license](LICENSE).
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/symfony/polyfill-php80/Resources/stubs/Attribute.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/symfony/polyfill-php80/Resources/stubs/Attribute.php
new file mode 100644
index 0000000000000000000000000000000000000000..7ea6d2772dcaa175ec17ec39b852553fd189b5cc
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/symfony/polyfill-php80/Resources/stubs/Attribute.php	
@@ -0,0 +1,22 @@
+<?php
+
+#[Attribute(Attribute::TARGET_CLASS)]
+final class Attribute
+{
+    public const TARGET_CLASS = 1;
+    public const TARGET_FUNCTION = 2;
+    public const TARGET_METHOD = 4;
+    public const TARGET_PROPERTY = 8;
+    public const TARGET_CLASS_CONSTANT = 16;
+    public const TARGET_PARAMETER = 32;
+    public const TARGET_ALL = 63;
+    public const IS_REPEATABLE = 64;
+
+    /** @var int */
+    public $flags;
+
+    public function __construct(int $flags = self::TARGET_ALL)
+    {
+        $this->flags = $flags;
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/symfony/polyfill-php80/Resources/stubs/Stringable.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/symfony/polyfill-php80/Resources/stubs/Stringable.php
new file mode 100644
index 0000000000000000000000000000000000000000..77e037cb58d5acc48e5eb675c337fc2acff1d3f3
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/symfony/polyfill-php80/Resources/stubs/Stringable.php	
@@ -0,0 +1,11 @@
+<?php
+
+if (\PHP_VERSION_ID < 80000) {
+    interface Stringable
+    {
+        /**
+         * @return string
+         */
+        public function __toString();
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php
new file mode 100644
index 0000000000000000000000000000000000000000..7fb2000e9e164de1e909cd366e9640a5a413eee8
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php	
@@ -0,0 +1,5 @@
+<?php
+
+class UnhandledMatchError extends Error
+{
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/symfony/polyfill-php80/Resources/stubs/ValueError.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/symfony/polyfill-php80/Resources/stubs/ValueError.php
new file mode 100644
index 0000000000000000000000000000000000000000..99843cad3353ce7e3e295fb452ed8307e86a1b57
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/symfony/polyfill-php80/Resources/stubs/ValueError.php	
@@ -0,0 +1,5 @@
+<?php
+
+class ValueError extends Error
+{
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/symfony/polyfill-php80/bootstrap.php b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/symfony/polyfill-php80/bootstrap.php
new file mode 100644
index 0000000000000000000000000000000000000000..4f791f9e3f022b8c78f7101ff08474704fa73826
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/symfony/polyfill-php80/bootstrap.php	
@@ -0,0 +1,42 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+use Symfony\Polyfill\Php80 as p;
+
+if (\PHP_VERSION_ID >= 80000) {
+    return;
+}
+
+if (!defined('FILTER_VALIDATE_BOOL') && defined('FILTER_VALIDATE_BOOLEAN')) {
+    define('FILTER_VALIDATE_BOOL', \FILTER_VALIDATE_BOOLEAN);
+}
+
+if (!function_exists('fdiv')) {
+    function fdiv(float $num1, float $num2): float { return p\Php80::fdiv($num1, $num2); }
+}
+if (!function_exists('preg_last_error_msg')) {
+    function preg_last_error_msg(): string { return p\Php80::preg_last_error_msg(); }
+}
+if (!function_exists('str_contains')) {
+    function str_contains(string $haystack, string $needle): bool { return p\Php80::str_contains($haystack, $needle); }
+}
+if (!function_exists('str_starts_with')) {
+    function str_starts_with(string $haystack, string $needle): bool { return p\Php80::str_starts_with($haystack, $needle); }
+}
+if (!function_exists('str_ends_with')) {
+    function str_ends_with(string $haystack, string $needle): bool { return p\Php80::str_ends_with($haystack, $needle); }
+}
+if (!function_exists('get_debug_type')) {
+    function get_debug_type($value): string { return p\Php80::get_debug_type($value); }
+}
+if (!function_exists('get_resource_id')) {
+    function get_resource_id($resource): int { return p\Php80::get_resource_id($resource); }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/symfony/polyfill-php80/composer.json b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/symfony/polyfill-php80/composer.json
new file mode 100644
index 0000000000000000000000000000000000000000..a9e6813c9706a4b82a79f9804e718ce22e340ab5
--- /dev/null
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/server/vendor/symfony/polyfill-php80/composer.json	
@@ -0,0 +1,40 @@
+{
+    "name": "symfony/polyfill-php80",
+    "type": "library",
+    "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions",
+    "keywords": ["polyfill", "shim", "compatibility", "portable"],
+    "homepage": "https://symfony.com",
+    "license": "MIT",
+    "authors": [
+        {
+            "name": "Ion Bazan",
+            "email": "ion.bazan@gmail.com"
+        },
+        {
+            "name": "Nicolas Grekas",
+            "email": "p@tchwork.com"
+        },
+        {
+            "name": "Symfony Community",
+            "homepage": "https://symfony.com/contributors"
+        }
+    ],
+    "require": {
+        "php": ">=7.1"
+    },
+    "autoload": {
+        "psr-4": { "Symfony\\Polyfill\\Php80\\": "" },
+        "files": [ "bootstrap.php" ],
+        "classmap": [ "Resources/stubs" ]
+    },
+    "minimum-stability": "dev",
+    "extra": {
+        "branch-alias": {
+            "dev-main": "1.22-dev"
+        },
+        "thanks": {
+            "name": "symfony/polyfill",
+            "url": "https://github.com/symfony/polyfill"
+        }
+    }
+}
diff --git a/NMP 3.0 Moodle Pluggin/fliplearning/styles.css b/NMP 3.0 Moodle Pluggin/fliplearning/styles.css
index 2784114a2aa9f0f6417b5a1c66eb8988a92873bd..549ba89d8585bb7218fb21a7f232521d45c3af54 100644
--- a/NMP 3.0 Moodle Pluggin/fliplearning/styles.css	
+++ b/NMP 3.0 Moodle Pluggin/fliplearning/styles.css	
@@ -1,4 +1,4 @@
-.color-white{ color: white !important; }
+.color-white{ color: white !important; }
 
 @font-face {
     font-family: poppins;