From db7e7f9828d3e00f4cf1a4c563d8a7927bc0b3a2 Mon Sep 17 00:00:00 2001
From: Andreas Braun <git@alcaeus.org>
Date: Fri, 22 Dec 2017 11:04:43 +0100
Subject: [PATCH 1/2] Drop commands to generate repository and entity stubs

---
 .../Command/GenerateDocumentsCommand.php      | 146 ------------------
 .../Command/GenerateRepositoriesCommand.php   |  90 -----------
 tools/sandbox/mongodb.php                     |   2 -
 3 files changed, 238 deletions(-)
 delete mode 100644 lib/Doctrine/ODM/MongoDB/Tools/Console/Command/GenerateDocumentsCommand.php
 delete mode 100644 lib/Doctrine/ODM/MongoDB/Tools/Console/Command/GenerateRepositoriesCommand.php

diff --git a/lib/Doctrine/ODM/MongoDB/Tools/Console/Command/GenerateDocumentsCommand.php b/lib/Doctrine/ODM/MongoDB/Tools/Console/Command/GenerateDocumentsCommand.php
deleted file mode 100644
index ed2aca0647..0000000000
--- a/lib/Doctrine/ODM/MongoDB/Tools/Console/Command/GenerateDocumentsCommand.php
+++ /dev/null
@@ -1,146 +0,0 @@
-<?php
-
-namespace Doctrine\ODM\MongoDB\Tools\Console\Command;
-
-use Symfony\Component\Console\Input\InputArgument;
-use Symfony\Component\Console\Input\InputOption;
-use Symfony\Component\Console;
-use Doctrine\ODM\MongoDB\Tools\Console\MetadataFilter;
-use Doctrine\ODM\MongoDB\Tools\DocumentGenerator;
-use Doctrine\ODM\MongoDB\Tools\DisconnectedClassMetadataFactory;
-
-/**
- * Command to generate document classes and method stubs from your mapping information.
- *
- * @since   1.0
- */
-class GenerateDocumentsCommand extends Console\Command\Command
-{
-    /**
-     * @see Console\Command\Command
-     */
-    protected function configure()
-    {
-        $this
-        ->setName('odm:generate:documents')
-        ->setDescription('Generate document classes and method stubs from your mapping information.')
-        ->setDefinition(array(
-            new InputOption(
-                'filter', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY,
-                'A string pattern used to match documents that should be processed.'
-            ),
-            new InputArgument(
-                'dest-path', InputArgument::REQUIRED, 'The path to generate your document classes.'
-            ),
-            new InputOption(
-                'generate-annotations', null, InputOption::VALUE_OPTIONAL,
-                'Flag to define if the generator should generate annotation metadata on documents.', false
-            ),
-            new InputOption(
-                'generate-methods', null, InputOption::VALUE_OPTIONAL,
-                'Flag to define if the generator should generate stub methods on documents.', true
-            ),
-            new InputOption(
-                'regenerate-documents', null, InputOption::VALUE_OPTIONAL,
-                'Flag to define if the generator should regenerate a document if it exists.', false
-            ),
-            new InputOption(
-                'update-documents', null, InputOption::VALUE_OPTIONAL,
-                'Flag to define if the generator should only update a document if it exists.', true
-            ),
-            new InputOption(
-                'extend', null, InputOption::VALUE_OPTIONAL,
-                'Defines a base class to be extended by generated document classes.'
-            ),
-            new InputOption(
-                'num-spaces', null, InputOption::VALUE_OPTIONAL,
-                'Defines the number of indentation spaces.', 4
-            ),
-            new InputOption(
-                'no-backup', null, InputOption::VALUE_NONE,
-                'Flag to define if the generator should provide a backup file of exisiting code.'
-            )
-        ))
-        ->setHelp(<<<EOT
-Generate document classes and method stubs from your mapping information.
-
-If you use the <comment>--update-documents</comment> or <comment>--regenerate-documents</comment> flags your exisiting
-code gets overwritten. The DocumentGenerator will only append new code to your
-file and will not delete the old code. However this approach may still be prone
-to error and we suggest you use code repositories such as GIT or SVN to make
-backups of your code.
-
-It makes sense to generate the document code if you are using documents as Data
-Access Objects only and dont put much additional logic on them. If you are
-however putting much more logic on the documents you should refrain from using
-the document-generator and code your documents manually.
-
-<error>Important:</error> Even if you specified Inheritance options in your
-XML or YAML Mapping files the generator cannot generate the base and
-child classes for you correctly, because it doesn't know which
-class is supposed to extend which. You have to adjust the document
-code manually for inheritance to work!
-EOT
-        );
-    }
-
-    /**
-     * @see Console\Command\Command
-     */
-    protected function execute(Console\Input\InputInterface $input, Console\Output\OutputInterface $output)
-    {
-        $dm = $this->getHelper('documentManager')->getDocumentManager();
-        
-        $cmf = new DisconnectedClassMetadataFactory();
-        $cmf->setDocumentManager($dm);
-        $cmf->setConfiguration($dm->getConfiguration());
-        $metadatas = $cmf->getAllMetadata();
-        $metadatas = MetadataFilter::filter($metadatas, $input->getOption('filter'));
-        
-        // Process destination directory
-        $destPath = realpath($input->getArgument('dest-path'));
-
-        if ( ! file_exists($destPath)) {
-            throw new \InvalidArgumentException(
-                sprintf("Documents destination directory '<info>%s</info>' does not exist.", $destPath)
-            );
-        } elseif ( ! is_writable($destPath)) {
-            throw new \InvalidArgumentException(
-                sprintf("Documents destination directory '<info>%s</info>' does not have write permissions.", $destPath)
-            );
-        }
-
-        if (count($metadatas)) {
-            // Create DocumentGenerator
-            $documentGenerator = new DocumentGenerator();
-
-            $documentGenerator->setGenerateAnnotations($input->getOption('generate-annotations'));
-            $documentGenerator->setGenerateStubMethods($input->getOption('generate-methods'));
-            $documentGenerator->setRegenerateDocumentIfExists($input->getOption('regenerate-documents'));
-            $documentGenerator->setUpdateDocumentIfExists($input->getOption('update-documents'));
-            $documentGenerator->setBackupExisting(!$input->getOption('no-backup'));
-            $documentGenerator->setNumSpaces($input->getOption('num-spaces'));
-
-            if (($extend = $input->getOption('extend')) !== null) {
-                $documentGenerator->setClassToExtend($extend);
-            }
-
-            foreach ($metadatas as $metadata) {
-                $output->writeln(
-                    sprintf('Processing document "<info>%s</info>".', $metadata->name)
-                );
-            }
-
-            // Generating Documents
-            $documentGenerator->generate($metadatas, $destPath);
-
-            // Outputting information message
-            $output->writeln(array(
-                '',
-                sprintf('Document classes have been generated to "<info>%s</info>".', $destPath)
-            ));
-        } else {
-            $output->writeln('No Metadata Classes to process.');
-        }
-    }
-}
diff --git a/lib/Doctrine/ODM/MongoDB/Tools/Console/Command/GenerateRepositoriesCommand.php b/lib/Doctrine/ODM/MongoDB/Tools/Console/Command/GenerateRepositoriesCommand.php
deleted file mode 100644
index 9b0298a489..0000000000
--- a/lib/Doctrine/ODM/MongoDB/Tools/Console/Command/GenerateRepositoriesCommand.php
+++ /dev/null
@@ -1,90 +0,0 @@
-<?php
-
-namespace Doctrine\ODM\MongoDB\Tools\Console\Command;
-
-use Symfony\Component\Console\Input\InputArgument;
-use Symfony\Component\Console\Input\InputOption;
-use Symfony\Component\Console;
-use Doctrine\ODM\MongoDB\Tools\Console\MetadataFilter;
-use Doctrine\ODM\MongoDB\Tools\DocumentRepositoryGenerator;
-
-/**
- * Command to generate repository classes for mapping information.
- *
- * @since   1.0
- */
-class GenerateRepositoriesCommand extends Console\Command\Command
-{
-    /**
-     * @see Console\Command\Command
-     */
-    protected function configure()
-    {
-        $this
-        ->setName('odm:generate:repositories')
-        ->setDescription('Generate repository classes from your mapping information.')
-        ->setDefinition(array(
-            new InputOption(
-                'filter', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY,
-                'A string pattern used to match documents that should be processed.'
-            ),
-            new InputArgument(
-                'dest-path', InputArgument::REQUIRED, 'The path to generate your repository classes.'
-            )
-        ))
-        ->setHelp(<<<EOT
-Generate repository classes from your mapping information.
-EOT
-        );
-    }
-
-    /**
-     * @see Console\Command\Command
-     */
-    protected function execute(Console\Input\InputInterface $input, Console\Output\OutputInterface $output)
-    {
-        $dm = $this->getHelper('documentManager')->getDocumentManager();
-        
-        $metadatas = $dm->getMetadataFactory()->getAllMetadata();
-        $metadatas = MetadataFilter::filter($metadatas, $input->getOption('filter'));
-
-        // Process destination directory
-        $destPath = realpath($input->getArgument('dest-path'));
-
-        if ( ! file_exists($destPath)) {
-            throw new \InvalidArgumentException(
-                sprintf("Documents destination directory '<info>%s</info>' does not exist.", $destPath)
-            );
-        } elseif ( ! is_writable($destPath)) {
-            throw new \InvalidArgumentException(
-                sprintf("Documents destination directory '<info>%s</info>' does not have write permissions.", $destPath)
-            );
-        }
-
-        if (count($metadatas)) {
-            $numRepositories = 0;
-            $generator = new DocumentRepositoryGenerator();
-
-            foreach ($metadatas as $metadata) {
-                if ($metadata->customRepositoryClassName) {
-                    $output->write(
-                        sprintf('Processing repository "<info>%s</info>"', $metadata->customRepositoryClassName) . PHP_EOL
-                    );
-
-                    $generator->writeDocumentRepositoryClass($metadata->customRepositoryClassName, $destPath);
-
-                    $numRepositories++;
-                }
-            }
-
-            if ($numRepositories) {
-                // Outputting information message
-                $output->write(PHP_EOL . sprintf('Repository classes generated to "<info>%s</INFO>"', $destPath) . PHP_EOL);
-            } else {
-                $output->write('No Repository classes were found to be processed.' . PHP_EOL);
-            }
-        } else {
-            $output->write('No Metadata Classes to process.' . PHP_EOL);
-        }
-    }
-}
diff --git a/tools/sandbox/mongodb.php b/tools/sandbox/mongodb.php
index 3ea1aba39f..0212e420a0 100644
--- a/tools/sandbox/mongodb.php
+++ b/tools/sandbox/mongodb.php
@@ -9,10 +9,8 @@
 }
 
 $app->addCommands(array(
-    new \Doctrine\ODM\MongoDB\Tools\Console\Command\GenerateDocumentsCommand(),
     new \Doctrine\ODM\MongoDB\Tools\Console\Command\GenerateHydratorsCommand(),
     new \Doctrine\ODM\MongoDB\Tools\Console\Command\GenerateProxiesCommand(),
-    new \Doctrine\ODM\MongoDB\Tools\Console\Command\GenerateRepositoriesCommand(),
     new \Doctrine\ODM\MongoDB\Tools\Console\Command\QueryCommand(),
     new \Doctrine\ODM\MongoDB\Tools\Console\Command\ClearCache\MetadataCommand(),
     new \Doctrine\ODM\MongoDB\Tools\Console\Command\Schema\CreateCommand(),

From cd90c5477c9df86a1d52d2e39b890957993a18fe Mon Sep 17 00:00:00 2001
From: Andreas Braun <git@alcaeus.org>
Date: Sun, 24 Dec 2017 12:56:50 +0100
Subject: [PATCH 2/2] Drop document and repository class generators

---
 .../DisconnectedClassMetadataFactory.php      |   47 -
 .../ODM/MongoDB/Tools/DocumentGenerator.php   | 1003 -----------------
 .../Tools/DocumentRepositoryGenerator.php     |   67 --
 .../Tests/Tools/DocumentGeneratorTest.php     |  300 -----
 .../Tools/DocumentRepositoryGeneratorTest.php |  106 --
 5 files changed, 1523 deletions(-)
 delete mode 100644 lib/Doctrine/ODM/MongoDB/Tools/DisconnectedClassMetadataFactory.php
 delete mode 100644 lib/Doctrine/ODM/MongoDB/Tools/DocumentGenerator.php
 delete mode 100644 lib/Doctrine/ODM/MongoDB/Tools/DocumentRepositoryGenerator.php
 delete mode 100644 tests/Doctrine/ODM/MongoDB/Tests/Tools/DocumentGeneratorTest.php
 delete mode 100644 tests/Doctrine/ODM/MongoDB/Tests/Tools/DocumentRepositoryGeneratorTest.php

diff --git a/lib/Doctrine/ODM/MongoDB/Tools/DisconnectedClassMetadataFactory.php b/lib/Doctrine/ODM/MongoDB/Tools/DisconnectedClassMetadataFactory.php
deleted file mode 100644
index 5ed51fbb6a..0000000000
--- a/lib/Doctrine/ODM/MongoDB/Tools/DisconnectedClassMetadataFactory.php
+++ /dev/null
@@ -1,47 +0,0 @@
-<?php
-
-namespace Doctrine\ODM\MongoDB\Tools;
-
-use Doctrine\ODM\MongoDB\Mapping\ClassMetadataFactory;
-use Doctrine\ODM\MongoDB\Mapping\ClassMetadataInfo;
-
-/**
- * The DisconnectedClassMetadataFactory is used to create ClassMetadata objects
- * that do not require the document class actually exist. This allows us to
- * load some mapping information and use it to do things like generate code
- * from the mapping information.
- *
- * @since   1.0
- */
-class DisconnectedClassMetadataFactory extends ClassMetadataFactory
-{
-    /**
-     * @override
-     */
-    protected function newClassMetadataInstance($className)
-    {
-        $metadata = new ClassMetadataInfo($className);
-        if (strpos($className, "\\") !== false) {
-            $metadata->namespace = strrev(substr( strrev($className), strpos(strrev($className), "\\")+1 ));
-        } else {
-            $metadata->namespace = '';
-        }
-        return $metadata;
-    }
-
-    /**
-     * @override
-     */
-    protected function getParentClasses($name)
-    {
-        return array();
-    }
-
-    /**
-     * @override
-     */
-    protected function validateIdentifier($class)
-    {
-        // do nothing as the DisconnectedClassMetadataFactory cannot validate an inherited id
-    }
-}
diff --git a/lib/Doctrine/ODM/MongoDB/Tools/DocumentGenerator.php b/lib/Doctrine/ODM/MongoDB/Tools/DocumentGenerator.php
deleted file mode 100644
index f0479c5b1a..0000000000
--- a/lib/Doctrine/ODM/MongoDB/Tools/DocumentGenerator.php
+++ /dev/null
@@ -1,1003 +0,0 @@
-<?php
-
-namespace Doctrine\ODM\MongoDB\Tools;
-
-use Doctrine\Common\Inflector\Inflector;
-use Doctrine\ODM\MongoDB\Mapping\ClassMetadataInfo;
-use Doctrine\ODM\MongoDB\Types\Type;
-
-/**
- * Generic class used to generate PHP5 document classes from ClassMetadataInfo instances
- *
- *     [php]
- *     $classes = $dm->getClassMetadataInfoFactory()->getAllMetadata();
- *
- *     $generator = new \Doctrine\ODM\MongoDB\Tools\DocumentGenerator();
- *     $generator->setGenerateAnnotations(true);
- *     $generator->setGenerateStubMethods(true);
- *     $generator->setRegenerateDocumentIfExists(false);
- *     $generator->setUpdateDocumentIfExists(true);
- *     $generator->generate($classes, '/path/to/generate/documents');
- *
- * @since   1.0
- */
-class DocumentGenerator
-{
-    /**
-     * @var bool
-     */
-    private $backupExisting = true;
-
-    /** The extension to use for written php files */
-    private $extension = '.php';
-
-    /** Whether or not the current ClassMetadataInfo instance is new or old */
-    private $isNew = true;
-
-    private $staticReflection = array();
-
-    /** Number of spaces to use for indention in generated code */
-    private $numSpaces = 4;
-
-    /** The actual spaces to use for indention */
-    private $spaces = '    ';
-
-    /** The class all generated documents should extend */
-    private $classToExtend;
-
-    /** Whether or not to generate annotations */
-    private $generateAnnotations = false;
-
-    /** Whether or not to generate stub methods */
-    private $generateDocumentStubMethods = false;
-
-    /** Whether or not to update the document class if it exists already */
-    private $updateDocumentIfExists = false;
-
-    /** Whether or not to re-generate document class if it exists already */
-    private $regenerateDocumentIfExists = false;
-
-    private static $classTemplate =
-'<?php
-
-<namespace>
-
-<imports>
-
-<documentAnnotation>
-<documentClassName>
-{
-<documentBody>
-}
-';
-
-    private static $getMethodTemplate =
-'/**
- * <description>
- *
- * @return <variableType>$<variableName>
- */
-public function <methodName>()
-{
-<spaces>return $this-><fieldName>;
-}';
-
-    private static $setMethodTemplate =
-'/**
- * <description>
- *
- * @param <variableType>$<variableName>
- * @return $this
- */
-public function <methodName>(<methodTypeHint>$<variableName><variableDefault>)
-{
-<spaces>$this-><fieldName> = $<variableName>;
-<spaces>return $this;
-}';
-
-    private static $addMethodTemplate =
-'/**
- * <description>
- *
- * @param <variableType>$<variableName>
- */
-public function <methodName>(<methodTypeHint>$<variableName>)
-{
-<spaces>$this-><fieldName>[] = $<variableName>;
-}';
-
-    private static $removeMethodTemplate =
-'/**
- * <description>
- *
- * @param <variableType>$<variableName>
- */
-public function <methodName>(<methodTypeHint>$<variableName>)
-{
-<spaces>$this-><fieldName>->removeElement($<variableName>);
-}';
-
-    private static $lifecycleCallbackMethodTemplate =
-'<comment>
-public function <methodName>()
-{
-<spaces>// Add your code here
-}';
-
-    private static $constructorMethodTemplate =
-'public function __construct()
-{
-<collections>
-}
-';
-
-    /**
-     * Generate and write document classes for the given array of ClassMetadataInfo instances
-     *
-     * @param array $metadatas
-     * @param string $outputDirectory
-     * @return void
-     */
-    public function generate(array $metadatas, $outputDirectory)
-    {
-        foreach ($metadatas as $metadata) {
-            $this->writeDocumentClass($metadata, $outputDirectory);
-        }
-    }
-
-    /**
-     * Generated and write document class to disk for the given ClassMetadataInfo instance
-     *
-     * @param ClassMetadataInfo $metadata
-     * @param string $outputDirectory
-     * @throws \RuntimeException
-     * @return void
-     */
-    public function writeDocumentClass(ClassMetadataInfo $metadata, $outputDirectory)
-    {
-        $path = $outputDirectory . '/' . str_replace('\\', DIRECTORY_SEPARATOR, $metadata->name) . $this->extension;
-        $dir = dirname($path);
-
-        if ( ! is_dir($dir)) {
-            mkdir($dir, 0775, true);
-        }
-
-        $this->isNew = ! file_exists($path) || (file_exists($path) && $this->regenerateDocumentIfExists);
-
-        if ( ! $this->isNew) {
-            $this->parseTokensInDocumentFile($path);
-        }
-
-        if ($this->backupExisting && file_exists($path)) {
-            $backupPath = dirname($path) . DIRECTORY_SEPARATOR . basename($path) . '~';
-            if ( ! copy($path, $backupPath)) {
-                throw new \RuntimeException('Attempt to backup overwritten document file but copy operation failed.');
-            }
-        }
-
-        // If document doesn't exist or we're re-generating the documents entirely
-        if ($this->isNew) {
-            file_put_contents($path, $this->generateDocumentClass($metadata));
-
-        // If document exists and we're allowed to update the document class
-        } elseif ( ! $this->isNew && $this->updateDocumentIfExists) {
-            file_put_contents($path, $this->generateUpdatedDocumentClass($metadata, $path));
-        }
-        chmod($path, 0664);
-    }
-
-    /**
-     * Generate a PHP5 Doctrine 2 document class from the given ClassMetadataInfo instance
-     *
-     * @param ClassMetadataInfo $metadata
-     * @return string $code
-     */
-    public function generateDocumentClass(ClassMetadataInfo $metadata)
-    {
-        $placeHolders = array(
-            '<namespace>',
-            '<imports>',
-            '<documentAnnotation>',
-            '<documentClassName>',
-            '<documentBody>'
-        );
-
-        $replacements = array(
-            $this->generateDocumentNamespace($metadata),
-            $this->generateDocumentImports(),
-            $this->generateDocumentDocBlock($metadata),
-            $this->generateDocumentClassName($metadata),
-            $this->generateDocumentBody($metadata)
-        );
-
-        $code = str_replace($placeHolders, $replacements, self::$classTemplate);
-        return str_replace('<spaces>', $this->spaces, $code);
-    }
-
-    /**
-     * Generate the updated code for the given ClassMetadataInfo and document at path
-     *
-     * @param ClassMetadataInfo $metadata
-     * @param string $path
-     * @return string $code;
-     */
-    public function generateUpdatedDocumentClass(ClassMetadataInfo $metadata, $path)
-    {
-        $currentCode = file_get_contents($path);
-
-        $body = $this->generateDocumentBody($metadata);
-        $body = str_replace('<spaces>', $this->spaces, $body);
-        $last = strrpos($currentCode, '}');
-
-        return substr($currentCode, 0, $last) . $body . (strlen($body) > 0 ? "\n" : '') . "}\n";
-    }
-
-    /**
-     * Set the number of spaces the exported class should have
-     *
-     * @param integer $numSpaces
-     * @return void
-     */
-    public function setNumSpaces($numSpaces)
-    {
-        $this->spaces = str_repeat(' ', $numSpaces);
-        $this->numSpaces = $numSpaces;
-    }
-
-    /**
-     * Set the extension to use when writing php files to disk
-     *
-     * @param string $extension
-     * @return void
-     */
-    public function setExtension($extension)
-    {
-        $this->extension = $extension;
-    }
-
-    /**
-     * Set the name of the class the generated classes should extend from
-     *
-     * @param string $classToExtend Class name.
-     * @return void
-     */
-    public function setClassToExtend($classToExtend)
-    {
-        $this->classToExtend = $classToExtend;
-    }
-
-    /**
-     * Set whether or not to generate annotations for the document
-     *
-     * @param bool $bool
-     * @return void
-     */
-    public function setGenerateAnnotations($bool)
-    {
-        $this->generateAnnotations = $bool;
-    }
-
-    /**
-     * Set whether or not to try and update the document if it already exists
-     *
-     * @param bool $bool
-     * @return void
-     */
-    public function setUpdateDocumentIfExists($bool)
-    {
-        $this->updateDocumentIfExists = $bool;
-    }
-
-    /**
-     * Set whether or not to regenerate the document if it exists
-     *
-     * @param bool $bool
-     * @return void
-     */
-    public function setRegenerateDocumentIfExists($bool)
-    {
-        $this->regenerateDocumentIfExists = $bool;
-    }
-
-    /**
-     * Set whether or not to generate stub methods for the document
-     *
-     * @param bool $bool
-     * @return void
-     */
-    public function setGenerateStubMethods($bool)
-    {
-        $this->generateDocumentStubMethods = $bool;
-    }
-
-    /**
-     * Sets a value indicating whether existing documents will be backed up.
-     *
-     * @param bool $bool True to backup existing document, false to overwrite.
-     */
-    public function setBackupExisting($bool)
-    {
-        $this->backupExisting = $bool;
-    }
-
-    private function generateDocumentNamespace(ClassMetadataInfo $metadata)
-    {
-        if ($this->hasNamespace($metadata)) {
-            return 'namespace ' . $this->getNamespace($metadata) . ';';
-        }
-    }
-
-    private function generateDocumentClassName(ClassMetadataInfo $metadata)
-    {
-        return 'class ' . $this->getClassName($metadata) .
-            ($this->extendsClass() ? ' extends ' . $this->getClassToExtendName() : null);
-    }
-
-    private function generateDocumentBody(ClassMetadataInfo $metadata)
-    {
-        $fieldMappingProperties = $this->generateDocumentFieldMappingProperties($metadata);
-        $associationMappingProperties = $this->generateDocumentAssociationMappingProperties($metadata);
-        $stubMethods = $this->generateDocumentStubMethods ? $this->generateDocumentStubMethods($metadata) : null;
-        $lifecycleCallbackMethods = $this->generateDocumentLifecycleCallbackMethods($metadata);
-
-        $code = array();
-
-        if ($fieldMappingProperties) {
-            $code[] = $fieldMappingProperties;
-        }
-
-        if ($associationMappingProperties) {
-            $code[] = $associationMappingProperties;
-        }
-
-        $code[] = $this->generateDocumentConstructor($metadata);
-
-        if ($stubMethods) {
-            $code[] = $stubMethods;
-        }
-
-        if ($lifecycleCallbackMethods) {
-            $code[] = "\n" . $lifecycleCallbackMethods;
-        }
-
-        return implode("\n", $code);
-    }
-
-    private function generateDocumentConstructor(ClassMetadataInfo $metadata)
-    {
-        if ($this->hasMethod('__construct', $metadata)) {
-            return '';
-        }
-
-        $collections = array();
-        foreach ($metadata->fieldMappings AS $mapping) {
-            if ($mapping['type'] === ClassMetadataInfo::MANY) {
-                $collections[] = '$this->' . $mapping['fieldName'] . ' = new \Doctrine\Common\Collections\ArrayCollection();';
-            }
-        }
-        if ($collections) {
-            return $this->prefixCodeWithSpaces(str_replace('<collections>', $this->spaces . implode("\n" . $this->spaces, $collections), self::$constructorMethodTemplate));
-        }
-        return '';
-    }
-
-    /**
-     * @todo this won't work if there is a namespace in brackets and a class outside of it.
-     * @param string $path
-     */
-    private function parseTokensInDocumentFile($path)
-    {
-        $tokens = token_get_all(file_get_contents($path));
-        $lastSeenNamespace = '';
-        $lastSeenClass = false;
-
-        for ($i = 0; $i < count($tokens); $i++) {
-            $token = $tokens[$i];
-            if ($token[0] == T_NAMESPACE) {
-                $peek = $i;
-                $lastSeenNamespace = '';
-                while (isset($tokens[++$peek])) {
-                    if (';' == $tokens[$peek]) {
-                        break;
-                    } elseif (is_array($tokens[$peek]) && in_array($tokens[$peek][0], array(T_STRING, T_NS_SEPARATOR))) {
-                        $lastSeenNamespace .= $tokens[$peek][1];
-                    }
-                }
-            } elseif ($token[0] == T_CLASS) {
-                $lastSeenClass = $lastSeenNamespace . '\\' . $tokens[$i + 2][1];
-                $this->staticReflection[$lastSeenClass]['properties'] = array();
-                $this->staticReflection[$lastSeenClass]['methods'] = array();
-            } elseif ($token[0] == T_FUNCTION) {
-                if ($tokens[$i + 2][0] == T_STRING) {
-                    $this->staticReflection[$lastSeenClass]['methods'][] = $tokens[$i + 2][1];
-                } elseif ($tokens[$i + 2][0] == '&' && $tokens[$i + 3][0] == T_STRING) {
-                    $this->staticReflection[$lastSeenClass]['methods'][] = $tokens[$i + 3][1];
-                }
-            } elseif (in_array($token[0], array(T_VAR, T_PUBLIC, T_PRIVATE, T_PROTECTED)) && $tokens[$i + 2][0] != T_FUNCTION) {
-                $this->staticReflection[$lastSeenClass]['properties'][] = substr($tokens[$i + 2][1], 1);
-            }
-        }
-    }
-
-    private function hasProperty($property, ClassMetadataInfo $metadata)
-    {
-        if ($this->extendsClass() || class_exists($metadata->name)) {
-            // don't generate property if its already on the base class.
-            $reflClass = new \ReflectionClass($this->getClassToExtend() ?: $metadata->name);
-
-            if ($reflClass->hasProperty($property)) {
-                return true;
-            }
-        }
-
-        foreach ($this->getTraits($metadata) as $trait) {
-            if ($trait->hasProperty($property)) {
-                return true;
-            }
-        }
-
-        return (
-            isset($this->staticReflection[$metadata->name]) &&
-            in_array($property, $this->staticReflection[$metadata->name]['properties'])
-        );
-    }
-
-    private function hasMethod($method, ClassMetadataInfo $metadata)
-    {
-        if ($this->extendsClass() || class_exists($metadata->name)) {
-            // don't generate method if its already on the base class.
-            $reflClass = new \ReflectionClass($this->getClassToExtend() ?: $metadata->name);
-
-            if ($reflClass->hasMethod($method)) {
-                return true;
-            }
-        }
-
-        foreach ($this->getTraits($metadata) as $trait) {
-            if ($trait->hasMethod($method)) {
-                return true;
-            }
-        }
-
-        return (
-            isset($this->staticReflection[$metadata->name]) &&
-            in_array($method, $this->staticReflection[$metadata->name]['methods'])
-        );
-    }
-
-    private function hasNamespace(ClassMetadataInfo $metadata)
-    {
-        return strpos($metadata->name, '\\') ? true : false;
-    }
-
-    private function extendsClass()
-    {
-        return $this->classToExtend ? true : false;
-    }
-
-    private function getClassToExtend()
-    {
-        return $this->classToExtend;
-    }
-
-    private function getClassToExtendName()
-    {
-        $refl = new \ReflectionClass($this->getClassToExtend());
-
-        return '\\' . $refl->getName();
-    }
-
-    private function getClassName(ClassMetadataInfo $metadata)
-    {
-        return ($pos = strrpos($metadata->name, '\\'))
-            ? substr($metadata->name, $pos + 1, strlen($metadata->name)) : $metadata->name;
-    }
-
-    private function getNamespace(ClassMetadataInfo $metadata)
-    {
-        return substr($metadata->name, 0, strrpos($metadata->name, '\\'));
-    }
-
-    /**
-     * @param ClassMetadataInfo $metadata
-     *
-     * @return array
-     */
-    protected function getTraits(ClassMetadataInfo $metadata)
-    {
-        if ($metadata->reflClass !== null || class_exists($metadata->name)) {
-            $reflClass = $metadata->reflClass === null ? new \ReflectionClass($metadata->name) : $metadata->reflClass;
-            $traits = array();
-            while ($reflClass !== false) {
-                $traits = array_merge($traits, $reflClass->getTraits());
-                $reflClass = $reflClass->getParentClass();
-            }
-            return $traits;
-        }
-        return array();
-    }
-
-    private function generateDocumentImports()
-    {
-        if ($this->generateAnnotations) {
-            return 'use Doctrine\\ODM\\MongoDB\\Mapping\\Annotations as ODM;';
-        }
-    }
-
-    private function generateDocumentDocBlock(ClassMetadataInfo $metadata)
-    {
-        $lines = array();
-        $lines[] = '/**';
-        $lines[] = ' * ' . $metadata->name;
-
-        if ($this->generateAnnotations) {
-            $lines[] = ' *';
-
-            if ($metadata->isMappedSuperclass) {
-                $lines[] = ' * @ODM\\MappedSuperclass';
-            } elseif ($metadata->isEmbeddedDocument) {
-                $lines[] = ' * @ODM\\EmbeddedDocument';
-            } elseif ($metadata->isQueryResultDocument) {
-                $lines[] = ' * @ODM\\QueryResultDocument';
-            } else {
-                $lines[] = ' * @ODM\\Document';
-            }
-
-            $document = array();
-            if ( ! $metadata->isMappedSuperclass && ! $metadata->isEmbeddedDocument && ! $metadata->isQueryResultDocument) {
-                if ($metadata->collection) {
-                    $document[] = ' *     collection="' . $metadata->collection . '"';
-                }
-                if ($metadata->customRepositoryClassName) {
-                    $document[] = ' *     repositoryClass="' . $metadata->customRepositoryClassName . '"';
-                }
-            }
-            if ($metadata->indexes) {
-                $indexes = array();
-                $indexLines = array();
-                $indexLines[] = ' *     indexes={';
-                foreach ($metadata->indexes as $index) {
-                    $keys = array();
-                    foreach ($index['keys'] as $key => $value) {
-                        $keys[] = '"' . $key . '"="' . $value . '"';
-                    }
-                    $options = array();
-                    foreach ($index['options'] as $key => $value) {
-                        $options[] = '"' . $key . '"="' . $value . '"';
-                    }
-                    $indexes[] = '@ODM\\Index(keys={' . implode(', ', $keys) . '}, options={' . implode(', ', $options) . '})';
-                }
-                $indexLines[] = "\n *         " . implode(",\n *         ", $indexes);
-                $indexLines[] = "\n *     }";
-
-                $document[] = implode(null, $indexLines);
-            }
-
-            if ($document) {
-                $lines[count($lines) - 1] .= '(';
-                $lines[] = implode(",\n", $document);
-                $lines[] = ' * )';
-            }
-
-            if ( ! empty($metadata->lifecycleCallbacks)) {
-                $lines[] = ' * @ODM\HasLifecycleCallbacks';
-            }
-
-            $methods = array(
-                'generateInheritanceAnnotation',
-                'generateDiscriminatorFieldAnnotation',
-                'generateDiscriminatorMapAnnotation',
-                'generateDefaultDiscriminatorValueAnnotation',
-                'generateChangeTrackingPolicyAnnotation'
-            );
-
-            foreach ($methods as $method) {
-                if ($code = $this->$method($metadata)) {
-                    $lines[] = ' * ' . $code;
-                }
-            }
-        }
-
-        $lines[] = ' */';
-        return implode("\n", $lines);
-    }
-
-    private function generateInheritanceAnnotation(ClassMetadataInfo $metadata)
-    {
-        if ($metadata->inheritanceType !== ClassMetadataInfo::INHERITANCE_TYPE_NONE) {
-            return '@ODM\\InheritanceType("' . $this->getInheritanceTypeString($metadata->inheritanceType) . '")';
-        }
-    }
-
-    private function generateDiscriminatorFieldAnnotation(ClassMetadataInfo $metadata)
-    {
-        if ($metadata->inheritanceType === ClassMetadataInfo::INHERITANCE_TYPE_SINGLE_COLLECTION) {
-            return '@ODM\\DiscriminatorField(name="' . $metadata->discriminatorField . '")';
-        }
-    }
-
-    private function generateDiscriminatorMapAnnotation(ClassMetadataInfo $metadata)
-    {
-        if ($metadata->inheritanceType === ClassMetadataInfo::INHERITANCE_TYPE_SINGLE_COLLECTION) {
-            $inheritanceClassMap = array();
-
-            foreach ($metadata->discriminatorMap as $type => $class) {
-                $inheritanceClassMap[] .= '"' . $type . '" = "' . $class . '"';
-            }
-
-            return '@ODM\\DiscriminatorMap({' . implode(', ', $inheritanceClassMap) . '})';
-        }
-    }
-
-    private function generateDefaultDiscriminatorValueAnnotation(ClassMetadataInfo $metadata)
-    {
-        if ($metadata->inheritanceType === ClassMetadataInfo::INHERITANCE_TYPE_SINGLE_COLLECTION && isset($metadata->defaultDiscriminatorValue)) {
-            return '@ODM\\DefaultDiscriminatorValue("' . $metadata->defaultDiscriminatorValue . '")';
-        }
-    }
-
-    private function generateChangeTrackingPolicyAnnotation(ClassMetadataInfo $metadata)
-    {
-        return '@ODM\\ChangeTrackingPolicy("' . $this->getChangeTrackingPolicyString($metadata->changeTrackingPolicy) . '")';
-    }
-
-    private function generateDocumentStubMethods(ClassMetadataInfo $metadata)
-    {
-        $methods = array();
-
-        foreach ($metadata->fieldMappings as $fieldMapping) {
-            if (isset($fieldMapping['id'])) {
-                if ($metadata->generatorType == ClassMetadataInfo::GENERATOR_TYPE_NONE) {
-                    if ($code = $this->generateDocumentStubMethod($metadata, 'set', $fieldMapping['fieldName'], $fieldMapping['type'])) {
-                        $methods[] = $code;
-                    }
-                }
-                if ($code = $code = $this->generateDocumentStubMethod($metadata, 'get', $fieldMapping['fieldName'], $fieldMapping['type'])) {
-                    $methods[] = $code;
-                }
-            } elseif ( ! isset($fieldMapping['association'])) {
-                if ($code = $code = $this->generateDocumentStubMethod($metadata, 'set', $fieldMapping['fieldName'], $fieldMapping['type'])) {
-                    $methods[] = $code;
-                }
-                if ($code = $code = $this->generateDocumentStubMethod($metadata, 'get', $fieldMapping['fieldName'], $fieldMapping['type'])) {
-                    $methods[] = $code;
-                }
-            } elseif ($fieldMapping['type'] === ClassMetadataInfo::ONE) {
-                $nullable = $this->isAssociationNullable($fieldMapping) ? 'null' : null;
-                if ($code = $this->generateDocumentStubMethod($metadata, 'set', $fieldMapping['fieldName'], $fieldMapping['targetDocument'] ?? null, $nullable)) {
-                    $methods[] = $code;
-                }
-                if ($code = $this->generateDocumentStubMethod($metadata, 'get', $fieldMapping['fieldName'], $fieldMapping['targetDocument'] ?? null)) {
-                    $methods[] = $code;
-                }
-            } elseif ($fieldMapping['type'] === ClassMetadataInfo::MANY) {
-                if ($code = $this->generateDocumentStubMethod($metadata, 'add', $fieldMapping['fieldName'], $fieldMapping['targetDocument'] ?? null)) {
-                    $methods[] = $code;
-                }
-                if ($code = $this->generateDocumentStubMethod($metadata, 'remove', $fieldMapping['fieldName'], $fieldMapping['targetDocument'] ?? null)) {
-                    $methods[] = $code;
-                }
-                if ($code = $this->generateDocumentStubMethod($metadata, 'get', $fieldMapping['fieldName'], '\Doctrine\Common\Collections\Collection')) {
-                    $methods[] = $code;
-                }
-            }
-        }
-
-        return implode("\n\n", $methods);
-    }
-
-    /**
-     * @param array $fieldMapping
-     *
-     * @return bool
-     */
-    protected function isAssociationNullable($fieldMapping)
-    {
-        return isset($fieldMapping['nullable']) && $fieldMapping['nullable'];
-    }
-
-    private function generateDocumentLifecycleCallbackMethods(ClassMetadataInfo $metadata)
-    {
-        if (empty($metadata->lifecycleCallbacks)) {
-            return '';
-        }
-
-        $methods = array();
-
-        foreach ($metadata->lifecycleCallbacks as $event => $callbacks) {
-            foreach ($callbacks as $callback) {
-                if ($code = $this->generateLifecycleCallbackMethod($event, $callback, $metadata)) {
-                    $methods[] = $code;
-                }
-            }
-        }
-
-        return implode("\n\n", $methods);
-    }
-
-    private function generateDocumentAssociationMappingProperties(ClassMetadataInfo $metadata)
-    {
-        $lines = array();
-
-        foreach ($metadata->fieldMappings as $fieldMapping) {
-            if ($this->hasProperty($fieldMapping['fieldName'], $metadata) ||
-                $metadata->isInheritedField($fieldMapping['fieldName'])) {
-                continue;
-            }
-            if ( ! isset($fieldMapping['association'])) {
-                continue;
-            }
-
-            $lines[] = $this->generateAssociationMappingPropertyDocBlock($fieldMapping);
-            $lines[] = $this->spaces . 'protected $' . $fieldMapping['fieldName']
-                . ($fieldMapping['type'] === ClassMetadataInfo::MANY ? ' = array()' : null) . ";\n";
-        }
-
-        return implode("\n", $lines);
-    }
-
-    private function generateDocumentFieldMappingProperties(ClassMetadataInfo $metadata)
-    {
-        $lines = array();
-
-        foreach ($metadata->fieldMappings as $fieldMapping) {
-            if ($this->hasProperty($fieldMapping['fieldName'], $metadata) ||
-                $metadata->isInheritedField($fieldMapping['fieldName'])) {
-                continue;
-            }
-            if (isset($fieldMapping['association']) && $fieldMapping['association']) {
-                continue;
-            }
-
-            $lines[] = $this->generateFieldMappingPropertyDocBlock($fieldMapping, $metadata);
-            $lines[] = $this->spaces . 'protected $' . $fieldMapping['fieldName']
-                . (isset($fieldMapping['default']) ? ' = ' . var_export($fieldMapping['default'], true) : null) . ";\n";
-        }
-
-        return implode("\n", $lines);
-    }
-
-    private function generateDocumentStubMethod(ClassMetadataInfo $metadata, $type, $fieldName, $typeHint = null, $defaultValue = null)
-    {
-        // Add/remove methods should use the singular form of the field name
-        $formattedFieldName = in_array($type, array('add', 'remove'))
-            ? Inflector::singularize($fieldName)
-            : $fieldName;
-
-        $methodName = $type . Inflector::classify($formattedFieldName);
-        $variableName = Inflector::camelize($formattedFieldName);
-
-        if ($this->hasMethod($methodName, $metadata)) {
-            return;
-        }
-
-        $description = ucfirst($type) . ' ' . $variableName;
-
-        $types = Type::getTypesMap();
-        $methodTypeHint = $typeHint && ! isset($types[$typeHint]) ? '\\' . $typeHint . ' ' : null;
-        $variableType = $typeHint ? $typeHint . ' ' : null;
-
-        $replacements = array(
-            '<description>'         => $description,
-            '<methodTypeHint>'      => $methodTypeHint,
-            '<variableType>'        => $variableType,
-            '<variableName>'        => $variableName,
-            '<methodName>'          => $methodName,
-            '<fieldName>'           => $fieldName,
-            '<variableDefault>'     => ($defaultValue !== null ) ? (' = ' . $defaultValue) : '',
-        );
-
-        $templateVar = sprintf('%sMethodTemplate', $type);
-
-        $method = str_replace(
-            array_keys($replacements),
-            array_values($replacements),
-            self::$$templateVar
-        );
-
-        return $this->prefixCodeWithSpaces($method);
-    }
-
-    private function generateLifecycleCallbackMethod($name, $methodName, ClassMetadataInfo $metadata)
-    {
-        if ($this->hasMethod($methodName, $metadata)) {
-            return;
-        }
-
-        $replacements = array(
-            '<comment>'    => $this->generateAnnotations ? '/** @ODM\\' . ucfirst($name) . ' */' : '',
-            '<methodName>' => $methodName,
-        );
-
-        $method = str_replace(
-            array_keys($replacements),
-            array_values($replacements),
-            self::$lifecycleCallbackMethodTemplate
-        );
-
-        return $this->prefixCodeWithSpaces($method);
-    }
-
-    private function generateAssociationMappingPropertyDocBlock(array $fieldMapping)
-    {
-        $lines = array();
-        $lines[] = $this->spaces . '/**';
-        $lines[] = $this->spaces . ' * @var ' . ($fieldMapping['targetDocument'] ?? 'object');
-
-        if ($this->generateAnnotations) {
-            $lines[] = $this->spaces . ' *';
-
-            $type = null;
-            switch ($fieldMapping['association']) {
-                case ClassMetadataInfo::EMBED_ONE:
-                    $type = 'EmbedOne';
-                    break;
-                case ClassMetadataInfo::EMBED_MANY:
-                    $type = 'EmbedMany';
-                    break;
-                case ClassMetadataInfo::REFERENCE_ONE:
-                    $type = 'ReferenceOne';
-                    break;
-                case ClassMetadataInfo::REFERENCE_MANY:
-                    $type = 'ReferenceMany';
-                    break;
-            }
-            $typeOptions = array();
-
-            if (isset($fieldMapping['targetDocument'])) {
-                $typeOptions[] = 'targetDocument="' . $fieldMapping['targetDocument'] . '"';
-            }
-
-            if (isset($fieldMapping['cascade']) && $fieldMapping['cascade']) {
-                $cascades = array();
-
-                if ($fieldMapping['isCascadePersist']) $cascades[] = '"persist"';
-                if ($fieldMapping['isCascadeRemove']) $cascades[] = '"remove"';
-                if ($fieldMapping['isCascadeDetach']) $cascades[] = '"detach"';
-                if ($fieldMapping['isCascadeMerge']) $cascades[] = '"merge"';
-                if ($fieldMapping['isCascadeRefresh']) $cascades[] = '"refresh"';
-
-                $typeOptions[] = 'cascade={' . implode(',', $cascades) . '}';
-            }
-
-            $lines[] = $this->spaces . ' * @ODM\\' . $type . '(' . implode(', ', $typeOptions) . ')';
-        }
-
-        $lines[] = $this->spaces . ' */';
-
-        return implode("\n", $lines);
-    }
-
-    private function generateFieldMappingPropertyDocBlock(array $fieldMapping, ClassMetadataInfo $metadata)
-    {
-        $lines = array();
-        $lines[] = $this->spaces . '/**';
-        if (isset($fieldMapping['id']) && $fieldMapping['id']) {
-            $fieldMapping['strategy'] = $fieldMapping['strategy'] ?? ClassMetadataInfo::GENERATOR_TYPE_AUTO;
-            if ($fieldMapping['strategy'] === ClassMetadataInfo::GENERATOR_TYPE_AUTO) {
-                $lines[] = $this->spaces . ' * @var MongoDB\BSON\ObjectId $' . $fieldMapping['fieldName'];
-            } elseif ($fieldMapping['strategy'] === ClassMetadataInfo::GENERATOR_TYPE_INCREMENT) {
-                $lines[] = $this->spaces . ' * @var integer $' . $fieldMapping['fieldName'];
-            } elseif ($fieldMapping['strategy'] === ClassMetadataInfo::GENERATOR_TYPE_UUID) {
-                $lines[] = $this->spaces . ' * @var string $' . $fieldMapping['fieldName'];
-            } elseif ($fieldMapping['strategy'] === ClassMetadataInfo::GENERATOR_TYPE_NONE) {
-                $lines[] = $this->spaces . ' * @var $' . $fieldMapping['fieldName'];
-            } else {
-                $lines[] = $this->spaces . ' * @var $' . $fieldMapping['fieldName'];
-            }
-        } else {
-            $lines[] = $this->spaces . ' * @var ' . $fieldMapping['type'] . ' $' . $fieldMapping['fieldName'];
-        }
-
-        if ($this->generateAnnotations) {
-            $lines[] = $this->spaces . ' *';
-
-            $field = array();
-            if (isset($fieldMapping['id']) && $fieldMapping['id']) {
-                if (isset($fieldMapping['strategy'])) {
-                    $field[] = 'strategy="' . $this->getIdGeneratorTypeString($metadata->generatorType) . '"';
-                }
-                $lines[] = $this->spaces . ' * @ODM\\Id(' . implode(', ', $field) . ')';
-            } else {
-                if (isset($fieldMapping['name'])) {
-                    $field[] = 'name="' . $fieldMapping['name'] . '"';
-                }
-
-                if (isset($fieldMapping['type'])) {
-                    $field[] = 'type="' . $fieldMapping['type'] . '"';
-                }
-
-                if (isset($fieldMapping['nullable']) && $fieldMapping['nullable'] === true) {
-                    $field[] = 'nullable=' . var_export($fieldMapping['nullable'], true);
-                }
-                if (isset($fieldMapping['options'])) {
-                    $options = array();
-                    foreach ($fieldMapping['options'] as $key => $value) {
-                        $options[] = '"' . $key . '" = "' . $value . '"';
-                    }
-                    $field[] = 'options={' . implode(', ', $options) . '}';
-                }
-                $lines[] = $this->spaces . ' * @ODM\\Field(' . implode(', ', $field) . ')';
-            }
-
-            if (isset($fieldMapping['version']) && $fieldMapping['version']) {
-                $lines[] = $this->spaces . ' * @ODM\\Version';
-            }
-        }
-
-        $lines[] = $this->spaces . ' */';
-
-        return implode("\n", $lines);
-    }
-
-    private function prefixCodeWithSpaces($code, $num = 1)
-    {
-        $lines = explode("\n", $code);
-
-        foreach ($lines as $key => $value) {
-            $lines[$key] = str_repeat($this->spaces, $num) . $lines[$key];
-        }
-
-        return implode("\n", $lines);
-    }
-
-    private function getInheritanceTypeString($type)
-    {
-        switch ($type) {
-            case ClassMetadataInfo::INHERITANCE_TYPE_NONE:
-                return 'NONE';
-
-            case ClassMetadataInfo::INHERITANCE_TYPE_SINGLE_COLLECTION:
-                return 'SINGLE_COLLECTION';
-
-            case ClassMetadataInfo::INHERITANCE_TYPE_COLLECTION_PER_CLASS:
-                return 'COLLECTION_PER_CLASS';
-
-            default:
-                throw new \InvalidArgumentException('Invalid provided InheritanceType: ' . $type);
-        }
-    }
-
-    private function getChangeTrackingPolicyString($policy)
-    {
-        switch ($policy) {
-            case ClassMetadataInfo::CHANGETRACKING_DEFERRED_IMPLICIT:
-                return 'DEFERRED_IMPLICIT';
-
-            case ClassMetadataInfo::CHANGETRACKING_DEFERRED_EXPLICIT:
-                return 'DEFERRED_EXPLICIT';
-
-            case ClassMetadataInfo::CHANGETRACKING_NOTIFY:
-                return 'NOTIFY';
-
-            default:
-                throw new \InvalidArgumentException('Invalid provided ChangeTrackingPolicy: ' . $policy);
-        }
-    }
-
-    private function getIdGeneratorTypeString($type)
-    {
-        switch ($type) {
-            case ClassMetadataInfo::GENERATOR_TYPE_AUTO:
-                return 'AUTO';
-
-            case ClassMetadataInfo::GENERATOR_TYPE_INCREMENT:
-                return 'INCREMENT';
-
-            case ClassMetadataInfo::GENERATOR_TYPE_UUID:
-                return 'UUID';
-
-            case ClassMetadataInfo::GENERATOR_TYPE_ALNUM:
-                return 'ALNUM';
-
-            case ClassMetadataInfo::GENERATOR_TYPE_CUSTOM:
-                return 'CUSTOM';
-
-            case ClassMetadataInfo::GENERATOR_TYPE_NONE:
-                return 'NONE';
-
-            default:
-                throw new \InvalidArgumentException('Invalid provided IdGeneratorType: ' . $type);
-        }
-    }
-}
diff --git a/lib/Doctrine/ODM/MongoDB/Tools/DocumentRepositoryGenerator.php b/lib/Doctrine/ODM/MongoDB/Tools/DocumentRepositoryGenerator.php
deleted file mode 100644
index 8815aa7305..0000000000
--- a/lib/Doctrine/ODM/MongoDB/Tools/DocumentRepositoryGenerator.php
+++ /dev/null
@@ -1,67 +0,0 @@
-<?php
-
-namespace Doctrine\ODM\MongoDB\Tools;
-
-/**
- * Class to generate document repository classes
- *
- * @since   1.0
- */
-class DocumentRepositoryGenerator
-{
-    protected static $template =
-'<?php
-
-namespace <namespace>;
-
-use Doctrine\ODM\MongoDB\DocumentRepository;
-
-/**
- * <className>
- *
- * This class was generated by the Doctrine ODM. Add your own custom
- * repository methods below.
- */
-class <className> extends DocumentRepository
-{
-}
-';
-
-    public function generateDocumentRepositoryClass($fullClassName)
-    {
-        $namespace = substr($fullClassName, 0, strrpos($fullClassName, '\\'));
-        $className = substr($fullClassName, strrpos($fullClassName, '\\') + 1, strlen($fullClassName));
-
-        $variables = array(
-            '<namespace>' => $namespace,
-            '<className>' => $className
-        );
-        return str_replace(array_keys($variables), array_values($variables), self::$template);
-    }
-
-    public function writeDocumentRepositoryClass($fullClassName, $outputDirectory, $outputDirectoryNamespace = null)
-    {
-        $code = $this->generateDocumentRepositoryClass($fullClassName);
-        
-        if (null === $outputDirectoryNamespace) {
-            $relativeClassName = $fullClassName;
-        } else {
-            $relativeClassName = preg_replace(
-                '/^'.str_replace('\\', '\\\\', $outputDirectoryNamespace).'\\\\/', '', $fullClassName
-            );
-        }
-        
-        $path = $outputDirectory . DIRECTORY_SEPARATOR
-              . str_replace('\\', \DIRECTORY_SEPARATOR, $relativeClassName) . '.php';
-        $dir = dirname($path);
-
-        if ( ! is_dir($dir)) {
-            mkdir($dir, 0775, true);
-        }
-
-        if ( ! file_exists($path)) {
-            file_put_contents($path, $code);
-            chmod($path, 0664);
-        }
-    }
-}
diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Tools/DocumentGeneratorTest.php b/tests/Doctrine/ODM/MongoDB/Tests/Tools/DocumentGeneratorTest.php
deleted file mode 100644
index 89691c1ec6..0000000000
--- a/tests/Doctrine/ODM/MongoDB/Tests/Tools/DocumentGeneratorTest.php
+++ /dev/null
@@ -1,300 +0,0 @@
-<?php
-
-namespace Doctrine\ODM\MongoDB\Tests\Tools;
-
-use Doctrine\ODM\MongoDB\Tools\DocumentGenerator;
-use Doctrine\ODM\MongoDB\Mapping\ClassMetadataInfo;
-
-class DocumentGeneratorTest extends \Doctrine\ODM\MongoDB\Tests\BaseTest
-{
-    private $generator;
-    private $tmpDir;
-    private $namespace;
-
-    public function setUp()
-    {
-        parent::setUp();
-        $this->namespace = uniqid("doctrine_");
-        $this->tmpDir = \sys_get_temp_dir();
-        \mkdir($this->tmpDir . \DIRECTORY_SEPARATOR . $this->namespace);
-        $this->generator = new DocumentGenerator();
-        $this->generator->setGenerateAnnotations(true);
-        $this->generator->setGenerateStubMethods(true);
-        $this->generator->setRegenerateDocumentIfExists(false);
-        $this->generator->setUpdateDocumentIfExists(true);
-    }
-
-    public function tearDown()
-    {
-        parent::tearDown();
-        $ri = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($this->tmpDir . '/' . $this->namespace));
-        foreach ($ri AS $file) {
-            /* @var $file \SplFileInfo */
-            if ($file->isFile()) {
-                \unlink($file->getPathname());
-            }
-        }
-        rmdir($this->tmpDir . '/' . $this->namespace);
-    }
-
-    public function generateBookDocumentFixture()
-    {
-        $metadata = new ClassMetadataInfo($this->namespace . '\DocumentGeneratorBook');
-        $metadata->namespace = $this->namespace;
-        $metadata->customRepositoryClassName = $this->namespace  . '\DocumentGeneratorBookRepository';
-
-        $metadata->collection = 'book';
-        $metadata->mapField(array('fieldName' => 'name', 'type' => 'string'));
-        $metadata->mapField(array('fieldName' => 'status', 'type' => 'string'));
-        $metadata->mapField(array('fieldName' => 'id', 'type' => 'integer', 'id' => true));
-        $metadata->mapOneReference(array('fieldName' => 'author', 'targetDocument' => 'Doctrine\ODM\MongoDB\Tests\Tools\DocumentGeneratorAuthor'));
-        $metadata->mapManyReference(array(
-            'fieldName' => 'comments',
-            'targetDocument' => 'Doctrine\ODM\MongoDB\Tests\Tools\DocumentGeneratorComment'
-        ));
-        $metadata->mapManyReference(array(
-                'fieldName' => 'searches',
-                'targetDocument' => 'Doctrine\ODM\MongoDB\Tests\Tools\DocumentGeneratorSearch'
-        ));
-        $metadata->addLifecycleCallback('loading', 'postLoad');
-        $metadata->addLifecycleCallback('willBeRemoved', 'preRemove');
-        $metadata->setIdGeneratorType(ClassMetadataInfo::GENERATOR_TYPE_CUSTOM);
-
-        $this->generator->writeDocumentClass($metadata, $this->tmpDir);
-
-        return $metadata;
-    }
-
-    /**
-     * @param  ClassMetadataInfo $metadata
-     * @return DocumentGeneratorBook
-     */
-    public function newInstance($metadata)
-    {
-        $path = $this->tmpDir . '/'. $this->namespace . '/DocumentGeneratorBook.php';
-        $this->assertFileExists($path);
-        require_once $path;
-
-        return new $metadata->name;
-    }
-
-    public function testGeneratedDocumentClass()
-    {
-        $metadata = $this->generateBookDocumentFixture();
-
-        $book = $this->newInstance($metadata);
-
-        $this->assertTrue(class_exists($metadata->name), "Class does not exist.");
-        $this->assertTrue(method_exists($metadata->namespace . '\DocumentGeneratorBook', '__construct'), "DocumentGeneratorBook::__construct() missing.");
-        $this->assertTrue(method_exists($metadata->namespace . '\DocumentGeneratorBook', 'getId'), "DocumentGeneratorBook::getId() missing.");
-        $this->assertTrue(method_exists($metadata->namespace . '\DocumentGeneratorBook', 'setName'), "DocumentGeneratorBook::setName() missing.");
-        $this->assertTrue(method_exists($metadata->namespace . '\DocumentGeneratorBook', 'getName'), "DocumentGeneratorBook::getName() missing.");
-        $this->assertTrue(method_exists($metadata->namespace . '\DocumentGeneratorBook', 'setAuthor'), "DocumentGeneratorBook::setAuthor() missing.");
-        $this->assertTrue(method_exists($metadata->namespace . '\DocumentGeneratorBook', 'getAuthor'), "DocumentGeneratorBook::getAuthor() missing.");
-        $this->assertTrue(method_exists($metadata->namespace . '\DocumentGeneratorBook', 'getComments'), "DocumentGeneratorBook::getComments() missing.");
-        $this->assertTrue(method_exists($metadata->namespace . '\DocumentGeneratorBook', 'addComment'), "DocumentGeneratorBook::addComment() missing.");
-        $this->assertTrue(method_exists($metadata->namespace . '\DocumentGeneratorBook', 'removeComment'), "DocumentGeneratorBook::removeComment() missing.");
-        $this->assertTrue(method_exists($metadata->namespace . '\DocumentGeneratorBook', 'getSearches'), "DocumentGeneratorBook::getSearches() missing.");
-        $this->assertTrue(method_exists($metadata->namespace . '\DocumentGeneratorBook', 'addSearch'), "DocumentGeneratorBook::addSearch() missing.");
-        $this->assertTrue(method_exists($metadata->namespace . '\DocumentGeneratorBook', 'removeSearch'), "DocumentGeneratorBook::removeSearch() missing.");
-
-        $book->setName('Jonathan H. Wage');
-        $this->assertEquals('Jonathan H. Wage', $book->getName());
-
-        $author = new DocumentGeneratorAuthor();
-        $book->setAuthor($author);
-        $this->assertEquals($author, $book->getAuthor());
-
-        $comment = new DocumentGeneratorComment();
-        $book->addComment($comment);
-        $this->assertInstanceOf('Doctrine\Common\Collections\ArrayCollection', $book->getComments());
-        $this->assertEquals(new \Doctrine\Common\Collections\ArrayCollection(array($comment)), $book->getComments());
-        $book->removeComment($comment);
-        $this->assertEquals(new \Doctrine\Common\Collections\ArrayCollection(array()), $book->getComments());
-    }
-
-    public function testDocumentUpdatingWorks()
-    {
-        $metadata = $this->generateBookDocumentFixture();
-        $metadata->mapField(array('fieldName' => 'test', 'type' => 'string'));
-
-        $this->generator->writeDocumentClass($metadata, $this->tmpDir);
-
-        $this->assertFileExists($this->tmpDir . "/" . $this->namespace . "/DocumentGeneratorBook.php");
-
-        $book = $this->newInstance($metadata);
-        $reflClass = new \ReflectionClass($metadata->name);
-
-        $this->assertTrue($reflClass->hasProperty('name'), "Regenerating keeps property 'name'.");
-        $this->assertTrue($reflClass->hasProperty('status'), "Regenerating keeps property 'status'.");
-        $this->assertTrue($reflClass->hasProperty('id'), "Regenerating keeps property 'id'.");
-
-        $this->assertTrue($reflClass->hasProperty('test'), "Check for property test failed.");
-        $this->assertTrue($reflClass->getProperty('test')->isProtected(), "Check for protected property test failed.");
-        $this->assertTrue($reflClass->hasMethod('getTest'), "Check for method 'getTest' failed.");
-        $this->assertTrue($reflClass->getMethod('getTest')->isPublic(), "Check for public visibility of method 'getTest' failed.");
-        $this->assertTrue($reflClass->hasMethod('setTest'), "Check for method 'getTest' failed.");
-        $this->assertTrue($reflClass->getMethod('getTest')->isPublic(), "Check for public visibility of method 'getTest' failed.");
-    }
-
-    public function testDocumentExtendsStdClass()
-    {
-        $this->generator->setClassToExtend('stdClass');
-        $metadata = $this->generateBookDocumentFixture();
-
-        $book = $this->newInstance($metadata);
-        $this->assertInstanceOf('stdClass', $book);
-    }
-
-    public function testLifecycleCallbacks()
-    {
-        $metadata = $this->generateBookDocumentFixture();
-
-        $book = $this->newInstance($metadata);
-        $reflClass = new \ReflectionClass($metadata->name);
-
-        $this->assertTrue($reflClass->hasMethod('loading'), "Check for postLoad lifecycle callback.");
-        $this->assertTrue($reflClass->hasMethod('willBeRemoved'), "Check for preRemove lifecycle callback.");
-    }
-
-    public function testLoadMetadata()
-    {
-        $metadata = $this->generateBookDocumentFixture();
-
-        $book = $this->newInstance($metadata);
-
-        $cm = new \Doctrine\ODM\MongoDB\Mapping\ClassMetadataInfo($metadata->name);
-        $reader = new \Doctrine\Common\Annotations\AnnotationReader();
-        $driver = new \Doctrine\ODM\MongoDB\Mapping\Driver\AnnotationDriver($reader);
-        $driver->loadMetadataForClass($cm->name, $cm);
-
-        $this->assertEquals($cm->getCollection(), $metadata->getCollection());
-        $this->assertEquals($cm->lifecycleCallbacks, $metadata->lifecycleCallbacks);
-        $this->assertEquals($cm->identifier, $metadata->identifier);
-        $this->assertEquals($cm->idGenerator, $metadata->idGenerator);
-        $this->assertEquals($cm->customRepositoryClassName, $metadata->customRepositoryClassName);
-    }
-
-    public function testLoadPrefixedMetadata()
-    {
-        $metadata = $this->generateBookDocumentFixture();
-
-        $book = $this->newInstance($metadata);
-
-        $cm = new \Doctrine\ODM\MongoDB\Mapping\ClassMetadataInfo($metadata->name);
-        $reader = new \Doctrine\Common\Annotations\AnnotationReader();
-        $driver = new \Doctrine\ODM\MongoDB\Mapping\Driver\AnnotationDriver($reader);
-        $driver->loadMetadataForClass($cm->name, $cm);
-
-        $this->assertEquals($cm->getCollection(), $metadata->getCollection());
-        $this->assertEquals($cm->lifecycleCallbacks, $metadata->lifecycleCallbacks);
-        $this->assertEquals($cm->identifier, $metadata->identifier);
-        $this->assertEquals($cm->idGenerator, $metadata->idGenerator);
-        $this->assertEquals($cm->customRepositoryClassName, $metadata->customRepositoryClassName);
-    }
-
-    public function testTraitPropertiesAndMethodsAreNotDuplicated()
-    {
-        $cmf = $this->dm->getMetadataFactory();
-        $user = new \Doctrine\ODM\MongoDB\Tests\Tools\GH297\User();
-        $metadata = $cmf->getMetadataFor(get_class($user));
-        $metadata->name = $this->namespace . "\User";
-        $metadata->namespace = $this->namespace;
-        $this->generator->writeDocumentClass($metadata, $this->tmpDir);
-        $this->assertFileExists($this->tmpDir . "/" . $this->namespace . "/User.php");
-        require $this->tmpDir . "/" . $this->namespace . "/User.php";
-        $reflClass = new \ReflectionClass($metadata->name);
-        $this->assertFalse($reflClass->hasProperty('address'));
-        $this->assertFalse($reflClass->hasMethod('setAddress'));
-        $this->assertFalse($reflClass->hasMethod('getAddress'));
-    }
-
-    public function testTraitPropertiesAndMethodsAreNotDuplicatedInChildClasses()
-    {
-        $cmf = $this->dm->getMetadataFactory();
-        $user = new \Doctrine\ODM\MongoDB\Tests\Tools\GH297\Admin();
-        $metadata = $cmf->getMetadataFor(get_class($user));
-        $metadata->name = $this->namespace . "\DDC2372Admin";
-        $metadata->namespace = $this->namespace;
-        $this->generator->writeDocumentClass($metadata, $this->tmpDir);
-        $this->assertFileExists($this->tmpDir . "/" . $this->namespace . "/DDC2372Admin.php");
-        require $this->tmpDir . "/" . $this->namespace . "/DDC2372Admin.php";
-        $reflClass = new \ReflectionClass($metadata->name);
-        $this->assertFalse($reflClass->hasProperty('address'));
-        $this->assertFalse($reflClass->hasMethod('setAddress'));
-        $this->assertFalse($reflClass->hasMethod('getAddress'));
-    }
-
-    /**
-     * Tests that properties, getters and setters are not duplicated on children classes
-     *
-     * @see https://github.com/doctrine/mongodb-odm/issues/1299
-     */
-    public function testMethodsAndPropertiesAreNotDuplicatedInChildClasses()
-    {
-        $cmf = $this->dm->getMetadataFactory();
-        $nsDir = $this->tmpDir.'/'.$this->namespace;
-
-        // Copy GH1299User class to temp dir
-        $content = str_replace(
-            'namespace Doctrine\ODM\MongoDB\Tests\Tools\GH1299',
-            'namespace '.$this->namespace,
-            file_get_contents(__DIR__.'/GH1299/GH1299User.php')
-        );
-        $fname = $nsDir.'/GH1299User.php';
-        file_put_contents($fname, $content);
-        require $fname;
-
-        // Generate document class
-        $metadata = $cmf->getMetadataFor($this->namespace.'\GH1299User');
-        $this->generator->writeDocumentClass($metadata, $this->tmpDir);
-
-        // Make a copy of the generated class that does not extend the BaseUser class
-        $source = file_get_contents($fname);
-
-        // class _DDC1590User extends DDC1590Entity { ... }
-        $source2 = str_replace('class GH1299User', 'class _GH1299User', $source);
-        $fname2  = $nsDir.'/_DDC1590User.php';
-        file_put_contents($fname2, $source2);
-        require $fname2;
-
-        $source3 = str_replace('class GH1299User extends BaseUser', 'class __GH1299User', $source);
-        $fname3  = $nsDir.'/_GH1299User.php';
-        file_put_contents($fname3, $source3);
-        require $fname3;
-
-        // The GH1299User class that extends BaseUser should have all properties, getters and setters
-        // (some of them are inherited from BaseUser)
-        $reflClass2 = new \ReflectionClass($this->namespace.'\_GH1299User');
-
-        $this->assertTrue($reflClass2->hasProperty('id'));
-        $this->assertTrue($reflClass2->hasProperty('name'));
-        $this->assertTrue($reflClass2->hasProperty('lastname'));
-
-        $this->assertTrue($reflClass2->hasMethod('getId'));
-        $this->assertFalse($reflClass2->hasMethod('setId'));
-        $this->assertTrue($reflClass2->hasMethod('getName'));
-        $this->assertTrue($reflClass2->hasMethod('setName'));
-        $this->assertTrue($reflClass2->hasMethod('getLastname'));
-        $this->assertTrue($reflClass2->hasMethod('setLastname'));
-
-        // The class that does not extend BaseUser should not have the properties and methods / setters
-        // from the BaseUser class, but only its own specific ones
-        $reflClass3 = new \ReflectionClass($this->namespace.'\__GH1299User');
-
-        $this->assertFalse($reflClass3->hasProperty('id'));
-        $this->assertFalse($reflClass3->hasProperty('name'));
-        $this->assertTrue($reflClass3->hasProperty('lastname'));
-
-        $this->assertFalse($reflClass3->hasMethod('getId'));
-        $this->assertFalse($reflClass3->hasMethod('setId'));
-        $this->assertFalse($reflClass3->hasMethod('getName'));
-        $this->assertFalse($reflClass3->hasMethod('setName'));
-        $this->assertTrue($reflClass3->hasMethod('getLastname'));
-        $this->assertTrue($reflClass3->hasMethod('setLastname'));
-    }
-}
-
-class DocumentGeneratorAuthor {}
-class DocumentGeneratorComment {}
-class DocumentGeneratorSearch {}
diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Tools/DocumentRepositoryGeneratorTest.php b/tests/Doctrine/ODM/MongoDB/Tests/Tools/DocumentRepositoryGeneratorTest.php
deleted file mode 100644
index 67afd92e4f..0000000000
--- a/tests/Doctrine/ODM/MongoDB/Tests/Tools/DocumentRepositoryGeneratorTest.php
+++ /dev/null
@@ -1,106 +0,0 @@
-<?php
-
-namespace Doctrine\ODM\MongoDB\Tests\Tools;
-
-use Doctrine\Common\EventManager;
-use Doctrine\ODM\MongoDB\Hydrator\HydratorFactory;
-use Doctrine\ODM\MongoDB\Mapping\ClassMetadata;
-use Doctrine\ODM\MongoDB\Tools\DocumentRepositoryGenerator;
-use Doctrine\ODM\MongoDB\UnitOfWork;
-use Stubs\DocumentManager;
-
-class DocumentRepositoryGeneratorTest extends \Doctrine\ODM\MongoDB\Tests\BaseTest
-{
-    /**
-     * @var string
-     */
-    private $tmpDir;
-
-    /**
-     * @var DocumentRepositoryGenerator
-     */
-    private $generator;
-
-    /**
-     * @var string
-     */
-    private $testBucket;
-
-    /**
-     * @var string
-     */
-    private $testBucketPath;
-
-    public function setUp()
-    {
-        parent::setUp();
-
-        $this->tmpDir = sys_get_temp_dir();
-
-        // We create a temporary directory for each test
-        $this->testBucket = uniqid("doctrine_mongo_odm_");
-        $this->testBucketPath = $this->tmpDir . DIRECTORY_SEPARATOR . $this->testBucket;
-        mkdir($this->testBucketPath);
-
-        $this->generator = new DocumentRepositoryGenerator();
-    }
-
-    public function tearDown()
-    {
-        parent::tearDown();
-
-        if (isset($this->testBucketPath) && !empty($this->testBucketPath)) {
-            $ri = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($this->testBucketPath));
-            foreach ($ri AS $file) {
-                /* @var $file \SplFileInfo */
-                if ($file->isFile()) {
-                    \unlink($file->getPathname());
-                }
-            }
-            rmdir($this->testBucketPath);
-        }
-    }
-
-    /**
-     * Checks if class files have been generated, and if is possible to load the classes.
-     * @param string $fullClassName
-     */
-    private function tryLoadingRepositoryClass($fullClassName)
-    {
-        $classNameParts = explode('\\', $fullClassName);
-        $simpleClassName = $classNameParts[count($classNameParts)-1];
-
-        $path = $this->testBucketPath . DIRECTORY_SEPARATOR . $simpleClassName .'.php';
-
-        $this->assertFileExists($path);
-
-        require_once $path;
-
-        $dm = new DocumentManager();
-        $em = new EventManager();
-        $hf = new HydratorFactory($dm, $em, $this->testBucketPath, $this->testBucket, 0);
-        $uow = new UnitOfWork($dm, $em, $hf);
-
-        return new $fullClassName($dm, $uow, new ClassMetadata($fullClassName));
-    }
-
-    public function testPersistedDocumentRepositoryClassWithSimpleNamespaceMapping()
-    {
-        $namespace = $this->testBucket;
-
-        $this->generator->writeDocumentRepositoryClass($namespace . '\\TestDocumentRepository', $this->tmpDir);
-
-        $this->tryLoadingRepositoryClass($namespace . '\\TestDocumentRepository');
-    }
-
-    public function testPersistedDocumentRepositoryClassWithArbitraryNamespaceMapping()
-    {
-        $namespace = 'A\B\C\D';
-
-        $this->generator->writeDocumentRepositoryClass(
-            $namespace . '\\TestDocumentRepository', $this->testBucketPath, $namespace
-        );
-
-        $this->tryLoadingRepositoryClass($namespace . '\\TestDocumentRepository');
-    }
-}