Julio Montoya 13 gadi atpakaļ
vecāks
revīzija
061feca3d9
100 mainītis faili ar 13804 papildinājumiem un 1 dzēšanām
  1. 3 1
      main/inc/global.inc.php
  2. 78 0
      main/inc/lib/db.lib.php
  3. 75 0
      main/inc/lib/symfony/Doctrine/Common/Annotations/Annotation.php
  4. 47 0
      main/inc/lib/symfony/Doctrine/Common/Annotations/Annotation/Attribute.php
  5. 37 0
      main/inc/lib/symfony/Doctrine/Common/Annotations/Annotation/Attributes.php
  6. 44 0
      main/inc/lib/symfony/Doctrine/Common/Annotations/Annotation/IgnoreAnnotation.php
  7. 33 0
      main/inc/lib/symfony/Doctrine/Common/Annotations/Annotation/Required.php
  8. 105 0
      main/inc/lib/symfony/Doctrine/Common/Annotations/Annotation/Target.php
  9. 111 0
      main/inc/lib/symfony/Doctrine/Common/Annotations/AnnotationException.php
  10. 301 0
      main/inc/lib/symfony/Doctrine/Common/Annotations/AnnotationReader.php
  11. 129 0
      main/inc/lib/symfony/Doctrine/Common/Annotations/AnnotationRegistry.php
  12. 179 0
      main/inc/lib/symfony/Doctrine/Common/Annotations/CachedReader.php
  13. 140 0
      main/inc/lib/symfony/Doctrine/Common/Annotations/DocLexer.php
  14. 891 0
      main/inc/lib/symfony/Doctrine/Common/Annotations/DocParser.php
  15. 209 0
      main/inc/lib/symfony/Doctrine/Common/Annotations/FileCacheReader.php
  16. 94 0
      main/inc/lib/symfony/Doctrine/Common/Annotations/IndexedReader.php
  17. 203 0
      main/inc/lib/symfony/Doctrine/Common/Annotations/PhpParser.php
  18. 35 0
      main/inc/lib/symfony/Doctrine/Common/Annotations/Reader.php
  19. 155 0
      main/inc/lib/symfony/Doctrine/Common/Annotations/SimpleAnnotationReader.php
  20. 97 0
      main/inc/lib/symfony/Doctrine/Common/Cache/ApcCache.php
  21. 96 0
      main/inc/lib/symfony/Doctrine/Common/Cache/ArrayCache.php
  22. 102 0
      main/inc/lib/symfony/Doctrine/Common/Cache/Cache.php
  23. 188 0
      main/inc/lib/symfony/Doctrine/Common/Cache/CacheProvider.php
  24. 118 0
      main/inc/lib/symfony/Doctrine/Common/Cache/MemcacheCache.php
  25. 121 0
      main/inc/lib/symfony/Doctrine/Common/Cache/MemcachedCache.php
  26. 92 0
      main/inc/lib/symfony/Doctrine/Common/Cache/WinCacheCache.php
  27. 110 0
      main/inc/lib/symfony/Doctrine/Common/Cache/XcacheCache.php
  28. 84 0
      main/inc/lib/symfony/Doctrine/Common/Cache/ZendDataCache.php
  29. 262 0
      main/inc/lib/symfony/Doctrine/Common/ClassLoader.php
  30. 447 0
      main/inc/lib/symfony/Doctrine/Common/Collections/ArrayCollection.php
  31. 243 0
      main/inc/lib/symfony/Doctrine/Common/Collections/Collection.php
  32. 28 0
      main/inc/lib/symfony/Doctrine/Common/CommonException.php
  33. 47 0
      main/inc/lib/symfony/Doctrine/Common/Comparable.php
  34. 69 0
      main/inc/lib/symfony/Doctrine/Common/EventArgs.php
  35. 136 0
      main/inc/lib/symfony/Doctrine/Common/EventManager.php
  36. 45 0
      main/inc/lib/symfony/Doctrine/Common/EventSubscriber.php
  37. 266 0
      main/inc/lib/symfony/Doctrine/Common/Lexer.php
  38. 45 0
      main/inc/lib/symfony/Doctrine/Common/NotifyPropertyChanged.php
  39. 218 0
      main/inc/lib/symfony/Doctrine/Common/Persistence/AbstractManagerRegistry.php
  40. 63 0
      main/inc/lib/symfony/Doctrine/Common/Persistence/ConnectionRegistry.php
  41. 77 0
      main/inc/lib/symfony/Doctrine/Common/Persistence/Event/LifecycleEventArgs.php
  42. 76 0
      main/inc/lib/symfony/Doctrine/Common/Persistence/Event/LoadClassMetadataEventArgs.php
  43. 59 0
      main/inc/lib/symfony/Doctrine/Common/Persistence/Event/ManagerEventArgs.php
  44. 84 0
      main/inc/lib/symfony/Doctrine/Common/Persistence/Event/OnClearEventArgs.php
  45. 129 0
      main/inc/lib/symfony/Doctrine/Common/Persistence/Event/PreUpdateEventArgs.php
  46. 112 0
      main/inc/lib/symfony/Doctrine/Common/Persistence/ManagerRegistry.php
  47. 359 0
      main/inc/lib/symfony/Doctrine/Common/Persistence/Mapping/AbstractClassMetadataFactory.php
  48. 165 0
      main/inc/lib/symfony/Doctrine/Common/Persistence/Mapping/ClassMetadata.php
  49. 74 0
      main/inc/lib/symfony/Doctrine/Common/Persistence/Mapping/ClassMetadataFactory.php
  50. 214 0
      main/inc/lib/symfony/Doctrine/Common/Persistence/Mapping/Driver/AnnotationDriver.php
  51. 169 0
      main/inc/lib/symfony/Doctrine/Common/Persistence/Mapping/Driver/DefaultFileLocator.php
  52. 178 0
      main/inc/lib/symfony/Doctrine/Common/Persistence/Mapping/Driver/FileDriver.php
  53. 69 0
      main/inc/lib/symfony/Doctrine/Common/Persistence/Mapping/Driver/FileLocator.php
  54. 56 0
      main/inc/lib/symfony/Doctrine/Common/Persistence/Mapping/Driver/MappingDriver.php
  55. 125 0
      main/inc/lib/symfony/Doctrine/Common/Persistence/Mapping/Driver/MappingDriverChain.php
  56. 70 0
      main/inc/lib/symfony/Doctrine/Common/Persistence/Mapping/Driver/PHPDriver.php
  57. 131 0
      main/inc/lib/symfony/Doctrine/Common/Persistence/Mapping/Driver/StaticPHPDriver.php
  58. 198 0
      main/inc/lib/symfony/Doctrine/Common/Persistence/Mapping/Driver/SymfonyFileLocator.php
  59. 57 0
      main/inc/lib/symfony/Doctrine/Common/Persistence/Mapping/MappingException.php
  60. 80 0
      main/inc/lib/symfony/Doctrine/Common/Persistence/Mapping/ReflectionService.php
  61. 102 0
      main/inc/lib/symfony/Doctrine/Common/Persistence/Mapping/RuntimeReflectionService.php
  62. 107 0
      main/inc/lib/symfony/Doctrine/Common/Persistence/Mapping/StaticReflectionService.php
  63. 143 0
      main/inc/lib/symfony/Doctrine/Common/Persistence/ObjectManager.php
  64. 49 0
      main/inc/lib/symfony/Doctrine/Common/Persistence/ObjectManagerAware.php
  65. 78 0
      main/inc/lib/symfony/Doctrine/Common/Persistence/ObjectRepository.php
  66. 233 0
      main/inc/lib/symfony/Doctrine/Common/Persistence/PersistentObject.php
  67. 60 0
      main/inc/lib/symfony/Doctrine/Common/Persistence/Proxy.php
  68. 48 0
      main/inc/lib/symfony/Doctrine/Common/PropertyChangedListener.php
  69. 103 0
      main/inc/lib/symfony/Doctrine/Common/Util/ClassUtils.php
  70. 123 0
      main/inc/lib/symfony/Doctrine/Common/Util/Debug.php
  71. 72 0
      main/inc/lib/symfony/Doctrine/Common/Util/Inflector.php
  72. 55 0
      main/inc/lib/symfony/Doctrine/Common/Version.php
  73. 94 0
      main/inc/lib/symfony/Doctrine/DBAL/Cache/ArrayStatement.php
  74. 37 0
      main/inc/lib/symfony/Doctrine/DBAL/Cache/CacheException.php
  75. 131 0
      main/inc/lib/symfony/Doctrine/DBAL/Cache/QueryCacheProfile.php
  76. 255 0
      main/inc/lib/symfony/Doctrine/DBAL/Cache/ResultCacheStatement.php
  77. 113 0
      main/inc/lib/symfony/Doctrine/DBAL/Configuration.php
  78. 1168 0
      main/inc/lib/symfony/Doctrine/DBAL/Connection.php
  79. 54 0
      main/inc/lib/symfony/Doctrine/DBAL/ConnectionException.php
  80. 328 0
      main/inc/lib/symfony/Doctrine/DBAL/Connections/MasterSlaveConnection.php
  81. 88 0
      main/inc/lib/symfony/Doctrine/DBAL/DBALException.php
  82. 72 0
      main/inc/lib/symfony/Doctrine/DBAL/Driver.php
  83. 42 0
      main/inc/lib/symfony/Doctrine/DBAL/Driver/Connection.php
  84. 115 0
      main/inc/lib/symfony/Doctrine/DBAL/Driver/IBMDB2/DB2Connection.php
  85. 111 0
      main/inc/lib/symfony/Doctrine/DBAL/Driver/IBMDB2/DB2Driver.php
  86. 27 0
      main/inc/lib/symfony/Doctrine/DBAL/Driver/IBMDB2/DB2Exception.php
  87. 215 0
      main/inc/lib/symfony/Doctrine/DBAL/Driver/IBMDB2/DB2Statement.php
  88. 69 0
      main/inc/lib/symfony/Doctrine/DBAL/Driver/Mysqli/Driver.php
  89. 146 0
      main/inc/lib/symfony/Doctrine/DBAL/Driver/Mysqli/MysqliConnection.php
  90. 26 0
      main/inc/lib/symfony/Doctrine/DBAL/Driver/Mysqli/MysqliException.php
  91. 335 0
      main/inc/lib/symfony/Doctrine/DBAL/Driver/Mysqli/MysqliStatement.php
  92. 95 0
      main/inc/lib/symfony/Doctrine/DBAL/Driver/OCI8/Driver.php
  93. 164 0
      main/inc/lib/symfony/Doctrine/DBAL/Driver/OCI8/OCI8Connection.php
  94. 30 0
      main/inc/lib/symfony/Doctrine/DBAL/Driver/OCI8/OCI8Exception.php
  95. 252 0
      main/inc/lib/symfony/Doctrine/DBAL/Driver/OCI8/OCI8Statement.php
  96. 40 0
      main/inc/lib/symfony/Doctrine/DBAL/Driver/PDOConnection.php
  97. 126 0
      main/inc/lib/symfony/Doctrine/DBAL/Driver/PDOIbm/Driver.php
  98. 102 0
      main/inc/lib/symfony/Doctrine/DBAL/Driver/PDOMySql/Driver.php
  99. 98 0
      main/inc/lib/symfony/Doctrine/DBAL/Driver/PDOOracle/Driver.php
  100. 70 0
      main/inc/lib/symfony/Doctrine/DBAL/Driver/PDOPgSql/Driver.php

+ 3 - 1
main/inc/global.inc.php

@@ -116,7 +116,9 @@ require_once $lib_path.'tracking.lib.php';
 require_once $lib_path.'formvalidator/FormValidator.class.php';
 require_once $lib_path.'online.inc.php';
 
-
+//Here we load the new Doctrine class (just for tests)
+//require_once $lib_path.'db.lib.php';
+//$db = new db();
 
 /*  DATABASE CONNECTION  */
 

+ 78 - 0
main/inc/lib/db.lib.php

@@ -0,0 +1,78 @@
+<?php
+/**
+ * This is a draft 
+ *  
+ */
+require_once api_get_path(LIBRARY_PATH).'symfony/symfony/Component/ClassLoader/UniversalClassLoader.php';
+use Doctrine\Common\ClassLoader;
+use Doctrine\DBAL\DriverManager;
+use Doctrine\ORM\Tools\Setup;
+
+require_once api_get_path(LIBRARY_PATH).'symfony/Doctrine/Common/ClassLoader.php';
+require_once api_get_path(LIBRARY_PATH).'symfony/Doctrine/ORM/Tools/Setup.php';
+
+use Doctrine\ORM\EntityManager,
+    Doctrine\ORM\Configuration;
+
+
+class db {
+    
+    function __construct() {
+        global $_configuration;
+        $connectionParams = array(
+            'dbname'    => $_configuration['main_database'],
+            'user'      => $_configuration['db_user'],
+            'password'  => $_configuration['db_password'],
+            'host'      => $_configuration['db_host'],
+            'driver'    => 'pdo_mysql',
+        );
+        
+  /*      $classLoader = new ClassLoader('Doctrine', api_get_path(LIBRARY_PATH).'symfony');
+        $classLoader->register();*/
+       /* $config = new Doctrine\DBAL\Configuration();                
+        
+        $conn = DriverManager::getConnection($connectionParams, $config);
+        
+        $sql = "SELECT * FROM user";
+        $stmt = $conn->query($sql); // Simple, but has several drawbacks        
+        */       
+             
+        $lib = api_get_path(LIBRARY_PATH).'symfony';
+        Doctrine\ORM\Tools\Setup::registerAutoloadDirectory($lib);
+        
+        $config = new Configuration;
+        $applicationMode = 'development';
+        
+        if ($applicationMode == "development") {
+            $cache = new \Doctrine\Common\Cache\ArrayCache;
+        } else {
+            $cache = new \Doctrine\Common\Cache\ApcCache;
+        }
+        $config->setMetadataCacheImpl($cache);
+        $driverImpl = $config->newDefaultAnnotationDriver(api_get_path(LIBRARY_PATH).'symfony/app_obj/entities');
+        $config->setMetadataDriverImpl($driverImpl);
+        $config->setQueryCacheImpl($cache);
+        $config->setProxyDir(api_get_path(LIBRARY_PATH).'proxies');
+        $config->setProxyNamespace('App\Proxies');        
+        
+        if ($applicationMode == "development") {
+            $config->setAutoGenerateProxyClasses(true);
+        } else {
+            $config->setAutoGenerateProxyClasses(false);
+        }
+        
+        $config = Setup::createYAMLMetadataConfiguration(array(api_get_path(LIBRARY_PATH).'symfony/app_obj/metadata'), true);
+                
+        $em = EntityManager::create($connectionParams, $config);
+        
+        require_once api_get_path(LIBRARY_PATH).'symfony/app_obj/entities/user.php';
+        
+        $user = new User();
+        $user->setUsername('salut');
+        $em->persist($user);
+        $em->flush();
+        echo "Created User with ID " . $user->getId() . "\n";
+    }
+}
+
+

+ 75 - 0
main/inc/lib/symfony/Doctrine/Common/Annotations/Annotation.php

@@ -0,0 +1,75 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Annotations;
+
+/**
+ * Annotations class
+ *
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class Annotation
+{
+    /**
+     * Value property. Common among all derived classes.
+     *
+     * @var string
+     */
+    public $value;
+
+    /**
+     * Constructor
+     *
+     * @param array $data Key-value for properties to be defined in this class
+     */
+    public final function __construct(array $data)
+    {
+        foreach ($data as $key => $value) {
+            $this->$key = $value;
+        }
+    }
+
+    /**
+     * Error handler for unknown property accessor in Annotation class.
+     *
+     * @param string $name Unknown property name
+     */
+    public function __get($name)
+    {
+        throw new \BadMethodCallException(
+            sprintf("Unknown property '%s' on annotation '%s'.", $name, get_class($this))
+        );
+    }
+
+    /**
+     * Error handler for unknown property mutator in Annotation class.
+     *
+     * @param string $name Unkown property name
+     * @param mixed $value Property value
+     */
+    public function __set($name, $value)
+    {
+        throw new \BadMethodCallException(
+            sprintf("Unknown property '%s' on annotation '%s'.", $name, get_class($this))
+        );
+    }
+}

+ 47 - 0
main/inc/lib/symfony/Doctrine/Common/Annotations/Annotation/Attribute.php

@@ -0,0 +1,47 @@
+<?php
+
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Annotations\Annotation;
+
+/**
+ * Annotation that can be used to signal to the parser
+ * to check the attribute type during the parsing process.
+ *
+ * @author Fabio B. Silva <fabio.bat.silva@gmail.com>
+ *
+ * @Annotation
+ */
+final class Attribute
+{
+    /**
+     * @var string
+     */
+    public $name;
+
+    /**
+     * @var string
+     */
+    public $type;
+
+    /**
+     * @var boolean
+     */
+    public $required = false;
+}

+ 37 - 0
main/inc/lib/symfony/Doctrine/Common/Annotations/Annotation/Attributes.php

@@ -0,0 +1,37 @@
+<?php
+
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Annotations\Annotation;
+
+/**
+ * Annotation that can be used to signal to the parser
+ * to check the types of all declared attributes during the parsing process.
+ *
+ * @author Fabio B. Silva <fabio.bat.silva@gmail.com>
+ *
+ * @Annotation
+ */
+final class Attributes
+{
+    /**
+     * @var array<Doctrine\Common\Annotations\Annotation\Attribute>
+     */
+    public $value;
+}

+ 44 - 0
main/inc/lib/symfony/Doctrine/Common/Annotations/Annotation/IgnoreAnnotation.php

@@ -0,0 +1,44 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Annotations\Annotation;
+
+/**
+ * Annotation that can be used to signal to the parser to ignore specific
+ * annotations during the parsing process.
+ *
+ * @Annotation
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+final class IgnoreAnnotation
+{
+    public $names;
+
+    public function __construct(array $values)
+    {
+        if (is_string($values['value'])) {
+            $values['value'] = array($values['value']);
+        }
+        if (!is_array($values['value'])) {
+            throw new \RuntimeException(sprintf('@IgnoreAnnotation expects either a string name, or an array of strings, but got %s.', json_encode($values['value'])));
+        }
+
+        $this->names = $values['value'];
+    }
+}

+ 33 - 0
main/inc/lib/symfony/Doctrine/Common/Annotations/Annotation/Required.php

@@ -0,0 +1,33 @@
+<?php
+
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Annotations\Annotation;
+
+/**
+ * Annotation that can be used to signal to the parser
+ * to check if that attribute is required during the parsing process.
+ *
+ * @author Fabio B. Silva <fabio.bat.silva@gmail.com>
+ *
+ * @Annotation
+ */
+final class Required
+{
+}

+ 105 - 0
main/inc/lib/symfony/Doctrine/Common/Annotations/Annotation/Target.php

@@ -0,0 +1,105 @@
+<?php
+
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Annotations\Annotation;
+
+/**
+ * Annotation that can be used to signal to the parser
+ * to check the annotation target during the parsing process.
+ *
+ * @author Fabio B. Silva <fabio.bat.silva@gmail.com>
+ *
+ * @Annotation
+ */
+final class Target
+{
+    const TARGET_CLASS              = 1;
+    const TARGET_METHOD             = 2;
+    const TARGET_PROPERTY           = 4;
+    const TARGET_ANNOTATION         = 8;
+    const TARGET_ALL                = 15;
+
+    /**
+     * @var array
+     */
+    private static $map = array(
+        'ALL'         => self::TARGET_ALL,
+        'CLASS'       => self::TARGET_CLASS,
+        'METHOD'      => self::TARGET_METHOD,
+        'PROPERTY'    => self::TARGET_PROPERTY,
+        'ANNOTATION'  => self::TARGET_ANNOTATION,
+    );
+
+    /**
+     * @var array
+     */
+    public $value;
+
+    /**
+     * Targets as bitmask.
+     *
+     * @var integer
+     */
+    public $targets;
+
+    /**
+     * Literal target declaration.
+     *
+     * @var integer
+     */
+    public $literal;
+
+    /**
+     * Annotation construct
+     *
+     * @param array $values
+     */
+    public function __construct(array $values)
+    {
+        if (!isset($values['value'])){
+            $values['value'] = null;
+        }
+        if (is_string($values['value'])){
+            $values['value'] = array($values['value']);
+        }
+        if (!is_array($values['value'])){
+            throw new \InvalidArgumentException(
+                sprintf('@Target expects either a string value, or an array of strings, "%s" given.',
+                    is_object($values['value']) ? get_class($values['value']) : gettype($values['value'])
+                )
+            );
+        }
+
+        $bitmask = 0;
+        foreach ($values['value'] as $literal) {
+            if(!isset(self::$map[$literal])){
+                throw new \InvalidArgumentException(
+                    sprintf('Invalid Target "%s". Available targets: [%s]',
+                            $literal,  implode(', ', array_keys(self::$map)))
+                );
+            }
+            $bitmask += self::$map[$literal];
+        }
+
+        $this->targets  = $bitmask;
+        $this->value    = $values['value'];
+        $this->literal  = implode(', ', $this->value);
+    }
+}

+ 111 - 0
main/inc/lib/symfony/Doctrine/Common/Annotations/AnnotationException.php

@@ -0,0 +1,111 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Annotations;
+
+/**
+ * Description of AnnotationException
+ *
+ * @since   2.0
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class AnnotationException extends \Exception
+{
+    /**
+     * Creates a new AnnotationException describing a Syntax error.
+     *
+     * @param string $message Exception message
+     * @return AnnotationException
+     */
+    public static function syntaxError($message)
+    {
+        return new self('[Syntax Error] ' . $message);
+    }
+
+    /**
+     * Creates a new AnnotationException describing a Semantical error.
+     *
+     * @param string $message Exception message
+     * @return AnnotationException
+     */
+    public static function semanticalError($message)
+    {
+        return new self('[Semantical Error] ' . $message);
+    }
+
+    /**
+     * Creates a new AnnotationException describing an error which occurred during
+     * the creation of the annotation.
+     *
+     * @since 2.2
+     * @param string $message
+     * @return AnnotationException
+     */
+    public static function creationError($message)
+    {
+        return new self('[Creation Error] ' . $message);
+    }
+
+    /**
+     * Creates a new AnnotationException describing an type error of an attribute.
+     *
+     * @since 2.2
+     * @param string $attributeName
+     * @param string $annotationName
+     * @param string $context
+     * @param string $expected
+     * @param mixed $actual
+     * @return AnnotationException
+     */
+    public static function typeError($attributeName, $annotationName, $context, $expected, $actual)
+    {
+        return new self(sprintf(
+            '[Type Error] Attribute "%s" of @%s declared on %s expects %s, but got %s.',
+            $attributeName,
+            $annotationName,
+            $context,
+            $expected,
+            is_object($actual) ? 'an instance of '.get_class($actual) : gettype($actual)
+        ));
+    }
+
+    /**
+     * Creates a new AnnotationException describing an required error of an attribute.
+     *
+     * @since 2.2
+     * @param string $attributeName
+     * @param string $annotationName
+     * @param string $context
+     * @param string $expected
+     * @return AnnotationException
+     */
+    public static function requiredError($attributeName, $annotationName, $context, $expected)
+    {
+        return new self(sprintf(
+            '[Type Error] Attribute "%s" of @%s declared on %s expects %s. This value should not be null.',
+            $attributeName,
+            $annotationName,
+            $context,
+            $expected
+        ));
+    }
+}

+ 301 - 0
main/inc/lib/symfony/Doctrine/Common/Annotations/AnnotationReader.php

@@ -0,0 +1,301 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Annotations;
+
+use Doctrine\Common\Annotations\Annotation\IgnoreAnnotation;
+use Doctrine\Common\Annotations\Annotation\Target;
+use Closure;
+use ReflectionClass;
+use ReflectionMethod;
+use ReflectionProperty;
+
+/**
+ * A reader for docblock annotations.
+ *
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ * @author  Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+final class AnnotationReader implements Reader
+{
+    /**
+     * Global map for imports.
+     *
+     * @var array
+     */
+    private static $globalImports = array(
+        'ignoreannotation' => 'Doctrine\Common\Annotations\Annotation\IgnoreAnnotation',
+    );
+
+    /**
+     * A list with annotations that are not causing exceptions when not resolved to an annotation class.
+     *
+     * The names are case sensitive.
+     *
+     * @var array
+     */
+    private static $globalIgnoredNames = array(
+        'access'=> true, 'author'=> true, 'copyright'=> true, 'deprecated'=> true,
+        'example'=> true, 'ignore'=> true, 'internal'=> true, 'link'=> true, 'see'=> true,
+        'since'=> true, 'tutorial'=> true, 'version'=> true, 'package'=> true,
+        'subpackage'=> true, 'name'=> true, 'global'=> true, 'param'=> true,
+        'return'=> true, 'staticvar'=> true, 'category'=> true, 'staticVar'=> true,
+        'static'=> true, 'var'=> true, 'throws'=> true, 'inheritdoc'=> true,
+        'inheritDoc'=> true, 'license'=> true, 'todo'=> true, 'deprecated'=> true,
+        'deprec'=> true, 'author'=> true, 'property' => true, 'method' => true,
+        'abstract'=> true, 'exception'=> true, 'magic' => true, 'api' => true,
+        'final'=> true, 'filesource'=> true, 'throw' => true, 'uses' => true,
+        'usedby'=> true, 'private' => true, 'Annotation' => true, 'override' => true,
+        'codeCoverageIgnore' => true, 'codeCoverageIgnoreStart' => true, 'codeCoverageIgnoreEnd' => true,
+        'Required' => true, 'Attribute' => true, 'Attributes' => true,
+        'Target' => true, 'SuppressWarnings' => true,
+    );
+
+    /**
+     * Add a new annotation to the globally ignored annotation names with regard to exception handling.
+     *
+     * @param string $name
+     */
+    static public function addGlobalIgnoredName($name)
+    {
+        self::$globalIgnoredNames[$name] = true;
+    }
+
+    /**
+     * Annotations Parser
+     *
+     * @var Doctrine\Common\Annotations\DocParser
+     */
+    private $parser;
+
+    /**
+     * Annotations Parser used to collect parsing metadata
+     *
+     * @var Doctrine\Common\Annotations\DocParser
+     */
+    private $preParser;
+
+    /**
+     * PHP Parser used to collect imports.
+     *
+     * @var Doctrine\Common\Annotations\PhpParser
+     */
+    private $phpParser;
+
+    /**
+     * In-memory cache mechanism to store imported annotations per class.
+     *
+     * @var array
+     */
+    private $imports = array();
+
+    /**
+     * In-memory cache mechanism to store ignored annotations per class.
+     *
+     * @var array
+     */
+    private $ignoredAnnotationNames = array();
+
+    /**
+     * Constructor.
+     *
+     * Initializes a new AnnotationReader.
+     */
+    public function __construct()
+    {
+        AnnotationRegistry::registerFile(__DIR__ . '/Annotation/IgnoreAnnotation.php');
+
+        $this->parser = new DocParser;
+
+        $this->preParser = new DocParser;
+        $this->preParser->setImports(self::$globalImports);
+        $this->preParser->setIgnoreNotImportedAnnotations(true);
+
+        $this->phpParser = new PhpParser;
+    }
+
+    /**
+     * Gets the annotations applied to a class.
+     *
+     * @param ReflectionClass $class The ReflectionClass of the class from which
+     *                               the class annotations should be read.
+     * @return array An array of Annotations.
+     */
+    public function getClassAnnotations(ReflectionClass $class)
+    {
+        $this->parser->setTarget(Target::TARGET_CLASS);
+        $this->parser->setImports($this->getImports($class));
+        $this->parser->setIgnoredAnnotationNames($this->getIgnoredAnnotationNames($class));
+
+        return $this->parser->parse($class->getDocComment(), 'class ' . $class->getName());
+    }
+
+    /**
+     * Gets a class annotation.
+     *
+     * @param ReflectionClass $class The ReflectionClass of the class from which
+     *                               the class annotations should be read.
+     * @param string $annotationName The name of the annotation.
+     * @return The Annotation or NULL, if the requested annotation does not exist.
+     */
+    public function getClassAnnotation(ReflectionClass $class, $annotationName)
+    {
+        $annotations = $this->getClassAnnotations($class);
+
+        foreach ($annotations as $annotation) {
+            if ($annotation instanceof $annotationName) {
+                return $annotation;
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Gets the annotations applied to a property.
+     *
+     * @param ReflectionProperty $property The ReflectionProperty of the property
+     *                                     from which the annotations should be read.
+     * @return array An array of Annotations.
+     */
+    public function getPropertyAnnotations(ReflectionProperty $property)
+    {
+        $class = $property->getDeclaringClass();
+        $context = 'property ' . $class->getName() . "::\$" . $property->getName();
+        $this->parser->setTarget(Target::TARGET_PROPERTY);
+        $this->parser->setImports($this->getImports($class));
+        $this->parser->setIgnoredAnnotationNames($this->getIgnoredAnnotationNames($class));
+
+        return $this->parser->parse($property->getDocComment(), $context);
+    }
+
+    /**
+     * Gets a property annotation.
+     *
+     * @param ReflectionProperty $property
+     * @param string $annotationName The name of the annotation.
+     * @return The Annotation or NULL, if the requested annotation does not exist.
+     */
+    public function getPropertyAnnotation(ReflectionProperty $property, $annotationName)
+    {
+        $annotations = $this->getPropertyAnnotations($property);
+
+        foreach ($annotations as $annotation) {
+            if ($annotation instanceof $annotationName) {
+                return $annotation;
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Gets the annotations applied to a method.
+     *
+     * @param ReflectionMethod $property The ReflectionMethod of the method from which
+     *                                   the annotations should be read.
+     * @return array An array of Annotations.
+     */
+    public function getMethodAnnotations(ReflectionMethod $method)
+    {
+        $class = $method->getDeclaringClass();
+        $context = 'method ' . $class->getName() . '::' . $method->getName() . '()';
+        $this->parser->setTarget(Target::TARGET_METHOD);
+        $this->parser->setImports($this->getImports($class));
+        $this->parser->setIgnoredAnnotationNames($this->getIgnoredAnnotationNames($class));
+
+        return $this->parser->parse($method->getDocComment(), $context);
+    }
+
+    /**
+     * Gets a method annotation.
+     *
+     * @param ReflectionMethod $method
+     * @param string $annotationName The name of the annotation.
+     * @return The Annotation or NULL, if the requested annotation does not exist.
+     */
+    public function getMethodAnnotation(ReflectionMethod $method, $annotationName)
+    {
+        $annotations = $this->getMethodAnnotations($method);
+
+        foreach ($annotations as $annotation) {
+            if ($annotation instanceof $annotationName) {
+                return $annotation;
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Returns the ignored annotations for the given class.
+     *
+     * @param ReflectionClass $class
+     * @return array
+     */
+    private function getIgnoredAnnotationNames(ReflectionClass $class)
+    {
+        if (isset($this->ignoredAnnotationNames[$name = $class->getName()])) {
+            return $this->ignoredAnnotationNames[$name];
+        }
+        $this->collectParsingMetadata($class);
+
+        return $this->ignoredAnnotationNames[$name];
+    }
+
+    private function getImports(ReflectionClass $class)
+    {
+        if (isset($this->imports[$name = $class->getName()])) {
+            return $this->imports[$name];
+        }
+        $this->collectParsingMetadata($class);
+
+        return $this->imports[$name];
+    }
+
+    /**
+     * Collects parsing metadata for a given class
+     *
+     * @param ReflectionClass $class
+     */
+    private function collectParsingMetadata(ReflectionClass $class)
+    {
+        $ignoredAnnotationNames = self::$globalIgnoredNames;
+
+        $annotations = $this->preParser->parse($class->getDocComment(), 'class '.$class->name);
+        foreach ($annotations as $annotation) {
+            if ($annotation instanceof IgnoreAnnotation) {
+                foreach ($annotation->names AS $annot) {
+                    $ignoredAnnotationNames[$annot] = true;
+                }
+            }
+        }
+
+        $name = $class->getName();
+        $this->imports[$name] = array_merge(
+            self::$globalImports,
+            $this->phpParser->parseClass($class),
+            array('__NAMESPACE__' => $class->getNamespaceName())
+        );
+        $this->ignoredAnnotationNames[$name] = $ignoredAnnotationNames;
+    }
+}

+ 129 - 0
main/inc/lib/symfony/Doctrine/Common/Annotations/AnnotationRegistry.php

@@ -0,0 +1,129 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Annotations;
+
+final class AnnotationRegistry
+{
+    /**
+     * A map of namespaces to use for autoloading purposes based on a PSR-0 convention.
+     *
+     * Contains the namespace as key and an array of directories as value. If the value is NULL
+     * the include path is used for checking for the corresponding file.
+     *
+     * This autoloading mechanism does not utilize the PHP autoloading but implements autoloading on its own.
+     *
+     * @var array
+     */
+    static private $autoloadNamespaces = array();
+
+    /**
+     * A map of autoloader callables.
+     *
+     * @var array
+     */
+    static private $loaders = array();
+
+    static public function reset()
+    {
+        self::$autoloadNamespaces = array();
+        self::$loaders = array();
+    }
+
+    static public function registerFile($file)
+    {
+        require_once $file;
+    }
+
+    /**
+     * Add a namespace with one or many directories to look for files or null for the include path.
+     *
+     * Loading of this namespaces will be done with a PSR-0 namespace loading algorithm.
+     *
+     * @param string $namespace
+     * @param string|array|null $dirs
+     */
+    static public function registerAutoloadNamespace($namespace, $dirs = null)
+    {
+        self::$autoloadNamespaces[$namespace] = $dirs;
+    }
+
+    /**
+     * Register multiple namespaces
+     *
+     * Loading of this namespaces will be done with a PSR-0 namespace loading algorithm.
+     *
+     * @param array $namespaces
+     */
+    static public function registerAutoloadNamespaces(array $namespaces)
+    {
+        self::$autoloadNamespaces = array_merge(self::$autoloadNamespaces, $namespaces);
+    }
+
+    /**
+     * Register an autoloading callabale for annotations, much like spl_autoload_register().
+     *
+     * NOTE: These class loaders HAVE to be silent when a class was not found!
+     * IMPORTANT: Loaders have to return true if they loaded a class that could contain the searched annotation class.
+     *
+     * @param callabale $callabale
+     */
+    static public function registerLoader($callabale)
+    {
+        if (!is_callable($callabale)) {
+            throw new \InvalidArgumentException("A callable is expected in AnnotationRegistry::registerLoader().");
+        }
+        self::$loaders[] = $callabale;
+    }
+
+    /**
+     * Autoload an annotation class silently.
+     *
+     * @param string $class
+     * @return void
+     */
+    static public function loadAnnotationClass($class)
+    {
+        foreach (self::$autoloadNamespaces AS $namespace => $dirs) {
+            if (strpos($class, $namespace) === 0) {
+                $file = str_replace("\\", DIRECTORY_SEPARATOR, $class) . ".php";
+                if ($dirs === null) {
+                    if ($path = stream_resolve_include_path($file)) {
+                        require $path;
+                        return true;
+                    }
+                } else {
+                    foreach((array)$dirs AS $dir) {
+                        if (file_exists($dir . DIRECTORY_SEPARATOR . $file)) {
+                            require $dir . DIRECTORY_SEPARATOR . $file;
+                            return true;
+                        }
+                    }
+                }
+            }
+        }
+
+        foreach (self::$loaders AS $loader) {
+            if (call_user_func($loader, $class) === true) {
+                return true;
+            }
+        }
+        return false;
+    }
+}

+ 179 - 0
main/inc/lib/symfony/Doctrine/Common/Annotations/CachedReader.php

@@ -0,0 +1,179 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Annotations;
+
+use Doctrine\Common\Cache\Cache;
+
+/**
+ * A cache aware annotation reader.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ */
+final class CachedReader implements Reader
+{
+    private static $CACHE_SALT = '@[Annot]';
+
+    /**
+     * @var Reader
+     */
+    private $delegate;
+
+    /**
+     * @var Cache
+     */
+    private $cache;
+
+    /**
+     * @var boolean
+     */
+    private $debug;
+
+    /**
+     * @var array
+     */
+    private $loadedAnnotations;
+
+    /**
+     * @param Reader $reader
+     * @param Cache $cache
+     */
+    public function __construct(Reader $reader, Cache $cache, $debug = false)
+    {
+        $this->delegate = $reader;
+        $this->cache = $cache;
+        $this->debug = $debug;
+    }
+
+    public function getClassAnnotations(\ReflectionClass $class)
+    {
+        $cacheKey = $class->getName() . self::$CACHE_SALT;
+
+        if (isset($this->loadedAnnotations[$cacheKey])) {
+            return $this->loadedAnnotations[$cacheKey];
+        }
+
+        // Attempt to grab data from cache
+        if (($data = $this->cache->fetch($cacheKey)) !== false) {
+            if (!$this->debug || $this->isCacheFresh($cacheKey, $class)) {
+                return $data;
+            }
+        }
+
+        $annots = $this->delegate->getClassAnnotations($class);
+        $this->cache->save($cacheKey, $annots);
+        $this->cache->save('[C]'.$cacheKey, time());
+
+        return $this->loadedAnnotations[$cacheKey] = $annots;
+    }
+
+    public function getClassAnnotation(\ReflectionClass $class, $annotationName)
+    {
+        foreach ($this->getClassAnnotations($class) as $annot) {
+            if ($annot instanceof $annotationName) {
+                return $annot;
+            }
+        }
+
+        return null;
+    }
+
+    public function getPropertyAnnotations(\ReflectionProperty $property)
+    {
+        $class = $property->getDeclaringClass();
+        $cacheKey = $class->getName().'$'.$property->getName().self::$CACHE_SALT;
+
+        if (isset($this->loadedAnnotations[$cacheKey])) {
+            return $this->loadedAnnotations[$cacheKey];
+        }
+
+        // Attempt to grab data from cache
+        if (($data = $this->cache->fetch($cacheKey)) !== false) {
+            if (!$this->debug || $this->isCacheFresh($cacheKey, $class)) {
+                return $data;
+            }
+        }
+
+        $annots = $this->delegate->getPropertyAnnotations($property);
+        $this->cache->save($cacheKey, $annots);
+        $this->cache->save('[C]'.$cacheKey, time());
+
+        return $this->loadedAnnotations[$cacheKey] = $annots;
+    }
+
+    public function getPropertyAnnotation(\ReflectionProperty $property, $annotationName)
+    {
+        foreach ($this->getPropertyAnnotations($property) as $annot) {
+            if ($annot instanceof $annotationName) {
+                return $annot;
+            }
+        }
+
+        return null;
+    }
+
+    public function getMethodAnnotations(\ReflectionMethod $method)
+    {
+        $class = $method->getDeclaringClass();
+        $cacheKey = $class->getName().'#'.$method->getName().self::$CACHE_SALT;
+
+        if (isset($this->loadedAnnotations[$cacheKey])) {
+            return $this->loadedAnnotations[$cacheKey];
+        }
+
+       // Attempt to grab data from cache
+        if (($data = $this->cache->fetch($cacheKey)) !== false) {
+            if (!$this->debug || $this->isCacheFresh($cacheKey, $class)) {
+                return $data;
+            }
+        }
+
+        $annots = $this->delegate->getMethodAnnotations($method);
+        $this->cache->save($cacheKey, $annots);
+        $this->cache->save('[C]'.$cacheKey, time());
+
+        return $this->loadedAnnotations[$cacheKey] = $annots;
+    }
+
+    public function getMethodAnnotation(\ReflectionMethod $method, $annotationName)
+    {
+        foreach ($this->getMethodAnnotations($method) as $annot) {
+            if ($annot instanceof $annotationName) {
+                return $annot;
+            }
+        }
+
+        return null;
+    }
+
+    public function clearLoadedAnnotations()
+    {
+        $this->loadedAnnotations = array();
+    }
+
+    private function isCacheFresh($cacheKey, \ReflectionClass $class)
+    {
+        if (false === $filename = $class->getFilename()) {
+            return true;
+        }
+
+        return $this->cache->fetch('[C]'.$cacheKey) >= filemtime($filename);
+    }
+}

+ 140 - 0
main/inc/lib/symfony/Doctrine/Common/Annotations/DocLexer.php

@@ -0,0 +1,140 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Annotations;
+
+use Doctrine\Common\Lexer;
+
+/**
+ * Simple lexer for docblock annotations.
+ *
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ * @author Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author Jonathan Wage <jonwage@gmail.com>
+ * @author Roman Borschel <roman@code-factory.org>
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+final class DocLexer extends Lexer
+{
+    const T_NONE                = 1;
+    const T_IDENTIFIER          = 2;
+    const T_INTEGER             = 3;
+    const T_STRING              = 4;
+    const T_FLOAT               = 5;
+
+    const T_AT                  = 101;
+    const T_CLOSE_CURLY_BRACES  = 102;
+    const T_CLOSE_PARENTHESIS   = 103;
+    const T_COMMA               = 104;
+    const T_EQUALS              = 105;
+    const T_FALSE               = 106;
+    const T_NAMESPACE_SEPARATOR = 107;
+    const T_OPEN_CURLY_BRACES   = 108;
+    const T_OPEN_PARENTHESIS    = 109;
+    const T_TRUE                = 110;
+    const T_NULL                = 111;
+    const T_COLON               = 112;
+
+    /**
+     * @inheritdoc
+     */
+    protected function getCatchablePatterns()
+    {
+        return array(
+            '[a-z_][a-z0-9_:]*',
+            '(?:[+-]?[0-9]+(?:[\.][0-9]+)*)(?:[eE][+-]?[0-9]+)?',
+            '"(?:[^"]|"")*"',
+        );
+    }
+
+    /**
+     * @inheritdoc
+     */
+    protected function getNonCatchablePatterns()
+    {
+        return array('\s+', '\*+', '(.)');
+    }
+
+    /**
+     * @inheritdoc
+     */
+    protected function getType(&$value)
+    {
+        $type = self::T_NONE;
+
+        // Checking numeric value
+        if (is_numeric($value)) {
+            return (strpos($value, '.') !== false || stripos($value, 'e') !== false)
+                ? self::T_FLOAT : self::T_INTEGER;
+        }
+
+        if ($value[0] === '"') {
+            $value = str_replace('""', '"', substr($value, 1, strlen($value) - 2));
+
+            return self::T_STRING;
+        } else {
+            switch (strtolower($value)) {
+                case '@':
+                    return self::T_AT;
+
+                case ',':
+                    return self::T_COMMA;
+
+                case '(':
+                    return self::T_OPEN_PARENTHESIS;
+
+                case ')':
+                    return self::T_CLOSE_PARENTHESIS;
+
+                case '{':
+                    return self::T_OPEN_CURLY_BRACES;
+
+                case '}':
+                    return self::T_CLOSE_CURLY_BRACES;
+
+                case '=':
+                    return self::T_EQUALS;
+
+                case '\\':
+                    return self::T_NAMESPACE_SEPARATOR;
+
+                case 'true':
+                    return self::T_TRUE;
+
+                case 'false':
+                    return self::T_FALSE;
+
+                case 'null':
+                    return self::T_NULL;
+
+                case ':':
+                    return self::T_COLON;
+
+                default:
+                    if (ctype_alpha($value[0]) || $value[0] === '_') {
+                        return self::T_IDENTIFIER;
+                    }
+
+                    break;
+            }
+        }
+
+        return $type;
+    }
+}

+ 891 - 0
main/inc/lib/symfony/Doctrine/Common/Annotations/DocParser.php

@@ -0,0 +1,891 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Annotations;
+
+use Closure;
+use ReflectionClass;
+use Doctrine\Common\Annotations\Annotation\Target;
+use Doctrine\Common\Annotations\Annotation\Attribute;
+use Doctrine\Common\Annotations\Annotation\Attributes;
+
+/**
+ * A parser for docblock annotations.
+ *
+ * It is strongly discouraged to change the default annotation parsing process.
+ *
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ * @author Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author Jonathan Wage <jonwage@gmail.com>
+ * @author Roman Borschel <roman@code-factory.org>
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ * @author Fabio B. Silva <fabio.bat.silva@gmail.com>
+ */
+final class DocParser
+{
+    /**
+     * An array of all valid tokens for a class name.
+     *
+     * @var array
+     */
+    private static $classIdentifiers = array(DocLexer::T_IDENTIFIER, DocLexer::T_TRUE, DocLexer::T_FALSE, DocLexer::T_NULL);
+
+    /**
+     * The lexer.
+     *
+     * @var Doctrine\Common\Annotations\DocLexer
+     */
+    private $lexer;
+
+    /**
+     * Current target context
+     *
+     * @var string
+     */
+    private $target;
+
+    /**
+     * Doc Parser used to collect annotation target
+     *
+     * @var Doctrine\Common\Annotations\DocParser
+     */
+    private static $metadataParser;
+
+    /**
+     * Flag to control if the current annotation is nested or not.
+     *
+     * @var boolean
+     */
+    private $isNestedAnnotation = false;
+
+    /**
+     * Hashmap containing all use-statements that are to be used when parsing
+     * the given doc block.
+     *
+     * @var array
+     */
+    private $imports = array();
+
+    /**
+     * This hashmap is used internally to cache results of class_exists()
+     * look-ups.
+     *
+     * @var array
+     */
+    private $classExists = array();
+
+    /**
+     * Whether annotations that have not been imported should be ignored.
+     *
+     * @var boolean
+     */
+    private $ignoreNotImportedAnnotations = false;
+
+    /**
+     * An array of default namespaces if operating in simple mode.
+     *
+     * @var array
+     */
+    private $namespaces = array();
+
+    /**
+     * A list with annotations that are not causing exceptions when not resolved to an annotation class.
+     *
+     * The names must be the raw names as used in the class, not the fully qualified
+     * class names.
+     *
+     * @var array
+     */
+    private $ignoredAnnotationNames = array();
+
+    /**
+     * @var string
+     */
+    private $context = '';
+
+    /**
+     * Hash-map for caching annotation metadata
+     * @var array
+     */
+    private static $annotationMetadata = array(
+        'Doctrine\Common\Annotations\Annotation\Target' => array(
+            'is_annotation'    => true,
+            'has_constructor'  => true,
+            'properties'       => array(),
+            'targets_literal'  => 'ANNOTATION_CLASS',
+            'targets'          => Target::TARGET_CLASS,
+            'default_property' => 'value',
+            'attribute_types'  => array(
+                'value'  => array(
+                    'required'  => false,
+                    'type'      =>'array',
+                    'array_type'=>'string',
+                    'value'     =>'array<string>'
+                )
+             ),
+        ),
+        'Doctrine\Common\Annotations\Annotation\Attribute' => array(
+            'is_annotation'    => true,
+            'has_constructor'  => false,
+            'targets_literal'  => 'ANNOTATION_ANNOTATION',
+            'targets'          => Target::TARGET_ANNOTATION,
+            'default_property' => 'name',
+            'properties'       => array(
+                'name'      => 'name',
+                'type'      => 'type',
+                'required'  => 'required'
+            ),
+            'attribute_types'  => array(
+                'value'  => array(
+                    'required'  => true,
+                    'type'      =>'string',
+                    'value'     =>'string'
+                ),
+                'type'  => array(
+                    'required'  =>true,
+                    'type'      =>'string',
+                    'value'     =>'string'
+                ),
+                'required'  => array(
+                    'required'  =>false,
+                    'type'      =>'boolean',
+                    'value'     =>'boolean'
+                )
+             ),
+        ),
+        'Doctrine\Common\Annotations\Annotation\Attributes' => array(
+            'is_annotation'    => true,
+            'has_constructor'  => false,
+            'targets_literal'  => 'ANNOTATION_CLASS',
+            'targets'          => Target::TARGET_CLASS,
+            'default_property' => 'value',
+            'properties'       => array(
+                'value' => 'value'
+            ),
+            'attribute_types'  => array(
+                'value' => array(
+                    'type'      =>'array',
+                    'required'  =>true,
+                    'array_type'=>'Doctrine\Common\Annotations\Annotation\Attribute',
+                    'value'     =>'array<Doctrine\Common\Annotations\Annotation\Attribute>'
+                )
+             ),
+        ),
+    );
+
+    /**
+     * Hash-map for handle types declaration
+     *
+     * @var array
+     */
+    private static $typeMap = array(
+        'float'     => 'double',
+        'bool'      => 'boolean',
+        // allow uppercase Boolean in honor of George Boole
+        'Boolean'   => 'boolean',
+        'int'       => 'integer',
+    );
+
+    /**
+     * Constructs a new DocParser.
+     */
+    public function __construct()
+    {
+        $this->lexer = new DocLexer;
+    }
+
+    /**
+     * Sets the annotation names that are ignored during the parsing process.
+     *
+     * The names are supposed to be the raw names as used in the class, not the
+     * fully qualified class names.
+     *
+     * @param array $names
+     */
+    public function setIgnoredAnnotationNames(array $names)
+    {
+        $this->ignoredAnnotationNames = $names;
+    }
+
+    public function setIgnoreNotImportedAnnotations($bool)
+    {
+        $this->ignoreNotImportedAnnotations = (Boolean) $bool;
+    }
+
+    /**
+     * Sets the default namespaces.
+     * @param array $namespaces
+     */
+    public function addNamespace($namespace)
+    {
+        if ($this->imports) {
+            throw new \RuntimeException('You must either use addNamespace(), or setImports(), but not both.');
+        }
+        $this->namespaces[] = $namespace;
+    }
+
+    public function setImports(array $imports)
+    {
+        if ($this->namespaces) {
+            throw new \RuntimeException('You must either use addNamespace(), or setImports(), but not both.');
+        }
+        $this->imports = $imports;
+    }
+
+     /**
+     * Sets current target context as bitmask.
+     *
+     * @param integer $target
+     */
+    public function setTarget($target)
+    {
+        $this->target = $target;
+    }
+
+    /**
+     * Parses the given docblock string for annotations.
+     *
+     * @param string $input The docblock string to parse.
+     * @param string $context The parsing context.
+     * @return array Array of annotations. If no annotations are found, an empty array is returned.
+     */
+    public function parse($input, $context = '')
+    {
+        if (false === $pos = strpos($input, '@')) {
+            return array();
+        }
+
+        // also parse whatever character is before the @
+        if ($pos > 0) {
+            $pos -= 1;
+        }
+
+        $this->context = $context;
+        $this->lexer->setInput(trim(substr($input, $pos), '* /'));
+        $this->lexer->moveNext();
+
+        return $this->Annotations();
+    }
+
+    /**
+     * Attempts to match the given token with the current lookahead token.
+     * If they match, updates the lookahead token; otherwise raises a syntax error.
+     *
+     * @param int Token type.
+     * @return bool True if tokens match; false otherwise.
+     */
+    private function match($token)
+    {
+        if ( ! $this->lexer->isNextToken($token) ) {
+            $this->syntaxError($this->lexer->getLiteral($token));
+        }
+
+        return $this->lexer->moveNext();
+    }
+
+    /**
+     * Attempts to match the current lookahead token with any of the given tokens.
+     *
+     * If any of them matches, this method updates the lookahead token; otherwise
+     * a syntax error is raised.
+     *
+     * @param array $tokens
+     * @return bool
+     */
+    private function matchAny(array $tokens)
+    {
+        if ( ! $this->lexer->isNextTokenAny($tokens)) {
+            $this->syntaxError(implode(' or ', array_map(array($this->lexer, 'getLiteral'), $tokens)));
+        }
+
+        return $this->lexer->moveNext();
+    }
+
+    /**
+     * Generates a new syntax error.
+     *
+     * @param string $expected Expected string.
+     * @param array $token Optional token.
+     * @throws SyntaxException
+     */
+    private function syntaxError($expected, $token = null)
+    {
+        if ($token === null) {
+            $token = $this->lexer->lookahead;
+        }
+
+        $message =  "Expected {$expected}, got ";
+
+        if ($this->lexer->lookahead === null) {
+            $message .= 'end of string';
+        } else {
+            $message .= "'{$token['value']}' at position {$token['position']}";
+        }
+
+        if (strlen($this->context)) {
+            $message .= ' in ' . $this->context;
+        }
+
+        $message .= '.';
+
+        throw AnnotationException::syntaxError($message);
+    }
+
+    /**
+     * Attempt to check if a class exists or not. This never goes through the PHP autoloading mechanism
+     * but uses the {@link AnnotationRegistry} to load classes.
+     *
+     * @param string $fqcn
+     * @return boolean
+     */
+    private function classExists($fqcn)
+    {
+        if (isset($this->classExists[$fqcn])) {
+            return $this->classExists[$fqcn];
+        }
+
+        // first check if the class already exists, maybe loaded through another AnnotationReader
+        if (class_exists($fqcn, false)) {
+            return $this->classExists[$fqcn] = true;
+        }
+
+        // final check, does this class exist?
+        return $this->classExists[$fqcn] = AnnotationRegistry::loadAnnotationClass($fqcn);
+    }
+
+    /**
+     * Collects parsing metadata for a given annotation class
+     *
+     * @param   string $name        The annotation name
+     */
+    private function collectAnnotationMetadata($name)
+    {
+        if (self::$metadataParser == null){
+            self::$metadataParser = new self();
+            self::$metadataParser->setTarget(Target::TARGET_CLASS);
+            self::$metadataParser->setIgnoreNotImportedAnnotations(true);
+            self::$metadataParser->setImports(array(
+                'target'        => 'Doctrine\Common\Annotations\Annotation\Target',
+                'attribute'     => 'Doctrine\Common\Annotations\Annotation\Attribute',
+                'attributes'    => 'Doctrine\Common\Annotations\Annotation\Attributes'
+            ));
+            AnnotationRegistry::registerFile(__DIR__ . '/Annotation/Target.php');
+            AnnotationRegistry::registerFile(__DIR__ . '/Annotation/Attribute.php');
+            AnnotationRegistry::registerFile(__DIR__ . '/Annotation/Attributes.php');
+        }
+
+        $class      = new \ReflectionClass($name);
+        $docComment = $class->getDocComment();
+
+        // Sets default values for annotation metadata
+        $metadata = array(
+            'default_property' => null,
+            'has_constructor'  => (null !== $constructor = $class->getConstructor()) && $constructor->getNumberOfParameters() > 0,
+            'properties'       => array(),
+            'property_types'   => array(),
+            'attribute_types'  => array(),
+            'targets_literal'  => null,
+            'targets'          => Target::TARGET_ALL,
+            'is_annotation'    => false !== strpos($docComment, '@Annotation'),
+        );
+
+        // verify that the class is really meant to be an annotation
+        if ($metadata['is_annotation']) {
+            foreach (self::$metadataParser->parse($docComment, 'class @' . $name) as $annotation) {
+                if ($annotation instanceof Target) {
+                    $metadata['targets']         = $annotation->targets;
+                    $metadata['targets_literal'] = $annotation->literal;
+
+                } elseif ($annotation instanceof Attributes) {
+                    foreach ($annotation->value as $attrib) {
+                        // handle internal type declaration
+                        $type = isset(self::$typeMap[$attrib->type]) ? self::$typeMap[$attrib->type] : $attrib->type;
+
+                        // handle the case if the property type is mixed
+                        if ('mixed' !== $type) {
+                            // Checks if the property has array<type>
+                            if (false !== $pos = strpos($type, '<')) {
+                                $arrayType  = substr($type, $pos+1, -1);
+                                $type       = 'array';
+
+                                if (isset(self::$typeMap[$arrayType])) {
+                                    $arrayType = self::$typeMap[$arrayType];
+                                }
+
+                                $metadata['attribute_types'][$attrib->name]['array_type'] = $arrayType;
+                            }
+
+                            $metadata['attribute_types'][$attrib->name]['type']     = $type;
+                            $metadata['attribute_types'][$attrib->name]['value']    = $attrib->type;
+                            $metadata['attribute_types'][$attrib->name]['required'] = $attrib->required;
+                        }
+                    }
+                }
+            }
+
+            // if not has a constructor will inject values into public properties
+            if (false === $metadata['has_constructor']) {
+                // collect all public properties
+                foreach ($class->getProperties(\ReflectionProperty::IS_PUBLIC) as $property) {
+                    $metadata['properties'][$property->name] = $property->name;
+
+                    // checks if the property has @var annotation
+                    if ((false !== $propertyComment = $property->getDocComment())
+                        && false !== strpos($propertyComment, '@var')
+                        && preg_match('/@var\s+([^\s]+)/',$propertyComment, $matches)) {
+                        // literal type declaration
+                        $value = $matches[1];
+
+                        // handle internal type declaration
+                        $type = isset(self::$typeMap[$value]) ? self::$typeMap[$value] : $value;
+
+                        // handle the case if the property type is mixed
+                        if ('mixed' !== $type) {
+                            // Checks if the property has @var array<type> annotation
+                            if (false !== $pos = strpos($type, '<')) {
+                                $arrayType = substr($type, $pos+1, -1);
+                                $type = 'array';
+
+                                if (isset(self::$typeMap[$arrayType])) {
+                                    $arrayType = self::$typeMap[$arrayType];
+                                }
+
+                                $metadata['attribute_types'][$property->name]['array_type'] = $arrayType;
+                            }
+
+                            $metadata['attribute_types'][$property->name]['type']       = $type;
+                            $metadata['attribute_types'][$property->name]['value']      = $value;
+                            $metadata['attribute_types'][$property->name]['required']   = false !== strpos($propertyComment, '@Required');
+                        }
+                    }
+                }
+
+                // choose the first property as default property
+                $metadata['default_property'] = reset($metadata['properties']);
+            }
+        }
+
+        self::$annotationMetadata[$name] = $metadata;
+    }
+
+    /**
+     * Annotations ::= Annotation {[ "*" ]* [Annotation]}*
+     *
+     * @return array
+     */
+    private function Annotations()
+    {
+        $annotations = array();
+
+        while (null !== $this->lexer->lookahead) {
+            if (DocLexer::T_AT !== $this->lexer->lookahead['type']) {
+                $this->lexer->moveNext();
+                continue;
+            }
+
+            // make sure the @ is preceded by non-catchable pattern
+            if (null !== $this->lexer->token && $this->lexer->lookahead['position'] === $this->lexer->token['position'] + strlen($this->lexer->token['value'])) {
+                $this->lexer->moveNext();
+                continue;
+            }
+
+            // make sure the @ is followed by either a namespace separator, or
+            // an identifier token
+            if ((null === $peek = $this->lexer->glimpse())
+                || (DocLexer::T_NAMESPACE_SEPARATOR !== $peek['type'] && !in_array($peek['type'], self::$classIdentifiers, true))
+                || $peek['position'] !== $this->lexer->lookahead['position'] + 1) {
+                $this->lexer->moveNext();
+                continue;
+            }
+
+            $this->isNestedAnnotation = false;
+            if (false !== $annot = $this->Annotation()) {
+                $annotations[] = $annot;
+            }
+        }
+
+        return $annotations;
+    }
+
+    /**
+     * Annotation     ::= "@" AnnotationName ["(" [Values] ")"]
+     * AnnotationName ::= QualifiedName | SimpleName
+     * QualifiedName  ::= NameSpacePart "\" {NameSpacePart "\"}* SimpleName
+     * NameSpacePart  ::= identifier | null | false | true
+     * SimpleName     ::= identifier | null | false | true
+     *
+     * @return mixed False if it is not a valid annotation.
+     */
+    private function Annotation()
+    {
+        $this->match(DocLexer::T_AT);
+
+        // check if we have an annotation
+        if ($this->lexer->isNextTokenAny(self::$classIdentifiers)) {
+            $this->lexer->moveNext();
+            $name = $this->lexer->token['value'];
+        } else if ($this->lexer->isNextToken(DocLexer::T_NAMESPACE_SEPARATOR)) {
+            $name = '';
+        } else {
+            $this->syntaxError('namespace separator or identifier');
+        }
+
+        while ($this->lexer->lookahead['position'] === $this->lexer->token['position'] + strlen($this->lexer->token['value']) && $this->lexer->isNextToken(DocLexer::T_NAMESPACE_SEPARATOR)) {
+            $this->match(DocLexer::T_NAMESPACE_SEPARATOR);
+            $this->matchAny(self::$classIdentifiers);
+            $name .= '\\'.$this->lexer->token['value'];
+        }
+
+        // only process names which are not fully qualified, yet
+        // fully qualified names must start with a \
+        $originalName = $name;
+        if ('\\' !== $name[0]) {
+            $alias = (false === $pos = strpos($name, '\\'))? $name : substr($name, 0, $pos);
+
+            $found = false;
+            if ($this->namespaces) {
+                foreach ($this->namespaces as $namespace) {
+                    if ($this->classExists($namespace.'\\'.$name)) {
+                        $name = $namespace.'\\'.$name;
+                        $found = true;
+                        break;
+                    }
+                }
+            } elseif (isset($this->imports[$loweredAlias = strtolower($alias)])) {
+                if (false !== $pos) {
+                    $name = $this->imports[$loweredAlias].substr($name, $pos);
+                } else {
+                    $name = $this->imports[$loweredAlias];
+                }
+                $found = true;
+            } elseif (isset($this->imports['__NAMESPACE__']) && $this->classExists($this->imports['__NAMESPACE__'].'\\'.$name)) {
+                 $name = $this->imports['__NAMESPACE__'].'\\'.$name;
+                 $found = true;
+            } elseif ($this->classExists($name)) {
+                $found = true;
+            }
+
+            if (!$found) {
+                if ($this->ignoreNotImportedAnnotations || isset($this->ignoredAnnotationNames[$name])) {
+                    return false;
+                }
+
+                throw AnnotationException::semanticalError(sprintf('The annotation "@%s" in %s was never imported. Did you maybe forget to add a "use" statement for this annotation?', $name, $this->context));
+            }
+        }
+
+        if (!$this->classExists($name)) {
+            throw AnnotationException::semanticalError(sprintf('The annotation "@%s" in %s does not exist, or could not be auto-loaded.', $name, $this->context));
+        }
+
+        // at this point, $name contains the fully qualified class name of the
+        // annotation, and it is also guaranteed that this class exists, and
+        // that it is loaded
+
+
+        // collects the metadata annotation only if there is not yet
+        if (!isset(self::$annotationMetadata[$name])) {
+            $this->collectAnnotationMetadata($name);
+        }
+
+        // verify that the class is really meant to be an annotation and not just any ordinary class
+        if (self::$annotationMetadata[$name]['is_annotation'] === false) {
+            if (isset($this->ignoredAnnotationNames[$originalName])) {
+                return false;
+            }
+
+            throw AnnotationException::semanticalError(sprintf('The class "%s" is not annotated with @Annotation. Are you sure this class can be used as annotation? If so, then you need to add @Annotation to the _class_ doc comment of "%s". If it is indeed no annotation, then you need to add @IgnoreAnnotation("%s") to the _class_ doc comment of %s.', $name, $name, $originalName, $this->context));
+        }
+
+        //if target is nested annotation
+        $target = $this->isNestedAnnotation ? Target::TARGET_ANNOTATION : $this->target;
+
+        // Next will be nested
+        $this->isNestedAnnotation = true;
+
+        //if annotation does not support current target
+        if (0 === (self::$annotationMetadata[$name]['targets'] & $target) && $target) {
+            throw AnnotationException::semanticalError(
+                sprintf('Annotation @%s is not allowed to be declared on %s. You may only use this annotation on these code elements: %s.',
+                     $originalName, $this->context, self::$annotationMetadata[$name]['targets_literal'])
+            );
+        }
+
+        $values = array();
+        if ($this->lexer->isNextToken(DocLexer::T_OPEN_PARENTHESIS)) {
+            $this->match(DocLexer::T_OPEN_PARENTHESIS);
+
+            if ( ! $this->lexer->isNextToken(DocLexer::T_CLOSE_PARENTHESIS)) {
+                $values = $this->Values();
+            }
+
+            $this->match(DocLexer::T_CLOSE_PARENTHESIS);
+        }
+
+        // checks all declared attributes
+        foreach (self::$annotationMetadata[$name]['attribute_types'] as $property => $type) {
+            if ($property === self::$annotationMetadata[$name]['default_property']
+                && !isset($values[$property]) && isset($values['value'])) {
+                $property = 'value';
+            }
+
+            // handle a not given attribute or null value
+            if (!isset($values[$property])) {
+                if ($type['required']) {
+                    throw AnnotationException::requiredError($property, $originalName, $this->context, 'a(n) '.$type['value']);
+                }
+
+                continue;
+            }
+
+            if ($type['type'] === 'array') {
+                // handle the case of a single value
+                if (!is_array($values[$property])) {
+                    $values[$property] = array($values[$property]);
+                }
+
+                // checks if the attribute has array type declaration, such as "array<string>"
+                if (isset($type['array_type'])) {
+                    foreach ($values[$property] as $item) {
+                        if (gettype($item) !== $type['array_type'] && !$item instanceof $type['array_type']) {
+                            throw AnnotationException::typeError($property, $originalName, $this->context, 'either a(n) '.$type['array_type'].', or an array of '.$type['array_type'].'s', $item);
+                        }
+                    }
+                }
+            } elseif (gettype($values[$property]) !== $type['type'] && !$values[$property] instanceof $type['type']) {
+                throw AnnotationException::typeError($property, $originalName, $this->context, 'a(n) '.$type['value'], $values[$property]);
+            }
+        }
+
+        // check if the annotation expects values via the constructor,
+        // or directly injected into public properties
+        if (self::$annotationMetadata[$name]['has_constructor'] === true) {
+            return new $name($values);
+        }
+
+        $instance = new $name();
+        foreach ($values as $property => $value) {
+            if (!isset(self::$annotationMetadata[$name]['properties'][$property])) {
+                if ('value' !== $property) {
+                    throw AnnotationException::creationError(sprintf('The annotation @%s declared on %s does not have a property named "%s". Available properties: %s', $originalName, $this->context, $property, implode(', ', self::$annotationMetadata[$name]['properties'])));
+                }
+
+                // handle the case if the property has no annotations
+                if (!$property = self::$annotationMetadata[$name]['default_property']) {
+                    throw AnnotationException::creationError(sprintf('The annotation @%s declared on %s does not accept any values, but got %s.', $originalName, $this->context, json_encode($values)));
+                }
+            }
+
+            $instance->{$property} = $value;
+        }
+
+        return $instance;
+    }
+
+    /**
+     * Values ::= Array | Value {"," Value}*
+     *
+     * @return array
+     */
+    private function Values()
+    {
+        $values = array();
+
+        // Handle the case of a single array as value, i.e. @Foo({....})
+        if ($this->lexer->isNextToken(DocLexer::T_OPEN_CURLY_BRACES)) {
+            $values['value'] = $this->Value();
+            return $values;
+        }
+
+        $values[] = $this->Value();
+
+        while ($this->lexer->isNextToken(DocLexer::T_COMMA)) {
+            $this->match(DocLexer::T_COMMA);
+            $token = $this->lexer->lookahead;
+            $value = $this->Value();
+
+            if ( ! is_object($value) && ! is_array($value)) {
+                $this->syntaxError('Value', $token);
+            }
+
+            $values[] = $value;
+        }
+
+        foreach ($values as $k => $value) {
+            if (is_object($value) && $value instanceof \stdClass) {
+                $values[$value->name] = $value->value;
+            } else if ( ! isset($values['value'])){
+                $values['value'] = $value;
+            } else {
+                if ( ! is_array($values['value'])) {
+                    $values['value'] = array($values['value']);
+                }
+
+                $values['value'][] = $value;
+            }
+
+            unset($values[$k]);
+        }
+
+        return $values;
+    }
+
+    /**
+     * Value ::= PlainValue | FieldAssignment
+     *
+     * @return mixed
+     */
+    private function Value()
+    {
+        $peek = $this->lexer->glimpse();
+
+        if (DocLexer::T_EQUALS === $peek['type']) {
+            return $this->FieldAssignment();
+        }
+
+        return $this->PlainValue();
+    }
+
+    /**
+     * PlainValue ::= integer | string | float | boolean | Array | Annotation
+     *
+     * @return mixed
+     */
+    private function PlainValue()
+    {
+        if ($this->lexer->isNextToken(DocLexer::T_OPEN_CURLY_BRACES)) {
+            return $this->Arrayx();
+        }
+
+        if ($this->lexer->isNextToken(DocLexer::T_AT)) {
+            return $this->Annotation();
+        }
+
+        switch ($this->lexer->lookahead['type']) {
+            case DocLexer::T_STRING:
+                $this->match(DocLexer::T_STRING);
+                return $this->lexer->token['value'];
+
+            case DocLexer::T_INTEGER:
+                $this->match(DocLexer::T_INTEGER);
+                return (int)$this->lexer->token['value'];
+
+            case DocLexer::T_FLOAT:
+                $this->match(DocLexer::T_FLOAT);
+                return (float)$this->lexer->token['value'];
+
+            case DocLexer::T_TRUE:
+                $this->match(DocLexer::T_TRUE);
+                return true;
+
+            case DocLexer::T_FALSE:
+                $this->match(DocLexer::T_FALSE);
+                return false;
+
+            case DocLexer::T_NULL:
+                $this->match(DocLexer::T_NULL);
+                return null;
+
+            default:
+                $this->syntaxError('PlainValue');
+        }
+    }
+
+    /**
+     * FieldAssignment ::= FieldName "=" PlainValue
+     * FieldName ::= identifier
+     *
+     * @return array
+     */
+    private function FieldAssignment()
+    {
+        $this->match(DocLexer::T_IDENTIFIER);
+        $fieldName = $this->lexer->token['value'];
+
+        $this->match(DocLexer::T_EQUALS);
+
+        $item = new \stdClass();
+        $item->name  = $fieldName;
+        $item->value = $this->PlainValue();
+
+        return $item;
+    }
+
+    /**
+     * Array ::= "{" ArrayEntry {"," ArrayEntry}* [","] "}"
+     *
+     * @return array
+     */
+    private function Arrayx()
+    {
+        $array = $values = array();
+
+        $this->match(DocLexer::T_OPEN_CURLY_BRACES);
+        $values[] = $this->ArrayEntry();
+
+        while ($this->lexer->isNextToken(DocLexer::T_COMMA)) {
+            $this->match(DocLexer::T_COMMA);
+
+            // optional trailing comma
+            if ($this->lexer->isNextToken(DocLexer::T_CLOSE_CURLY_BRACES)) {
+                break;
+            }
+
+            $values[] = $this->ArrayEntry();
+        }
+
+        $this->match(DocLexer::T_CLOSE_CURLY_BRACES);
+
+        foreach ($values as $value) {
+            list ($key, $val) = $value;
+
+            if ($key !== null) {
+                $array[$key] = $val;
+            } else {
+                $array[] = $val;
+            }
+        }
+
+        return $array;
+    }
+
+    /**
+     * ArrayEntry ::= Value | KeyValuePair
+     * KeyValuePair ::= Key ("=" | ":") PlainValue
+     * Key ::= string | integer
+     *
+     * @return array
+     */
+    private function ArrayEntry()
+    {
+        $peek = $this->lexer->glimpse();
+
+        if (DocLexer::T_EQUALS === $peek['type']
+                || DocLexer::T_COLON === $peek['type']) {
+            $this->matchAny(array(DocLexer::T_INTEGER, DocLexer::T_STRING));
+
+            $key = $this->lexer->token['value'];
+            $this->matchAny(array(DocLexer::T_EQUALS, DocLexer::T_COLON));
+
+            return array($key, $this->PlainValue());
+        }
+
+        return array(null, $this->Value());
+    }
+}

+ 209 - 0
main/inc/lib/symfony/Doctrine/Common/Annotations/FileCacheReader.php

@@ -0,0 +1,209 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Annotations;
+
+
+/**
+ * File cache reader for annotations.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ */
+class FileCacheReader implements Reader
+{
+    /**
+     * @var Reader
+     */
+    private $reader;
+    private $dir;
+    private $debug;
+    private $loadedAnnotations = array();
+
+    public function __construct(Reader $reader, $cacheDir, $debug = false)
+    {
+        $this->reader = $reader;
+        if (!is_dir($cacheDir) && !@mkdir($cacheDir, 0777, true)) {
+            throw new \InvalidArgumentException(sprintf('The directory "%s" does not exist and could not be created.', $cacheDir));
+        }
+        if (!is_writable($cacheDir)) {
+            throw new \InvalidArgumentException(sprintf('The directory "%s" is not writable. Both, the webserver and the console user need access. You can manage access rights for multiple users with "chmod +a". If your system does not support this, check out the acl package.', $cacheDir));
+        }
+
+        $this->dir   = rtrim($cacheDir, '\\/');
+        $this->debug = $debug;
+    }
+
+    public function getClassAnnotations(\ReflectionClass $class)
+    {
+        $key = $class->getName();
+
+        if (isset($this->loadedAnnotations[$key])) {
+            return $this->loadedAnnotations[$key];
+        }
+
+        $path = $this->dir.'/'.strtr($key, '\\', '-').'.cache.php';
+        if (!file_exists($path)) {
+            $annot = $this->reader->getClassAnnotations($class);
+            $this->saveCacheFile($path, $annot);
+            return $this->loadedAnnotations[$key] = $annot;
+        }
+
+        if ($this->debug
+            && (false !== $filename = $class->getFilename())
+            && filemtime($path) < filemtime($filename)) {
+            @unlink($path);
+
+            $annot = $this->reader->getClassAnnotations($class);
+            $this->saveCacheFile($path, $annot);
+            return $this->loadedAnnotations[$key] = $annot;
+        }
+
+        return $this->loadedAnnotations[$key] = include $path;
+    }
+
+    public function getPropertyAnnotations(\ReflectionProperty $property)
+    {
+        $class = $property->getDeclaringClass();
+        $key = $class->getName().'$'.$property->getName();
+
+        if (isset($this->loadedAnnotations[$key])) {
+            return $this->loadedAnnotations[$key];
+        }
+
+        $path = $this->dir.'/'.strtr($key, '\\', '-').'.cache.php';
+        if (!file_exists($path)) {
+            $annot = $this->reader->getPropertyAnnotations($property);
+            $this->saveCacheFile($path, $annot);
+            return $this->loadedAnnotations[$key] = $annot;
+        }
+
+        if ($this->debug
+            && (false !== $filename = $class->getFilename())
+            && filemtime($path) < filemtime($filename)) {
+            unlink($path);
+
+            $annot = $this->reader->getPropertyAnnotations($property);
+            $this->saveCacheFile($path, $annot);
+            return $this->loadedAnnotations[$key] = $annot;
+        }
+
+        return $this->loadedAnnotations[$key] = include $path;
+    }
+
+    public function getMethodAnnotations(\ReflectionMethod $method)
+    {
+        $class = $method->getDeclaringClass();
+        $key = $class->getName().'#'.$method->getName();
+
+        if (isset($this->loadedAnnotations[$key])) {
+            return $this->loadedAnnotations[$key];
+        }
+
+        $path = $this->dir.'/'.strtr($key, '\\', '-').'.cache.php';
+        if (!file_exists($path)) {
+            $annot = $this->reader->getMethodAnnotations($method);
+            $this->saveCacheFile($path, $annot);
+            return $this->loadedAnnotations[$key] = $annot;
+        }
+
+        if ($this->debug
+            && (false !== $filename = $class->getFilename())
+            && filemtime($path) < filemtime($filename)) {
+            unlink($path);
+
+            $annot = $this->reader->getMethodAnnotations($method);
+            $this->saveCacheFile($path, $annot);
+            return $this->loadedAnnotations[$key] = $annot;
+        }
+
+        return $this->loadedAnnotations[$key] = include $path;
+    }
+
+    private function saveCacheFile($path, $data)
+    {
+        file_put_contents($path, '<?php return unserialize('.var_export(serialize($data), true).');');
+    }
+
+    /**
+     * Gets a class annotation.
+     *
+     * @param ReflectionClass $class The ReflectionClass of the class from which
+     *                               the class annotations should be read.
+     * @param string $annotationName The name of the annotation.
+     * @return The Annotation or NULL, if the requested annotation does not exist.
+     */
+    public function getClassAnnotation(\ReflectionClass $class, $annotationName)
+    {
+        $annotations = $this->getClassAnnotations($class);
+
+        foreach ($annotations as $annotation) {
+            if ($annotation instanceof $annotationName) {
+                return $annotation;
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Gets a method annotation.
+     *
+     * @param ReflectionMethod $method
+     * @param string $annotationName The name of the annotation.
+     * @return The Annotation or NULL, if the requested annotation does not exist.
+     */
+    public function getMethodAnnotation(\ReflectionMethod $method, $annotationName)
+    {
+        $annotations = $this->getMethodAnnotations($method);
+
+        foreach ($annotations as $annotation) {
+            if ($annotation instanceof $annotationName) {
+                return $annotation;
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Gets a property annotation.
+     *
+     * @param ReflectionProperty $property
+     * @param string $annotationName The name of the annotation.
+     * @return The Annotation or NULL, if the requested annotation does not exist.
+     */
+    public function getPropertyAnnotation(\ReflectionProperty $property, $annotationName)
+    {
+        $annotations = $this->getPropertyAnnotations($property);
+
+        foreach ($annotations as $annotation) {
+            if ($annotation instanceof $annotationName) {
+                return $annotation;
+            }
+        }
+
+        return null;
+    }
+
+    public function clearLoadedAnnotations()
+    {
+        $this->loadedAnnotations = array();
+    }
+}

+ 94 - 0
main/inc/lib/symfony/Doctrine/Common/Annotations/IndexedReader.php

@@ -0,0 +1,94 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Annotations;
+
+use Doctrine\Common\Annotations\Reader;
+
+/**
+ * Allows the reader to be used in-place of Doctrine's reader.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+class IndexedReader implements Reader
+{
+    private $delegate;
+
+    public function __construct(Reader $reader)
+    {
+        $this->delegate = $reader;
+    }
+
+    public function getClassAnnotations(\ReflectionClass $class)
+    {
+        $annotations = array();
+        foreach ($this->delegate->getClassAnnotations($class) as $annot) {
+            $annotations[get_class($annot)] = $annot;
+        }
+
+        return $annotations;
+    }
+
+    public function getClassAnnotation(\ReflectionClass $class, $annotation)
+    {
+        return $this->delegate->getClassAnnotation($class, $annotation);
+    }
+
+    public function getMethodAnnotations(\ReflectionMethod $method)
+    {
+        $annotations = array();
+        foreach ($this->delegate->getMethodAnnotations($method) as $annot) {
+            $annotations[get_class($annot)] = $annot;
+        }
+
+        return $annotations;
+    }
+
+    public function getMethodAnnotation(\ReflectionMethod $method, $annotation)
+    {
+        return $this->delegate->getMethodAnnotation($method, $annotation);
+    }
+
+    public function getPropertyAnnotations(\ReflectionProperty $property)
+    {
+        $annotations = array();
+        foreach ($this->delegate->getPropertyAnnotations($property) as $annot) {
+            $annotations[get_class($annot)] = $annot;
+        }
+
+        return $annotations;
+    }
+
+    public function getPropertyAnnotation(\ReflectionProperty $property, $annotation)
+    {
+        return $this->delegate->getPropertyAnnotation($property, $annotation);
+    }
+
+    /**
+     * Proxy all methods to the delegate.
+     *
+     * @param type $method
+     * @param type $args
+     * @return type
+     */
+    public function __call($method, $args)
+    {
+        return call_user_func_array(array($this->delegate, $method), $args);
+    }
+}

+ 203 - 0
main/inc/lib/symfony/Doctrine/Common/Annotations/PhpParser.php

@@ -0,0 +1,203 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Annotations;
+
+use SplFileObject;
+
+/**
+ * Parses a file for namespaces/use/class declarations.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ * @author Christian Kaps <christian.kaps@mohiva.com>
+ */
+final class PhpParser
+{
+    /**
+     * The token list.
+     *
+     * @var array
+     */
+    private $tokens;
+
+    /**
+     * The number of tokens.
+     *
+     * @var int
+     */
+    private $numTokens = 0;
+
+    /**
+     * The current array pointer.
+     *
+     * @var int
+     */
+    private $pointer = 0;
+
+    /**
+     * Parses a class.
+     *
+     * @param \ReflectionClass $class A <code>ReflectionClass</code> object.
+     * @return array A list with use statements in the form (Alias => FQN).
+     */
+    public function parseClass(\ReflectionClass $class)
+    {
+        if (false === $filename = $class->getFilename()) {
+            return array();
+        }
+
+        $content = $this->getFileContent($filename, $class->getStartLine());
+        $namespace = str_replace('\\', '\\\\', $class->getNamespaceName());
+        $content = preg_replace('/^.*?(\bnamespace\s+' . $namespace . '\s*[;{].*)$/s', '\\1', $content);
+        $this->tokens = token_get_all('<?php ' . $content);
+        $this->numTokens = count($this->tokens);
+        $this->pointer = 0;
+
+        $statements = $this->parseUseStatements($class->getNamespaceName());
+
+        return $statements;
+    }
+
+    /**
+     * Get the content of the file right up to the given line number.
+     *
+     * @param string $filename The name of the file to load.
+     * @param int $lineNumber The number of lines to read from file.
+     * @return string The content of the file.
+     */
+    private function getFileContent($filename, $lineNumber)
+    {
+        $content = '';
+        $lineCnt = 0;
+        $file = new SplFileObject($filename);
+        while(!$file->eof()) {
+            if ($lineCnt++ == $lineNumber) {
+                break;
+            }
+
+            $content .= $file->fgets();
+        }
+
+        return $content;
+    }
+
+    /**
+     * Gets the next non whitespace and non comment token.
+     *
+     * @return array The token if exists, null otherwise.
+     */
+    private function next()
+    {
+        for ($i = $this->pointer; $i < $this->numTokens; $i++) {
+            $this->pointer++;
+            if ($this->tokens[$i][0] === T_WHITESPACE ||
+                $this->tokens[$i][0] === T_COMMENT ||
+                $this->tokens[$i][0] === T_DOC_COMMENT) {
+
+                continue;
+            }
+
+            return $this->tokens[$i];
+        }
+
+        return null;
+    }
+
+    /**
+     * Get all use statements.
+     *
+     * @param string $namespaceName The namespace name of the reflected class.
+     * @return array A list with all found use statements.
+     */
+    private function parseUseStatements($namespaceName)
+    {
+        $statements = array();
+        while (($token = $this->next())) {
+            if ($token[0] === T_USE) {
+                $statements = array_merge($statements, $this->parseUseStatement());
+                continue;
+            } else if ($token[0] !== T_NAMESPACE || $this->parseNamespace() != $namespaceName) {
+                continue;
+            }
+
+            // Get fresh array for new namespace. This is to prevent the parser to collect the use statements
+            // for a previous namespace with the same name. This is the case if a namespace is defined twice
+            // or if a namespace with the same name is commented out.
+            $statements = array();
+        }
+
+        return $statements;
+    }
+
+    /**
+     * Get the namespace name.
+     *
+     * @return string The found namespace name.
+     */
+    private function parseNamespace()
+    {
+        $namespace = '';
+        while (($token = $this->next())){
+            if ($token[0] === T_STRING || $token[0] === T_NS_SEPARATOR) {
+                $namespace .= $token[1];
+            } else {
+                break;
+            }
+        }
+
+        return $namespace;
+    }
+
+    /**
+     * Parse a single use statement.
+     *
+     * @return array A list with all found class names for a use statement.
+     */
+    private function parseUseStatement()
+    {
+        $class = '';
+        $alias = '';
+        $statements = array();
+        $explicitAlias = false;
+        while (($token = $this->next())) {
+            $isNameToken = $token[0] === T_STRING || $token[0] === T_NS_SEPARATOR;
+            if (!$explicitAlias && $isNameToken) {
+                $class .= $token[1];
+                $alias = $token[1];
+            } else if ($explicitAlias && $isNameToken) {
+                $alias .= $token[1];
+            } else if ($token[0] === T_AS) {
+                $explicitAlias = true;
+                $alias = '';
+            } else if ($token === ',') {
+                $statements[strtolower($alias)] = $class;
+                $class = '';
+                $alias = '';
+                $explicitAlias = false;
+            } else if ($token === ';') {
+                $statements[strtolower($alias)] = $class;
+                break;
+            } else {
+                break;
+            }
+        }
+
+        return $statements;
+    }
+}

+ 35 - 0
main/inc/lib/symfony/Doctrine/Common/Annotations/Reader.php

@@ -0,0 +1,35 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Annotations;
+
+/**
+ * Interface for annotation readers.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+interface Reader
+{
+    function getClassAnnotations(\ReflectionClass $class);
+    function getClassAnnotation(\ReflectionClass $class, $annotationName);
+    function getMethodAnnotations(\ReflectionMethod $method);
+    function getMethodAnnotation(\ReflectionMethod $method, $annotationName);
+    function getPropertyAnnotations(\ReflectionProperty $property);
+    function getPropertyAnnotation(\ReflectionProperty $property, $annotationName);
+}

+ 155 - 0
main/inc/lib/symfony/Doctrine/Common/Annotations/SimpleAnnotationReader.php

@@ -0,0 +1,155 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Annotations;
+
+use Doctrine\Common\Annotations\Annotation\Target;
+
+/**
+ * Simple Annotation Reader.
+ *
+ * This annotation reader is intended to be used in projects where you have
+ * full-control over all annotations that are available.
+ *
+ * @since  2.2
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ * @author Fabio B. Silva <fabio.bat.silva@gmail.com>
+ */
+class SimpleAnnotationReader implements Reader
+{
+    /**
+     * @var DocParser
+     */
+    private $parser;
+
+    /**
+     * Constructor.
+     *
+     * Initializes a new SimpleAnnotationReader.
+     */
+    public function __construct()
+    {
+        $this->parser = new DocParser();
+        $this->parser->setIgnoreNotImportedAnnotations(true);
+    }
+
+    /**
+     * Adds a namespace in which we will look for annotations.
+     *
+     * @param string $namespace
+     */
+    public function addNamespace($namespace)
+    {
+        $this->parser->addNamespace($namespace);
+    }
+
+    /**
+     * Gets the annotations applied to a class.
+     *
+     * @param ReflectionClass $class The ReflectionClass of the class from which
+     *                               the class annotations should be read.
+     * @return array An array of Annotations.
+     */
+    public function getClassAnnotations(\ReflectionClass $class)
+    {
+        $this->parser->setTarget(Target::TARGET_CLASS);
+        return $this->parser->parse($class->getDocComment(), 'class '.$class->getName());
+    }
+
+     /**
+     * Gets the annotations applied to a method.
+     *
+     * @param ReflectionMethod $property The ReflectionMethod of the method from which
+     *                                   the annotations should be read.
+     * @return array An array of Annotations.
+     */
+    public function getMethodAnnotations(\ReflectionMethod $method)
+    {
+        $this->parser->setTarget(Target::TARGET_METHOD);
+        return $this->parser->parse($method->getDocComment(), 'method '.$method->getDeclaringClass()->name.'::'.$method->getName().'()');
+    }
+
+    /**
+     * Gets the annotations applied to a property.
+     *
+     * @param ReflectionProperty $property The ReflectionProperty of the property
+     *                                     from which the annotations should be read.
+     * @return array An array of Annotations.
+     */
+    public function getPropertyAnnotations(\ReflectionProperty $property)
+    {
+        $this->parser->setTarget(Target::TARGET_PROPERTY);
+        return $this->parser->parse($property->getDocComment(), 'property '.$property->getDeclaringClass()->name.'::$'.$property->getName());
+    }
+
+    /**
+     * Gets a class annotation.
+     *
+     * @param ReflectionClass $class The ReflectionClass of the class from which
+     *                               the class annotations should be read.
+     * @param string $annotationName The name of the annotation.
+     * @return The Annotation or NULL, if the requested annotation does not exist.
+     */
+    public function getClassAnnotation(\ReflectionClass $class, $annotationName)
+    {
+        foreach ($this->getClassAnnotations($class) as $annot) {
+            if ($annot instanceof $annotationName) {
+                return $annot;
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Gets a method annotation.
+     *
+     * @param ReflectionMethod $method
+     * @param string $annotationName The name of the annotation.
+     * @return The Annotation or NULL, if the requested annotation does not exist.
+     */
+    public function getMethodAnnotation(\ReflectionMethod $method, $annotationName)
+    {
+        foreach ($this->getMethodAnnotations($method) as $annot) {
+            if ($annot instanceof $annotationName) {
+                return $annot;
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Gets a property annotation.
+     *
+     * @param ReflectionProperty $property
+     * @param string $annotationName The name of the annotation.
+     * @return The Annotation or NULL, if the requested annotation does not exist.
+     */
+    public function getPropertyAnnotation(\ReflectionProperty $property, $annotationName)
+    {
+        foreach ($this->getPropertyAnnotations($property) as $annot) {
+            if ($annot instanceof $annotationName) {
+                return $annot;
+            }
+        }
+
+        return null;
+    }
+}

+ 97 - 0
main/inc/lib/symfony/Doctrine/Common/Cache/ApcCache.php

@@ -0,0 +1,97 @@
+<?php
+
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Cache;
+
+/**
+ * APC cache provider.
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ * @author  David Abdemoulaie <dave@hobodave.com>
+ */
+class ApcCache extends CacheProvider
+{
+    /**
+     * {@inheritdoc}
+     */
+    protected function doFetch($id)
+    {
+        return apc_fetch($id);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doContains($id)
+    {
+        $found = false;
+
+        apc_fetch($id, $found);
+
+        return $found;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doSave($id, $data, $lifeTime = 0)
+    {
+        return (bool) apc_store($id, $data, (int) $lifeTime);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doDelete($id)
+    {
+        return apc_delete($id);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doFlush()
+    {
+        return apc_clear_cache() && apc_clear_cache('user');
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doGetStats()
+    {
+        $info = apc_cache_info();
+        $sma  = apc_sma_info();
+
+        return array(
+            Cache::STATS_HITS              => $info['num_hits'],
+            Cache::STATS_MISSES            => $info['num_misses'],
+            Cache::STATS_UPTIME            => $info['start_time'],
+            Cache::STATS_MEMORY_USAGE      => $info['mem_size'],
+            Cache::STATS_MEMORY_AVAILIABLE => $sma['avail_mem'],
+        );
+    }
+}

+ 96 - 0
main/inc/lib/symfony/Doctrine/Common/Cache/ArrayCache.php

@@ -0,0 +1,96 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Cache;
+
+/**
+ * Array cache driver.
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ * @author  David Abdemoulaie <dave@hobodave.com>
+ */
+class ArrayCache extends CacheProvider
+{
+    /**
+     * @var array $data
+     */
+    private $data = array();
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doFetch($id)
+    {
+        return (isset($this->data[$id])) ? $this->data[$id] : false;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doContains($id)
+    {
+        return isset($this->data[$id]);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doSave($id, $data, $lifeTime = 0)
+    {
+        $this->data[$id] = $data;
+
+        return true;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doDelete($id)
+    {
+        unset($this->data[$id]);
+
+        return true;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doFlush()
+    {
+        $this->data = array();
+
+        return true;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doGetStats()
+    {
+        return null;
+    }
+}

+ 102 - 0
main/inc/lib/symfony/Doctrine/Common/Cache/Cache.php

@@ -0,0 +1,102 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Cache;
+
+/**
+ * Interface for cache drivers.
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ * @author  Fabio B. Silva <fabio.bat.silva@gmail.com>
+ */
+interface Cache
+{
+    const STATS_HITS    = 'hits';
+    const STATS_MISSES  = 'misses';
+    const STATS_UPTIME  = 'uptime';
+    const STATS_MEMORY_USAGE        = 'memory_usage';
+    const STATS_MEMORY_AVAILIABLE   = 'memory_available';
+
+    /**
+     * Fetches an entry from the cache.
+     *
+     * @param string $id cache id The id of the cache entry to fetch.
+     * @return string The cached data or FALSE, if no cache entry exists for the given id.
+     */
+    function fetch($id);
+
+    /**
+     * Test if an entry exists in the cache.
+     *
+     * @param string $id cache id The cache id of the entry to check for.
+     * @return boolean TRUE if a cache entry exists for the given cache id, FALSE otherwise.
+     */
+    function contains($id);
+
+    /**
+     * Puts data into the cache.
+     *
+     * @param string $id The cache id.
+     * @param string $data The cache entry/data.
+     * @param int $lifeTime The lifetime. If != 0, sets a specific lifetime for this cache entry (0 => infinite lifeTime).
+     * @return boolean TRUE if the entry was successfully stored in the cache, FALSE otherwise.
+     */
+    function save($id, $data, $lifeTime = 0);
+
+    /**
+     * Deletes a cache entry.
+     *
+     * @param string $id cache id
+     * @return boolean TRUE if the cache entry was successfully deleted, FALSE otherwise.
+     */
+    function delete($id);
+
+    /**
+     * Retrieves cached information from data store
+     *
+     * The server's statistics array has the following values:
+     *
+     * - <b>hits</b>
+     * Number of keys that have been requested and found present.
+     *
+     * - <b>misses</b>
+     * Number of items that have been requested and not found.
+     *
+     * - <b>uptime</b>
+     * Time that the server is running.
+     *
+     * - <b>memory_usage</b>
+     * Memory used by this server to store items.
+     *
+     * - <b>memory_available</b>
+     * Memory allowed to use for storage.
+     *
+     * @since   2.2
+     * @var     array Associative array with server's statistics if available, NULL otherwise.
+     */
+    function getStats();
+}

+ 188 - 0
main/inc/lib/symfony/Doctrine/Common/Cache/CacheProvider.php

@@ -0,0 +1,188 @@
+<?php
+
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Cache;
+
+/**
+ * Base class for cache provider implementations.
+ *
+ * @since   2.2
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ * @author  Fabio B. Silva <fabio.bat.silva@gmail.com>
+ */
+abstract class CacheProvider implements Cache
+{
+    const DOCTRINE_NAMESPACE_CACHEKEY = 'DoctrineNamespaceCacheKey[%s]';
+
+    /**
+     * @var string The namespace to prefix all cache ids with
+     */
+    private $namespace = '';
+
+    /**
+     * Set the namespace to prefix all cache ids with.
+     *
+     * @param string $namespace
+     * @return void
+     */
+    public function setNamespace($namespace)
+    {
+        $this->namespace = (string) $namespace;
+    }
+
+    /**
+     * Retrieve the namespace that prefixes all cache ids.
+     *
+     * @return string
+     */
+    public function getNamespace()
+    {
+        return $this->namespace;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function fetch($id)
+    {
+        return $this->doFetch($this->getNamespacedId($id));
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function contains($id)
+    {
+        return $this->doContains($this->getNamespacedId($id));
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function save($id, $data, $lifeTime = 0)
+    {
+        return $this->doSave($this->getNamespacedId($id), $data, $lifeTime);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function delete($id)
+    {
+        return $this->doDelete($this->getNamespacedId($id));
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getStats()
+    {
+        return $this->doGetStats();
+    }
+
+    /**
+     * Deletes all cache entries.
+     *
+     * @return boolean TRUE if the cache entries were successfully flushed, FALSE otherwise.
+     */
+    public function flushAll()
+    {
+        return $this->doFlush();
+    }
+
+    /**
+     * Delete all cache entries.
+     *
+     * @return boolean TRUE if the cache entries were successfully deleted, FALSE otherwise.
+     */
+    public function deleteAll()
+    {
+        $namespaceCacheKey = sprintf(self::DOCTRINE_NAMESPACE_CACHEKEY, $this->namespace);
+        $namespaceVersion  = ($this->doContains($namespaceCacheKey)) ? $this->doFetch($namespaceCacheKey) : 1;
+
+        return $this->doSave($namespaceCacheKey, $namespaceVersion + 1);
+    }
+
+    /**
+     * Prefix the passed id with the configured namespace value
+     *
+     * @param string $id  The id to namespace
+     * @return string $id The namespaced id
+     */
+    private function getNamespacedId($id)
+    {
+        $namespaceCacheKey = sprintf(self::DOCTRINE_NAMESPACE_CACHEKEY, $this->namespace);
+        $namespaceVersion  = ($this->doContains($namespaceCacheKey)) ? $this->doFetch($namespaceCacheKey) : 1;
+
+        return sprintf('%s[%s][%s]', $this->namespace, $id, $namespaceVersion);
+    }
+
+    /**
+     * Fetches an entry from the cache.
+     *
+     * @param string $id cache id The id of the cache entry to fetch.
+     * @return string The cached data or FALSE, if no cache entry exists for the given id.
+     */
+    abstract protected function doFetch($id);
+
+    /**
+     * Test if an entry exists in the cache.
+     *
+     * @param string $id cache id The cache id of the entry to check for.
+     * @return boolean TRUE if a cache entry exists for the given cache id, FALSE otherwise.
+     */
+    abstract protected function doContains($id);
+
+    /**
+     * Puts data into the cache.
+     *
+     * @param string $id The cache id.
+     * @param string $data The cache entry/data.
+     * @param int $lifeTime The lifetime. If != false, sets a specific lifetime for this cache entry (null => infinite lifeTime).
+     * @return boolean TRUE if the entry was successfully stored in the cache, FALSE otherwise.
+     */
+    abstract protected function doSave($id, $data, $lifeTime = false);
+
+    /**
+     * Deletes a cache entry.
+     *
+     * @param string $id cache id
+     * @return boolean TRUE if the cache entry was successfully deleted, FALSE otherwise.
+     */
+    abstract protected function doDelete($id);
+
+    /**
+     * Deletes all cache entries.
+     *
+     * @return boolean TRUE if the cache entry was successfully deleted, FALSE otherwise.
+     */
+    abstract protected function doFlush();
+
+     /**
+     * Retrieves cached information from data store
+     *
+     * @since   2.2
+     * @return  array An associative array with server's statistics if available, NULL otherwise.
+     */
+    abstract protected function doGetStats();
+}

+ 118 - 0
main/inc/lib/symfony/Doctrine/Common/Cache/MemcacheCache.php

@@ -0,0 +1,118 @@
+<?php
+
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Cache;
+
+use \Memcache;
+
+/**
+ * Memcache cache provider.
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ * @author  David Abdemoulaie <dave@hobodave.com>
+ */
+class MemcacheCache extends CacheProvider
+{
+    /**
+     * @var Memcache
+     */
+    private $memcache;
+
+    /**
+     * Sets the memcache instance to use.
+     *
+     * @param Memcache $memcache
+     */
+    public function setMemcache(Memcache $memcache)
+    {
+        $this->memcache = $memcache;
+    }
+
+    /**
+     * Gets the memcache instance used by the cache.
+     *
+     * @return Memcache
+     */
+    public function getMemcache()
+    {
+        return $this->memcache;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doFetch($id)
+    {
+        return $this->memcache->get($id);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doContains($id)
+    {
+        return (bool) $this->memcache->get($id);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doSave($id, $data, $lifeTime = 0)
+    {
+        return $this->memcache->set($id, $data, 0, (int) $lifeTime);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doDelete($id)
+    {
+        return $this->memcache->delete($id);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doFlush()
+    {
+        return $this->memcache->flush();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doGetStats()
+    {
+        $stats = $this->memcache->getStats();
+        return array(
+            Cache::STATS_HITS   => $stats['get_hits'],
+            Cache::STATS_MISSES => $stats['get_misses'],
+            Cache::STATS_UPTIME => $stats['uptime'],
+            Cache::STATS_MEMORY_USAGE       => $stats['bytes'],
+            Cache::STATS_MEMORY_AVAILIABLE  => $stats['limit_maxbytes'],
+        );
+    }
+}

+ 121 - 0
main/inc/lib/symfony/Doctrine/Common/Cache/MemcachedCache.php

@@ -0,0 +1,121 @@
+<?php
+
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Cache;
+
+use \Memcached;
+
+/**
+ * Memcached cache provider.
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.2
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ * @author  David Abdemoulaie <dave@hobodave.com>
+ */
+class MemcachedCache extends CacheProvider
+{
+    /**
+     * @var Memcached
+     */
+    private $memcached;
+
+    /**
+     * Sets the memcache instance to use.
+     *
+     * @param Memcached $memcached
+     */
+    public function setMemcached(Memcached $memcached)
+    {
+        $this->memcached = $memcached;
+    }
+
+    /**
+     * Gets the memcached instance used by the cache.
+     *
+     * @return Memcached
+     */
+    public function getMemcached()
+    {
+        return $this->memcached;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doFetch($id)
+    {
+        return $this->memcached->get($id);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doContains($id)
+    {
+        return (false !== $this->memcached->get($id));
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doSave($id, $data, $lifeTime = 0)
+    {
+        return $this->memcached->set($id, $data, (int) $lifeTime);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doDelete($id)
+    {
+        return $this->memcached->delete($id);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doFlush()
+    {
+        return $this->memcached->flush();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doGetStats()
+    {
+        $stats   = $this->memcached->getStats();
+        $servers = $this->memcached->getServerList();
+        $key     = $servers[0]['host'] . ':' . $servers[0]['port'];
+        $stats   = $stats[$key];
+        return array(
+            Cache::STATS_HITS   => $stats['get_hits'],
+            Cache::STATS_MISSES => $stats['get_misses'],
+            Cache::STATS_UPTIME => $stats['uptime'],
+            Cache::STATS_MEMORY_USAGE       => $stats['bytes'],
+            Cache::STATS_MEMORY_AVAILIABLE  => $stats['limit_maxbytes'],
+        );
+    }
+}

+ 92 - 0
main/inc/lib/symfony/Doctrine/Common/Cache/WinCacheCache.php

@@ -0,0 +1,92 @@
+<?php
+
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Cache;
+
+/**
+ * WinCache cache provider.
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.2
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ * @author  David Abdemoulaie <dave@hobodave.com>
+ */
+class WincacheCache extends CacheProvider
+{
+    /**
+     * {@inheritdoc}
+     */
+    protected function doFetch($id)
+    {
+        return wincache_ucache_get($id);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doContains($id)
+    {
+        return wincache_ucache_exists($id);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doSave($id, $data, $lifeTime = 0)
+    {
+        return (bool) wincache_ucache_set($id, $data, (int) $lifeTime);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doDelete($id)
+    {
+        return wincache_ucache_delete($id);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doFlush()
+    {
+        return wincache_ucache_clear();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doGetStats()
+    {
+        $info   = wincache_ucache_info();
+        $meminfo= wincache_ucache_meminfo();
+        return array(
+            Cache::STATS_HITS   => $info['total_hit_count'],
+            Cache::STATS_MISSES => $info['total_miss_count'],
+            Cache::STATS_UPTIME => $info['total_cache_uptime'],
+            Cache::STATS_MEMORY_USAGE       => $meminfo['memory_total'],
+            Cache::STATS_MEMORY_AVAILIABLE  => $meminfo['memory_free'],
+        );
+    }
+}

+ 110 - 0
main/inc/lib/symfony/Doctrine/Common/Cache/XcacheCache.php

@@ -0,0 +1,110 @@
+<?php
+
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Cache;
+
+/**
+ * Xcache cache driver.
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ * @author  David Abdemoulaie <dave@hobodave.com>
+ */
+class XcacheCache extends CacheProvider
+{
+    /**
+     * {@inheritdoc}
+     */
+    protected function doFetch($id)
+    {
+        return $this->doContains($id) ? unserialize(xcache_get($id)) : false;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doContains($id)
+    {
+        return xcache_isset($id);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doSave($id, $data, $lifeTime = 0)
+    {
+        return xcache_set($id, serialize($data), (int) $lifeTime);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doDelete($id)
+    {
+        return xcache_unset($id);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doFlush()
+    {
+        $this->checkAuthorization();
+
+        xcache_clear_cache(XC_TYPE_VAR, 0);
+
+        return true;
+    }
+
+    /**
+     * Checks that xcache.admin.enable_auth is Off
+     *
+     * @throws \BadMethodCallException When xcache.admin.enable_auth is On
+     * @return void
+     */
+    protected function checkAuthorization()
+    {
+        if (ini_get('xcache.admin.enable_auth')) {
+            throw new \BadMethodCallException('To use all features of \Doctrine\Common\Cache\XcacheCache, you must set "xcache.admin.enable_auth" to "Off" in your php.ini.');
+        }
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doGetStats()
+    {
+        $this->checkAuthorization();
+
+        $info = xcache_info(XC_TYPE_VAR, 0);
+        return array(
+            Cache::STATS_HITS   => $info['hits'],
+            Cache::STATS_MISSES => $info['misses'],
+            Cache::STATS_UPTIME => null,
+            Cache::STATS_MEMORY_USAGE       => $info['size'],
+            Cache::STATS_MEMORY_AVAILIABLE  => $info['avail'],
+        );
+    }
+}

+ 84 - 0
main/inc/lib/symfony/Doctrine/Common/Cache/ZendDataCache.php

@@ -0,0 +1,84 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Cache;
+
+/**
+ * Zend Data Cache cache driver.
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @author  Ralph Schindler <ralph.schindler@zend.com>
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ */
+class ZendDataCache extends CacheProvider
+{
+    /**
+     * {@inheritdoc}
+     */
+    protected function doFetch($id)
+    {
+        return zend_shm_cache_fetch($id);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doContains($id)
+    {
+        return (false !== zend_shm_cache_fetch($id));
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doSave($id, $data, $lifeTime = 0)
+    {
+        return zend_shm_cache_store($id, $data, $lifeTime);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doDelete($id)
+    {
+        return zend_shm_cache_delete($id);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doFlush()
+    {
+        $namespace = $this->getNamespace();
+        if (empty($namespace)) {
+            return zend_shm_cache_clear();
+        }
+        return zend_shm_cache_clear($namespace);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doGetStats()
+    {
+        return null;
+    }
+}

+ 262 - 0
main/inc/lib/symfony/Doctrine/Common/ClassLoader.php

@@ -0,0 +1,262 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common;
+
+/**
+ * A <tt>ClassLoader</tt> is an autoloader for class files that can be
+ * installed on the SPL autoload stack. It is a class loader that either loads only classes
+ * of a specific namespace or all namespaces and it is suitable for working together
+ * with other autoloaders in the SPL autoload stack.
+ *
+ * If no include path is configured through the constructor or {@link setIncludePath}, a ClassLoader
+ * relies on the PHP <code>include_path</code>.
+ *
+ * @author Roman Borschel <roman@code-factory.org>
+ * @since 2.0
+ */
+class ClassLoader
+{
+    /**
+     * @var string PHP file extension
+     */
+    protected $fileExtension = '.php';
+
+    /**
+     * @var string Current namespace
+     */
+    protected $namespace;
+
+    /**
+     * @var string Current include path
+     */
+    protected $includePath;
+
+    /**
+     * @var string PHP namespace separator
+     */
+    protected $namespaceSeparator = '\\';
+
+    /**
+     * Creates a new <tt>ClassLoader</tt> that loads classes of the
+     * specified namespace from the specified include path.
+     *
+     * If no include path is given, the ClassLoader relies on the PHP include_path.
+     * If neither a namespace nor an include path is given, the ClassLoader will
+     * be responsible for loading all classes, thereby relying on the PHP include_path.
+     *
+     * @param string $ns The namespace of the classes to load.
+     * @param string $includePath The base include path to use.
+     */
+    public function __construct($ns = null, $includePath = null)
+    {
+        $this->namespace = $ns;
+        $this->includePath = $includePath;
+    }
+
+    /**
+     * Sets the namespace separator used by classes in the namespace of this ClassLoader.
+     *
+     * @param string $sep The separator to use.
+     */
+    public function setNamespaceSeparator($sep)
+    {
+        $this->namespaceSeparator = $sep;
+    }
+
+    /**
+     * Gets the namespace separator used by classes in the namespace of this ClassLoader.
+     *
+     * @return string
+     */
+    public function getNamespaceSeparator()
+    {
+        return $this->namespaceSeparator;
+    }
+
+    /**
+     * Sets the base include path for all class files in the namespace of this ClassLoader.
+     *
+     * @param string $includePath
+     */
+    public function setIncludePath($includePath)
+    {
+        $this->includePath = $includePath;
+    }
+
+    /**
+     * Gets the base include path for all class files in the namespace of this ClassLoader.
+     *
+     * @return string
+     */
+    public function getIncludePath()
+    {
+        return $this->includePath;
+    }
+
+    /**
+     * Sets the file extension of class files in the namespace of this ClassLoader.
+     *
+     * @param string $fileExtension
+     */
+    public function setFileExtension($fileExtension)
+    {
+        $this->fileExtension = $fileExtension;
+    }
+
+    /**
+     * Gets the file extension of class files in the namespace of this ClassLoader.
+     *
+     * @return string
+     */
+    public function getFileExtension()
+    {
+        return $this->fileExtension;
+    }
+
+    /**
+     * Registers this ClassLoader on the SPL autoload stack.
+     */
+    public function register()
+    {
+        spl_autoload_register(array($this, 'loadClass'));
+    }
+
+    /**
+     * Removes this ClassLoader from the SPL autoload stack.
+     */
+    public function unregister()
+    {
+        spl_autoload_unregister(array($this, 'loadClass'));
+    }
+
+    /**
+     * Loads the given class or interface.
+     *
+     * @param string $classname The name of the class to load.
+     * @return boolean TRUE if the class has been successfully loaded, FALSE otherwise.
+     */
+    public function loadClass($className)
+    {
+        if ($this->namespace !== null && strpos($className, $this->namespace.$this->namespaceSeparator) !== 0) {
+            return false;
+        }
+
+        require ($this->includePath !== null ? $this->includePath . DIRECTORY_SEPARATOR : '')
+               . str_replace($this->namespaceSeparator, DIRECTORY_SEPARATOR, $className)
+               . $this->fileExtension;
+
+        return true;
+    }
+
+    /**
+     * Asks this ClassLoader whether it can potentially load the class (file) with
+     * the given name.
+     *
+     * @param string $className The fully-qualified name of the class.
+     * @return boolean TRUE if this ClassLoader can load the class, FALSE otherwise.
+     */
+    public function canLoadClass($className)
+    {
+        if ($this->namespace !== null && strpos($className, $this->namespace.$this->namespaceSeparator) !== 0) {
+            return false;
+        }
+
+        $file = str_replace($this->namespaceSeparator, DIRECTORY_SEPARATOR, $className) . $this->fileExtension;
+
+        if ($this->includePath !== null) {
+            return file_exists($this->includePath . DIRECTORY_SEPARATOR . $file);
+        }
+
+        return (false !== stream_resolve_include_path($file));
+    }
+
+    /**
+     * Checks whether a class with a given name exists. A class "exists" if it is either
+     * already defined in the current request or if there is an autoloader on the SPL
+     * autoload stack that is a) responsible for the class in question and b) is able to
+     * load a class file in which the class definition resides.
+     *
+     * If the class is not already defined, each autoloader in the SPL autoload stack
+     * is asked whether it is able to tell if the class exists. If the autoloader is
+     * a <tt>ClassLoader</tt>, {@link canLoadClass} is used, otherwise the autoload
+     * function of the autoloader is invoked and expected to return a value that
+     * evaluates to TRUE if the class (file) exists. As soon as one autoloader reports
+     * that the class exists, TRUE is returned.
+     *
+     * Note that, depending on what kinds of autoloaders are installed on the SPL
+     * autoload stack, the class (file) might already be loaded as a result of checking
+     * for its existence. This is not the case with a <tt>ClassLoader</tt>, who separates
+     * these responsibilities.
+     *
+     * @param string $className The fully-qualified name of the class.
+     * @return boolean TRUE if the class exists as per the definition given above, FALSE otherwise.
+     */
+    public static function classExists($className)
+    {
+        if (class_exists($className, false) || interface_exists($className, false)) {
+            return true;
+        }
+
+        foreach (spl_autoload_functions() as $loader) {
+            if (is_array($loader)) { // array(???, ???)
+                if (is_object($loader[0])) {
+                    if ($loader[0] instanceof ClassLoader) { // array($obj, 'methodName')
+                        if ($loader[0]->canLoadClass($className)) {
+                            return true;
+                        }
+                    } else if ($loader[0]->{$loader[1]}($className)) {
+                        return true;
+                    }
+                } else if ($loader[0]::$loader[1]($className)) { // array('ClassName', 'methodName')
+                    return true;
+                }
+            } else if ($loader instanceof \Closure) { // function($className) {..}
+                if ($loader($className)) {
+                    return true;
+                }
+            } else if (is_string($loader) && $loader($className)) { // "MyClass::loadClass"
+                return true;
+            }
+        }
+
+        return class_exists($className, false) || interface_exists($className, false);
+    }
+
+    /**
+     * Gets the <tt>ClassLoader</tt> from the SPL autoload stack that is responsible
+     * for (and is able to load) the class with the given name.
+     *
+     * @param string $className The name of the class.
+     * @return The <tt>ClassLoader</tt> for the class or NULL if no such <tt>ClassLoader</tt> exists.
+     */
+    public static function getClassLoader($className)
+    {
+         foreach (spl_autoload_functions() as $loader) {
+            if (is_array($loader)
+                && $loader[0] instanceof ClassLoader
+                && $loader[0]->canLoadClass($className)
+            ) {
+                return $loader[0];
+            }
+        }
+
+        return null;
+    }
+}

+ 447 - 0
main/inc/lib/symfony/Doctrine/Common/Collections/ArrayCollection.php

@@ -0,0 +1,447 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Collections;
+
+use Closure, ArrayIterator;
+
+/**
+ * An ArrayCollection is a Collection implementation that wraps a regular PHP array.
+ *
+ * @since   2.0
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class ArrayCollection implements Collection
+{
+    /**
+     * An array containing the entries of this collection.
+     *
+     * @var array
+     */
+    private $_elements;
+
+    /**
+     * Initializes a new ArrayCollection.
+     *
+     * @param array $elements
+     */
+    public function __construct(array $elements = array())
+    {
+        $this->_elements = $elements;
+    }
+
+    /**
+     * Gets the PHP array representation of this collection.
+     *
+     * @return array The PHP array representation of this collection.
+     */
+    public function toArray()
+    {
+        return $this->_elements;
+    }
+
+    /**
+     * Sets the internal iterator to the first element in the collection and
+     * returns this element.
+     *
+     * @return mixed
+     */
+    public function first()
+    {
+        return reset($this->_elements);
+    }
+
+    /**
+     * Sets the internal iterator to the last element in the collection and
+     * returns this element.
+     *
+     * @return mixed
+     */
+    public function last()
+    {
+        return end($this->_elements);
+    }
+
+    /**
+     * Gets the current key/index at the current internal iterator position.
+     *
+     * @return mixed
+     */
+    public function key()
+    {
+        return key($this->_elements);
+    }
+
+    /**
+     * Moves the internal iterator position to the next element.
+     *
+     * @return mixed
+     */
+    public function next()
+    {
+        return next($this->_elements);
+    }
+
+    /**
+     * Gets the element of the collection at the current internal iterator position.
+     *
+     * @return mixed
+     */
+    public function current()
+    {
+        return current($this->_elements);
+    }
+
+    /**
+     * Removes an element with a specific key/index from the collection.
+     *
+     * @param mixed $key
+     * @return mixed The removed element or NULL, if no element exists for the given key.
+     */
+    public function remove($key)
+    {
+        if (isset($this->_elements[$key])) {
+            $removed = $this->_elements[$key];
+            unset($this->_elements[$key]);
+
+            return $removed;
+        }
+
+        return null;
+    }
+
+    /**
+     * Removes the specified element from the collection, if it is found.
+     *
+     * @param mixed $element The element to remove.
+     * @return boolean TRUE if this collection contained the specified element, FALSE otherwise.
+     */
+    public function removeElement($element)
+    {
+        $key = array_search($element, $this->_elements, true);
+
+        if ($key !== false) {
+            unset($this->_elements[$key]);
+
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * ArrayAccess implementation of offsetExists()
+     *
+     * @see containsKey()
+     */
+    public function offsetExists($offset)
+    {
+        return $this->containsKey($offset);
+    }
+
+    /**
+     * ArrayAccess implementation of offsetGet()
+     *
+     * @see get()
+     */
+    public function offsetGet($offset)
+    {
+        return $this->get($offset);
+    }
+
+    /**
+     * ArrayAccess implementation of offsetGet()
+     *
+     * @see add()
+     * @see set()
+     */
+    public function offsetSet($offset, $value)
+    {
+        if ( ! isset($offset)) {
+            return $this->add($value);
+        }
+        return $this->set($offset, $value);
+    }
+
+    /**
+     * ArrayAccess implementation of offsetUnset()
+     *
+     * @see remove()
+     */
+    public function offsetUnset($offset)
+    {
+        return $this->remove($offset);
+    }
+
+    /**
+     * Checks whether the collection contains a specific key/index.
+     *
+     * @param mixed $key The key to check for.
+     * @return boolean TRUE if the given key/index exists, FALSE otherwise.
+     */
+    public function containsKey($key)
+    {
+        return isset($this->_elements[$key]);
+    }
+
+    /**
+     * Checks whether the given element is contained in the collection.
+     * Only element values are compared, not keys. The comparison of two elements
+     * is strict, that means not only the value but also the type must match.
+     * For objects this means reference equality.
+     *
+     * @param mixed $element
+     * @return boolean TRUE if the given element is contained in the collection,
+     *          FALSE otherwise.
+     */
+    public function contains($element)
+    {
+        foreach ($this->_elements as $collectionElement) {
+            if ($element === $collectionElement) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Tests for the existance of an element that satisfies the given predicate.
+     *
+     * @param Closure $p The predicate.
+     * @return boolean TRUE if the predicate is TRUE for at least one element, FALSE otherwise.
+     */
+    public function exists(Closure $p)
+    {
+        foreach ($this->_elements as $key => $element) {
+            if ($p($key, $element)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Searches for a given element and, if found, returns the corresponding key/index
+     * of that element. The comparison of two elements is strict, that means not
+     * only the value but also the type must match.
+     * For objects this means reference equality.
+     *
+     * @param mixed $element The element to search for.
+     * @return mixed The key/index of the element or FALSE if the element was not found.
+     */
+    public function indexOf($element)
+    {
+        return array_search($element, $this->_elements, true);
+    }
+
+    /**
+     * Gets the element with the given key/index.
+     *
+     * @param mixed $key The key.
+     * @return mixed The element or NULL, if no element exists for the given key.
+     */
+    public function get($key)
+    {
+        if (isset($this->_elements[$key])) {
+            return $this->_elements[$key];
+        }
+        return null;
+    }
+
+    /**
+     * Gets all keys/indexes of the collection elements.
+     *
+     * @return array
+     */
+    public function getKeys()
+    {
+        return array_keys($this->_elements);
+    }
+
+    /**
+     * Gets all elements.
+     *
+     * @return array
+     */
+    public function getValues()
+    {
+        return array_values($this->_elements);
+    }
+
+    /**
+     * Returns the number of elements in the collection.
+     *
+     * Implementation of the Countable interface.
+     *
+     * @return integer The number of elements in the collection.
+     */
+    public function count()
+    {
+        return count($this->_elements);
+    }
+
+    /**
+     * Adds/sets an element in the collection at the index / with the specified key.
+     *
+     * When the collection is a Map this is like put(key,value)/add(key,value).
+     * When the collection is a List this is like add(position,value).
+     *
+     * @param mixed $key
+     * @param mixed $value
+     */
+    public function set($key, $value)
+    {
+        $this->_elements[$key] = $value;
+    }
+
+    /**
+     * Adds an element to the collection.
+     *
+     * @param mixed $value
+     * @return boolean Always TRUE.
+     */
+    public function add($value)
+    {
+        $this->_elements[] = $value;
+        return true;
+    }
+
+    /**
+     * Checks whether the collection is empty.
+     *
+     * Note: This is preferrable over count() == 0.
+     *
+     * @return boolean TRUE if the collection is empty, FALSE otherwise.
+     */
+    public function isEmpty()
+    {
+        return ! $this->_elements;
+    }
+
+    /**
+     * Gets an iterator for iterating over the elements in the collection.
+     *
+     * @return ArrayIterator
+     */
+    public function getIterator()
+    {
+        return new ArrayIterator($this->_elements);
+    }
+
+    /**
+     * Applies the given function to each element in the collection and returns
+     * a new collection with the elements returned by the function.
+     *
+     * @param Closure $func
+     * @return Collection
+     */
+    public function map(Closure $func)
+    {
+        return new static(array_map($func, $this->_elements));
+    }
+
+    /**
+     * Returns all the elements of this collection that satisfy the predicate p.
+     * The order of the elements is preserved.
+     *
+     * @param Closure $p The predicate used for filtering.
+     * @return Collection A collection with the results of the filter operation.
+     */
+    public function filter(Closure $p)
+    {
+        return new static(array_filter($this->_elements, $p));
+    }
+
+    /**
+     * Applies the given predicate p to all elements of this collection,
+     * returning true, if the predicate yields true for all elements.
+     *
+     * @param Closure $p The predicate.
+     * @return boolean TRUE, if the predicate yields TRUE for all elements, FALSE otherwise.
+     */
+    public function forAll(Closure $p)
+    {
+        foreach ($this->_elements as $key => $element) {
+            if ( ! $p($key, $element)) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * Partitions this collection in two collections according to a predicate.
+     * Keys are preserved in the resulting collections.
+     *
+     * @param Closure $p The predicate on which to partition.
+     * @return array An array with two elements. The first element contains the collection
+     *               of elements where the predicate returned TRUE, the second element
+     *               contains the collection of elements where the predicate returned FALSE.
+     */
+    public function partition(Closure $p)
+    {
+        $coll1 = $coll2 = array();
+        foreach ($this->_elements as $key => $element) {
+            if ($p($key, $element)) {
+                $coll1[$key] = $element;
+            } else {
+                $coll2[$key] = $element;
+            }
+        }
+        return array(new static($coll1), new static($coll2));
+    }
+
+    /**
+     * Returns a string representation of this object.
+     *
+     * @return string
+     */
+    public function __toString()
+    {
+        return __CLASS__ . '@' . spl_object_hash($this);
+    }
+
+    /**
+     * Clears the collection.
+     */
+    public function clear()
+    {
+        $this->_elements = array();
+    }
+
+    /**
+     * Extract a slice of $length elements starting at position $offset from the Collection.
+     *
+     * If $length is null it returns all elements from $offset to the end of the Collection.
+     * Keys have to be preserved by this method. Calling this method will only return the
+     * selected slice and NOT change the elements contained in the collection slice is called on.
+     *
+     * @param int $offset
+     * @param int $length
+     * @return array
+     */
+    public function slice($offset, $length = null)
+    {
+        return array_slice($this->_elements, $offset, $length, true);
+    }
+}

+ 243 - 0
main/inc/lib/symfony/Doctrine/Common/Collections/Collection.php

@@ -0,0 +1,243 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Collections;
+
+use Closure, Countable, IteratorAggregate, ArrayAccess;
+
+/**
+ * The missing (SPL) Collection/Array/OrderedMap interface.
+ *
+ * A Collection resembles the nature of a regular PHP array. That is,
+ * it is essentially an <b>ordered map</b> that can also be used
+ * like a list.
+ *
+ * A Collection has an internal iterator just like a PHP array. In addition,
+ * a Collection can be iterated with external iterators, which is preferrable.
+ * To use an external iterator simply use the foreach language construct to
+ * iterate over the collection (which calls {@link getIterator()} internally) or
+ * explicitly retrieve an iterator though {@link getIterator()} which can then be
+ * used to iterate over the collection.
+ * You can not rely on the internal iterator of the collection being at a certain
+ * position unless you explicitly positioned it before. Prefer iteration with
+ * external iterators.
+ *
+ * @since   2.0
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+interface Collection extends Countable, IteratorAggregate, ArrayAccess
+{
+    /**
+     * Adds an element at the end of the collection.
+     *
+     * @param mixed $element The element to add.
+     * @return boolean Always TRUE.
+     */
+    function add($element);
+
+    /**
+     * Clears the collection, removing all elements.
+     */
+    function clear();
+
+    /**
+     * Checks whether an element is contained in the collection.
+     * This is an O(n) operation, where n is the size of the collection.
+     *
+     * @param mixed $element The element to search for.
+     * @return boolean TRUE if the collection contains the element, FALSE otherwise.
+     */
+    function contains($element);
+
+    /**
+     * Checks whether the collection is empty (contains no elements).
+     *
+     * @return boolean TRUE if the collection is empty, FALSE otherwise.
+     */
+    function isEmpty();
+
+    /**
+     * Removes the element at the specified index from the collection.
+     *
+     * @param string|integer $key The kex/index of the element to remove.
+     * @return mixed The removed element or NULL, if the collection did not contain the element.
+     */
+    function remove($key);
+
+    /**
+     * Removes the specified element from the collection, if it is found.
+     *
+     * @param mixed $element The element to remove.
+     * @return boolean TRUE if this collection contained the specified element, FALSE otherwise.
+     */
+    function removeElement($element);
+
+    /**
+     * Checks whether the collection contains an element with the specified key/index.
+     *
+     * @param string|integer $key The key/index to check for.
+     * @return boolean TRUE if the collection contains an element with the specified key/index,
+     *          FALSE otherwise.
+     */
+    function containsKey($key);
+
+    /**
+     * Gets the element at the specified key/index.
+     *
+     * @param string|integer $key The key/index of the element to retrieve.
+     * @return mixed
+     */
+    function get($key);
+
+    /**
+     * Gets all keys/indices of the collection.
+     *
+     * @return array The keys/indices of the collection, in the order of the corresponding
+     *          elements in the collection.
+     */
+    function getKeys();
+
+    /**
+     * Gets all values of the collection.
+     *
+     * @return array The values of all elements in the collection, in the order they
+     *          appear in the collection.
+     */
+    function getValues();
+
+    /**
+     * Sets an element in the collection at the specified key/index.
+     *
+     * @param string|integer $key The key/index of the element to set.
+     * @param mixed $value The element to set.
+     */
+    function set($key, $value);
+
+    /**
+     * Gets a native PHP array representation of the collection.
+     *
+     * @return array
+     */
+    function toArray();
+
+    /**
+     * Sets the internal iterator to the first element in the collection and
+     * returns this element.
+     *
+     * @return mixed
+     */
+    function first();
+
+    /**
+     * Sets the internal iterator to the last element in the collection and
+     * returns this element.
+     *
+     * @return mixed
+     */
+    function last();
+
+    /**
+     * Gets the key/index of the element at the current iterator position.
+     *
+     */
+    function key();
+
+    /**
+     * Gets the element of the collection at the current iterator position.
+     *
+     */
+    function current();
+
+    /**
+     * Moves the internal iterator position to the next element.
+     *
+     */
+    function next();
+
+    /**
+     * Tests for the existence of an element that satisfies the given predicate.
+     *
+     * @param Closure $p The predicate.
+     * @return boolean TRUE if the predicate is TRUE for at least one element, FALSE otherwise.
+     */
+    function exists(Closure $p);
+
+    /**
+     * Returns all the elements of this collection that satisfy the predicate p.
+     * The order of the elements is preserved.
+     *
+     * @param Closure $p The predicate used for filtering.
+     * @return Collection A collection with the results of the filter operation.
+     */
+    function filter(Closure $p);
+
+    /**
+     * Applies the given predicate p to all elements of this collection,
+     * returning true, if the predicate yields true for all elements.
+     *
+     * @param Closure $p The predicate.
+     * @return boolean TRUE, if the predicate yields TRUE for all elements, FALSE otherwise.
+     */
+    function forAll(Closure $p);
+
+    /**
+     * Applies the given function to each element in the collection and returns
+     * a new collection with the elements returned by the function.
+     *
+     * @param Closure $func
+     * @return Collection
+     */
+    function map(Closure $func);
+
+    /**
+     * Partitions this collection in two collections according to a predicate.
+     * Keys are preserved in the resulting collections.
+     *
+     * @param Closure $p The predicate on which to partition.
+     * @return array An array with two elements. The first element contains the collection
+     *               of elements where the predicate returned TRUE, the second element
+     *               contains the collection of elements where the predicate returned FALSE.
+     */
+    function partition(Closure $p);
+
+    /**
+     * Gets the index/key of a given element. The comparison of two elements is strict,
+     * that means not only the value but also the type must match.
+     * For objects this means reference equality.
+     *
+     * @param mixed $element The element to search for.
+     * @return mixed The key/index of the element or FALSE if the element was not found.
+     */
+    function indexOf($element);
+
+    /**
+     * Extract a slice of $length elements starting at position $offset from the Collection.
+     *
+     * If $length is null it returns all elements from $offset to the end of the Collection.
+     * Keys have to be preserved by this method. Calling this method will only return the
+     * selected slice and NOT change the elements contained in the collection slice is called on.
+     *
+     * @param int $offset
+     * @param int $length
+     * @return array
+     */
+    function slice($offset, $length = null);
+}

+ 28 - 0
main/inc/lib/symfony/Doctrine/Common/CommonException.php

@@ -0,0 +1,28 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common;
+
+/**
+ * Base exception class for package Doctrine\Common
+ * @author heinrich
+ *
+ */
+class CommonException extends \Exception {
+}

+ 47 - 0
main/inc/lib/symfony/Doctrine/Common/Comparable.php

@@ -0,0 +1,47 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+
+namespace Doctrine\Common;
+
+/**
+ * Comparable interface that allows to compare two value objects to each other for similarity.
+ *
+ * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link        www.doctrine-project.com
+ * @since       2.2
+ * @author      Benjamin Eberlei <kontakt@beberlei.de>
+ * @author      Guilherme Blanco <guilhermeblanco@hotmail.com>
+ */
+interface Comparable
+{
+    /**
+     * Compare the current object to the passed $other.
+     *
+     * Returns 0 if they are semantically equal, 1 if the other object
+     * is less than the current one, or -1 if its more than the current one.
+     *
+     * This method should not check for identity using ===, only for semantical equality for example
+     * when two different DateTime instances point to the exact same Date + TZ.
+     *
+     * @return int
+     */
+    public function compareTo($other);
+}
+

+ 69 - 0
main/inc/lib/symfony/Doctrine/Common/EventArgs.php

@@ -0,0 +1,69 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common;
+
+/**
+ * EventArgs is the base class for classes containing event data.
+ *
+ * This class contains no event data. It is used by events that do not pass state
+ * information to an event handler when an event is raised. The single empty EventArgs
+ * instance can be obtained through {@link getEmptyInstance}.
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision: 3938 $
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class EventArgs
+{
+    /**
+     * @var EventArgs Single instance of EventArgs
+     * @static
+     */
+    private static $_emptyEventArgsInstance;
+
+    /**
+     * Gets the single, empty and immutable EventArgs instance.
+     *
+     * This instance will be used when events are dispatched without any parameter,
+     * like this: EventManager::dispatchEvent('eventname');
+     *
+     * The benefit from this is that only one empty instance is instantiated and shared
+     * (otherwise there would be instances for every dispatched in the abovementioned form)
+     *
+     * @see EventManager::dispatchEvent
+     * @link http://msdn.microsoft.com/en-us/library/system.eventargs.aspx
+     * @static
+     * @return EventArgs
+     */
+    public static function getEmptyInstance()
+    {
+        if ( ! self::$_emptyEventArgsInstance) {
+            self::$_emptyEventArgsInstance = new EventArgs;
+        }
+
+        return self::$_emptyEventArgsInstance;
+    }
+}

+ 136 - 0
main/inc/lib/symfony/Doctrine/Common/EventManager.php

@@ -0,0 +1,136 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common;
+
+/**
+ * The EventManager is the central point of Doctrine's event listener system.
+ * Listeners are registered on the manager and events are dispatched through the
+ * manager.
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision: 3938 $
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class EventManager
+{
+    /**
+     * Map of registered listeners.
+     * <event> => <listeners>
+     *
+     * @var array
+     */
+    private $_listeners = array();
+
+    /**
+     * Dispatches an event to all registered listeners.
+     *
+     * @param string $eventName The name of the event to dispatch. The name of the event is
+     *                          the name of the method that is invoked on listeners.
+     * @param EventArgs $eventArgs The event arguments to pass to the event handlers/listeners.
+     *                             If not supplied, the single empty EventArgs instance is used.
+     * @return boolean
+     */
+    public function dispatchEvent($eventName, EventArgs $eventArgs = null)
+    {
+        if (isset($this->_listeners[$eventName])) {
+            $eventArgs = $eventArgs === null ? EventArgs::getEmptyInstance() : $eventArgs;
+
+            foreach ($this->_listeners[$eventName] as $listener) {
+                $listener->$eventName($eventArgs);
+            }
+        }
+    }
+
+    /**
+     * Gets the listeners of a specific event or all listeners.
+     *
+     * @param string $event The name of the event.
+     * @return array The event listeners for the specified event, or all event listeners.
+     */
+    public function getListeners($event = null)
+    {
+        return $event ? $this->_listeners[$event] : $this->_listeners;
+    }
+
+    /**
+     * Checks whether an event has any registered listeners.
+     *
+     * @param string $event
+     * @return boolean TRUE if the specified event has any listeners, FALSE otherwise.
+     */
+    public function hasListeners($event)
+    {
+        return isset($this->_listeners[$event]) && $this->_listeners[$event];
+    }
+
+    /**
+     * Adds an event listener that listens on the specified events.
+     *
+     * @param string|array $events The event(s) to listen on.
+     * @param object $listener The listener object.
+     */
+    public function addEventListener($events, $listener)
+    {
+        // Picks the hash code related to that listener
+        $hash = spl_object_hash($listener);
+
+        foreach ((array) $events as $event) {
+            // Overrides listener if a previous one was associated already
+            // Prevents duplicate listeners on same event (same instance only)
+            $this->_listeners[$event][$hash] = $listener;
+        }
+    }
+
+    /**
+     * Removes an event listener from the specified events.
+     *
+     * @param string|array $events
+     * @param object $listener
+     */
+    public function removeEventListener($events, $listener)
+    {
+        // Picks the hash code related to that listener
+        $hash = spl_object_hash($listener);
+
+        foreach ((array) $events as $event) {
+            // Check if actually have this listener associated
+            if (isset($this->_listeners[$event][$hash])) {
+                unset($this->_listeners[$event][$hash]);
+            }
+        }
+    }
+
+    /**
+     * Adds an EventSubscriber. The subscriber is asked for all the events he is
+     * interested in and added as a listener for these events.
+     *
+     * @param Doctrine\Common\EventSubscriber $subscriber The subscriber.
+     */
+    public function addEventSubscriber(EventSubscriber $subscriber)
+    {
+        $this->addEventListener($subscriber->getSubscribedEvents(), $subscriber);
+    }
+}

+ 45 - 0
main/inc/lib/symfony/Doctrine/Common/EventSubscriber.php

@@ -0,0 +1,45 @@
+<?php
+/*
+ *  $Id: EventListener.php 4653 2008-07-10 17:17:58Z romanb $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common;
+
+/**
+ * An EventSubscriber knows himself what events he is interested in.
+ * If an EventSubscriber is added to an EventManager, the manager invokes
+ * {@link getSubscribedEvents} and registers the subscriber as a listener for all
+ * returned events.
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+interface EventSubscriber
+{
+    /**
+     * Returns an array of events this subscriber wants to listen to.
+     *
+     * @return array
+     */
+    function getSubscribedEvents();
+}

+ 266 - 0
main/inc/lib/symfony/Doctrine/Common/Lexer.php

@@ -0,0 +1,266 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common;
+
+/**
+ * Base class for writing simple lexers, i.e. for creating small DSLs.
+ *
+ * @since   2.0
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ * @todo Rename: AbstractLexer
+ */
+abstract class Lexer
+{
+    /**
+     * @var array Array of scanned tokens
+     */
+    private $tokens = array();
+
+    /**
+     * @var integer Current lexer position in input string
+     */
+    private $position = 0;
+
+    /**
+     * @var integer Current peek of current lexer position
+     */
+    private $peek = 0;
+
+    /**
+     * @var array The next token in the input.
+     */
+    public $lookahead;
+
+    /**
+     * @var array The last matched/seen token.
+     */
+    public $token;
+
+    /**
+     * Sets the input data to be tokenized.
+     *
+     * The Lexer is immediately reset and the new input tokenized.
+     * Any unprocessed tokens from any previous input are lost.
+     *
+     * @param string $input The input to be tokenized.
+     */
+    public function setInput($input)
+    {
+        $this->tokens = array();
+        $this->reset();
+        $this->scan($input);
+    }
+
+    /**
+     * Resets the lexer.
+     */
+    public function reset()
+    {
+        $this->lookahead = null;
+        $this->token = null;
+        $this->peek = 0;
+        $this->position = 0;
+    }
+
+    /**
+     * Resets the peek pointer to 0.
+     */
+    public function resetPeek()
+    {
+        $this->peek = 0;
+    }
+
+    /**
+     * Resets the lexer position on the input to the given position.
+     *
+     * @param integer $position Position to place the lexical scanner
+     */
+    public function resetPosition($position = 0)
+    {
+        $this->position = $position;
+    }
+
+    /**
+     * Checks whether a given token matches the current lookahead.
+     *
+     * @param integer|string $token
+     * @return boolean
+     */
+    public function isNextToken($token)
+    {
+        return null !== $this->lookahead && $this->lookahead['type'] === $token;
+    }
+
+    /**
+     * Checks whether any of the given tokens matches the current lookahead
+     *
+     * @param array $tokens
+     * @return boolean
+     */
+    public function isNextTokenAny(array $tokens)
+    {
+        return null !== $this->lookahead && in_array($this->lookahead['type'], $tokens, true);
+    }
+
+    /**
+     * Moves to the next token in the input string.
+     *
+     * A token is an associative array containing three items:
+     *  - 'value'    : the string value of the token in the input string
+     *  - 'type'     : the type of the token (identifier, numeric, string, input
+     *                 parameter, none)
+     *  - 'position' : the position of the token in the input string
+     *
+     * @return array|null the next token; null if there is no more tokens left
+     */
+    public function moveNext()
+    {
+        $this->peek = 0;
+        $this->token = $this->lookahead;
+        $this->lookahead = (isset($this->tokens[$this->position]))
+            ? $this->tokens[$this->position++] : null;
+
+        return $this->lookahead !== null;
+    }
+
+    /**
+     * Tells the lexer to skip input tokens until it sees a token with the given value.
+     *
+     * @param $type The token type to skip until.
+     */
+    public function skipUntil($type)
+    {
+        while ($this->lookahead !== null && $this->lookahead['type'] !== $type) {
+            $this->moveNext();
+        }
+    }
+
+    /**
+     * Checks if given value is identical to the given token
+     *
+     * @param mixed $value
+     * @param integer $token
+     * @return boolean
+     */
+    public function isA($value, $token)
+    {
+        return $this->getType($value) === $token;
+    }
+
+    /**
+     * Moves the lookahead token forward.
+     *
+     * @return array | null The next token or NULL if there are no more tokens ahead.
+     */
+    public function peek()
+    {
+        if (isset($this->tokens[$this->position + $this->peek])) {
+            return $this->tokens[$this->position + $this->peek++];
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Peeks at the next token, returns it and immediately resets the peek.
+     *
+     * @return array|null The next token or NULL if there are no more tokens ahead.
+     */
+    public function glimpse()
+    {
+        $peek = $this->peek();
+        $this->peek = 0;
+        return $peek;
+    }
+
+    /**
+     * Scans the input string for tokens.
+     *
+     * @param string $input a query string
+     */
+    protected function scan($input)
+    {
+        static $regex;
+
+        if ( ! isset($regex)) {
+            $regex = '/(' . implode(')|(', $this->getCatchablePatterns()) . ')|'
+                   . implode('|', $this->getNonCatchablePatterns()) . '/i';
+        }
+
+        $flags = PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_OFFSET_CAPTURE;
+        $matches = preg_split($regex, $input, -1, $flags);
+
+        foreach ($matches as $match) {
+            // Must remain before 'value' assignment since it can change content
+            $type = $this->getType($match[0]);
+
+            $this->tokens[] = array(
+                'value' => $match[0],
+                'type'  => $type,
+                'position' => $match[1],
+            );
+        }
+    }
+
+    /**
+     * Gets the literal for a given token.
+     *
+     * @param integer $token
+     * @return string
+     */
+    public function getLiteral($token)
+    {
+        $className = get_class($this);
+        $reflClass = new \ReflectionClass($className);
+        $constants = $reflClass->getConstants();
+
+        foreach ($constants as $name => $value) {
+            if ($value === $token) {
+                return $className . '::' . $name;
+            }
+        }
+
+        return $token;
+    }
+
+    /**
+     * Lexical catchable patterns.
+     *
+     * @return array
+     */
+    abstract protected function getCatchablePatterns();
+
+    /**
+     * Lexical non-catchable patterns.
+     *
+     * @return array
+     */
+    abstract protected function getNonCatchablePatterns();
+
+    /**
+     * Retrieve token type. Also processes the token value if necessary.
+     *
+     * @param string $value
+     * @return integer
+     */
+    abstract protected function getType(&$value);
+}

+ 45 - 0
main/inc/lib/symfony/Doctrine/Common/NotifyPropertyChanged.php

@@ -0,0 +1,45 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common;
+
+/**
+ * Contract for classes that provide the service of notifying listeners of
+ * changes to their properties.
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision: 3938 $
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+interface NotifyPropertyChanged
+{
+    /**
+     * Adds a listener that wants to be notified about property changes.
+     *
+     * @param PropertyChangedListener $listener
+     */
+    function addPropertyChangedListener(PropertyChangedListener $listener);
+}
+

+ 218 - 0
main/inc/lib/symfony/Doctrine/Common/Persistence/AbstractManagerRegistry.php

@@ -0,0 +1,218 @@
+<?php
+
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Persistence;
+
+use Doctrine\Common\Persistence\ManagerRegistry;
+
+/**
+ * Abstract implementation of the ManagerRegistry contract.
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.2
+ * @author  Fabien Potencier <fabien@symfony.com>
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ * @author  Lukas Kahwe Smith <smith@pooteeweet.org>
+ */
+abstract class AbstractManagerRegistry implements ManagerRegistry
+{
+    private $name;
+    private $connections;
+    private $managers;
+    private $defaultConnection;
+    private $defaultManager;
+    private $proxyInterfaceName;
+
+    public function __construct($name, array $connections, array $managers, $defaultConnection, $defaultManager, $proxyInterfaceName)
+    {
+        $this->name = $name;
+        $this->connections = $connections;
+        $this->managers = $managers;
+        $this->defaultConnection = $defaultConnection;
+        $this->defaultManager = $defaultManager;
+        $this->proxyInterfaceName = $proxyInterfaceName;
+    }
+
+    /**
+     * Fetches/creates the given services
+     *
+     * A service in this context is connection or a manager instance
+     *
+     * @param string $name name of the service
+     * @return object instance of the given service
+     */
+    abstract protected function getService($name);
+
+    /**
+     * Resets the given services
+     *
+     * A service in this context is connection or a manager instance
+     *
+     * @param string $name name of the service
+     * @return void
+     */
+    abstract protected function resetService($name);
+
+    /**
+     * Get the name of the registry
+     *
+     * @return string
+     */
+    public function getName()
+    {
+        return $this->name;
+    }
+
+    /**
+     * @inheritdoc
+     */
+    public function getConnection($name = null)
+    {
+        if (null === $name) {
+            $name = $this->defaultConnection;
+        }
+
+        if (!isset($this->connections[$name])) {
+            throw new \InvalidArgumentException(sprintf('Doctrine %s Connection named "%s" does not exist.', $this->name, $name));
+        }
+
+        return $this->getService($this->connections[$name]);
+    }
+
+    /**
+     * @inheritdoc
+     */
+    public function getConnectionNames()
+    {
+        return $this->connections;
+    }
+
+    /**
+     * @inheritdoc
+     */
+    public function getConnections()
+    {
+        $connections = array();
+        foreach ($this->connections as $name => $id) {
+            $connections[$name] = $this->getService($id);
+        }
+
+        return $connections;
+    }
+
+    /**
+     * @inheritdoc
+     */
+    public function getDefaultConnectionName()
+    {
+        return $this->defaultConnection;
+    }
+
+    /**
+     * @inheritdoc
+     */
+    public function getDefaultManagerName()
+    {
+        return $this->defaultManager;
+    }
+
+    /**
+     * @inheritdoc
+     */
+    public function getManager($name = null)
+    {
+        if (null === $name) {
+            $name = $this->defaultManager;
+        }
+
+        if (!isset($this->managers[$name])) {
+            throw new \InvalidArgumentException(sprintf('Doctrine %s Manager named "%s" does not exist.', $this->name, $name));
+        }
+
+        return $this->getService($this->managers[$name]);
+    }
+
+    /**
+     * @inheritdoc
+     */
+    public function getManagerForClass($class)
+    {
+        $proxyClass = new \ReflectionClass($class);
+        if ($proxyClass->implementsInterface($this->proxyInterfaceName)) {
+            $class = $proxyClass->getParentClass()->getName();
+        }
+
+        foreach ($this->managers as $id) {
+            $manager = $this->getService($id);
+
+            if (!$manager->getMetadataFactory()->isTransient($class)) {
+                return $manager;
+            }
+        }
+    }
+
+    /**
+     * @inheritdoc
+     */
+    public function getManagerNames()
+    {
+        return $this->managers;
+    }
+
+    /**
+     * @inheritdoc
+     */
+    public function getManagers()
+    {
+        $dms = array();
+        foreach ($this->managers as $name => $id) {
+            $dms[$name] = $this->getService($id);
+        }
+
+        return $dms;
+    }
+
+    /**
+     * @inheritdoc
+     */
+    public function getRepository($persistentObjectName, $persistentManagerName = null)
+    {
+        return $this->getManager($persistentManagerName)->getRepository($persistentObjectName);
+    }
+
+    /**
+     * @inheritdoc
+     */
+    public function resetManager($name = null)
+    {
+        if (null === $name) {
+            $name = $this->defaultManager;
+        }
+
+        if (!isset($this->managers[$name])) {
+            throw new \InvalidArgumentException(sprintf('Doctrine %s Manager named "%s" does not exist.', $this->name, $name));
+        }
+
+        // force the creation of a new document manager
+        // if the current one is closed
+        $this->resetService($this->managers[$name]);
+    }
+}

+ 63 - 0
main/inc/lib/symfony/Doctrine/Common/Persistence/ConnectionRegistry.php

@@ -0,0 +1,63 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Persistence;
+
+/**
+ * Contract covering connection for a Doctrine persistence layer ManagerRegistry class to implement.
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.2
+ * @author  Fabien Potencier <fabien@symfony.com>
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ * @author  Lukas Kahwe Smith <smith@pooteeweet.org>
+ */
+interface ConnectionRegistry
+{
+    /**
+     * Gets the default connection name.
+     *
+     * @return string The default connection name
+     */
+    function getDefaultConnectionName();
+
+    /**
+     * Gets the named connection.
+     *
+     * @param string $name The connection name (null for the default one)
+     *
+     * @return Connection
+     */
+    function getConnection($name = null);
+
+    /**
+     * Gets an array of all registered connections
+     *
+     * @return array An array of Connection instances
+     */
+    function getConnections();
+
+    /**
+     * Gets all connection names.
+     *
+     * @return array An array of connection names
+     */
+    function getConnectionNames();
+}

+ 77 - 0
main/inc/lib/symfony/Doctrine/Common/Persistence/Event/LifecycleEventArgs.php

@@ -0,0 +1,77 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+*/
+
+namespace Doctrine\Common\Persistence\Event;
+
+use Doctrine\Common\EventArgs;
+use Doctrine\Common\Persistence\ObjectManager;
+
+/**
+ * Lifecycle Events are triggered by the UnitOfWork during lifecycle transitions
+ * of entities.
+ *
+ * @link   www.doctrine-project.org
+ * @since  2.2
+ * @author Roman Borschel <roman@code-factory.de>
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ */
+class LifecycleEventArgs extends EventArgs
+{
+    /**
+     * @var ObjectManager
+     */
+    private $objectManager;
+
+    /**
+     * @var object
+     */
+    private $entity;
+
+    /**
+     * Constructor
+     *
+     * @param object $entity
+     * @param ObjectManager $objectManager
+     */
+    public function __construct($entity, ObjectManager $objectManager)
+    {
+        $this->entity = $entity;
+        $this->objectManager = $objectManager;
+    }
+
+    /**
+     * Retireve associated Entity.
+     *
+     * @return object
+     */
+    public function getEntity()
+    {
+        return $this->entity;
+    }
+
+    /**
+     * Retrieve associated ObjectManager.
+     *
+     * @return ObjectManager
+     */
+    public function getObjectManager()
+    {
+        return $this->objectManager;
+    }
+}

+ 76 - 0
main/inc/lib/symfony/Doctrine/Common/Persistence/Event/LoadClassMetadataEventArgs.php

@@ -0,0 +1,76 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Persistence\Event;
+
+use Doctrine\Common\EventArgs;
+use Doctrine\Common\Persistence\ObjectManager;
+use Doctrine\Common\Persistence\Mapping\ClassMetadata;
+
+/**
+ * Class that holds event arguments for a loadMetadata event.
+ *
+ * @author Jonathan H. Wage <jonwage@gmail.com>
+ * @since  2.2
+ */
+class LoadClassMetadataEventArgs extends EventArgs
+{
+    /**
+     * @var ClassMetadata
+     */
+    private $classMetadata;
+
+    /**
+     * @var ObjectManager
+     */
+    private $objectManager;
+
+    /**
+     * Constructor.
+     *
+     * @param ClasseMetadata $classMetadata
+     * @param ObjectManager $objectManager
+     */
+    public function __construct(ClassMetadata $classMetadata, ObjectManager $objectManager)
+    {
+        $this->classMetadata = $classMetadata;
+        $this->objectManager = $objectManager;
+    }
+
+    /**
+     * Retrieve associated ClassMetadata.
+     *
+     * @return ClassMetadata
+     */
+    public function getClassMetadata()
+    {
+        return $this->classMetadata;
+    }
+
+    /**
+     * Retrieve associated ObjectManager.
+     *
+     * @return ObjectManager
+     */
+    public function getObjectManager()
+    {
+        return $this->objectManager;
+    }
+}
+

+ 59 - 0
main/inc/lib/symfony/Doctrine/Common/Persistence/Event/ManagerEventArgs.php

@@ -0,0 +1,59 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+*/
+
+namespace Doctrine\Common\Persistence\Event;
+
+use Doctrine\Common\Persistence\ObjectManager;
+
+/**
+ * Provides event arguments for the preFlush event.
+ *
+ * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link        www.doctrine-project.org
+ * @since       2.2
+ * @author      Roman Borschel <roman@code-factory.de>
+ * @author      Benjamin Eberlei <kontakt@beberlei.de>
+ */
+class ManagerEventArgs extends \Doctrine\Common\EventArgs
+{
+    /**
+     * @var ObjectManager
+     */
+    private $objectManager;
+
+    /**
+     * Constructor.
+     *
+     * @param ObjectManager $objectManager
+     */
+    public function __construct(ObjectManager $objectManager)
+    {
+        $this->objectManager = $objectManager;
+    }
+
+    /**
+     * Retrieve associated ObjectManager.
+     *
+     * @return ObjectManager
+     */
+    public function getObjectManager()
+    {
+        return $this->objectManager;
+    }
+}

+ 84 - 0
main/inc/lib/symfony/Doctrine/Common/Persistence/Event/OnClearEventArgs.php

@@ -0,0 +1,84 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Persistence\Event;
+
+/**
+ * Provides event arguments for the onClear event.
+ *
+ * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link        www.doctrine-project.org
+ * @since       2.2
+ * @author      Roman Borschel <roman@code-factory.de>
+ * @author      Benjamin Eberlei <kontakt@beberlei.de>
+ */
+class OnClearEventArgs extends \Doctrine\Common\EventArgs
+{
+    /**
+     * @var ObjectManager
+     */
+    private $objectManager;
+
+    /**
+     * @var string
+     */
+    private $entityClass;
+
+    /**
+     * Constructor.
+     *
+     * @param ObjectManager $objectManager
+     * @param string $entityClass Optional entity class
+     */
+    public function __construct($objectManager, $entityClass = null)
+    {
+        $this->objectManager = $objectManager;
+        $this->entityClass = $entityClass;
+    }
+
+    /**
+     * Retrieve associated ObjectManager.
+     *
+     * @return ObjectManager
+     */
+    public function getObjectManager()
+    {
+        return $this->objectManager;
+    }
+
+    /**
+     * Name of the entity class that is cleared, or empty if all are cleared.
+     *
+     * @return string
+     */
+    public function getEntityClass()
+    {
+        return $this->entityClass;
+    }
+
+    /**
+     * Check if event clears all entities.
+     *
+     * @return bool
+     */
+    public function clearsAllEntities()
+    {
+        return ($this->entityClass === null);
+    }
+}

+ 129 - 0
main/inc/lib/symfony/Doctrine/Common/Persistence/Event/PreUpdateEventArgs.php

@@ -0,0 +1,129 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Persistence\Event;
+
+use Doctrine\Common\EventArgs,
+    Doctrine\Common\Persistence\ObjectManager;
+
+/**
+ * Class that holds event arguments for a preUpdate event.
+ *
+ * @author Guilherme Blanco <guilehrmeblanco@hotmail.com>
+ * @author Roman Borschel <roman@code-factory.org>
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ * @since  2.2
+ */
+class PreUpdateEventArgs extends LifecycleEventArgs
+{
+    /**
+     * @var array
+     */
+    private $entityChangeSet;
+
+    /**
+     * Constructor.
+     *
+     * @param object $entity
+     * @param ObjectManager $objectManager
+     * @param array $changeSet
+     */
+    public function __construct($entity, ObjectManager $objectManager, array &$changeSet)
+    {
+        parent::__construct($entity, $objectManager);
+
+        $this->entityChangeSet = &$changeSet;
+    }
+
+    /**
+     * Retrieve entity changeset.
+     *
+     * @return array
+     */
+    public function getEntityChangeSet()
+    {
+        return $this->entityChangeSet;
+    }
+
+    /**
+     * Check if field has a changeset.
+     *
+     * @return boolean
+     */
+    public function hasChangedField($field)
+    {
+        return isset($this->entityChangeSet[$field]);
+    }
+
+    /**
+     * Get the old value of the changeset of the changed field.
+     *
+     * @param  string $field
+     * @return mixed
+     */
+    public function getOldValue($field)
+    {
+        $this->assertValidField($field);
+
+        return $this->entityChangeSet[$field][0];
+    }
+
+    /**
+     * Get the new value of the changeset of the changed field.
+     *
+     * @param  string $field
+     * @return mixed
+     */
+    public function getNewValue($field)
+    {
+        $this->assertValidField($field);
+
+        return $this->entityChangeSet[$field][1];
+    }
+
+    /**
+     * Set the new value of this field.
+     *
+     * @param string $field
+     * @param mixed $value
+     */
+    public function setNewValue($field, $value)
+    {
+        $this->assertValidField($field);
+
+        $this->entityChangeSet[$field][1] = $value;
+    }
+
+    /**
+     * Assert the field exists in changeset.
+     *
+     * @param string $field
+     */
+    private function assertValidField($field)
+    {
+        if ( ! isset($this->entityChangeSet[$field])) {
+            throw new \InvalidArgumentException(sprintf(
+                'Field "%s" is not a valid field of the entity "%s" in PreUpdateEventArgs.',
+                $field,
+                get_class($this->getEntity())
+            ));
+        }
+    }
+}
+

+ 112 - 0
main/inc/lib/symfony/Doctrine/Common/Persistence/ManagerRegistry.php

@@ -0,0 +1,112 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Persistence;
+
+/**
+ * Contract covering object managers for a Doctrine persistence layer ManagerRegistry class to implement.
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.2
+ * @author  Fabien Potencier <fabien@symfony.com>
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ * @author  Lukas Kahwe Smith <smith@pooteeweet.org>
+ */
+interface ManagerRegistry extends ConnectionRegistry
+{
+    /**
+     * Gets the default object manager name.
+     *
+     * @return string The default object manager name
+     */
+    function getDefaultManagerName();
+
+    /**
+     * Gets a named object manager.
+     *
+     * @param string $name The object manager name (null for the default one)
+     *
+     * @return \Doctrine\Common\Persistence\ObjectManager
+     */
+    function getManager($name = null);
+
+    /**
+     * Gets an array of all registered object managers
+     *
+     * @return array An array of ObjectManager instances
+     */
+    function getManagers();
+
+    /**
+     * Resets a named object manager.
+     *
+     * This method is useful when an object manager has been closed
+     * because of a rollbacked transaction AND when you think that
+     * it makes sense to get a new one to replace the closed one.
+     *
+     * Be warned that you will get a brand new object manager as
+     * the existing one is not useable anymore. This means that any
+     * other object with a dependency on this object manager will
+     * hold an obsolete reference. You can inject the registry instead
+     * to avoid this problem.
+     *
+     * @param string $name The object manager name (null for the default one)
+     *
+     * @return \Doctrine\Common\Persistence\ObjectManager
+     */
+    function resetManager($name = null);
+
+    /**
+     * Resolves a registered namespace alias to the full namespace.
+     *
+     * This method looks for the alias in all registered object managers.
+     *
+     * @param string $alias The alias
+     *
+     * @return string The full namespace
+     */
+    function getAliasNamespace($alias);
+
+    /**
+     * Gets all connection names.
+     *
+     * @return array An array of connection names
+     */
+    function getManagerNames();
+
+    /**
+     * Gets the ObjectRepository for an persistent object.
+     *
+     * @param string $persistentObject        The name of the persistent object.
+     * @param string $persistentManagerName The object manager name (null for the default one)
+     *
+     * @return \Doctrine\Common\Persistence\ObjectRepository
+     */
+    function getRepository($persistentObject, $persistentManagerName = null);
+
+    /**
+     * Gets the object manager associated with a given class.
+     *
+     * @param string $class A persistent object class name
+     *
+     * @return \Doctrine\Common\Persistence\ObjectManager|null
+     */
+    function getManagerForClass($class);
+}

+ 359 - 0
main/inc/lib/symfony/Doctrine/Common/Persistence/Mapping/AbstractClassMetadataFactory.php

@@ -0,0 +1,359 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Persistence\Mapping;
+
+use Doctrine\Common\Cache\Cache;
+
+/**
+ * The ClassMetadataFactory is used to create ClassMetadata objects that contain all the
+ * metadata mapping informations of a class which describes how a class should be mapped
+ * to a relational database.
+ *
+ * This class was abstracted from the ORM ClassMetadataFactory
+ *
+ * @since   2.2
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+abstract class AbstractClassMetadataFactory implements ClassMetadataFactory
+{
+    /**
+     * Salt used by specific Object Manager implementation.
+     *
+     * @var string
+     */
+    protected $cacheSalt = "\$CLASSMETADATA";
+
+    /**
+     * @var \Doctrine\Common\Cache\Cache
+     */
+    private $cacheDriver;
+
+    /**
+     * @var array
+     */
+    private $loadedMetadata = array();
+
+    /**
+     * @var bool
+     */
+    protected $initialized = false;
+
+    /**
+     * @var ReflectionService
+     */
+    private $reflectionService;
+
+    /**
+     * Sets the cache driver used by the factory to cache ClassMetadata instances.
+     *
+     * @param Doctrine\Common\Cache\Cache $cacheDriver
+     */
+    public function setCacheDriver(Cache $cacheDriver = null)
+    {
+        $this->cacheDriver = $cacheDriver;
+    }
+
+    /**
+     * Gets the cache driver used by the factory to cache ClassMetadata instances.
+     *
+     * @return Doctrine\Common\Cache\Cache
+     */
+    public function getCacheDriver()
+    {
+        return $this->cacheDriver;
+    }
+
+    /**
+     * Return an array of all the loaded metadata currently in memory.
+     *
+     * @return array
+     */
+    public function getLoadedMetadata()
+    {
+        return $this->loadedMetadata;
+    }
+
+    /**
+     * Forces the factory to load the metadata of all classes known to the underlying
+     * mapping driver.
+     *
+     * @return array The ClassMetadata instances of all mapped classes.
+     */
+    public function getAllMetadata()
+    {
+        if ( ! $this->initialized) {
+            $this->initialize();
+        }
+
+        $driver = $this->getDriver();
+        $metadata = array();
+        foreach ($driver->getAllClassNames() as $className) {
+            $metadata[] = $this->getMetadataFor($className);
+        }
+
+        return $metadata;
+    }
+
+    /**
+     * Lazy initialization of this stuff, especially the metadata driver,
+     * since these are not needed at all when a metadata cache is active.
+     *
+     * @return void
+     */
+    abstract protected function initialize();
+
+    /**
+     * Get the fully qualified class-name from the namespace alias.
+     *
+     * @param string $namespaceAlias
+     * @param string $simpleClassName
+     * @return string
+     */
+    abstract protected function getFqcnFromAlias($namespaceAlias, $simpleClassName);
+
+    /**
+     * Return the mapping driver implementation.
+     *
+     * @return MappingDriver
+     */
+    abstract protected function getDriver();
+
+    /**
+     * Wakeup reflection after ClassMetadata gets unserialized from cache.
+     *
+     * @param ClassMetadata $class
+     * @param ReflectionService $reflService
+     * @return void
+     */
+    abstract protected function wakeupReflection(ClassMetadata $class, ReflectionService $reflService);
+
+    /**
+     * Initialize Reflection after ClassMetadata was constructed.
+     *
+     * @param ClassMetadata $class
+     * @param ReflectionSErvice $reflService
+     * @return void
+     */
+    abstract protected function initializeReflection(ClassMetadata $class, ReflectionService $reflService);
+
+    /**
+     * Gets the class metadata descriptor for a class.
+     *
+     * @param string $className The name of the class.
+     * @return Doctrine\Common\Persistence\Mapping\ClassMetadata
+     */
+    public function getMetadataFor($className)
+    {
+        if ( ! isset($this->loadedMetadata[$className])) {
+            $realClassName = $className;
+
+            // Check for namespace alias
+            if (strpos($className, ':') !== false) {
+                list($namespaceAlias, $simpleClassName) = explode(':', $className);
+                $realClassName = $this->getFqcnFromAlias($namespaceAlias, $simpleClassName);
+
+                if (isset($this->loadedMetadata[$realClassName])) {
+                    // We do not have the alias name in the map, include it
+                    $this->loadedMetadata[$className] = $this->loadedMetadata[$realClassName];
+
+                    return $this->loadedMetadata[$realClassName];
+                }
+            }
+
+            if ($this->cacheDriver) {
+                if (($cached = $this->cacheDriver->fetch($realClassName . $this->cacheSalt)) !== false) {
+                    $this->loadedMetadata[$realClassName] = $cached;
+                    $this->wakeupReflection($cached, $this->getReflectionService());
+                } else {
+                    foreach ($this->loadMetadata($realClassName) as $loadedClassName) {
+                        $this->cacheDriver->save(
+                            $loadedClassName . $this->cacheSalt, $this->loadedMetadata[$loadedClassName], null
+                        );
+                    }
+                }
+            } else {
+                $this->loadMetadata($realClassName);
+            }
+
+            if ($className != $realClassName) {
+                // We do not have the alias name in the map, include it
+                $this->loadedMetadata[$className] = $this->loadedMetadata[$realClassName];
+            }
+        }
+
+        return $this->loadedMetadata[$className];
+    }
+
+    /**
+     * Checks whether the factory has the metadata for a class loaded already.
+     *
+     * @param string $className
+     * @return boolean TRUE if the metadata of the class in question is already loaded, FALSE otherwise.
+     */
+    public function hasMetadataFor($className)
+    {
+        return isset($this->loadedMetadata[$className]);
+    }
+
+    /**
+     * Sets the metadata descriptor for a specific class.
+     *
+     * NOTE: This is only useful in very special cases, like when generating proxy classes.
+     *
+     * @param string $className
+     * @param ClassMetadata $class
+     */
+    public function setMetadataFor($className, $class)
+    {
+        $this->loadedMetadata[$className] = $class;
+    }
+
+    /**
+     * Get array of parent classes for the given entity class
+     *
+     * @param string $name
+     * @return array $parentClasses
+     */
+    protected function getParentClasses($name)
+    {
+        // Collect parent classes, ignoring transient (not-mapped) classes.
+        $parentClasses = array();
+        foreach (array_reverse($this->getReflectionService()->getParentClasses($name)) as $parentClass) {
+            if ( ! $this->getDriver()->isTransient($parentClass)) {
+                $parentClasses[] = $parentClass;
+            }
+        }
+        return $parentClasses;
+    }
+
+    /**
+     * Loads the metadata of the class in question and all it's ancestors whose metadata
+     * is still not loaded.
+     *
+     * @param string $name The name of the class for which the metadata should get loaded.
+     * @param array  $tables The metadata collection to which the loaded metadata is added.
+     */
+    protected function loadMetadata($name)
+    {
+        if ( ! $this->initialized) {
+            $this->initialize();
+        }
+
+        $loaded = array();
+
+        $parentClasses = $this->getParentClasses($name);
+        $parentClasses[] = $name;
+
+        // Move down the hierarchy of parent classes, starting from the topmost class
+        $parent = null;
+        $rootEntityFound = false;
+        $visited = array();
+        $reflService = $this->getReflectionService();
+        foreach ($parentClasses as $className) {
+            if (isset($this->loadedMetadata[$className])) {
+                $parent = $this->loadedMetadata[$className];
+                if (isset($parent->isMappedSuperclass) && $parent->isMappedSuperclass === false) {
+                    $rootEntityFound = true;
+                    array_unshift($visited, $className);
+                }
+                continue;
+            }
+
+            $class = $this->newClassMetadataInstance($className);
+            $this->initializeReflection($class, $reflService);
+
+            $this->doLoadMetadata($class, $parent, $rootEntityFound);
+
+            $this->loadedMetadata[$className] = $class;
+
+            $parent = $class;
+
+            if (isset($parent->isMappedSuperclass) && $class->isMappedSuperclass === false) {
+                $rootEntityFound = true;
+                array_unshift($visited, $className);
+            }
+
+            $this->wakeupReflection($class, $reflService);
+
+            $loaded[] = $className;
+        }
+
+        return $loaded;
+    }
+
+    /**
+     * Actually load the metadata from the underlying metadata
+     *
+     * @param ClassMetadata $class
+     * @param ClassMetadata $parent
+     * @param bool $rootEntityFound
+     * @return void
+     */
+    abstract protected function doLoadMetadata($class, $parent, $rootEntityFound);
+
+    /**
+     * Creates a new ClassMetadata instance for the given class name.
+     *
+     * @param string $className
+     * @return ClassMetadata
+     */
+    abstract protected function newClassMetadataInstance($className);
+
+    /**
+     * Check if this class is mapped by this Object Manager + ClassMetadata configuration
+     *
+     * @param $class
+     * @return bool
+     */
+    public function isTransient($class)
+    {
+        if ( ! $this->initialized) {
+            $this->initialize();
+        }
+
+        return $this->getDriver()->isTransient($class);
+    }
+
+    /**
+     * Set reflectionService.
+     *
+     * @param ReflectionService $reflectionService
+     */
+    public function setReflectionService(ReflectionService $reflectionService)
+    {
+        $this->reflectionService = $reflectionService;
+    }
+
+    /**
+     * Get the reflection service associated with this metadata factory.
+     *
+     * @return ReflectionService
+     */
+    public function getReflectionService()
+    {
+        if ($this->reflectionService === null) {
+            $this->reflectionService = new RuntimeReflectionService();
+        }
+        return $this->reflectionService;
+    }
+}

+ 165 - 0
main/inc/lib/symfony/Doctrine/Common/Persistence/Mapping/ClassMetadata.php

@@ -0,0 +1,165 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Persistence\Mapping;
+
+/**
+ * Contract for a Doctrine persistence layer ClassMetadata class to implement.
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.1
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ */
+interface ClassMetadata
+{
+    /**
+     * Get fully-qualified class name of this persistent class.
+     *
+     * @return string
+     */
+    function getName();
+
+    /**
+     * Gets the mapped identifier field name.
+     *
+     * The returned structure is an array of the identifier field names.
+     *
+     * @return array
+     */
+    function getIdentifier();
+
+    /**
+     * Gets the ReflectionClass instance for this mapped class.
+     *
+     * @return ReflectionClass
+     */
+    function getReflectionClass();
+
+    /**
+     * Checks if the given field name is a mapped identifier for this class.
+     *
+     * @param string $fieldName
+     * @return boolean
+     */
+    function isIdentifier($fieldName);
+
+    /**
+     * Checks if the given field is a mapped property for this class.
+     *
+     * @param string $fieldName
+     * @return boolean
+     */
+    function hasField($fieldName);
+
+    /**
+     * Checks if the given field is a mapped association for this class.
+     *
+     * @param string $fieldName
+     * @return boolean
+     */
+    function hasAssociation($fieldName);
+
+    /**
+     * Checks if the given field is a mapped single valued association for this class.
+     *
+     * @param string $fieldName
+     * @return boolean
+     */
+    function isSingleValuedAssociation($fieldName);
+
+    /**
+     * Checks if the given field is a mapped collection valued association for this class.
+     *
+     * @param string $fieldName
+     * @return boolean
+     */
+    function isCollectionValuedAssociation($fieldName);
+
+    /**
+     * A numerically indexed list of field names of this persistent class.
+     *
+     * This array includes identifier fields if present on this class.
+     *
+     * @return array
+     */
+    function getFieldNames();
+
+    /**
+     * Returns an array of identifier field names numerically indexed.
+     *
+     * @return array
+     */
+    function getIdentifierFieldNames();
+
+    /**
+     * A numerically indexed list of association names of this persistent class.
+     *
+     * This array includes identifier associations if present on this class.
+     *
+     * @return array
+     */
+    function getAssociationNames();
+
+    /**
+     * Returns a type name of this field.
+     *
+     * This type names can be implementation specific but should at least include the php types:
+     * integer, string, boolean, float/double, datetime.
+     *
+     * @param string $fieldName
+     * @return string
+     */
+    function getTypeOfField($fieldName);
+
+    /**
+     * Returns the target class name of the given association.
+     *
+     * @param string $assocName
+     * @return string
+     */
+    function getAssociationTargetClass($assocName);
+
+    /**
+     * Checks if the association is the inverse side of a bidirectional association
+     *
+     * @param string $assocName
+     * @return boolean
+     */
+    function isAssociationInverseSide($assocName);
+
+    /**
+     * Returns the target field of the owning side of the association
+     *
+     * @param string $assocName
+     * @return string
+     */
+    function getAssociationMappedByTargetField($assocName);
+
+    /**
+     * Return the identifier of this object as an array with field name as key.
+     *
+     * Has to return an empty array if no identifier isset.
+     *
+     * @param object $object
+     * @return array
+     */
+    function getIdentifierValues($object);
+}

+ 74 - 0
main/inc/lib/symfony/Doctrine/Common/Persistence/Mapping/ClassMetadataFactory.php

@@ -0,0 +1,74 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Persistence\Mapping;
+
+/**
+ * Contract for a Doctrine persistence layer ClassMetadata class to implement.
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.1
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ */
+interface ClassMetadataFactory
+{
+    /**
+     * Forces the factory to load the metadata of all classes known to the underlying
+     * mapping driver.
+     *
+     * @return array The ClassMetadata instances of all mapped classes.
+     */
+    function getAllMetadata();
+
+    /**
+     * Gets the class metadata descriptor for a class.
+     *
+     * @param string $className The name of the class.
+     * @return ClassMetadata
+     */
+    function getMetadataFor($className);
+
+    /**
+     * Checks whether the factory has the metadata for a class loaded already.
+     *
+     * @param string $className
+     * @return boolean TRUE if the metadata of the class in question is already loaded, FALSE otherwise.
+     */
+    function hasMetadataFor($className);
+
+    /**
+     * Sets the metadata descriptor for a specific class.
+     *
+     * @param string $className
+     * @param ClassMetadata $class
+     */
+    function setMetadataFor($className, $class);
+
+    /**
+     * Whether the class with the specified name should have its metadata loaded.
+     * This is only the case if it is either mapped directly or as a
+     * MappedSuperclass.
+     *
+     * @param string $className
+     * @return boolean
+     */
+    function isTransient($className);
+}

+ 214 - 0
main/inc/lib/symfony/Doctrine/Common/Persistence/Mapping/Driver/AnnotationDriver.php

@@ -0,0 +1,214 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Persistence\Mapping\Driver;
+
+use Doctrine\Common\Cache\ArrayCache,
+    Doctrine\Common\Annotations\AnnotationReader,
+    Doctrine\Common\Annotations\AnnotationRegistry,
+    Doctrine\Common\Persistence\Mapping\MappingException;
+
+/**
+ * The AnnotationDriver reads the mapping metadata from docblock annotations.
+ *
+ * @since 2.2
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ * @author Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author Jonathan H. Wage <jonwage@gmail.com>
+ * @author Roman Borschel <roman@code-factory.org>
+ */
+abstract class AnnotationDriver implements MappingDriver
+{
+    /**
+     * The AnnotationReader.
+     *
+     * @var AnnotationReader
+     */
+    protected $reader;
+
+    /**
+     * The paths where to look for mapping files.
+     *
+     * @var array
+     */
+    protected $paths = array();
+
+    /**
+     * The file extension of mapping documents.
+     *
+     * @var string
+     */
+    protected $fileExtension = '.php';
+
+    /**
+     * Cache for AnnotationDriver#getAllClassNames()
+     *
+     * @var array
+     */
+    protected $classNames;
+
+    /**
+     * Name of the entity annotations as keys
+     *
+     * @var array
+     */
+    protected $entityAnnotationClasses = array();
+
+    /**
+     * Initializes a new AnnotationDriver that uses the given AnnotationReader for reading
+     * docblock annotations.
+     *
+     * @param AnnotationReader $reader The AnnotationReader to use, duck-typed.
+     * @param string|array $paths One or multiple paths where mapping classes can be found.
+     */
+    public function __construct($reader, $paths = null)
+    {
+        $this->reader = $reader;
+        if ($paths) {
+            $this->addPaths((array) $paths);
+        }
+    }
+
+    /**
+     * Append lookup paths to metadata driver.
+     *
+     * @param array $paths
+     */
+    public function addPaths(array $paths)
+    {
+        $this->paths = array_unique(array_merge($this->paths, $paths));
+    }
+
+    /**
+     * Retrieve the defined metadata lookup paths.
+     *
+     * @return array
+     */
+    public function getPaths()
+    {
+        return $this->paths;
+    }
+
+    /**
+     * Retrieve the current annotation reader
+     *
+     * @return AnnotationReader
+     */
+    public function getReader()
+    {
+        return $this->reader;
+    }
+
+    /**
+     * Get the file extension used to look for mapping files under
+     *
+     * @return void
+     */
+    public function getFileExtension()
+    {
+        return $this->fileExtension;
+    }
+
+    /**
+     * Set the file extension used to look for mapping files under
+     *
+     * @param string $fileExtension The file extension to set
+     * @return void
+     */
+    public function setFileExtension($fileExtension)
+    {
+        $this->fileExtension = $fileExtension;
+    }
+
+    /**
+     * Whether the class with the specified name is transient. Only non-transient
+     * classes, that is entities and mapped superclasses, should have their metadata loaded.
+     *
+     * A class is non-transient if it is annotated with an annotation
+     * from the {@see AnnotationDriver::entityAnnotationClasses}.
+     *
+     * @param string $className
+     * @return boolean
+     */
+    public function isTransient($className)
+    {
+        $classAnnotations = $this->reader->getClassAnnotations(new \ReflectionClass($className));
+
+        foreach ($classAnnotations as $annot) {
+            if (isset($this->entityAnnotationClasses[get_class($annot)])) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getAllClassNames()
+    {
+        if ($this->classNames !== null) {
+            return $this->classNames;
+        }
+
+        if (!$this->paths) {
+            throw MappingException::pathRequired();
+        }
+
+        $classes = array();
+        $includedFiles = array();
+
+        foreach ($this->paths as $path) {
+            if ( ! is_dir($path)) {
+                throw MappingException::fileMappingDriversRequireConfiguredDirectoryPath($path);
+            }
+
+            $iterator = new \RegexIterator(
+                new \RecursiveIteratorIterator(
+                    new \RecursiveDirectoryIterator($path, \FilesystemIterator::SKIP_DOTS),
+                    \RecursiveIteratorIterator::LEAVES_ONLY
+                ),
+                '/^.+' . str_replace('.', '\.', $this->fileExtension) . '$/i',
+                \RecursiveRegexIterator::GET_MATCH
+            );
+
+            foreach ($iterator as $file) {
+                $sourceFile = realpath($file[0]);
+
+                require_once $sourceFile;
+
+                $includedFiles[] = $sourceFile;
+            }
+        }
+
+        $declared = get_declared_classes();
+
+        foreach ($declared as $className) {
+            $rc = new \ReflectionClass($className);
+            $sourceFile = $rc->getFileName();
+            if (in_array($sourceFile, $includedFiles) && ! $this->isTransient($className)) {
+                $classes[] = $className;
+            }
+        }
+
+        $this->classNames = $classes;
+
+        return $classes;
+    }
+}

+ 169 - 0
main/inc/lib/symfony/Doctrine/Common/Persistence/Mapping/Driver/DefaultFileLocator.php

@@ -0,0 +1,169 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+*/
+
+namespace Doctrine\Common\Persistence\Mapping\Driver;
+
+use Doctrine\Common\Persistence\Mapping\MappingException;
+
+/**
+ * Locate the file that contains the metadata information for a given class name.
+ *
+ * This behavior is inpependent of the actual content of the file. It just detects
+ * the file which is responsible for the given class name.
+ *
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+class DefaultFileLocator implements FileLocator
+{
+    /**
+     * The paths where to look for mapping files.
+     *
+     * @var array
+     */
+    protected $paths = array();
+
+    /**
+     * The file extension of mapping documents.
+     *
+     * @var string
+     */
+    protected $fileExtension;
+
+    /**
+     * Initializes a new FileDriver that looks in the given path(s) for mapping
+     * documents and operates in the specified operating mode.
+     *
+     * @param string|array $paths One or multiple paths where mapping documents can be found.
+     */
+    public function __construct($paths, $fileExtension = null)
+    {
+        $this->addPaths((array) $paths);
+        $this->fileExtension = $fileExtension;
+    }
+
+    /**
+     * Append lookup paths to metadata driver.
+     *
+     * @param array $paths
+     */
+    public function addPaths(array $paths)
+    {
+        $this->paths = array_unique(array_merge($this->paths, $paths));
+    }
+
+    /**
+     * Retrieve the defined metadata lookup paths.
+     *
+     * @return array
+     */
+    public function getPaths()
+    {
+        return $this->paths;
+    }
+
+    /**
+     * Get the file extension used to look for mapping files under
+     *
+     * @return void
+     */
+    public function getFileExtension()
+    {
+        return $this->fileExtension;
+    }
+
+    /**
+     * Set the file extension used to look for mapping files under
+     *
+     * @param string $fileExtension The file extension to set
+     * @return void
+     */
+    public function setFileExtension($fileExtension)
+    {
+        $this->fileExtension = $fileExtension;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function findMappingFile($className)
+    {
+        $fileName = str_replace('\\', '.', $className) . $this->fileExtension;
+
+        // Check whether file exists
+        foreach ($this->paths as $path) {
+            if (file_exists($path . DIRECTORY_SEPARATOR . $fileName)) {
+                return $path . DIRECTORY_SEPARATOR . $fileName;
+            }
+        }
+
+        throw MappingException::mappingFileNotFound($className, $fileName);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getAllClassNames($globalBasename)
+    {
+        $classes = array();
+
+        if ($this->paths) {
+            foreach ($this->paths as $path) {
+                if ( ! is_dir($path)) {
+                    throw MappingException::fileMappingDriversRequireConfiguredDirectoryPath($path);
+                }
+
+                $iterator = new \RecursiveIteratorIterator(
+                    new \RecursiveDirectoryIterator($path),
+                    \RecursiveIteratorIterator::LEAVES_ONLY
+                );
+
+                foreach ($iterator as $file) {
+                    $fileName = $file->getBasename($this->fileExtension);
+
+                    if ($fileName == $file->getBasename() || $fileName == $globalBasename) {
+                        continue;
+                    }
+
+                    // NOTE: All files found here means classes are not transient!
+                    $classes[] = str_replace('.', '\\', $fileName);
+                }
+            }
+        }
+
+        return $classes;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function fileExists($className)
+    {
+        $fileName = str_replace('\\', '.', $className) . $this->fileExtension;
+
+        // Check whether file exists
+        foreach ((array) $this->paths as $path) {
+            if (file_exists($path . DIRECTORY_SEPARATOR . $fileName)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+}

+ 178 - 0
main/inc/lib/symfony/Doctrine/Common/Persistence/Mapping/Driver/FileDriver.php

@@ -0,0 +1,178 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Persistence\Mapping\Driver;
+
+use Doctrine\Common\Persistence\Mapping\MappingException;
+
+/**
+ * Base driver for file-based metadata drivers.
+ *
+ * A file driver operates in a mode where it loads the mapping files of individual
+ * classes on demand. This requires the user to adhere to the convention of 1 mapping
+ * file per class and the file names of the mapping files must correspond to the full
+ * class name, including namespace, with the namespace delimiters '\', replaced by dots '.'.
+ *
+ * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link        www.doctrine-project.com
+ * @since       2.2
+ * @author      Benjamin Eberlei <kontakt@beberlei.de>
+ * @author      Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author      Jonathan H. Wage <jonwage@gmail.com>
+ * @author      Roman Borschel <roman@code-factory.org>
+ */
+abstract class FileDriver implements MappingDriver
+{
+    /**
+     * @var FileLocator
+     */
+    protected $locator;
+
+    /**
+     * @var array
+     */
+    protected $classCache;
+
+    /**
+     * @var string
+     */
+    protected $globalBasename;
+
+    /**
+     * Initializes a new FileDriver that looks in the given path(s) for mapping
+     * documents and operates in the specified operating mode.
+     *
+     * @param string|array|FileLocator $paths A FileLocator or one/multiple paths where mapping documents can be found.
+     * @param string $fileExtension
+     */
+    public function __construct($locator, $fileExtension = null)
+    {
+        if ($locator instanceof FileLocator) {
+            $this->locator = $locator;
+        } else {
+            $this->locator = new DefaultFileLocator((array)$locator, $fileExtension);
+        }
+    }
+
+    public function setGlobalBasename($file)
+    {
+        $this->globalBasename = $file;
+    }
+
+    public function getGlobalBasename()
+    {
+        return $this->globalBasename;
+    }
+
+    /**
+     * Get the element of schema meta data for the class from the mapping file.
+     * This will lazily load the mapping file if it is not loaded yet
+     *
+     * @return array $element  The element of schema meta data
+     */
+    public function getElement($className)
+    {
+        if ($this->classCache === null) {
+            $this->initialize();
+        }
+
+        if (isset($this->classCache[$className])) {
+            return $this->classCache[$className];
+        }
+
+        $result = $this->loadMappingFile($this->locator->findMappingFile($className));
+
+        return $result[$className];
+    }
+
+    /**
+     * Whether the class with the specified name should have its metadata loaded.
+     * This is only the case if it is either mapped as an Entity or a
+     * MappedSuperclass.
+     *
+     * @param string $className
+     * @return boolean
+     */
+    public function isTransient($className)
+    {
+        if ($this->classCache === null) {
+            $this->initialize();
+        }
+
+        if (isset($this->classCache[$className])) {
+            return false;
+        }
+
+        return !$this->locator->fileExists($className);
+    }
+
+    /**
+     * Gets the names of all mapped classes known to this driver.
+     *
+     * @return array The names of all mapped classes known to this driver.
+     */
+    public function getAllClassNames()
+    {
+        if ($this->classCache === null) {
+            $this->initialize();
+        }
+
+        $classNames = (array)$this->locator->getAllClassNames($this->globalBasename);
+        if ($this->classCache) {
+            $classNames = array_merge(array_keys($this->classCache), $classNames);
+        }
+        return $classNames;
+    }
+
+    /**
+     * Loads a mapping file with the given name and returns a map
+     * from class/entity names to their corresponding file driver elements.
+     *
+     * @param string $file The mapping file to load.
+     * @return array
+     */
+    abstract protected function loadMappingFile($file);
+
+    /**
+     * Initialize the class cache from all the global files.
+     *
+     * Using this feature adds a substantial performance hit to file drivers as
+     * more metadata has to be loaded into memory than might actually be
+     * necessary. This may not be relevant to scenarios where caching of
+     * metadata is in place, however hits very hard in scenarios where no
+     * caching is used.
+     *
+     * @return void
+     */
+    protected function initialize()
+    {
+        $this->classCache = array();
+        if (null !== $this->globalBasename) {
+            foreach ($this->locator->getPaths() as $path) {
+                $file = $path.'/'.$this->globalBasename.$this->locator->getFileExtension();
+                if (is_file($file)) {
+                    $this->classCache = array_merge(
+                        $this->classCache,
+                        $this->loadMappingFile($file)
+                    );
+                }
+            }
+        }
+    }
+}

+ 69 - 0
main/inc/lib/symfony/Doctrine/Common/Persistence/Mapping/Driver/FileLocator.php

@@ -0,0 +1,69 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+*/
+
+namespace Doctrine\Common\Persistence\Mapping\Driver;
+
+/**
+ * Locate the file that contains the metadata information for a given class name.
+ *
+ * This behavior is inpependent of the actual content of the file. It just detects
+ * the file which is responsible for the given class name.
+ *
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+interface FileLocator
+{
+    /**
+     * Locate mapping file for the given class name.
+     *
+     * @param string $className
+     * @return string
+     */
+    function findMappingFile($className);
+
+    /**
+     * Get all class names that are found with this file locator.
+     *
+     * @param string $globalBasename Passed to allow excluding the basename
+     * @return array
+     */
+    function getAllClassNames($globalBasename);
+
+    /**
+     * Check if a file can be found for this class name.
+     *
+     * @return bool
+     */
+    function fileExists($className);
+
+    /**
+     * Get all the paths that this file locator looks for mapping files.
+     *
+     * @return array
+     */
+    function getPaths();
+
+    /**
+     * Get the file extension that mapping files are suffixed with.
+     *
+     * @return string
+     */
+    function getFileExtension();
+}

+ 56 - 0
main/inc/lib/symfony/Doctrine/Common/Persistence/Mapping/Driver/MappingDriver.php

@@ -0,0 +1,56 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Persistence\Mapping\Driver;
+
+use Doctrine\Common\Persistence\Mapping\ClassMetadata;
+
+/**
+ * Contract for metadata drivers.
+ *
+ * @since 2.2
+ * @author Jonathan H. Wage <jonwage@gmail.com>
+ */
+interface MappingDriver
+{
+    /**
+     * Loads the metadata for the specified class into the provided container.
+     *
+     * @param string $className
+     * @param ClassMetadata $metadata
+     */
+    function loadMetadataForClass($className, ClassMetadata $metadata);
+
+    /**
+     * Gets the names of all mapped classes known to this driver.
+     *
+     * @return array The names of all mapped classes known to this driver.
+     */
+    function getAllClassNames();
+
+    /**
+     * Whether the class with the specified name should have its metadata loaded.
+     * This is only the case if it is either mapped as an Entity or a
+     * MappedSuperclass.
+     *
+     * @param string $className
+     * @return boolean
+     */
+    function isTransient($className);
+}

+ 125 - 0
main/inc/lib/symfony/Doctrine/Common/Persistence/Mapping/Driver/MappingDriverChain.php

@@ -0,0 +1,125 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Persistence\Mapping\Driver;
+
+use Doctrine\Common\Persistence\Mapping\Driver\MappingDriver,
+    Doctrine\Common\Persistence\Mapping\ClassMetadata,
+    Doctrine\Common\Persistence\Mapping\MappingException;
+
+/**
+ * The DriverChain allows you to add multiple other mapping drivers for
+ * certain namespaces
+ *
+ * @since  2.2
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ * @author Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author Jonathan H. Wage <jonwage@gmail.com>
+ * @author Roman Borschel <roman@code-factory.org>
+ */
+class MappingDriverChain implements MappingDriver
+{
+    /**
+     * @var array
+     */
+    private $drivers = array();
+
+    /**
+     * Add a nested driver.
+     *
+     * @param Driver $nestedDriver
+     * @param string $namespace
+     */
+    public function addDriver(MappingDriver $nestedDriver, $namespace)
+    {
+        $this->drivers[$namespace] = $nestedDriver;
+    }
+
+    /**
+     * Get the array of nested drivers.
+     *
+     * @return array $drivers
+     */
+    public function getDrivers()
+    {
+        return $this->drivers;
+    }
+
+    /**
+     * Loads the metadata for the specified class into the provided container.
+     *
+     * @param string $className
+     * @param ClassMetadataInfo $metadata
+     */
+    public function loadMetadataForClass($className, ClassMetadata $metadata)
+    {
+        foreach ($this->drivers as $namespace => $driver) {
+            if (strpos($className, $namespace) === 0) {
+                $driver->loadMetadataForClass($className, $metadata);
+                return;
+            }
+        }
+
+        throw MappingException::classNotFoundInNamespaces($className, array_keys($this->drivers));
+    }
+
+    /**
+     * Gets the names of all mapped classes known to this driver.
+     *
+     * @return array The names of all mapped classes known to this driver.
+     */
+    public function getAllClassNames()
+    {
+        $classNames = array();
+        $driverClasses = array();
+        foreach ($this->drivers AS $namespace => $driver) {
+            $oid = spl_object_hash($driver);
+            if (!isset($driverClasses[$oid])) {
+                $driverClasses[$oid] = $driver->getAllClassNames();
+            }
+
+            foreach ($driverClasses[$oid] AS $className) {
+                if (strpos($className, $namespace) === 0) {
+                    $classNames[$className] = true;
+                }
+            }
+        }
+        return array_keys($classNames);
+    }
+
+    /**
+     * Whether the class with the specified name should have its metadata loaded.
+     *
+     * This is only the case for non-transient classes either mapped as an Entity or MappedSuperclass.
+     *
+     * @param string $className
+     * @return boolean
+     */
+    public function isTransient($className)
+    {
+        foreach ($this->drivers AS $namespace => $driver) {
+            if (strpos($className, $namespace) === 0) {
+                return $driver->isTransient($className);
+            }
+        }
+
+        // class isTransient, i.e. not an entity or mapped superclass
+        return true;
+    }
+}

+ 70 - 0
main/inc/lib/symfony/Doctrine/Common/Persistence/Mapping/Driver/PHPDriver.php

@@ -0,0 +1,70 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Persistence\Mapping\Driver;
+
+use Doctrine\Common\Persistence\Mapping\ClassMetadata;
+
+/**
+ * The PHPDriver includes php files which just populate ClassMetadataInfo
+ * instances with plain php code
+ *
+ * @license 	http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    	www.doctrine-project.org
+ * @since   	2.0
+ * @version     $Revision$
+ * @author      Benjamin Eberlei <kontakt@beberlei.de>
+ * @author      Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author      Jonathan H. Wage <jonwage@gmail.com>
+ * @author      Roman Borschel <roman@code-factory.org>
+ */
+class PHPDriver extends FileDriver
+{
+    /**
+     * {@inheritdoc}
+     */
+    protected $metadata;
+
+    /**
+     * {@inheritDoc}
+     */
+    public function __construct($locator, $fileExtension = null)
+    {
+        $fileExtension = ".php";
+        parent::__construct($locator, $fileExtension);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function loadMetadataForClass($className, ClassMetadata $metadata)
+    {
+        $this->metadata = $metadata;
+        $this->loadMappingFile($this->locator->findMappingFile($className));
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function loadMappingFile($file)
+    {
+        $metadata = $this->metadata;
+        include $file;
+    }
+}

+ 131 - 0
main/inc/lib/symfony/Doctrine/Common/Persistence/Mapping/Driver/StaticPHPDriver.php

@@ -0,0 +1,131 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Persistence\Mapping\Driver;
+
+use Doctrine\Common\Persistence\Mapping\ClassMetadata;
+use Doctrine\Common\Persistence\Mapping\MappingException;
+
+/**
+ * The StaticPHPDriver calls a static loadMetadata() method on your entity
+ * classes where you can manually populate the ClassMetadata instance.
+ *
+ * @license 	http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    	www.doctrine-project.org
+ * @since   	2.2
+ * @author      Benjamin Eberlei <kontakt@beberlei.de>
+ * @author      Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author      Jonathan H. Wage <jonwage@gmail.com>
+ * @author      Roman Borschel <roman@code-factory.org>
+ */
+class StaticPHPDriver implements MappingDriver
+{
+    /**
+     * Paths of entity directories.
+     *
+     * @var array
+     */
+    private $paths = array();
+
+    /**
+     * Map of all class names.
+     *
+     * @var array
+     */
+    private $classNames;
+
+    public function __construct($paths)
+    {
+        $this->addPaths((array) $paths);
+    }
+
+    public function addPaths(array $paths)
+    {
+        $this->paths = array_unique(array_merge($this->paths, $paths));
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function loadMetadataForClass($className, ClassMetadata $metadata)
+    {
+        $className::loadMetadata($metadata);
+    }
+
+    /**
+     * {@inheritDoc}
+     * @todo Same code exists in AnnotationDriver, should we re-use it somehow or not worry about it?
+     */
+    public function getAllClassNames()
+    {
+        if ($this->classNames !== null) {
+            return $this->classNames;
+        }
+
+        if (!$this->paths) {
+            throw MappingException::pathRequired();
+        }
+
+        $classes = array();
+        $includedFiles = array();
+
+        foreach ($this->paths as $path) {
+            if (!is_dir($path)) {
+                throw MappingException::fileMappingDriversRequireConfiguredDirectoryPath($path);
+            }
+
+            $iterator = new \RecursiveIteratorIterator(
+                new \RecursiveDirectoryIterator($path),
+                \RecursiveIteratorIterator::LEAVES_ONLY
+            );
+
+            foreach ($iterator as $file) {
+                if ($file->getBasename('.php') == $file->getBasename()) {
+                    continue;
+                }
+
+                $sourceFile = realpath($file->getPathName());
+                require_once $sourceFile;
+                $includedFiles[] = $sourceFile;
+            }
+        }
+
+        $declared = get_declared_classes();
+
+        foreach ($declared as $className) {
+            $rc = new \ReflectionClass($className);
+            $sourceFile = $rc->getFileName();
+            if (in_array($sourceFile, $includedFiles) && !$this->isTransient($className)) {
+                $classes[] = $className;
+            }
+        }
+
+        $this->classNames = $classes;
+
+        return $classes;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function isTransient($className)
+    {
+        return ! method_exists($className, 'loadMetadata');
+    }
+}

+ 198 - 0
main/inc/lib/symfony/Doctrine/Common/Persistence/Mapping/Driver/SymfonyFileLocator.php

@@ -0,0 +1,198 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+*/
+
+namespace Doctrine\Common\Persistence\Mapping\Driver;
+
+use Doctrine\Common\Persistence\Mapping\MappingException;
+
+/**
+ * The Symfony File Locator makes a simplifying assumptions compared
+ * to the DefaultFileLocator. By assuming paths only contain entities of a certain
+ * namespace the mapping files consists of the short classname only.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ * @license MIT
+ */
+class SymfonyFileLocator implements FileLocator
+{
+    /**
+     * The paths where to look for mapping files.
+     *
+     * @var array
+     */
+    protected $paths = array();
+
+    /**
+     * A map of mapping directory path to namespace prefix used to expand class shortnames.
+     *
+     * @var array
+     */
+    protected $prefixes = array();
+
+    /**
+     * File extension that is searched for.
+     *
+     * @var string
+     */
+    protected $fileExtension;
+
+    public function __construct(array $prefixes, $fileExtension = null)
+    {
+        $this->addNamespacePrefixes($prefixes);
+        $this->fileExtension = $fileExtension;
+    }
+
+    public function addNamespacePrefixes(array $prefixes)
+    {
+        $this->prefixes = array_merge($this->prefixes, $prefixes);
+        $this->paths = array_merge($this->paths, array_keys($prefixes));
+    }
+
+    public function getNamespacePrefixes()
+    {
+        return $this->prefixes;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getPaths()
+    {
+        return $this->paths;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getFileExtension()
+    {
+        return $this->fileExtension;
+    }
+
+    /**
+     * Set the file extension used to look for mapping files under
+     *
+     * @param string $fileExtension The file extension to set
+     * @return void
+     */
+    public function setFileExtension($fileExtension)
+    {
+        $this->fileExtension = $fileExtension;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function fileExists($className)
+    {
+        $defaultFileName = str_replace('\\', '.', $className).$this->fileExtension;
+        foreach ($this->paths as $path) {
+            if (!isset($this->prefixes[$path])) {
+                // global namespace class
+                if (is_file($path.DIRECTORY_SEPARATOR.$defaultFileName)) {
+                    return true;
+                }
+
+                continue;
+            }
+
+            $prefix = $this->prefixes[$path];
+
+            if (0 !== strpos($className, $prefix.'\\')) {
+                continue;
+            }
+
+            $filename = $path.'/'.strtr(substr($className, strlen($prefix)+1), '\\', '.').$this->fileExtension;
+            return is_file($filename);
+        }
+
+        return false;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getAllClassNames($globalBasename = null)
+    {
+        $classes = array();
+
+        if ($this->paths) {
+            foreach ((array) $this->paths as $path) {
+                if (!is_dir($path)) {
+                    throw MappingException::fileMappingDriversRequireConfiguredDirectoryPath($path);
+                }
+
+                $iterator = new \RecursiveIteratorIterator(
+                    new \RecursiveDirectoryIterator($path),
+                    \RecursiveIteratorIterator::LEAVES_ONLY
+                );
+
+                foreach ($iterator as $file) {
+                    $fileName = $file->getBasename($this->fileExtension);
+
+                    if ($fileName == $file->getBasename() || $fileName == $globalBasename) {
+                        continue;
+                    }
+
+                    // NOTE: All files found here means classes are not transient!
+                    if (isset($this->prefixes[$path])) {
+                        $classes[] = $this->prefixes[$path].'\\'.str_replace('.', '\\', $fileName);
+                    } else {
+                        $classes[] = str_replace('.', '\\', $fileName);
+                    }
+                }
+            }
+        }
+
+        return $classes;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function findMappingFile($className)
+    {
+        $defaultFileName = str_replace('\\', '.', $className).$this->fileExtension;
+        foreach ($this->paths as $path) {
+            if (!isset($this->prefixes[$path])) {
+                if (is_file($path.DIRECTORY_SEPARATOR.$defaultFileName)) {
+                    return $path.DIRECTORY_SEPARATOR.$defaultFileName;
+                }
+
+                continue;
+            }
+
+            $prefix = $this->prefixes[$path];
+
+            if (0 !== strpos($className, $prefix.'\\')) {
+                continue;
+            }
+
+            $filename = $path.'/'.strtr(substr($className, strlen($prefix)+1), '\\', '.').$this->fileExtension;
+            if (is_file($filename)) {
+                return $filename;
+            }
+
+            throw MappingException::mappingFileNotFound($className, $filename);
+        }
+
+        throw MappingException::mappingFileNotFound($className, substr($className, strrpos($className, '\\') + 1).$this->fileExtension);
+    }
+}

+ 57 - 0
main/inc/lib/symfony/Doctrine/Common/Persistence/Mapping/MappingException.php

@@ -0,0 +1,57 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.phpdoctrine.org>.
+ */
+
+namespace Doctrine\Common\Persistence\Mapping;
+
+/**
+ * A MappingException indicates that something is wrong with the mapping setup.
+ *
+ * @since 2.2
+ */
+class MappingException extends \Exception
+{
+    public static function classNotFoundInNamespaces($className, $namespaces)
+    {
+        return new self("The class '" . $className . "' was not found in the ".
+            "chain configured namespaces " . implode(", ", $namespaces));
+    }
+
+    public static function pathRequired()
+    {
+        return new self("Specifying the paths to your entities is required ".
+            "in the AnnotationDriver to retrieve all class names.");
+    }
+
+    public static function fileMappingDriversRequireConfiguredDirectoryPath($path = null)
+    {
+        if ( ! empty($path)) {
+            $path = '[' . $path . ']';
+        }
+
+        return new self(
+            'File mapping drivers must have a valid directory path, ' .
+            'however the given path ' . $path . ' seems to be incorrect!'
+        );
+    }
+
+    public static function mappingFileNotFound($entityName, $fileName)
+    {
+        return new self("No mapping file found named '$fileName' for class '$entityName'.");
+    }
+}

+ 80 - 0
main/inc/lib/symfony/Doctrine/Common/Persistence/Mapping/ReflectionService.php

@@ -0,0 +1,80 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Persistence\Mapping;
+
+/**
+ * Very simple reflection service abstraction.
+ *
+ * This is required inside metadata layers that may require either
+ * static or runtime reflection.
+ *
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ */
+interface ReflectionService
+{
+    /**
+     * Return an array of the parent classes (not interfaces) for the given class.
+     *
+     * @param string $class
+     * @return array
+     */
+    function getParentClasses($class);
+
+    /**
+     * Return the shortname of a class.
+     *
+     * @param string $class
+     * @return string
+     */
+    function getClassShortName($class);
+
+    /**
+     * @param string $class
+     * @return string
+     */
+    function getClassNamespace($class);
+
+    /**
+     * Return a reflection class instance or null
+     *
+     * @param string $class
+     * @return ReflectionClass|null
+     */
+    function getClass($class);
+
+    /**
+     * Return an accessible property (setAccessible(true)) or null.
+     *
+     * @param string $class
+     * @param string $property
+     * @return ReflectionProperty|null
+     */
+    function getAccessibleProperty($class, $property);
+
+    /**
+     * Check if the class have a public method with the given name.
+     *
+     * @param mixed $class
+     * @param mixed $method
+     * @return bool
+     */
+    function hasPublicMethod($class, $method);
+}
+

+ 102 - 0
main/inc/lib/symfony/Doctrine/Common/Persistence/Mapping/RuntimeReflectionService.php

@@ -0,0 +1,102 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Persistence\Mapping;
+
+use ReflectionClass;
+use ReflectionProperty;
+
+/**
+ * PHP Runtime Reflection Service
+ *
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ */
+class RuntimeReflectionService implements ReflectionService
+{
+    /**
+     * Return an array of the parent classes (not interfaces) for the given class.
+     *
+     * @param string $class
+     * @return array
+     */
+    public function getParentClasses($class)
+    {
+        return class_parents($class);
+    }
+
+    /**
+     * Return the shortname of a class.
+     *
+     * @param string $class
+     * @return string
+     */
+    public function getClassShortName($class)
+    {
+        $r = new ReflectionClass($class);
+        return $r->getShortName();
+    }
+
+    /**
+     * @param string $class
+     * @return string
+     */
+    public function getClassNamespace($class)
+    {
+        $r = new ReflectionClass($class);
+        return $r->getNamespaceName();
+    }
+
+    /**
+     * Return a reflection class instance or null
+     *
+     * @param string $class
+     * @return ReflectionClass|null
+     */
+    public function getClass($class)
+    {
+        return new ReflectionClass($class);
+    }
+
+    /**
+     * Return an accessible property (setAccessible(true)) or null.
+     *
+     * @param string $class
+     * @param string $property
+     * @return ReflectionProperty|null
+     */
+    public function getAccessibleProperty($class, $property)
+    {
+        $property = new ReflectionProperty($class, $property);
+        $property->setAccessible(true);
+        return $property;
+    }
+
+    /**
+     * Check if the class have a public method with the given name.
+     *
+     * @param mixed $class
+     * @param mixed $method
+     * @return bool
+     */
+    public function hasPublicMethod($class, $method)
+    {
+        return method_exists($class, $method) && is_callable(array($class, $method));
+    }
+}
+

+ 107 - 0
main/inc/lib/symfony/Doctrine/Common/Persistence/Mapping/StaticReflectionService.php

@@ -0,0 +1,107 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Persistence\Mapping;
+
+use ReflectionClass;
+use ReflectionProperty;
+
+/**
+ * PHP Runtime Reflection Service
+ *
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ */
+class StaticReflectionService implements ReflectionService
+{
+    /**
+     * Return an array of the parent classes (not interfaces) for the given class.
+     *
+     * @param string $class
+     * @return array
+     */
+    public function getParentClasses($class)
+    {
+        return array();
+    }
+
+    /**
+     * Return the shortname of a class.
+     *
+     * @param string $className
+     * @return string
+     */
+    public function getClassShortName($className)
+    {
+        if (strpos($className, '\\') !== false) {
+            $className = substr($className, strrpos($className, "\\")+1);
+        }
+        return $className;
+    }
+
+    /**
+     * Return the namespace of a class.
+     *
+     * @param string $className
+     * @return string
+     */
+    public function getClassNamespace($className)
+    {
+        $namespace = '';
+        if (strpos($className, '\\') !== false) {
+            $namespace = strrev(substr( strrev($className), strpos(strrev($className), '\\')+1 ));
+        }
+        return $namespace;
+    }
+
+    /**
+     * Return a reflection class instance or null
+     *
+     * @param string $class
+     * @return ReflectionClass|null
+     */
+    public function getClass($class)
+    {
+        return null;
+    }
+
+    /**
+     * Return an accessible property (setAccessible(true)) or null.
+     *
+     * @param string $class
+     * @param string $property
+     * @return ReflectionProperty|null
+     */
+    public function getAccessibleProperty($class, $property)
+    {
+        return null;
+    }
+
+    /**
+     * Check if the class have a public method with the given name.
+     *
+     * @param mixed $class
+     * @param mixed $method
+     * @return bool
+     */
+    public function hasPublicMethod($class, $method)
+    {
+        return method_exists($class, $method) && is_callable(array($class, $method));
+    }
+}
+

+ 143 - 0
main/inc/lib/symfony/Doctrine/Common/Persistence/ObjectManager.php

@@ -0,0 +1,143 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Persistence;
+
+/**
+ * Contract for a Doctrine persistence layer ObjectManager class to implement.
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.1
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ */
+interface ObjectManager
+{
+    /**
+     * Finds a object by its identifier.
+     *
+     * This is just a convenient shortcut for getRepository($className)->find($id).
+     *
+     * @param string
+     * @param mixed
+     * @return object
+     */
+    function find($className, $id);
+
+    /**
+     * Tells the ObjectManager to make an instance managed and persistent.
+     *
+     * The object will be entered into the database as a result of the flush operation.
+     *
+     * NOTE: The persist operation always considers objects that are not yet known to
+     * this ObjectManager as NEW. Do not pass detached objects to the persist operation.
+     *
+     * @param object $object The instance to make managed and persistent.
+     */
+    function persist($object);
+
+    /**
+     * Removes an object instance.
+     *
+     * A removed object will be removed from the database as a result of the flush operation.
+     *
+     * @param object $object The object instance to remove.
+     */
+    function remove($object);
+
+    /**
+     * Merges the state of a detached object into the persistence context
+     * of this ObjectManager and returns the managed copy of the object.
+     * The object passed to merge will not become associated/managed with this ObjectManager.
+     *
+     * @param object $object
+     */
+    function merge($object);
+
+    /**
+     * Detaches an object from the ObjectManager, causing a managed object to
+     * become detached. Unflushed changes made to the object if any
+     * (including removal of the object), will not be synchronized to the database.
+     * Objects which previously referenced the detached object will continue to
+     * reference it.
+     *
+     * @param object $object The object to detach.
+     */
+    function detach($object);
+
+    /**
+     * Refreshes the persistent state of an object from the database,
+     * overriding any local changes that have not yet been persisted.
+     *
+     * @param object $object The object to refresh.
+     */
+    function refresh($object);
+
+    /**
+     * Flushes all changes to objects that have been queued up to now to the database.
+     * This effectively synchronizes the in-memory state of managed objects with the
+     * database.
+     */
+    function flush();
+
+    /**
+     * Gets the repository for a class.
+     *
+     * @param string $className
+     * @return \Doctrine\Common\Persistence\ObjectRepository
+     */
+    function getRepository($className);
+
+    /**
+     * Returns the ClassMetadata descriptor for a class.
+     *
+     * The class name must be the fully-qualified class name without a leading backslash
+     * (as it is returned by get_class($obj)).
+     *
+     * @param string $className
+     * @return \Doctrine\Common\Persistence\Mapping\ClassMetadata
+     */
+    function getClassMetadata($className);
+
+    /**
+     * Gets the metadata factory used to gather the metadata of classes.
+     *
+     * @return Doctrine\Common\Persistence\Mapping\ClassMetadataFactory
+     */
+    function getMetadataFactory();
+
+    /**
+     * Helper method to initialize a lazy loading proxy or persistent collection.
+     *
+     * This method is a no-op for other objects.
+     *
+     * @param object $obj
+     */
+    function initializeObject($obj);
+
+    /**
+     * Check if the object is part of the current UnitOfWork and therefore
+     * managed.
+     *
+     * @param object $object
+     * @return bool
+     */
+    function contains($object);
+}

+ 49 - 0
main/inc/lib/symfony/Doctrine/Common/Persistence/ObjectManagerAware.php

@@ -0,0 +1,49 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Persistence;
+
+use Doctrine\Common\Persistence\Mapping\ClassMetadata;
+
+/**
+ * Makes a Persistent Objects aware of its own object-manager.
+ *
+ * Using this interface the managing object manager and class metadata instances
+ * are injected into the persistent object after construction. This allows
+ * you to implement ActiveRecord functionality on top of the persistance-ignorance
+ * that Doctrine propagates.
+ *
+ * Word of Warning: This is a very powerful hook to change how you can work with your domain models.
+ * Using this hook will break the Single Responsibility Principle inside your Domain Objects
+ * and increase the coupling of database and objects.
+ *
+ * Every ObjectManager has to implement this functionality itself.
+ *
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ */
+interface ObjectManagerAware
+{
+    /**
+     * Injects responsible ObjectManager and the ClassMetadata into this persistent object.
+     *
+     * @param ObjectManager $objectManager
+     * @param ClassMetadata $classMetadata
+     */
+    public function injectObjectManager(ObjectManager $objectManager, ClassMetadata $classMetadata);
+}

+ 78 - 0
main/inc/lib/symfony/Doctrine/Common/Persistence/ObjectRepository.php

@@ -0,0 +1,78 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Persistence;
+
+/**
+ * Contract for a Doctrine persistence layer ObjectRepository class to implement.
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.1
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ */
+interface ObjectRepository
+{
+    /**
+     * Finds an object by its primary key / identifier.
+     *
+     * @param $id The identifier.
+     * @return object The object.
+     */
+    function find($id);
+
+    /**
+     * Finds all objects in the repository.
+     *
+     * @return mixed The objects.
+     */
+    function findAll();
+
+    /**
+     * Finds objects by a set of criteria.
+     *
+     * Optionally sorting and limiting details can be passed. An implementation may throw
+     * an UnexpectedValueException if certain values of the sorting or limiting details are
+     * not supported.
+     *
+     * @throws UnexpectedValueException
+     * @param array $criteria
+     * @param array|null $orderBy
+     * @param int|null $limit
+     * @param int|null $offset
+     * @return mixed The objects.
+     */
+    function findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null);
+
+    /**
+     * Finds a single object by a set of criteria.
+     *
+     * @param array $criteria
+     * @return object The object.
+     */
+    function findOneBy(array $criteria);
+
+    /**
+     * Returns the class name of the object managed by the repository
+     *
+     * @return string
+     */
+    function getClassName();
+}

+ 233 - 0
main/inc/lib/symfony/Doctrine/Common/Persistence/PersistentObject.php

@@ -0,0 +1,233 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Persistence;
+
+use Doctrine\Common\Persistence\Mapping\ClassMetadata;
+use Doctrine\Common\Collections\ArrayCollection;
+use Doctrine\Common\Collections\Collection;
+
+/**
+ * PersistentObject base class that implements getter/setter methods for all mapped fields and associations
+ * by overriding __call.
+ *
+ * This class is a forward compatible implementation of the PersistentObject trait.
+ *
+ *
+ * Limitations:
+ *
+ * 1. All persistent objects have to be associated with a single ObjectManager, multiple
+ *    ObjectManagers are not supported. You can set the ObjectManager with `PersistentObject#setObjectManager()`.
+ * 2. Setters and getters only work if a ClassMetadata instance was injected into the PersistentObject.
+ *    This is either done on `postLoad` of an object or by accessing the global object manager.
+ * 3. There are no hooks for setters/getters. Just implement the method yourself instead of relying on __call().
+ * 4. Slower than handcoded implementations: An average of 7 method calls per access to a field and 11 for an association.
+ * 5. Only the inverse side associations get autoset on the owning side aswell. Setting objects on the owning side
+ *    will not set the inverse side associations.
+ *
+ * @example
+ *
+ *  PersistentObject::setObjectManager($em);
+ *
+ *  class Foo extends PersistentObject
+ *  {
+ *      private $id;
+ *  }
+ *
+ *  $foo = new Foo();
+ *  $foo->getId(); // method exists through __call
+ *
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ */
+abstract class PersistentObject implements ObjectManagerAware
+{
+    /**
+     * @var ObjectManager
+     */
+    private static $objectManager;
+
+    /**
+     * @var ClassMetadata
+     */
+    private $cm;
+
+    /**
+     * Set the object manager responsible for all persistent object base classes.
+     *
+     * @param ObjectManager $objectManager
+     */
+    static public function setObjectManager(ObjectManager $objectManager = null)
+    {
+        self::$objectManager = $objectManager;
+    }
+
+    /**
+     * @return ObjectManager
+     */
+    static public function getObjectManager()
+    {
+        return self::$objectManager;
+    }
+
+    /**
+     * Inject Doctrine Object Manager
+     *
+     * @param ObjectManager $objectManager
+     * @param ClassMetadata $classMetadata
+     */
+    public function injectObjectManager(ObjectManager $objectManager, ClassMetadata $classMetadata)
+    {
+        if ($objectManager !== self::$objectManager) {
+            throw new \RuntimeException("Trying to use PersistentObject with different ObjectManager instances. " .
+                "Was PersistentObject::setObjectManager() called?");
+        }
+
+        $this->cm = $classMetadata;
+    }
+
+    /**
+     * Sets a persistent fields value.
+     *
+     * @throws InvalidArgumentException - When the wrong target object type is passed to an association
+     * @throws BadMethodCallException - When no persistent field exists by that name.
+     * @param string $field
+     * @param array $args
+     * @return void
+     */
+    private function set($field, $args)
+    {
+        $this->initializeDoctrine();
+
+        if ($this->cm->hasField($field) && !$this->cm->isIdentifier($field)) {
+            $this->$field = $args[0];
+        } else if ($this->cm->hasAssociation($field) && $this->cm->isSingleValuedAssociation($field)) {
+            $targetClass = $this->cm->getAssociationTargetClass($field);
+            if (!($args[0] instanceof $targetClass) && $args[0] !== null) {
+                throw new \InvalidArgumentException("Expected persistent object of type '".$targetClass."'");
+            }
+            $this->$field = $args[0];
+            $this->completeOwningSide($field, $targetClass, $args[0]);
+        } else {
+            throw new \BadMethodCallException("no field with name '".$field."' exists on '".$this->cm->getName()."'");
+        }
+    }
+
+    /**
+     * Get persistent field value.
+     *
+     * @throws BadMethodCallException - When no persistent field exists by that name.
+     * @param string $field
+     * @return mixed
+     */
+    private function get($field)
+    {
+        $this->initializeDoctrine();
+
+        if ( $this->cm->hasField($field) || $this->cm->hasAssociation($field) ) {
+            return $this->$field;
+        } else {
+            throw new \BadMethodCallException("no field with name '".$field."' exists on '".$this->cm->getName()."'");
+        }
+    }
+
+    /**
+     * If this is an inverse side association complete the owning side.
+     *
+     * @param string $field
+     * @param ClassMetadata $targetClass
+     * @param object $targetObject
+     */
+    private function completeOwningSide($field, $targetClass, $targetObject)
+    {
+        // add this object on the owning side aswell, for obvious infinite recursion
+        // reasons this is only done when called on the inverse side.
+        if ($this->cm->isAssociationInverseSide($field)) {
+            $mappedByField = $this->cm->getAssociationMappedByTargetField($field);
+            $targetMetadata = self::$objectManager->getClassMetadata($targetClass);
+
+            $setter = ($targetMetadata->isCollectionValuedAssociation($mappedByField) ? "add" : "set").$mappedByField;
+            $targetObject->$setter($this);
+        }
+    }
+
+    /**
+     * Add an object to a collection
+     *
+     * @param type $field
+     * @param assoc $args
+     */
+    private function add($field, $args)
+    {
+        $this->initializeDoctrine();
+
+        if ($this->cm->hasAssociation($field) && $this->cm->isCollectionValuedAssociation($field)) {
+            $targetClass = $this->cm->getAssociationTargetClass($field);
+            if (!($args[0] instanceof $targetClass)) {
+                throw new \InvalidArgumentException("Expected persistent object of type '".$targetClass."'");
+            }
+            if (!($this->$field instanceof Collection)) {
+                $this->$field = new ArrayCollection($this->$field ?: array());
+            }
+            $this->$field->add($args[0]);
+            $this->completeOwningSide($field, $targetClass, $args[0]);
+        } else {
+            throw new \BadMethodCallException("There is no method add".$field."() on ".$this->cm->getName());
+        }
+    }
+
+    /**
+     * Initialize Doctrine Metadata for this class.
+     *
+     * @return void
+     */
+    private function initializeDoctrine()
+    {
+        if ($this->cm !== null) {
+            return;
+        }
+
+        if (!self::$objectManager) {
+            throw new \RuntimeException("No runtime object manager set. Call PersistentObject#setObjectManager().");
+        }
+
+        $this->cm = self::$objectManager->getClassMetadata(get_class($this));
+    }
+
+    /**
+     * Magic method that implements
+     *
+     * @param string $method
+     * @param array $args
+     * @return mixed
+     */
+    public function __call($method, $args)
+    {
+        $command = substr($method, 0, 3);
+        $field = lcfirst(substr($method, 3));
+        if ($command == "set") {
+            $this->set($field, $args);
+        } else if ($command == "get") {
+            return $this->get($field);
+        } else if ($command == "add") {
+            $this->add($field, $args);
+        } else {
+            throw new \BadMethodCallException("There is no method ".$method." on ".$this->cm->getName());
+        }
+    }
+}

+ 60 - 0
main/inc/lib/symfony/Doctrine/Common/Persistence/Proxy.php

@@ -0,0 +1,60 @@
+<?php
+
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Persistence;
+
+/**
+ * Interface for proxy classes.
+ *
+ * @author Roman Borschel <roman@code-factory.org>
+ * @since 2.2
+ */
+interface Proxy
+{
+    /**
+     * Marker for Proxy class names.
+     *
+     * @var string
+     */
+    const MARKER = '__CG__';
+
+    /**
+     * Length of the proxy marker
+     *
+     * @var int
+     */
+    const MARKER_LENGTH = 6;
+
+    /**
+     * Initialize this proxy if its not yet initialized.
+     *
+     * Acts as a no-op if already initialized.
+     *
+     * @return void
+     */
+    public function __load();
+
+    /**
+     * Is this proxy initialized or not.
+     *
+     * @return bool
+     */
+    public function __isInitialized();
+}

+ 48 - 0
main/inc/lib/symfony/Doctrine/Common/PropertyChangedListener.php

@@ -0,0 +1,48 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common;
+
+/**
+ * Contract for classes that are potential listeners of a <tt>NotifyPropertyChanged</tt>
+ * implementor.
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision: 3938 $
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+interface PropertyChangedListener
+{
+    /**
+     * Notifies the listener of a property change.
+     *
+     * @param object $sender The object on which the property changed.
+     * @param string $propertyName The name of the property that changed.
+     * @param mixed $oldValue The old value of the property that changed.
+     * @param mixed $newValue The new value of the property that changed.
+     */
+    function propertyChanged($sender, $propertyName, $oldValue, $newValue);
+}
+

+ 103 - 0
main/inc/lib/symfony/Doctrine/Common/Util/ClassUtils.php

@@ -0,0 +1,103 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Util;
+
+use Doctrine\Common\Persistence\Proxy;
+
+/**
+ * Class and reflection related functionality for objects that
+ * might or not be proxy objects at the moment.
+ *
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ * @author Johannes Schmitt <schmittjoh@gmail.com>
+ */
+class ClassUtils
+{
+    /**
+     * Get the real class name of a class name that could be a proxy.
+     *
+     * @param string
+     * @return string
+     */
+    public static function getRealClass($class)
+    {
+        if (false === $pos = strrpos($class, '\\'.Proxy::MARKER.'\\')) {
+            return $class;
+        }
+
+        return substr($class, $pos + Proxy::MARKER_LENGTH + 2);
+    }
+
+    /**
+     * Get the real class name of an object (even if its a proxy)
+     *
+     * @param object
+     * @return string
+     */
+    public static function getClass($object)
+    {
+        return self::getRealClass(get_class($object));
+    }
+
+    /**
+     * Get the real parent class name of a class or object
+     *
+     * @param string
+     * @return string
+     */
+    public static function getParentClass($className)
+    {
+        return get_parent_class( self::getRealClass( $className ) );
+    }
+
+    /**
+     * Create a new reflection class
+     *
+     * @param string
+     * @return ReflectionClass
+     */
+    public static function newReflectionClass($class)
+    {
+        return new \ReflectionClass( self::getRealClass( $class ) );
+    }
+
+    /**
+     * Create a new reflection object
+     *
+     * @param object
+     * @return ReflectionObject
+     */
+    public static function newReflectionObject($object)
+    {
+        return self::newReflectionClass( self::getClass( $object ) );
+    }
+
+    /**
+     * Given a class name and a proxy namespace return the proxy name.
+     *
+     * @param string $className
+     * @param string $proxyNamespace
+     * @return string
+     */
+    public static function generateProxyClassName($className, $proxyNamespace)
+    {
+        return rtrim($proxyNamespace, '\\') . '\\'.Proxy::MARKER.'\\' . ltrim($className, '\\');
+    }
+}

+ 123 - 0
main/inc/lib/symfony/Doctrine/Common/Util/Debug.php

@@ -0,0 +1,123 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Util;
+
+/**
+ * Static class containing most used debug methods.
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ * @author  Giorgio Sironi <piccoloprincipeazzurro@gmail.com>
+ */
+final class Debug
+{
+    /**
+     * Private constructor (prevents from instantiation)
+     *
+     */
+    private function __construct() {}
+
+    /**
+     * Prints a dump of the public, protected and private properties of $var.
+     *
+     * @static
+     * @link http://xdebug.org/
+     * @param mixed $var
+     * @param integer $maxDepth Maximum nesting level for object properties
+     * @param boolean $stripTags Flag that indicate if output should strip HTML tags
+     */
+    public static function dump($var, $maxDepth = 2, $stripTags = true)
+    {
+        ini_set('html_errors', 'On');
+
+        if (extension_loaded('xdebug')) {
+            ini_set('xdebug.var_display_max_depth', $maxDepth);
+        }
+
+        $var = self::export($var, $maxDepth++);
+
+        ob_start();
+        var_dump($var);
+        $dump = ob_get_contents();
+        ob_end_clean();
+
+        echo ($stripTags ? strip_tags(html_entity_decode($dump)) : $dump);
+
+        ini_set('html_errors', 'Off');
+    }
+
+    public static function export($var, $maxDepth)
+    {
+        $return = null;
+        $isObj = is_object($var);
+
+        if ($isObj && in_array('Doctrine\Common\Collections\Collection', class_implements($var))) {
+            $var = $var->toArray();
+        }
+
+        if ($maxDepth) {
+            if (is_array($var)) {
+                $return = array();
+
+                foreach ($var as $k => $v) {
+                    $return[$k] = self::export($v, $maxDepth - 1);
+                }
+            } else if ($isObj) {
+                $return = new \stdclass();
+                if ($var instanceof \DateTime) {
+                    $return->__CLASS__ = "DateTime";
+                    $return->date = $var->format('c');
+                    $return->timezone = $var->getTimeZone()->getName();
+                } else {
+                    $reflClass = ClassUtils::newReflectionObject($var);
+                    $return->__CLASS__ = ClassUtils::getClass($var);
+
+                    if ($var instanceof \Doctrine\Common\Persistence\Proxy) {
+                        $return->__IS_PROXY__ = true;
+                        $return->__PROXY_INITIALIZED__ = $var->__isInitialized();
+                    }
+
+                    foreach ($reflClass->getProperties() as $reflProperty) {
+                        $name  = $reflProperty->getName();
+
+                        $reflProperty->setAccessible(true);
+                        $return->$name = self::export($reflProperty->getValue($var), $maxDepth - 1);
+                    }
+                }
+            } else {
+                $return = $var;
+            }
+        } else {
+            $return = is_object($var) ? get_class($var)
+                : (is_array($var) ? 'Array(' . count($var) . ')' : $var);
+        }
+
+        return $return;
+    }
+
+    public static function toString($obj)
+    {
+        return method_exists('__toString', $obj) ? (string) $obj : get_class($obj) . '@' . spl_object_hash($obj);
+    }
+}

+ 72 - 0
main/inc/lib/symfony/Doctrine/Common/Util/Inflector.php

@@ -0,0 +1,72 @@
+<?php
+/*
+ *  $Id: Inflector.php 3189 2007-11-18 20:37:44Z meus $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Util;
+
+/**
+ * Doctrine inflector has static methods for inflecting text
+ *
+ * The methods in these classes are from several different sources collected
+ * across several different php projects and several different authors. The
+ * original author names and emails are not known
+ *
+ * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link        www.doctrine-project.org
+ * @since       1.0
+ * @version     $Revision: 3189 $
+ * @author      Konsta Vesterinen <kvesteri@cc.hut.fi>
+ * @author      Jonathan H. Wage <jonwage@gmail.com>
+ */
+class Inflector
+{
+    /**
+     * Convert word in to the format for a Doctrine table name. Converts 'ModelName' to 'model_name'
+     *
+     * @param  string $word  Word to tableize
+     * @return string $word  Tableized word
+     */
+    public static function tableize($word)
+    {
+        return strtolower(preg_replace('~(?<=\\w)([A-Z])~', '_$1', $word));
+    }
+
+    /**
+     * Convert a word in to the format for a Doctrine class name. Converts 'table_name' to 'TableName'
+     *
+     * @param string  $word  Word to classify
+     * @return string $word  Classified word
+     */
+    public static function classify($word)
+    {
+        return str_replace(" ", "", ucwords(strtr($word, "_-", "  ")));
+    }
+
+    /**
+     * Camelize a word. This uses the classify() method and turns the first character to lowercase
+     *
+     * @param string $word
+     * @return string $word
+     */
+    public static function camelize($word)
+    {
+        return lcfirst(self::classify($word));
+    }
+}

+ 55 - 0
main/inc/lib/symfony/Doctrine/Common/Version.php

@@ -0,0 +1,55 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common;
+
+/**
+ * Class to store and retrieve the version of Doctrine
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @version $Revision$
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ */
+class Version
+{
+    /**
+     * Current Doctrine Version
+     */
+    const VERSION = '2.2.0';
+
+    /**
+     * Compares a Doctrine version with the current one.
+     *
+     * @param string $version Doctrine version to compare.
+     * @return int Returns -1 if older, 0 if it is the same, 1 if version
+     *             passed as argument is newer.
+     */
+    public static function compare($version)
+    {
+        $currentVersion = str_replace(' ', '', strtolower(self::VERSION));
+        $version = str_replace(' ', '', $version);
+
+        return version_compare($version, $currentVersion);
+    }
+}

+ 94 - 0
main/inc/lib/symfony/Doctrine/DBAL/Cache/ArrayStatement.php

@@ -0,0 +1,94 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Cache;
+
+use Doctrine\DBAL\Driver\ResultStatement;
+use PDO;
+
+class ArrayStatement implements \IteratorAggregate, ResultStatement
+{
+    private $data;
+    private $columnCount = 0;
+    private $num = 0;
+    private $defaultFetchStyle = PDO::FETCH_BOTH;
+
+    public function __construct(array $data)
+    {
+        $this->data = $data;
+        if (count($data)) {
+            $this->columnCount = count($data[0]);
+        }
+    }
+
+    public function closeCursor()
+    {
+        unset ($this->data);
+    }
+
+    public function columnCount()
+    {
+        return $this->columnCount;
+    }
+
+    public function setFetchMode($fetchStyle)
+    {
+        $this->defaultFetchStyle = $fetchStyle;
+    }
+
+    public function getIterator()
+    {
+        $data = $this->fetchAll($this->defaultFetchStyle);
+        return new \ArrayIterator($data);
+    }
+
+    public function fetch($fetchStyle = PDO::FETCH_BOTH)
+    {
+        if (isset($this->data[$this->num])) {
+            $row = $this->data[$this->num++];
+            if ($fetchStyle === PDO::FETCH_ASSOC) {
+                return $row;
+            } else if ($fetchStyle === PDO::FETCH_NUM) {
+                return array_values($row);
+            } else if ($fetchStyle === PDO::FETCH_BOTH) {
+                return array_merge($row, array_values($row));
+            }
+        }
+        return false;
+    }
+
+    public function fetchAll($fetchStyle = PDO::FETCH_BOTH)
+    {
+        $rows = array();
+        while ($row = $this->fetch($fetchStyle)) {
+            $rows[] = $row;
+        }
+        return $rows;
+    }
+
+    public function fetchColumn($columnIndex = 0)
+    {
+        $row = $this->fetch(PDO::FETCH_NUM);
+        if (!isset($row[$columnIndex])) {
+            // TODO: verify this is correct behavior
+            return false;
+        }
+        return $row[$columnIndex];
+    }
+}

+ 37 - 0
main/inc/lib/symfony/Doctrine/DBAL/Cache/CacheException.php

@@ -0,0 +1,37 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Cache;
+
+/**
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ * @since 2.2
+ */
+class CacheException extends \Doctrine\DBAL\DBALException
+{
+    static public function noCacheKey()
+    {
+        return new self("No cache key was set.");
+    }
+
+    static public function noResultDriverConfigured()
+    {
+        return new self("Trying to cache a query but no result driver is configured.");
+    }
+}

+ 131 - 0
main/inc/lib/symfony/Doctrine/DBAL/Cache/QueryCacheProfile.php

@@ -0,0 +1,131 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Cache;
+
+use Doctrine\Common\Cache\Cache;
+
+/**
+ * Query Cache Profile handles the data relevant for query caching.
+ *
+ * It is a value object, setter methods return NEW instances.
+ *
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ */
+class QueryCacheProfile
+{
+    /**
+     * @var Cache
+     */
+    private $resultCacheDriver;
+    /**
+     * @var int
+     */
+    private $lifetime = 0;
+    /**
+     * @var string
+     */
+    private $cacheKey;
+
+    /**
+     * @param int $lifetime
+     * @param string $cacheKey
+     * @param Cache $resultCache
+     */
+    public function __construct($lifetime = 0, $cacheKey = null, Cache $resultCache = null)
+    {
+        $this->lifetime = $lifetime;
+        $this->cacheKey = $cacheKey;
+        $this->resultCacheDriver = $resultCache;
+    }
+
+    /**
+     * @return Cache
+     */
+    public function getResultCacheDriver()
+    {
+        return $this->resultCacheDriver;
+    }
+
+    /**
+     * @return int
+     */
+    public function getLifetime()
+    {
+        return $this->lifetime;
+    }
+
+    /**
+     * @return string
+     */
+    public function getCacheKey()
+    {
+        if ($this->cacheKey === null) {
+            throw CacheException::noCacheKey();
+        }
+        return $this->cacheKey;
+    }
+
+    /**
+     * Generate the real cache key from query, params and types.
+     *
+     * @param string $query
+     * @param array $params
+     * @param array $types
+     * @return array
+     */
+    public function generateCacheKeys($query, $params, $types)
+    {
+        $realCacheKey = $query . "-" . serialize($params) . "-" . serialize($types);
+        // should the key be automatically generated using the inputs or is the cache key set?
+        if ($this->cacheKey === null) {
+            $cacheKey = sha1($realCacheKey);
+        } else {
+            $cacheKey = $this->cacheKey;
+        }
+        return array($cacheKey, $realCacheKey);
+    }
+
+    /**
+     * @param Cache $cache
+     * @return QueryCacheProfile
+     */
+    public function setResultCacheDriver(Cache $cache)
+    {
+        return new QueryCacheProfile($this->lifetime, $this->cacheKey, $cache);
+    }
+
+    /**
+     * @param string|null $cacheKey
+     * @return QueryCacheProfile
+     */
+    public function setCacheKey($cacheKey)
+    {
+        return new QueryCacheProfile($this->lifetime, $cacheKey, $this->resultCacheDriver);
+    }
+
+    /**
+     * @param  int $lifetime
+     * @return QueryCacheProfile
+     */
+    public function setLifetime($lifetime)
+    {
+        return new QueryCacheProfile($lifetime, $this->cacheKey, $this->resultCacheDriver);
+    }
+}

+ 255 - 0
main/inc/lib/symfony/Doctrine/DBAL/Cache/ResultCacheStatement.php

@@ -0,0 +1,255 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Cache;
+
+use Doctrine\DBAL\Driver\Statement;
+use Doctrine\DBAL\Driver\ResultStatement;
+use Doctrine\DBAL\Connection;
+use Doctrine\Common\Cache\Cache;
+use PDO;
+
+/**
+ * Cache statement for SQL results.
+ *
+ * A result is saved in multiple cache keys, there is the originally specified
+ * cache key which is just pointing to result rows by key. The following things
+ * have to be ensured:
+ *
+ * 1. lifetime of the original key has to be longer than that of all the individual rows keys
+ * 2. if any one row key is missing the query has to be re-executed.
+ *
+ * Also you have to realize that the cache will load the whole result into memory at once to ensure 2.
+ * This means that the memory usage for cached results might increase by using this feature.
+ */
+class ResultCacheStatement implements \IteratorAggregate, ResultStatement
+{
+    /**
+     * @var \Doctrine\Common\Cache\Cache
+     */
+    private $resultCache;
+
+    /**
+     *
+     * @var string
+     */
+    private $cacheKey;
+
+    /**
+     * @var string
+     */
+    private $realKey;
+
+    /**
+     * @var int
+     */
+    private $lifetime;
+
+    /**
+     * @var Doctrine\DBAL\Driver\Statement
+     */
+    private $statement;
+
+    /**
+     * Did we reach the end of the statement?
+     *
+     * @var bool
+     */
+    private $emptied = false;
+
+    /**
+     * @var array
+     */
+    private $data;
+
+    /**
+     * @var int
+     */
+    private $defaultFetchStyle = PDO::FETCH_BOTH;
+
+    /**
+     * @param Statement $stmt
+     * @param Cache $resultCache
+     * @param string $cacheKey
+     * @param string $realKey
+     * @param int $lifetime
+     */
+    public function __construct(Statement $stmt, Cache $resultCache, $cacheKey, $realKey, $lifetime)
+    {
+        $this->statement = $stmt;
+        $this->resultCache = $resultCache;
+        $this->cacheKey = $cacheKey;
+        $this->realKey = $realKey;
+        $this->lifetime = $lifetime;
+    }
+
+    /**
+     * Closes the cursor, enabling the statement to be executed again.
+     *
+     * @return boolean              Returns TRUE on success or FALSE on failure.
+     */
+    public function closeCursor()
+    {
+        $this->statement->closeCursor();
+        if ($this->emptied && $this->data !== null) {
+            $data = $this->resultCache->fetch($this->cacheKey);
+            if (!$data) {
+                $data = array();
+            }
+            $data[$this->realKey] = $this->data;
+
+            $this->resultCache->save($this->cacheKey, $data, $this->lifetime);
+            unset($this->data);
+        }
+    }
+
+    /**
+     * columnCount
+     * Returns the number of columns in the result set
+     *
+     * @return integer              Returns the number of columns in the result set represented
+     *                              by the PDOStatement object. If there is no result set,
+     *                              this method should return 0.
+     */
+    public function columnCount()
+    {
+        return $this->statement->columnCount();
+    }
+
+    public function setFetchMode($fetchStyle)
+    {
+        $this->defaultFetchStyle = $fetchStyle;
+    }
+
+    public function getIterator()
+    {
+        $data = $this->fetchAll($this->defaultFetchStyle);
+        return new \ArrayIterator($data);
+    }
+
+    /**
+     * fetch
+     *
+     * @see Query::HYDRATE_* constants
+     * @param integer $fetchStyle           Controls how the next row will be returned to the caller.
+     *                                      This value must be one of the Query::HYDRATE_* constants,
+     *                                      defaulting to Query::HYDRATE_BOTH
+     *
+     * @param integer $cursorOrientation    For a PDOStatement object representing a scrollable cursor,
+     *                                      this value determines which row will be returned to the caller.
+     *                                      This value must be one of the Query::HYDRATE_ORI_* constants, defaulting to
+     *                                      Query::HYDRATE_ORI_NEXT. To request a scrollable cursor for your
+     *                                      PDOStatement object,
+     *                                      you must set the PDO::ATTR_CURSOR attribute to Doctrine::CURSOR_SCROLL when you
+     *                                      prepare the SQL statement with Doctrine_Adapter_Interface->prepare().
+     *
+     * @param integer $cursorOffset         For a PDOStatement object representing a scrollable cursor for which the
+     *                                      $cursorOrientation parameter is set to Query::HYDRATE_ORI_ABS, this value specifies
+     *                                      the absolute number of the row in the result set that shall be fetched.
+     *
+     *                                      For a PDOStatement object representing a scrollable cursor for
+     *                                      which the $cursorOrientation parameter is set to Query::HYDRATE_ORI_REL, this value
+     *                                      specifies the row to fetch relative to the cursor position before
+     *                                      PDOStatement->fetch() was called.
+     *
+     * @return mixed
+     */
+    public function fetch($fetchStyle = PDO::FETCH_BOTH)
+    {
+        if ($this->data === null) {
+            $this->data = array();
+        }
+
+        $row = $this->statement->fetch(PDO::FETCH_ASSOC);
+        if ($row) {
+            $this->data[] = $row;
+
+            if ($fetchStyle == PDO::FETCH_ASSOC) {
+                return $row;
+            } else if ($fetchStyle == PDO::FETCH_NUM) {
+                return array_values($row);
+            } else if ($fetchStyle == PDO::FETCH_BOTH) {
+                return array_merge($row, array_values($row));
+            } else {
+                throw new \InvalidArgumentException("Invalid fetch-style given for caching result.");
+            }
+        }
+        $this->emptied = true;
+        return false;
+    }
+
+    /**
+     * Returns an array containing all of the result set rows
+     *
+     * @param integer $fetchStyle           Controls how the next row will be returned to the caller.
+     *                                      This value must be one of the Query::HYDRATE_* constants,
+     *                                      defaulting to Query::HYDRATE_BOTH
+     *
+     * @param integer $columnIndex          Returns the indicated 0-indexed column when the value of $fetchStyle is
+     *                                      Query::HYDRATE_COLUMN. Defaults to 0.
+     *
+     * @return array
+     */
+    public function fetchAll($fetchStyle = PDO::FETCH_BOTH)
+    {
+        $rows = array();
+        while ($row = $this->fetch($fetchStyle)) {
+            $rows[] = $row;
+        }
+        return $rows;
+    }
+
+    /**
+     * fetchColumn
+     * Returns a single column from the next row of a
+     * result set or FALSE if there are no more rows.
+     *
+     * @param integer $columnIndex          0-indexed number of the column you wish to retrieve from the row. If no
+     *                                      value is supplied, PDOStatement->fetchColumn()
+     *                                      fetches the first column.
+     *
+     * @return string                       returns a single column in the next row of a result set.
+     */
+    public function fetchColumn($columnIndex = 0)
+    {
+        $row = $this->fetch(PDO::FETCH_NUM);
+        if (!isset($row[$columnIndex])) {
+            // TODO: verify this is correct behavior
+            return false;
+        }
+        return $row[$columnIndex];
+    }
+
+    /**
+     * rowCount
+     * rowCount() returns the number of rows affected by the last DELETE, INSERT, or UPDATE statement
+     * executed by the corresponding object.
+     *
+     * If the last SQL statement executed by the associated Statement object was a SELECT statement,
+     * some databases may return the number of rows returned by that statement. However,
+     * this behaviour is not guaranteed for all databases and should not be
+     * relied on for portable applications.
+     *
+     * @return integer                      Returns the number of rows.
+     */
+    public function rowCount()
+    {
+        return $this->statement->rowCount();
+    }
+}

+ 113 - 0
main/inc/lib/symfony/Doctrine/DBAL/Configuration.php

@@ -0,0 +1,113 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL;
+
+use Doctrine\DBAL\Logging\SQLLogger;
+use Doctrine\Common\Cache\Cache;
+
+/**
+ * Configuration container for the Doctrine DBAL.
+ *
+ * @since   2.0
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ * @internal When adding a new configuration option just write a getter/setter
+ *           pair and add the option to the _attributes array with a proper default value.
+ */
+class Configuration
+{
+    /**
+     * The attributes that are contained in the configuration.
+     * Values are default values.
+     *
+     * @var array
+     */
+    protected $_attributes = array();
+
+    /**
+     * Sets the SQL logger to use. Defaults to NULL which means SQL logging is disabled.
+     *
+     * @param SQLLogger $logger
+     */
+    public function setSQLLogger(SQLLogger $logger = null)
+    {
+        $this->_attributes['sqlLogger'] = $logger;
+    }
+
+    /**
+     * Gets the SQL logger that is used.
+     *
+     * @return SQLLogger
+     */
+    public function getSQLLogger()
+    {
+        return isset($this->_attributes['sqlLogger']) ?
+                $this->_attributes['sqlLogger'] : null;
+    }
+
+    /**
+     * Gets the cache driver implementation that is used for query result caching.
+     *
+     * @return \Doctrine\Common\Cache\Cache
+     */
+    public function getResultCacheImpl()
+    {
+        return isset($this->_attributes['resultCacheImpl']) ?
+                $this->_attributes['resultCacheImpl'] : null;
+    }
+
+    /**
+     * Sets the cache driver implementation that is used for query result caching.
+     *
+     * @param \Doctrine\Common\Cache\Cache $cacheImpl
+     */
+    public function setResultCacheImpl(Cache $cacheImpl)
+    {
+        $this->_attributes['resultCacheImpl'] = $cacheImpl;
+    }
+
+    /**
+     * Filter schema assets expression.
+     *
+     * Only include tables/sequences matching the filter expression regexp in
+     * schema instances generated for the active connection when calling
+     * {AbstractSchemaManager#createSchema()}.
+     *
+     * @param string $filterExpression
+     */
+    public function setFilterSchemaAssetsExpression($filterExpression)
+    {
+        $this->_attributes['filterSchemaAssetsExpression'] = $filterExpression;
+    }
+
+    /**
+     * Return filter schema assets expression.
+     *
+     * @return string|null
+     */
+    public function getFilterSchemaAssetsExpression()
+    {
+        if (isset($this->_attributes['filterSchemaAssetsExpression'])) {
+            return $this->_attributes['filterSchemaAssetsExpression'];
+        }
+        return null;
+    }
+}

+ 1168 - 0
main/inc/lib/symfony/Doctrine/DBAL/Connection.php

@@ -0,0 +1,1168 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL;
+
+use PDO, Closure, Exception,
+    Doctrine\DBAL\Types\Type,
+    Doctrine\DBAL\Driver\Connection as DriverConnection,
+    Doctrine\Common\EventManager,
+    Doctrine\DBAL\DBALException,
+    Doctrine\DBAL\Cache\ResultCacheStatement,
+    Doctrine\DBAL\Cache\QueryCacheProfile,
+    Doctrine\DBAL\Cache\ArrayStatement,
+    Doctrine\DBAL\Cache\CacheException;
+
+/**
+ * A wrapper around a Doctrine\DBAL\Driver\Connection that adds features like
+ * events, transaction isolation levels, configuration, emulated transaction nesting,
+ * lazy connecting and more.
+ *
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link    www.doctrine-project.org
+ * @since   2.0
+ * @author  Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author  Jonathan Wage <jonwage@gmail.com>
+ * @author  Roman Borschel <roman@code-factory.org>
+ * @author  Konsta Vesterinen <kvesteri@cc.hut.fi>
+ * @author  Lukas Smith <smith@pooteeweet.org> (MDB2 library)
+ * @author  Benjamin Eberlei <kontakt@beberlei.de>
+ */
+class Connection implements DriverConnection
+{
+    /**
+     * Constant for transaction isolation level READ UNCOMMITTED.
+     */
+    const TRANSACTION_READ_UNCOMMITTED = 1;
+
+    /**
+     * Constant for transaction isolation level READ COMMITTED.
+     */
+    const TRANSACTION_READ_COMMITTED = 2;
+
+    /**
+     * Constant for transaction isolation level REPEATABLE READ.
+     */
+    const TRANSACTION_REPEATABLE_READ = 3;
+
+    /**
+     * Constant for transaction isolation level SERIALIZABLE.
+     */
+    const TRANSACTION_SERIALIZABLE = 4;
+
+    /**
+     * Represents an array of ints to be expanded by Doctrine SQL parsing.
+     *
+     * @var int
+     */
+    const PARAM_INT_ARRAY = 101;
+
+    /**
+     * Represents an array of strings to be expanded by Doctrine SQL parsing.
+     *
+     * @var int
+     */
+    const PARAM_STR_ARRAY = 102;
+
+    /**
+     * Offset by which PARAM_* constants are detected as arrays of the param type.
+     *
+     * @var int
+     */
+    const ARRAY_PARAM_OFFSET = 100;
+
+    /**
+     * The wrapped driver connection.
+     *
+     * @var Doctrine\DBAL\Driver\Connection
+     */
+    protected $_conn;
+
+    /**
+     * @var Doctrine\DBAL\Configuration
+     */
+    protected $_config;
+
+    /**
+     * @var Doctrine\Common\EventManager
+     */
+    protected $_eventManager;
+
+    /**
+     * @var Doctrine\DBAL\Query\ExpressionBuilder
+     */
+    protected $_expr;
+
+    /**
+     * Whether or not a connection has been established.
+     *
+     * @var boolean
+     */
+    private $_isConnected = false;
+
+    /**
+     * The transaction nesting level.
+     *
+     * @var integer
+     */
+    private $_transactionNestingLevel = 0;
+
+    /**
+     * The currently active transaction isolation level.
+     *
+     * @var integer
+     */
+    private $_transactionIsolationLevel;
+
+    /**
+     * If nested transations should use savepoints
+     *
+     * @var integer
+     */
+    private $_nestTransactionsWithSavepoints;
+
+    /**
+     * The parameters used during creation of the Connection instance.
+     *
+     * @var array
+     */
+    private $_params = array();
+
+    /**
+     * The DatabasePlatform object that provides information about the
+     * database platform used by the connection.
+     *
+     * @var Doctrine\DBAL\Platforms\AbstractPlatform
+     */
+    protected $_platform;
+
+    /**
+     * The schema manager.
+     *
+     * @var Doctrine\DBAL\Schema\SchemaManager
+     */
+    protected $_schemaManager;
+
+    /**
+     * The used DBAL driver.
+     *
+     * @var Doctrine\DBAL\Driver
+     */
+    protected $_driver;
+
+    /**
+     * Flag that indicates whether the current transaction is marked for rollback only.
+     *
+     * @var boolean
+     */
+    private $_isRollbackOnly = false;
+
+    /**
+     * Initializes a new instance of the Connection class.
+     *
+     * @param array $params  The connection parameters.
+     * @param Driver $driver
+     * @param Configuration $config
+     * @param EventManager $eventManager
+     */
+    public function __construct(array $params, Driver $driver, Configuration $config = null,
+            EventManager $eventManager = null)
+    {
+        $this->_driver = $driver;
+        $this->_params = $params;
+
+        if (isset($params['pdo'])) {
+            $this->_conn = $params['pdo'];
+            $this->_isConnected = true;
+        }
+
+        // Create default config and event manager if none given
+        if ( ! $config) {
+            $config = new Configuration();
+        }
+
+        if ( ! $eventManager) {
+            $eventManager = new EventManager();
+        }
+
+        $this->_config = $config;
+        $this->_eventManager = $eventManager;
+
+        $this->_expr = new Query\Expression\ExpressionBuilder($this);
+
+        if ( ! isset($params['platform'])) {
+            $this->_platform = $driver->getDatabasePlatform();
+        } else if ($params['platform'] instanceof Platforms\AbstractPlatform) {
+            $this->_platform = $params['platform'];
+        } else {
+            throw DBALException::invalidPlatformSpecified();
+        }
+
+        $this->_platform->setEventManager($eventManager);
+
+        $this->_transactionIsolationLevel = $this->_platform->getDefaultTransactionIsolationLevel();
+    }
+
+    /**
+     * Gets the parameters used during instantiation.
+     *
+     * @return array $params
+     */
+    public function getParams()
+    {
+        return $this->_params;
+    }
+
+    /**
+     * Gets the name of the database this Connection is connected to.
+     *
+     * @return string $database
+     */
+    public function getDatabase()
+    {
+        return $this->_driver->getDatabase($this);
+    }
+
+    /**
+     * Gets the hostname of the currently connected database.
+     *
+     * @return string
+     */
+    public function getHost()
+    {
+        return isset($this->_params['host']) ? $this->_params['host'] : null;
+    }
+
+    /**
+     * Gets the port of the currently connected database.
+     *
+     * @return mixed
+     */
+    public function getPort()
+    {
+        return isset($this->_params['port']) ? $this->_params['port'] : null;
+    }
+
+    /**
+     * Gets the username used by this connection.
+     *
+     * @return string
+     */
+    public function getUsername()
+    {
+        return isset($this->_params['user']) ? $this->_params['user'] : null;
+    }
+
+    /**
+     * Gets the password used by this connection.
+     *
+     * @return string
+     */
+    public function getPassword()
+    {
+        return isset($this->_params['password']) ? $this->_params['password'] : null;
+    }
+
+    /**
+     * Gets the DBAL driver instance.
+     *
+     * @return \Doctrine\DBAL\Driver
+     */
+    public function getDriver()
+    {
+        return $this->_driver;
+    }
+
+    /**
+     * Gets the Configuration used by the Connection.
+     *
+     * @return \Doctrine\DBAL\Configuration
+     */
+    public function getConfiguration()
+    {
+        return $this->_config;
+    }
+
+    /**
+     * Gets the EventManager used by the Connection.
+     *
+     * @return \Doctrine\Common\EventManager
+     */
+    public function getEventManager()
+    {
+        return $this->_eventManager;
+    }
+
+    /**
+     * Gets the DatabasePlatform for the connection.
+     *
+     * @return \Doctrine\DBAL\Platforms\AbstractPlatform
+     */
+    public function getDatabasePlatform()
+    {
+        return $this->_platform;
+    }
+
+    /**
+     * Gets the ExpressionBuilder for the connection.
+     *
+     * @return \Doctrine\DBAL\Query\ExpressionBuilder
+     */
+    public function getExpressionBuilder()
+    {
+        return $this->_expr;
+    }
+
+    /**
+     * Establishes the connection with the database.
+     *
+     * @return boolean TRUE if the connection was successfully established, FALSE if
+     *                 the connection is already open.
+     */
+    public function connect()
+    {
+        if ($this->_isConnected) return false;
+
+        $driverOptions = isset($this->_params['driverOptions']) ?
+                $this->_params['driverOptions'] : array();
+        $user = isset($this->_params['user']) ? $this->_params['user'] : null;
+        $password = isset($this->_params['password']) ?
+                $this->_params['password'] : null;
+
+        $this->_conn = $this->_driver->connect($this->_params, $user, $password, $driverOptions);
+        $this->_isConnected = true;
+
+        if ($this->_eventManager->hasListeners(Events::postConnect)) {
+            $eventArgs = new Event\ConnectionEventArgs($this);
+            $this->_eventManager->dispatchEvent(Events::postConnect, $eventArgs);
+        }
+
+        return true;
+    }
+
+    /**
+     * Prepares and executes an SQL query and returns the first row of the result
+     * as an associative array.
+     *
+     * @param string $statement The SQL query.
+     * @param array $params The query parameters.
+     * @return array
+     */
+    public function fetchAssoc($statement, array $params = array())
+    {
+        return $this->executeQuery($statement, $params)->fetch(PDO::FETCH_ASSOC);
+    }
+
+    /**
+     * Prepares and executes an SQL query and returns the first row of the result
+     * as a numerically indexed array.
+     *
+     * @param string $statement         sql query to be executed
+     * @param array $params             prepared statement params
+     * @return array
+     */
+    public function fetchArray($statement, array $params = array())
+    {
+        return $this->executeQuery($statement, $params)->fetch(PDO::FETCH_NUM);
+    }
+
+    /**
+     * Prepares and executes an SQL query and returns the value of a single column
+     * of the first row of the result.
+     *
+     * @param string $statement         sql query to be executed
+     * @param array $params             prepared statement params
+     * @param int $colnum               0-indexed column number to retrieve
+     * @return mixed
+     */
+    public function fetchColumn($statement, array $params = array(), $colnum = 0)
+    {
+        return $this->executeQuery($statement, $params)->fetchColumn($colnum);
+    }
+
+    /**
+     * Whether an actual connection to the database is established.
+     *
+     * @return boolean
+     */
+    public function isConnected()
+    {
+        return $this->_isConnected;
+    }
+
+    /**
+     * Checks whether a transaction is currently active.
+     *
+     * @return boolean TRUE if a transaction is currently active, FALSE otherwise.
+     */
+    public function isTransactionActive()
+    {
+        return $this->_transactionNestingLevel > 0;
+    }
+
+    /**
+     * Executes an SQL DELETE statement on a table.
+     *
+     * @param string $table The name of the table on which to delete.
+     * @param array $identifier The deletion criteria. An associateve array containing column-value pairs.
+     * @return integer The number of affected rows.
+     */
+    public function delete($tableName, array $identifier)
+    {
+        $this->connect();
+
+        $criteria = array();
+
+        foreach (array_keys($identifier) as $columnName) {
+            $criteria[] = $columnName . ' = ?';
+        }
+
+        $query = 'DELETE FROM ' . $tableName . ' WHERE ' . implode(' AND ', $criteria);
+
+        return $this->executeUpdate($query, array_values($identifier));
+    }
+
+    /**
+     * Closes the connection.
+     *
+     * @return void
+     */
+    public function close()
+    {
+        unset($this->_conn);
+
+        $this->_isConnected = false;
+    }
+
+    /**
+     * Sets the transaction isolation level.
+     *
+     * @param integer $level The level to set.
+     */
+    public function setTransactionIsolation($level)
+    {
+        $this->_transactionIsolationLevel = $level;
+
+        return $this->executeUpdate($this->_platform->getSetTransactionIsolationSQL($level));
+    }
+
+    /**
+     * Gets the currently active transaction isolation level.
+     *
+     * @return integer The current transaction isolation level.
+     */
+    public function getTransactionIsolation()
+    {
+        return $this->_transactionIsolationLevel;
+    }
+
+    /**
+     * Executes an SQL UPDATE statement on a table.
+     *
+     * @param string $table The name of the table to update.
+     * @param array $identifier The update criteria. An associative array containing column-value pairs.
+     * @param array $types Types of the merged $data and $identifier arrays in that order.
+     * @return integer The number of affected rows.
+     */
+    public function update($tableName, array $data, array $identifier, array $types = array())
+    {
+        $this->connect();
+        $set = array();
+        foreach ($data as $columnName => $value) {
+            $set[] = $columnName . ' = ?';
+        }
+
+        $params = array_merge(array_values($data), array_values($identifier));
+
+        $sql  = 'UPDATE ' . $tableName . ' SET ' . implode(', ', $set)
+                . ' WHERE ' . implode(' = ? AND ', array_keys($identifier))
+                . ' = ?';
+
+        return $this->executeUpdate($sql, $params, $types);
+    }
+
+    /**
+     * Inserts a table row with specified data.
+     *
+     * @param string $table The name of the table to insert data into.
+     * @param array $data An associative array containing column-value pairs.
+     * @param array $types Types of the inserted data.
+     * @return integer The number of affected rows.
+     */
+    public function insert($tableName, array $data, array $types = array())
+    {
+        $this->connect();
+
+        // column names are specified as array keys
+        $cols = array();
+        $placeholders = array();
+
+        foreach ($data as $columnName => $value) {
+            $cols[] = $columnName;
+            $placeholders[] = '?';
+        }
+
+        $query = 'INSERT INTO ' . $tableName
+               . ' (' . implode(', ', $cols) . ')'
+               . ' VALUES (' . implode(', ', $placeholders) . ')';
+
+        return $this->executeUpdate($query, array_values($data), $types);
+    }
+
+    /**
+     * Sets the given charset on the current connection.
+     *
+     * @param string $charset The charset to set.
+     */
+    public function setCharset($charset)
+    {
+        $this->executeUpdate($this->_platform->getSetCharsetSQL($charset));
+    }
+
+    /**
+     * Quote a string so it can be safely used as a table or column name, even if
+     * it is a reserved name.
+     *
+     * Delimiting style depends on the underlying database platform that is being used.
+     *
+     * NOTE: Just because you CAN use quoted identifiers does not mean
+     * you SHOULD use them. In general, they end up causing way more
+     * problems than they solve.
+     *
+     * @param string $str The name to be quoted.
+     * @return string The quoted name.
+     */
+    public function quoteIdentifier($str)
+    {
+        return $this->_platform->quoteIdentifier($str);
+    }
+
+    /**
+     * Quotes a given input parameter.
+     *
+     * @param mixed $input Parameter to be quoted.
+     * @param string $type Type of the parameter.
+     * @return string The quoted parameter.
+     */
+    public function quote($input, $type = null)
+    {
+        $this->connect();
+
+        list($value, $bindingType) = $this->getBindingInfo($input, $type);
+        return $this->_conn->quote($input, $bindingType);
+    }
+
+    /**
+     * Prepares and executes an SQL query and returns the result as an associative array.
+     *
+     * @param string $sql The SQL query.
+     * @param array $params The query parameters.
+     * @return array
+     */
+    public function fetchAll($sql, array $params = array())
+    {
+        return $this->executeQuery($sql, $params)->fetchAll(PDO::FETCH_ASSOC);
+    }
+
+    /**
+     * Prepares an SQL statement.
+     *
+     * @param string $statement The SQL statement to prepare.
+     * @return Doctrine\DBAL\Driver\Statement The prepared statement.
+     */
+    public function prepare($statement)
+    {
+        $this->connect();
+
+        return new Statement($statement, $this);
+    }
+
+    /**
+     * Executes an, optionally parameterized, SQL query.
+     *
+     * If the query is parameterized, a prepared statement is used.
+     * If an SQLLogger is configured, the execution is logged.
+     *
+     * @param string $query The SQL query to execute.
+     * @param array $params The parameters to bind to the query, if any.
+     * @param array $types The types the previous parameters are in.
+     * @param QueryCacheProfile $qcp
+     * @return Doctrine\DBAL\Driver\Statement The executed statement.
+     * @internal PERF: Directly prepares a driver statement, not a wrapper.
+     */
+    public function executeQuery($query, array $params = array(), $types = array(), QueryCacheProfile $qcp = null)
+    {
+        if ($qcp !== null) {
+            return $this->executeCacheQuery($query, $params, $types, $qcp);
+        }
+
+        $this->connect();
+
+        $hasLogger = $this->_config->getSQLLogger() !== null;
+        if ($hasLogger) {
+            $this->_config->getSQLLogger()->startQuery($query, $params, $types);
+        }
+
+        if ($params) {
+            list($query, $params, $types) = SQLParserUtils::expandListParameters($query, $params, $types);
+
+            $stmt = $this->_conn->prepare($query);
+            if ($types) {
+                $this->_bindTypedValues($stmt, $params, $types);
+                $stmt->execute();
+            } else {
+                $stmt->execute($params);
+            }
+        } else {
+            $stmt = $this->_conn->query($query);
+        }
+
+        if ($hasLogger) {
+            $this->_config->getSQLLogger()->stopQuery();
+        }
+
+        return $stmt;
+    }
+
+    /**
+     * Execute a caching query and
+     *
+     * @param string $query
+     * @param array $params
+     * @param array $types
+     * @param QueryCacheProfile $qcp
+     * @return \Doctrine\DBAL\Driver\ResultStatement
+     */
+    public function executeCacheQuery($query, $params, $types, QueryCacheProfile $qcp)
+    {
+        $resultCache = $qcp->getResultCacheDriver() ?: $this->_config->getResultCacheImpl();
+        if (!$resultCache) {
+            throw CacheException::noResultDriverConfigured();
+        }
+
+        list($cacheKey, $realKey) = $qcp->generateCacheKeys($query, $params, $types);
+
+        // fetch the row pointers entry
+        if ($data = $resultCache->fetch($cacheKey)) {
+            // is the real key part of this row pointers map or is the cache only pointing to other cache keys?
+            if (isset($data[$realKey])) {
+                return new ArrayStatement($data[$realKey]);
+            } else if (array_key_exists($realKey, $data)) {
+                return new ArrayStatement(array());
+            }
+        }
+        return new ResultCacheStatement($this->executeQuery($query, $params, $types), $resultCache, $cacheKey, $realKey, $qcp->getLifetime());
+    }
+
+    /**
+     * Executes an, optionally parameterized, SQL query and returns the result,
+     * applying a given projection/transformation function on each row of the result.
+     *
+     * @param string $query The SQL query to execute.
+     * @param array $params The parameters, if any.
+     * @param Closure $mapper The transformation function that is applied on each row.
+     *                        The function receives a single paramater, an array, that
+     *                        represents a row of the result set.
+     * @return mixed The projected result of the query.
+     */
+    public function project($query, array $params, Closure $function)
+    {
+        $result = array();
+        $stmt = $this->executeQuery($query, $params ?: array());
+
+        while ($row = $stmt->fetch()) {
+            $result[] = $function($row);
+        }
+
+        $stmt->closeCursor();
+
+        return $result;
+    }
+
+    /**
+     * Executes an SQL statement, returning a result set as a Statement object.
+     *
+     * @param string $statement
+     * @param integer $fetchType
+     * @return Doctrine\DBAL\Driver\Statement
+     */
+    public function query()
+    {
+        $this->connect();
+
+        $args = func_get_args();
+
+        $logger = $this->getConfiguration()->getSQLLogger();
+        if ($logger) {
+            $logger->startQuery($args[0]);
+        }
+
+        $statement = call_user_func_array(array($this->_conn, 'query'), $args);
+
+        if ($logger) {
+            $logger->stopQuery();
+        }
+
+        return $statement;
+    }
+
+    /**
+     * Executes an SQL INSERT/UPDATE/DELETE query with the given parameters
+     * and returns the number of affected rows.
+     *
+     * This method supports PDO binding types as well as DBAL mapping types.
+     *
+     * @param string $query The SQL query.
+     * @param array $params The query parameters.
+     * @param array $types The parameter types.
+     * @return integer The number of affected rows.
+     * @internal PERF: Directly prepares a driver statement, not a wrapper.
+     */
+    public function executeUpdate($query, array $params = array(), array $types = array())
+    {
+        $this->connect();
+
+        $hasLogger = $this->_config->getSQLLogger() !== null;
+        if ($hasLogger) {
+            $this->_config->getSQLLogger()->startQuery($query, $params, $types);
+        }
+
+        if ($params) {
+            list($query, $params, $types) = SQLParserUtils::expandListParameters($query, $params, $types);
+
+            $stmt = $this->_conn->prepare($query);
+            if ($types) {
+                $this->_bindTypedValues($stmt, $params, $types);
+                $stmt->execute();
+            } else {
+                $stmt->execute($params);
+            }
+            $result = $stmt->rowCount();
+        } else {
+            $result = $this->_conn->exec($query);
+        }
+
+        if ($hasLogger) {
+            $this->_config->getSQLLogger()->stopQuery();
+        }
+
+        return $result;
+    }
+
+    /**
+     * Execute an SQL statement and return the number of affected rows.
+     *
+     * @param string $statement
+     * @return integer The number of affected rows.
+     */
+    public function exec($statement)
+    {
+        $this->connect();
+        return $this->_conn->exec($statement);
+    }
+
+    /**
+     * Returns the current transaction nesting level.
+     *
+     * @return integer The nesting level. A value of 0 means there's no active transaction.
+     */
+    public function getTransactionNestingLevel()
+    {
+        return $this->_transactionNestingLevel;
+    }
+
+    /**
+     * Fetch the SQLSTATE associated with the last database operation.
+     *
+     * @return integer The last error code.
+     */
+    public function errorCode()
+    {
+        $this->connect();
+        return $this->_conn->errorCode();
+    }
+
+    /**
+     * Fetch extended error information associated with the last database operation.
+     *
+     * @return array The last error information.
+     */
+    public function errorInfo()
+    {
+        $this->connect();
+        return $this->_conn->errorInfo();
+    }
+
+    /**
+     * Returns the ID of the last inserted row, or the last value from a sequence object,
+     * depending on the underlying driver.
+     *
+     * Note: This method may not return a meaningful or consistent result across different drivers,
+     * because the underlying database may not even support the notion of AUTO_INCREMENT/IDENTITY
+     * columns or sequences.
+     *
+     * @param string $seqName Name of the sequence object from which the ID should be returned.
+     * @return string A string representation of the last inserted ID.
+     */
+    public function lastInsertId($seqName = null)
+    {
+        $this->connect();
+        return $this->_conn->lastInsertId($seqName);
+    }
+
+    /**
+     * Executes a function in a transaction.
+     *
+     * The function gets passed this Connection instance as an (optional) parameter.
+     *
+     * If an exception occurs during execution of the function or transaction commit,
+     * the transaction is rolled back and the exception re-thrown.
+     *
+     * @param Closure $func The function to execute transactionally.
+     */
+    public function transactional(Closure $func)
+    {
+        $this->beginTransaction();
+        try {
+            $func($this);
+            $this->commit();
+        } catch (Exception $e) {
+            $this->rollback();
+            throw $e;
+        }
+    }
+
+    /**
+     * Set if nested transactions should use savepoints
+     *
+     * @param boolean
+     * @return void
+     */
+    public function setNestTransactionsWithSavepoints($nestTransactionsWithSavepoints)
+    {
+        if ($this->_transactionNestingLevel > 0) {
+            throw ConnectionException::mayNotAlterNestedTransactionWithSavepointsInTransaction();
+        }
+
+        if (!$this->_platform->supportsSavepoints()) {
+            throw ConnectionException::savepointsNotSupported();
+        }
+
+        $this->_nestTransactionsWithSavepoints = $nestTransactionsWithSavepoints;
+    }
+
+    /**
+     * Get if nested transactions should use savepoints
+     *
+     * @return boolean
+     */
+    public function getNestTransactionsWithSavepoints()
+    {
+        return $this->_nestTransactionsWithSavepoints;
+    }
+
+    /**
+     * Returns the savepoint name to use for nested transactions are false if they are not supported
+     * "savepointFormat" parameter is not set
+     *
+     * @return mixed a string with the savepoint name or false
+     */
+    protected function _getNestedTransactionSavePointName()
+    {
+        return 'DOCTRINE2_SAVEPOINT_'.$this->_transactionNestingLevel;
+    }
+
+    /**
+     * Starts a transaction by suspending auto-commit mode.
+     *
+     * @return void
+     */
+    public function beginTransaction()
+    {
+        $this->connect();
+
+        ++$this->_transactionNestingLevel;
+
+        if ($this->_transactionNestingLevel == 1) {
+            $this->_conn->beginTransaction();
+        } else if ($this->_nestTransactionsWithSavepoints) {
+            $this->createSavepoint($this->_getNestedTransactionSavePointName());
+        }
+    }
+
+    /**
+     * Commits the current transaction.
+     *
+     * @return void
+     * @throws ConnectionException If the commit failed due to no active transaction or
+     *                             because the transaction was marked for rollback only.
+     */
+    public function commit()
+    {
+        if ($this->_transactionNestingLevel == 0) {
+            throw ConnectionException::noActiveTransaction();
+        }
+        if ($this->_isRollbackOnly) {
+            throw ConnectionException::commitFailedRollbackOnly();
+        }
+
+        $this->connect();
+
+        if ($this->_transactionNestingLevel == 1) {
+            $this->_conn->commit();
+        } else if ($this->_nestTransactionsWithSavepoints) {
+            $this->releaseSavepoint($this->_getNestedTransactionSavePointName());
+        }
+
+        --$this->_transactionNestingLevel;
+    }
+
+    /**
+     * Cancel any database changes done during the current transaction.
+     *
+     * this method can be listened with onPreTransactionRollback and onTransactionRollback
+     * eventlistener methods
+     *
+     * @throws ConnectionException If the rollback operation failed.
+     */
+    public function rollback()
+    {
+        if ($this->_transactionNestingLevel == 0) {
+            throw ConnectionException::noActiveTransaction();
+        }
+
+        $this->connect();
+
+        if ($this->_transactionNestingLevel == 1) {
+            $this->_transactionNestingLevel = 0;
+            $this->_conn->rollback();
+            $this->_isRollbackOnly = false;
+        } else if ($this->_nestTransactionsWithSavepoints) {
+            $this->rollbackSavepoint($this->_getNestedTransactionSavePointName());
+            --$this->_transactionNestingLevel;
+        } else {
+            $this->_isRollbackOnly = true;
+            --$this->_transactionNestingLevel;
+        }
+    }
+
+    /**
+     * createSavepoint
+     * creates a new savepoint
+     *
+     * @param string $savepoint     name of a savepoint to set
+     * @return void
+     */
+    public function createSavepoint($savepoint)
+    {
+        if (!$this->_platform->supportsSavepoints()) {
+            throw ConnectionException::savepointsNotSupported();
+        }
+
+        $this->_conn->exec($this->_platform->createSavePoint($savepoint));
+    }
+
+    /**
+     * releaseSavePoint
+     * releases given savepoint
+     *
+     * @param string $savepoint     name of a savepoint to release
+     * @return void
+     */
+    public function releaseSavepoint($savepoint)
+    {
+        if (!$this->_platform->supportsSavepoints()) {
+            throw ConnectionException::savepointsNotSupported();
+        }
+
+        if ($this->_platform->supportsReleaseSavepoints()) {
+            $this->_conn->exec($this->_platform->releaseSavePoint($savepoint));
+        }
+    }
+
+    /**
+     * rollbackSavePoint
+     * releases given savepoint
+     *
+     * @param string $savepoint     name of a savepoint to rollback to
+     * @return void
+     */
+    public function rollbackSavepoint($savepoint)
+    {
+        if (!$this->_platform->supportsSavepoints()) {
+            throw ConnectionException::savepointsNotSupported();
+        }
+
+        $this->_conn->exec($this->_platform->rollbackSavePoint($savepoint));
+    }
+
+    /**
+     * Gets the wrapped driver connection.
+     *
+     * @return Doctrine\DBAL\Driver\Connection
+     */
+    public function getWrappedConnection()
+    {
+        $this->connect();
+
+        return $this->_conn;
+    }
+
+    /**
+     * Gets the SchemaManager that can be used to inspect or change the
+     * database schema through the connection.
+     *
+     * @return Doctrine\DBAL\Schema\AbstractSchemaManager
+     */
+    public function getSchemaManager()
+    {
+        if ( ! $this->_schemaManager) {
+            $this->_schemaManager = $this->_driver->getSchemaManager($this);
+        }
+
+        return $this->_schemaManager;
+    }
+
+    /**
+     * Marks the current transaction so that the only possible
+     * outcome for the transaction to be rolled back.
+     *
+     * @throws ConnectionException If no transaction is active.
+     */
+    public function setRollbackOnly()
+    {
+        if ($this->_transactionNestingLevel == 0) {
+            throw ConnectionException::noActiveTransaction();
+        }
+        $this->_isRollbackOnly = true;
+    }
+
+    /**
+     * Check whether the current transaction is marked for rollback only.
+     *
+     * @return boolean
+     * @throws ConnectionException If no transaction is active.
+     */
+    public function isRollbackOnly()
+    {
+        if ($this->_transactionNestingLevel == 0) {
+            throw ConnectionException::noActiveTransaction();
+        }
+        return $this->_isRollbackOnly;
+    }
+
+    /**
+     * Converts a given value to its database representation according to the conversion
+     * rules of a specific DBAL mapping type.
+     *
+     * @param mixed $value The value to convert.
+     * @param string $type The name of the DBAL mapping type.
+     * @return mixed The converted value.
+     */
+    public function convertToDatabaseValue($value, $type)
+    {
+        return Type::getType($type)->convertToDatabaseValue($value, $this->_platform);
+    }
+
+    /**
+     * Converts a given value to its PHP representation according to the conversion
+     * rules of a specific DBAL mapping type.
+     *
+     * @param mixed $value The value to convert.
+     * @param string $type The name of the DBAL mapping type.
+     * @return mixed The converted type.
+     */
+    public function convertToPHPValue($value, $type)
+    {
+        return Type::getType($type)->convertToPHPValue($value, $this->_platform);
+    }
+
+    /**
+     * Binds a set of parameters, some or all of which are typed with a PDO binding type
+     * or DBAL mapping type, to a given statement.
+     *
+     * @param $stmt The statement to bind the values to.
+     * @param array $params The map/list of named/positional parameters.
+     * @param array $types The parameter types (PDO binding types or DBAL mapping types).
+     * @internal Duck-typing used on the $stmt parameter to support driver statements as well as
+     *           raw PDOStatement instances.
+     */
+    private function _bindTypedValues($stmt, array $params, array $types)
+    {
+        // Check whether parameters are positional or named. Mixing is not allowed, just like in PDO.
+        if (is_int(key($params))) {
+            // Positional parameters
+            $typeOffset = array_key_exists(0, $types) ? -1 : 0;
+            $bindIndex = 1;
+            foreach ($params as $position => $value) {
+                $typeIndex = $bindIndex + $typeOffset;
+                if (isset($types[$typeIndex])) {
+                    $type = $types[$typeIndex];
+                    list($value, $bindingType) = $this->getBindingInfo($value, $type);
+                    $stmt->bindValue($bindIndex, $value, $bindingType);
+                } else {
+                    $stmt->bindValue($bindIndex, $value);
+                }
+                ++$bindIndex;
+            }
+        } else {
+            // Named parameters
+            foreach ($params as $name => $value) {
+                if (isset($types[$name])) {
+                    $type = $types[$name];
+                    list($value, $bindingType) = $this->getBindingInfo($value, $type);
+                    $stmt->bindValue($name, $value, $bindingType);
+                } else {
+                    $stmt->bindValue($name, $value);
+                }
+            }
+        }
+    }
+
+    /**
+     * Gets the binding type of a given type. The given type can be a PDO or DBAL mapping type.
+     *
+     * @param mixed $value The value to bind
+     * @param mixed $type The type to bind (PDO or DBAL)
+     * @return array [0] => the (escaped) value, [1] => the binding type
+     */
+    private function getBindingInfo($value, $type)
+    {
+        if (is_string($type)) {
+            $type = Type::getType($type);
+        }
+        if ($type instanceof Type) {
+            $value = $type->convertToDatabaseValue($value, $this->_platform);
+            $bindingType = $type->getBindingType();
+        } else {
+            $bindingType = $type; // PDO::PARAM_* constants
+        }
+        return array($value, $bindingType);
+    }
+
+    /**
+     * Create a new instance of a SQL query builder.
+     *
+     * @return Query\QueryBuilder
+     */
+    public function createQueryBuilder()
+    {
+        return new Query\QueryBuilder($this);
+    }
+}

+ 54 - 0
main/inc/lib/symfony/Doctrine/DBAL/ConnectionException.php

@@ -0,0 +1,54 @@
+<?php
+/*
+ *  $Id: Exception.php 4628 2008-07-04 16:32:19Z romanb $
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL;
+
+/**
+ * Doctrine\DBAL\ConnectionException
+ *
+ * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link        www.doctrine-project.org
+ * @since       2.0
+ * @version     $Revision: 4628 $
+ * @author      Jonathan H. Wage <jonwage@gmail.com
+ */
+class ConnectionException extends DBALException
+{
+    public static function commitFailedRollbackOnly()
+    {
+        return new self("Transaction commit failed because the transaction has been marked for rollback only.");
+    }
+
+    public static function noActiveTransaction()
+    {
+        return new self("There is no active transaction.");
+    }
+
+    public static function savepointsNotSupported()
+    {
+        return new self("Savepoints are not supported by this driver.");
+    }
+
+    public static function mayNotAlterNestedTransactionWithSavepointsInTransaction()
+    {
+        return new self("May not alter the nested transaction with savepoints behavior while a transaction is open.");
+    }
+}

+ 328 - 0
main/inc/lib/symfony/Doctrine/DBAL/Connections/MasterSlaveConnection.php

@@ -0,0 +1,328 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Connections;
+
+
+use Doctrine\DBAL\Connection,
+    Doctrine\DBAL\Driver,
+    Doctrine\DBAL\Configuration,
+    Doctrine\Common\EventManager,
+    Doctrine\DBAL\Events;
+
+/**
+ * Master-Slave Connection
+ *
+ * Connection can be used with master-slave setups.
+ *
+ * Important for the understanding of this connection should be how and when
+ * it picks the slave or master.
+ *
+ * 1. Slave if master was never picked before and ONLY if 'getWrappedConnection'
+ *    or 'executeQuery' is used.
+ * 2. Master picked when 'exec', 'executeUpdate', 'insert', 'delete', 'update', 'createSavepoint',
+ *    'releaseSavepoint', 'beginTransaction', 'rollback', 'commit', 'query' or
+ *    'prepare' is called.
+ * 3. If master was picked once during the lifetime of the connection it will always get picked afterwards.
+ * 4. One slave connection is randomly picked ONCE during a request.
+ *
+ * ATTENTION: You can write to the slave with this connection if you execute a write query without
+ * opening up a transaction. For example:
+ *
+ *      $conn = DriverManager::getConnection(...);
+ *      $conn->executeQuery("DELETE FROM table");
+ *
+ * Be aware that Connection#executeQuery is a method specifically for READ
+ * operations only.
+ *
+ * This connection is limited to slave operations using the
+ * Connection#executeQuery operation only, because it wouldn't be compatible
+ * with the ORM or SchemaManager code otherwise. Both use all the other
+ * operations in a context where writes could happen to a slave, which makes
+ * this restricted approach necessary.
+ *
+ * You can manually connect to the master at any time by calling:
+ *
+ *      $conn->connect('master');
+ *
+ * Instantiation through the DriverManager looks like:
+ *
+ * @example
+ *
+ * $conn = DriverManager::getConnection(array(
+ *    'wrapperClass' => 'Doctrine\DBAL\Connections\MasterSlaveConnection',
+ *    'driver' => 'pdo_mysql',
+ *    'master' => array('user' => '', 'password' => '', 'host' => '', 'dbname' => ''),
+ *    'slaves' => array(
+ *        array('user' => 'slave1', 'password', 'host' => '', 'dbname' => ''),
+ *        array('user' => 'slave2', 'password', 'host' => '', 'dbname' => ''),
+ *    )
+ * ));
+ *
+ * You can also pass 'driverOptions' and any other documented option to each of this drivers to pass additional information.
+ *
+ * @author Lars Strojny <lstrojny@php.net>
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ */
+class MasterSlaveConnection extends Connection
+{
+    /**
+     * Master and slave connection (one of the randomly picked slaves)
+     *
+     * @var Doctrine\DBAL\Driver\Connection[]
+     */
+    protected $connections = array('master' => null, 'slave' => null);
+
+    /**
+     * Create Master Slave Connection
+     *
+     * @param array $params
+     * @param Driver $driver
+     * @param Configuration $config
+     * @param EventManager $eventManager
+     */
+    public function __construct(array $params, Driver $driver, Configuration $config = null, EventManager $eventManager = null)
+    {
+        if ( !isset($params['slaves']) || !isset($params['master']) ) {
+            throw new \InvalidArgumentException('master or slaves configuration missing');
+        }
+        if ( count($params['slaves']) == 0 ) {
+            throw new \InvalidArgumentException('You have to configure at least one slaves.');
+        }
+
+        $params['master']['driver'] = $params['driver'];
+        foreach ($params['slaves'] as $slaveKey => $slave) {
+            $params['slaves'][$slaveKey]['driver'] = $params['driver'];
+        }
+
+        parent::__construct($params, $driver, $config, $eventManager);
+    }
+
+    /**
+     * Check if the connection is currently towards the master or not.
+     *
+     * @return bool
+     */
+    public function isConnectedToMaster()
+    {
+        return $this->_conn !== null && $this->_conn === $this->connections['master'];
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function connect($connectionName = 'slave')
+    {
+        if ( $connectionName !== 'slave' && $connectionName !== 'master' ) {
+            throw new \InvalidArgumentException("Invalid option to connect(), only master or slave allowed.");
+        }
+
+        $forceMasterAsSlave = false;
+
+        if ($this->getTransactionNestingLevel() > 0) {
+            $connectionName = 'master';
+            $forceMasterAsSlave = true;
+        }
+
+        if ($this->connections[$connectionName]) {
+            if ($forceMasterAsSlave) {
+                $this->connections['slave'] = $this->_conn = $this->connections['master'];
+            } else {
+                $this->_conn = $this->connections[$connectionName];
+            }
+            return false;
+        }
+
+        if ($connectionName === 'master') {
+            /** Set slave connection to master to avoid invalid reads */
+            if ($this->connections['slave']) {
+                unset($this->connections['slave']);
+            }
+
+            $this->connections['master'] = $this->connections['slave'] = $this->_conn = $this->connectTo($connectionName);
+        } else {
+            $this->connections['slave'] = $this->_conn = $this->connectTo($connectionName);
+        }
+
+        if ($this->_eventManager->hasListeners(Events::postConnect)) {
+            $eventArgs = new Event\ConnectionEventArgs($this);
+            $this->_eventManager->dispatchEvent(Events::postConnect, $eventArgs);
+        }
+
+        return true;
+    }
+
+    /**
+     * Connect to a specific connection
+     *
+     * @param  string $connectionName
+     * @return Driver
+     */
+    protected function connectTo($connectionName)
+    {
+        $params = $this->getParams();
+
+        $driverOptions = isset($params['driverOptions']) ? $params['driverOptions'] : array();
+
+        $connectionParams = $this->chooseConnectionConfiguration($connectionName, $params);
+
+        $user = isset($connectionParams['user']) ? $connectionParams['user'] : null;
+        $password = isset($connectionParams['password']) ? $connectionParams['password'] : null;
+
+        return $this->_driver->connect($connectionParams, $user, $password, $driverOptions);
+    }
+
+    protected function chooseConnectionConfiguration($connectionName, $params)
+    {
+        if ($connectionName === 'master') {
+            return $params['master'];
+        }
+
+        return $params['slaves'][array_rand($params['slaves'])];
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function executeUpdate($query, array $params = array(), array $types = array())
+    {
+        $this->connect('master');
+        return parent::executeUpdate($query, $params, $types);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function beginTransaction()
+    {
+        $this->connect('master');
+        return parent::beginTransaction();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function commit()
+    {
+        $this->connect('master');
+        return parent::commit();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function rollback()
+    {
+        $this->connect('master');
+        return parent::rollback();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function delete($tableName, array $identifier)
+    {
+        $this->connect('master');
+        return parent::delete($tableName, $identifier);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function update($tableName, array $data, array $identifier, array $types = array())
+    {
+        $this->connect('master');
+        return parent::update($tableName, $data, $identifier, $types);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function insert($tableName, array $data, array $types = array())
+    {
+        $this->connect('master');
+        return parent::insert($tableName, $data, $types);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function exec($statement)
+    {
+        $this->connect('master');
+        return parent::exec($statement);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function createSavepoint($savepoint)
+    {
+        $this->connect('master');
+
+        return parent::createSavepoint($savepoint);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function releaseSavepoint($savepoint)
+    {
+        $this->connect('master');
+
+        return parent::releaseSavepoint($savepoint);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function rollbackSavepoint($savepoint)
+    {
+        $this->connect('master');
+
+        return parent::rollbackSavepoint($savepoint);
+    }
+
+    public function query()
+    {
+        $this->connect('master');
+
+        $args = func_get_args();
+
+        $logger = $this->getConfiguration()->getSQLLogger();
+        if ($logger) {
+            $logger->startQuery($args[0]);
+        }
+
+        $statement = call_user_func_array(array($this->_conn, 'query'), $args);
+
+        if ($logger) {
+            $logger->stopQuery();
+        }
+
+        return $statement;
+    }
+
+    public function prepare($statement)
+    {
+        $this->connect('master');
+
+        return parent::prepare($statement);
+    }
+}

+ 88 - 0
main/inc/lib/symfony/Doctrine/DBAL/DBALException.php

@@ -0,0 +1,88 @@
+<?php
+
+namespace Doctrine\DBAL;
+
+class DBALException extends \Exception
+{
+    public static function notSupported($method)
+    {
+        return new self("Operation '$method' is not supported by platform.");
+    }
+
+    public static function invalidPlatformSpecified()
+    {
+        return new self(
+            "Invalid 'platform' option specified, need to give an instance of ".
+            "\Doctrine\DBAL\Platforms\AbstractPlatform.");
+    }
+
+    public static function invalidPdoInstance()
+    {
+        return new self(
+            "The 'pdo' option was used in DriverManager::getConnection() but no ".
+            "instance of PDO was given."
+        );
+    }
+
+    public static function driverRequired()
+    {
+        return new self("The options 'driver' or 'driverClass' are mandatory if no PDO ".
+            "instance is given to DriverManager::getConnection().");
+    }
+
+    public static function unknownDriver($unknownDriverName, array $knownDrivers)
+    {
+        return new self("The given 'driver' ".$unknownDriverName." is unknown, ".
+            "Doctrine currently supports only the following drivers: ".implode(", ", $knownDrivers));
+    }
+
+    public static function invalidWrapperClass($wrapperClass)
+    {
+        return new self("The given 'wrapperClass' ".$wrapperClass." has to be a ".
+            "subtype of \Doctrine\DBAL\Connection.");
+    }
+
+    public static function invalidDriverClass($driverClass)
+    {
+        return new self("The given 'driverClass' ".$driverClass." has to implement the ".
+            "\Doctrine\DBAL\Driver interface.");
+    }
+
+    /**
+     * @param string $tableName
+     * @return DBALException
+     */
+    public static function invalidTableName($tableName)
+    {
+        return new self("Invalid table name specified: ".$tableName);
+    }
+
+    /**
+     * @param string $tableName
+     * @return DBALException
+     */
+    public static function noColumnsSpecifiedForTable($tableName)
+    {
+        return new self("No columns specified for table ".$tableName);
+    }
+
+    public static function limitOffsetInvalid()
+    {
+        return new self("Invalid Offset in Limit Query, it has to be larger or equal to 0.");
+    }
+
+    public static function typeExists($name)
+    {
+        return new self('Type '.$name.' already exists.');
+    }
+
+    public static function unknownColumnType($name)
+    {
+        return new self('Unknown column type '.$name.' requested.');
+    }
+
+    public static function typeNotFound($name)
+    {
+        return new self('Type to be overwritten '.$name.' does not exist.');
+    }
+}

+ 72 - 0
main/inc/lib/symfony/Doctrine/DBAL/Driver.php

@@ -0,0 +1,72 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL;
+
+/**
+ * Driver interface.
+ * Interface that all DBAL drivers must implement.
+ *
+ * @since 2.0
+ */
+interface Driver
+{
+    /**
+     * Attempts to create a connection with the database.
+     *
+     * @param array $params All connection parameters passed by the user.
+     * @param string $username The username to use when connecting.
+     * @param string $password The password to use when connecting.
+     * @param array $driverOptions The driver options to use when connecting.
+     * @return Doctrine\DBAL\Driver\Connection The database connection.
+     */
+    public function connect(array $params, $username = null, $password = null, array $driverOptions = array());
+
+    /**
+     * Gets the DatabasePlatform instance that provides all the metadata about
+     * the platform this driver connects to.
+     *
+     * @return Doctrine\DBAL\Platforms\AbstractPlatform The database platform.
+     */
+    public function getDatabasePlatform();
+
+    /**
+     * Gets the SchemaManager that can be used to inspect and change the underlying
+     * database schema of the platform this driver connects to.
+     *
+     * @param  Doctrine\DBAL\Connection $conn
+     * @return Doctrine\DBAL\SchemaManager
+     */
+    public function getSchemaManager(Connection $conn);
+
+    /**
+     * Gets the name of the driver.
+     *
+     * @return string The name of the driver.
+     */
+    public function getName();
+
+    /**
+     * Get the name of the database connected to for this driver.
+     *
+     * @param  Doctrine\DBAL\Connection $conn
+     * @return string $database
+     */
+    public function getDatabase(Connection $conn);
+}

+ 42 - 0
main/inc/lib/symfony/Doctrine/DBAL/Driver/Connection.php

@@ -0,0 +1,42 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Driver;
+
+/**
+ * Connection interface.
+ * Driver connections must implement this interface.
+ *
+ * This resembles (a subset of) the PDO interface.
+ *
+ * @since 2.0
+ */
+interface Connection
+{
+    function prepare($prepareString);
+    function query();
+    function quote($input, $type=\PDO::PARAM_STR);
+    function exec($statement);
+    function lastInsertId($name = null);
+    function beginTransaction();
+    function commit();
+    function rollBack();
+    function errorCode();
+    function errorInfo();
+}

+ 115 - 0
main/inc/lib/symfony/Doctrine/DBAL/Driver/IBMDB2/DB2Connection.php

@@ -0,0 +1,115 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+*/
+
+namespace Doctrine\DBAL\Driver\IBMDB2;
+
+class DB2Connection implements \Doctrine\DBAL\Driver\Connection
+{
+    private $_conn = null;
+
+    public function __construct(array $params, $username, $password, $driverOptions = array())
+    {
+        $isPersistant = (isset($params['persistent']) && $params['persistent'] == true);
+
+        if ($isPersistant) {
+            $this->_conn = db2_pconnect($params['dbname'], $username, $password, $driverOptions);
+        } else {
+            $this->_conn = db2_connect($params['dbname'], $username, $password, $driverOptions);
+        }
+        if (!$this->_conn) {
+            throw new DB2Exception(db2_conn_errormsg());
+        }
+    }
+
+    public function prepare($sql)
+    {
+        $stmt = @db2_prepare($this->_conn, $sql);
+        if (!$stmt) {
+            throw new DB2Exception(db2_stmt_errormsg());
+        }
+        return new DB2Statement($stmt);
+    }
+
+    public function query()
+    {
+        $args = func_get_args();
+        $sql = $args[0];
+        $stmt = $this->prepare($sql);
+        $stmt->execute();
+        return $stmt;
+    }
+
+    public function quote($input, $type=\PDO::PARAM_STR)
+    {
+        $input = db2_escape_string($input);
+        if ($type == \PDO::PARAM_INT ) {
+            return $input;
+        } else {
+            return "'".$input."'";
+        }
+    }
+
+    public function exec($statement)
+    {
+        $stmt = $this->prepare($statement);
+        $stmt->execute();
+        return $stmt->rowCount();
+    }
+
+    public function lastInsertId($name = null)
+    {
+        return db2_last_insert_id($this->_conn);
+    }
+
+    public function beginTransaction()
+    {
+        db2_autocommit($this->_conn, DB2_AUTOCOMMIT_OFF);
+    }
+
+    public function commit()
+    {
+        if (!db2_commit($this->_conn)) {
+            throw new DB2Exception(db2_conn_errormsg($this->_conn));
+        }
+        db2_autocommit($this->_conn, DB2_AUTOCOMMIT_ON);
+    }
+
+    public function rollBack()
+    {
+        if (!db2_rollback($this->_conn)) {
+            throw new DB2Exception(db2_conn_errormsg($this->_conn));
+        }
+        db2_autocommit($this->_conn, DB2_AUTOCOMMIT_ON);
+    }
+
+    public function errorCode()
+    {
+        return db2_conn_error($this->_conn);
+    }
+
+    public function errorInfo()
+    {
+        return array(
+            0 => db2_conn_errormsg($this->_conn),
+            1 => $this->errorCode(),
+        );
+    }
+}

+ 111 - 0
main/inc/lib/symfony/Doctrine/DBAL/Driver/IBMDB2/DB2Driver.php

@@ -0,0 +1,111 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+*/
+
+namespace Doctrine\DBAL\Driver\IBMDB2;
+
+use Doctrine\DBAL\Driver,
+    Doctrine\DBAL\Connection;
+
+/**
+ * IBM DB2 Driver
+ *
+ * @since 2.0
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ */
+class DB2Driver implements Driver
+{
+    /**
+     * Attempts to create a connection with the database.
+     *
+     * @param array $params All connection parameters passed by the user.
+     * @param string $username The username to use when connecting.
+     * @param string $password The password to use when connecting.
+     * @param array $driverOptions The driver options to use when connecting.
+     * @return Doctrine\DBAL\Driver\Connection The database connection.
+     */
+    public function connect(array $params, $username = null, $password = null, array $driverOptions = array())
+    {
+        if ( ! isset($params['protocol'])) {
+            $params['protocol'] = 'TCPIP';
+        }
+
+        if ($params['host'] !== 'localhost' && $params['host'] != '127.0.0.1') {
+            // if the host isn't localhost, use extended connection params
+            $params['dbname'] = 'DRIVER={IBM DB2 ODBC DRIVER}' .
+                     ';DATABASE=' . $params['dbname'] .
+                     ';HOSTNAME=' . $params['host'] .
+                     ';PROTOCOL=' . $params['protocol'] .
+                     ';UID='      . $username .
+                     ';PWD='      . $password .';';
+            if (isset($params['port'])) {
+                $params['dbname'] .= 'PORT=' . $params['port'];
+            }
+
+            $username = null;
+            $password = null;
+        }
+
+        return new DB2Connection($params, $username, $password, $driverOptions);
+    }
+
+    /**
+     * Gets the DatabasePlatform instance that provides all the metadata about
+     * the platform this driver connects to.
+     *
+     * @return Doctrine\DBAL\Platforms\AbstractPlatform The database platform.
+     */
+    public function getDatabasePlatform()
+    {
+        return new \Doctrine\DBAL\Platforms\DB2Platform;
+    }
+
+    /**
+     * Gets the SchemaManager that can be used to inspect and change the underlying
+     * database schema of the platform this driver connects to.
+     *
+     * @param  Doctrine\DBAL\Connection $conn
+     * @return Doctrine\DBAL\SchemaManager
+     */
+    public function getSchemaManager(Connection $conn)
+    {
+        return new \Doctrine\DBAL\Schema\DB2SchemaManager($conn);
+    }
+
+    /**
+     * Gets the name of the driver.
+     *
+     * @return string The name of the driver.
+     */
+    public function getName()
+    {
+        return 'ibm_db2';
+    }
+
+    /**
+     * Get the name of the database connected to for this driver.
+     *
+     * @param  Doctrine\DBAL\Connection $conn
+     * @return string $database
+     */
+    public function getDatabase(\Doctrine\DBAL\Connection $conn)
+    {
+        $params = $conn->getParams();
+        return $params['dbname'];
+    }
+}

+ 27 - 0
main/inc/lib/symfony/Doctrine/DBAL/Driver/IBMDB2/DB2Exception.php

@@ -0,0 +1,27 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+*/
+
+namespace Doctrine\DBAL\Driver\IBMDB2;
+
+class DB2Exception extends \Exception
+{
+
+}

+ 215 - 0
main/inc/lib/symfony/Doctrine/DBAL/Driver/IBMDB2/DB2Statement.php

@@ -0,0 +1,215 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+*/
+
+namespace Doctrine\DBAL\Driver\IBMDB2;
+
+use \Doctrine\DBAL\Driver\Statement;
+
+class DB2Statement implements \IteratorAggregate, Statement
+{
+    private $_stmt = null;
+
+    private $_bindParam = array();
+
+    private $_defaultFetchStyle = \PDO::FETCH_BOTH;
+
+    /**
+     * DB2_BINARY, DB2_CHAR, DB2_DOUBLE, or DB2_LONG
+     * @var array
+     */
+    static private $_typeMap = array(
+        \PDO::PARAM_INT => DB2_LONG,
+        \PDO::PARAM_STR => DB2_CHAR,
+    );
+
+    public function __construct($stmt)
+    {
+        $this->_stmt = $stmt;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function bindValue($param, $value, $type = null)
+    {
+        return $this->bindParam($param, $value, $type);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function bindParam($column, &$variable, $type = null)
+    {
+        $this->_bindParam[$column] =& $variable;
+
+        if ($type && isset(self::$_typeMap[$type])) {
+            $type = self::$_typeMap[$type];
+        } else {
+            $type = DB2_CHAR;
+        }
+
+        if (!db2_bind_param($this->_stmt, $column, "variable", DB2_PARAM_IN, $type)) {
+            throw new DB2Exception(db2_stmt_errormsg());
+        }
+        return true;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function closeCursor()
+    {
+        if (!$this->_stmt) {
+            return false;
+        }
+
+        $this->_bindParam = array();
+        db2_free_result($this->_stmt);
+        $ret = db2_free_stmt($this->_stmt);
+        $this->_stmt = false;
+        return $ret;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function columnCount()
+    {
+        if (!$this->_stmt) {
+            return false;
+        }
+        return db2_num_fields($this->_stmt);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function errorCode()
+    {
+        return db2_stmt_error();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function errorInfo()
+    {
+        return array(
+            0 => db2_stmt_errormsg(),
+            1 => db2_stmt_error(),
+        );
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function execute($params = null)
+    {
+        if (!$this->_stmt) {
+            return false;
+        }
+
+        /*$retval = true;
+        if ($params !== null) {
+            $retval = @db2_execute($this->_stmt, $params);
+        } else {
+            $retval = @db2_execute($this->_stmt);
+        }*/
+        if ($params === null) {
+            ksort($this->_bindParam);
+            $params = array_values($this->_bindParam);
+        }
+        $retval = @db2_execute($this->_stmt, $params);
+
+        if ($retval === false) {
+            throw new DB2Exception(db2_stmt_errormsg());
+        }
+        return $retval;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function setFetchMode($fetchStyle = \PDO::FETCH_BOTH)
+    {
+        $this->_defaultFetchStyle = $fetchStyle;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getIterator()
+    {
+        $data = $this->fetchAll($this->_defaultFetchStyle);
+        return new \ArrayIterator($data);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function fetch($fetchStyle = null)
+    {
+        $fetchStyle = $fetchStyle ?: $this->_defaultFetchStyle;
+        switch ($fetchStyle) {
+            case \PDO::FETCH_BOTH:
+                return db2_fetch_both($this->_stmt);
+            case \PDO::FETCH_ASSOC:
+                return db2_fetch_assoc($this->_stmt);
+            case \PDO::FETCH_NUM:
+                return db2_fetch_array($this->_stmt);
+            default:
+                throw new DB2Exception("Given Fetch-Style " . $fetchStyle . " is not supported.");
+        }
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function fetchAll($fetchStyle = null)
+    {
+        $fetchStyle = $fetchStyle ?: $this->_defaultFetchStyle;
+        $rows = array();
+        while ($row = $this->fetch($fetchStyle)) {
+            $rows[] = $row;
+        }
+        return $rows;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function fetchColumn($columnIndex = 0)
+    {
+        $row = $this->fetch(\PDO::FETCH_NUM);
+        if ($row && isset($row[$columnIndex])) {
+            return $row[$columnIndex];
+        }
+        return false;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function rowCount()
+    {
+        return (@db2_num_rows($this->_stmt))?:0;
+    }
+}

+ 69 - 0
main/inc/lib/symfony/Doctrine/DBAL/Driver/Mysqli/Driver.php

@@ -0,0 +1,69 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Driver\Mysqli;
+
+use Doctrine\DBAL\Driver as DriverInterface;
+
+/**
+ * @author Kim Hemsø Rasmussen <kimhemsoe@gmail.com>
+ */
+class Driver implements DriverInterface
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function connect(array $params, $username = null, $password = null, array $driverOptions = array())
+    {
+        return new MysqliConnection($params, $username, $password, $driverOptions);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getName()
+    {
+        return 'mysqli';
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getSchemaManager(\Doctrine\DBAL\Connection $conn)
+    {
+        return new \Doctrine\DBAL\Schema\MySqlSchemaManager($conn);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getDatabasePlatform()
+    {
+        return new \Doctrine\DBAL\Platforms\MySqlPlatform();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getDatabase(\Doctrine\DBAL\Connection $conn)
+    {
+        $params = $conn->getParams();
+        return $params['dbname'];
+    }
+}

+ 146 - 0
main/inc/lib/symfony/Doctrine/DBAL/Driver/Mysqli/MysqliConnection.php

@@ -0,0 +1,146 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Driver\Mysqli;
+
+use Doctrine\DBAL\Driver\Connection as Connection;
+
+/**
+ * @author Kim Hemsø Rasmussen <kimhemsoe@gmail.com>
+ */
+class MysqliConnection implements Connection
+{
+    /**
+     * @var \mysqli
+     */
+    private $_conn;
+
+    public function __construct(array $params, $username, $password, array $driverOptions = array())
+    {
+        $port = isset($params['port']) ? $params['port'] : ini_get('mysqli.default_port');
+        $socket = isset($params['unix_socket']) ? $params['unix_socket'] : ini_get('mysqli.default_socket');
+
+        $this->_conn = mysqli_init();
+        if (!$this->_conn->real_connect($params['host'], $username, $password, $params['dbname'], $port, $socket)) {
+            throw new MysqliException($this->_conn->connect_error, $this->_conn->connect_errno);
+        }
+
+        if (isset($params['charset'])) {
+            $this->_conn->set_charset($params['charset']);
+        }
+    }
+
+    /**
+     * Retrieve mysqli native resource handle.
+     *
+     * Could be used if part of your application is not using DBAL
+     *
+     * @return mysqli
+     */
+    public function getWrappedResourceHandle()
+    {
+        return $this->_conn;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function prepare($prepareString)
+    {
+        return new MysqliStatement($this->_conn, $prepareString);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function query()
+    {
+        $args = func_get_args();
+        $sql = $args[0];
+        $stmt = $this->prepare($sql);
+        $stmt->execute();
+        return $stmt;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function quote($input, $type=\PDO::PARAM_STR)
+    {
+        return "'". $this->_conn->escape_string($input) ."'";
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function exec($statement)
+    {
+        $this->_conn->query($statement);
+        return $this->_conn->affected_rows;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function lastInsertId($name = null)
+    {
+        return $this->_conn->insert_id;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function beginTransaction()
+    {
+        $this->_conn->query('START TRANSACTION');
+        return true;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function commit()
+    {
+        return $this->_conn->commit();
+    }
+
+    /**
+     * {@inheritdoc}non-PHPdoc)
+     */
+    public function rollBack()
+    {
+        return $this->_conn->rollback();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function errorCode()
+    {
+        return $this->_conn->errno;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function errorInfo()
+    {
+        return $this->_conn->error;
+    }
+}

+ 26 - 0
main/inc/lib/symfony/Doctrine/DBAL/Driver/Mysqli/MysqliException.php

@@ -0,0 +1,26 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+*/
+
+namespace Doctrine\DBAL\Driver\Mysqli;
+
+/**
+ * @author Kim Hemsø Rasmussen <kimhemsoe@gmail.com>
+ */
+class MysqliException extends \Exception
+{}

+ 335 - 0
main/inc/lib/symfony/Doctrine/DBAL/Driver/Mysqli/MysqliStatement.php

@@ -0,0 +1,335 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Driver\Mysqli;
+
+use Doctrine\DBAL\Driver\Statement;
+use PDO;
+
+/**
+ * @author Kim Hemsø Rasmussen <kimhemsoe@gmail.com>
+ */
+class MysqliStatement implements \IteratorAggregate, Statement
+{
+    protected static $_paramTypeMap = array(
+        PDO::PARAM_STR => 's',
+        PDO::PARAM_BOOL => 'i',
+        PDO::PARAM_NULL => 's',
+        PDO::PARAM_INT => 'i',
+        PDO::PARAM_LOB => 's' // TODO Support LOB bigger then max package size.
+    );
+
+    protected $_conn;
+    protected $_stmt;
+
+    /**
+     * @var null|false|array
+     */
+    protected $_columnNames;
+
+    /**
+     * @var null|array
+     */
+    protected $_rowBindedValues;
+
+    /**
+     * @var array
+     */
+    protected $_bindedValues;
+
+    /**
+     * Contains ref values for bindValue()
+     *
+     * @var array
+     */
+    protected $_values = array();
+
+    protected $_defaultFetchStyle = PDO::FETCH_BOTH;
+
+    public function __construct(\mysqli $conn, $prepareString)
+    {
+        $this->_conn = $conn;
+        $this->_stmt = $conn->prepare($prepareString);
+        if (false === $this->_stmt) {
+            throw new MysqliException($this->_conn->error, $this->_conn->errno);
+        }
+
+        $paramCount = $this->_stmt->param_count;
+        if (0 < $paramCount) {
+            // Index 0 is types
+            // Need to init the string else php think we are trying to access it as a array.
+            $bindedValues = array(0 => str_repeat('s', $paramCount));
+            $null = null;
+            for ($i = 1; $i < $paramCount; $i++) {
+                $bindedValues[] =& $null;
+            }
+            $this->_bindedValues = $bindedValues;
+        }
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function bindParam($column, &$variable, $type = null)
+    {
+        if (null === $type) {
+            $type = 's';
+        } else {
+            if (isset(self::$_paramTypeMap[$type])) {
+                $type = self::$_paramTypeMap[$type];
+            } else {
+                throw new MysqliException("Unkown type: '{$type}'");
+            }
+        }
+
+        $this->_bindedValues[$column] =& $variable;
+        $this->_bindedValues[0][$column - 1] = 's';
+        return true;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function bindValue($param, $value, $type = null)
+    {
+        if (null === $type) {
+            $type = 's';
+        } else {
+            if (isset(self::$_paramTypeMap[$type])) {
+                $type = self::$_paramTypeMap[$type];
+            } else {
+                throw new MysqliException("Unknown type: '{$type}'");
+            }
+        }
+
+        $this->_values[$param] = $value;
+        $this->_bindedValues[$param] =& $this->_values[$param];
+        $this->_bindedValues[0][$param - 1] = 's';
+        return true;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function execute($params = null)
+    {
+        if (null !== $this->_bindedValues) {
+            if (null !== $params) {
+                if (!$this->_bindValues($params)) {
+                    throw new MysqliException($this->_stmt->error, $this->_stmt->errno);
+                }
+            } else {
+                if (!call_user_func_array(array($this->_stmt, 'bind_param'), $this->_bindedValues)) {
+                    throw new MysqliException($this->_stmt->error, $this->_stmt->errno);
+                }
+            }
+        }
+
+        if (!$this->_stmt->execute()) {
+            throw new MysqliException($this->_stmt->error, $this->_stmt->errno);
+        }
+
+        if (null === $this->_columnNames) {
+            $meta = $this->_stmt->result_metadata();
+            if (false !== $meta) {
+                $columnNames = array();
+                foreach ($meta->fetch_fields() as $col) {
+                    $columnNames[] = $col->name;
+                }
+                $meta->free();
+
+                $this->_columnNames = $columnNames;
+                $this->_rowBindedValues = array_fill(0, count($columnNames), NULL);
+
+                $refs = array();
+                foreach ($this->_rowBindedValues as $key => &$value) {
+                    $refs[$key] =& $value;
+                }
+
+                if (!call_user_func_array(array($this->_stmt, 'bind_result'), $refs)) {
+                    throw new MysqliException($this->_stmt->error, $this->_stmt->errno);
+                }
+            } else {
+                $this->_columnNames = false;
+            }
+        }
+
+        // We have a result.
+        if (false !== $this->_columnNames) {
+            $this->_stmt->store_result();
+        }
+        return true;
+    }
+
+    /**
+     * Bind a array of values to bound parameters
+     *
+     * @param array $values
+     * @return boolean
+     */
+    private function _bindValues($values)
+    {
+        $params = array();
+        $types = str_repeat('s', count($values));
+        $params[0] = $types;
+
+        foreach ($values as &$v) {
+            $params[] =& $v;
+        }
+        return call_user_func_array(array($this->_stmt, 'bind_param'), $params);
+    }
+
+    /**
+     * @return null|false|array
+     */
+    private function _fetch()
+    {
+        $ret = $this->_stmt->fetch();
+
+        if (true === $ret) {
+            $values = array();
+            foreach ($this->_rowBindedValues as $v) {
+                // Mysqli converts them to a scalar type it can fit in.
+                $values[] = null === $v ? null : (string)$v;
+            }
+            return $values;
+        }
+        return $ret;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function fetch($fetchStyle = null)
+    {
+        $values = $this->_fetch();
+        if (null === $values) {
+            return null;
+        }
+
+        if (false === $values) {
+            throw new MysqliException($this->_stmt->error, $this->_stmt->errno);
+        }
+
+        $fetchStyle = $fetchStyle ?: $this->_defaultFetchStyle;
+
+        switch ($fetchStyle) {
+            case PDO::FETCH_NUM:
+                return $values;
+
+            case PDO::FETCH_ASSOC:
+                return array_combine($this->_columnNames, $values);
+
+            case PDO::FETCH_BOTH:
+                $ret = array_combine($this->_columnNames, $values);
+                $ret += $values;
+                return $ret;
+
+            default:
+                throw new MysqliException("Unknown fetch type '{$fetchStyle}'");
+        }
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function fetchAll($fetchStyle = null)
+    {
+        $fetchStyle = $fetchStyle ?: $this->_defaultFetchStyle;
+
+        $a = array();
+        while (($row = $this->fetch($fetchStyle)) !== null) {
+            $a[] = $row;
+        }
+        return $a;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function fetchColumn($columnIndex = 0)
+    {
+        $row = $this->fetch(PDO::FETCH_NUM);
+        if (null === $row) {
+            return null;
+        }
+        return $row[$columnIndex];
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function errorCode()
+    {
+        return $this->_stmt->errno;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function errorInfo()
+    {
+        return $this->_stmt->error;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function closeCursor()
+    {
+        $this->_stmt->free_result();
+        return true;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function rowCount()
+    {
+        if (false === $this->_columnNames) {
+            return $this->_stmt->affected_rows;
+        }
+        return $this->_stmt->num_rows;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function columnCount()
+    {
+        return $this->_stmt->field_count;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function setFetchMode($fetchMode = PDO::FETCH_BOTH)
+    {
+        $this->_defaultFetchStyle = $fetchMode;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getIterator()
+    {
+        $data = $this->fetchAll($this->_defaultFetchStyle);
+        return new \ArrayIterator($data);
+    }
+}

+ 95 - 0
main/inc/lib/symfony/Doctrine/DBAL/Driver/OCI8/Driver.php

@@ -0,0 +1,95 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Driver\OCI8;
+
+use Doctrine\DBAL\Platforms;
+
+/**
+ * A Doctrine DBAL driver for the Oracle OCI8 PHP extensions.
+ *
+ * @author Roman Borschel <roman@code-factory.org>
+ * @since 2.0
+ */
+class Driver implements \Doctrine\DBAL\Driver
+{
+    public function connect(array $params, $username = null, $password = null, array $driverOptions = array())
+    {
+        return new OCI8Connection(
+            $username,
+            $password,
+            $this->_constructDsn($params),
+            isset($params['charset']) ? $params['charset'] : null,
+            isset($params['sessionMode']) ? $params['sessionMode'] : OCI_DEFAULT
+        );
+    }
+
+    /**
+     * Constructs the Oracle DSN.
+     *
+     * @return string The DSN.
+     */
+    protected function _constructDsn(array $params)
+    {
+        $dsn = '';
+        if (isset($params['host']) && $params['host'] != '') {
+            $dsn .= '(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)' .
+                   '(HOST=' . $params['host'] . ')';
+
+            if (isset($params['port'])) {
+                $dsn .= '(PORT=' . $params['port'] . ')';
+            } else {
+                $dsn .= '(PORT=1521)';
+            }
+
+            if (isset($params['service']) && $params['service'] == true) {
+                $dsn .= '))(CONNECT_DATA=(SERVICE_NAME=' . $params['dbname'] . ')))';
+            } else {
+                $dsn .= '))(CONNECT_DATA=(SID=' . $params['dbname'] . ')))';
+            }
+        } else {
+            $dsn .= $params['dbname'];
+        }
+
+        return $dsn;
+    }
+
+    public function getDatabasePlatform()
+    {
+        return new \Doctrine\DBAL\Platforms\OraclePlatform();
+    }
+
+    public function getSchemaManager(\Doctrine\DBAL\Connection $conn)
+    {
+        return new \Doctrine\DBAL\Schema\OracleSchemaManager($conn);
+    }
+
+    public function getName()
+    {
+        return 'oci8';
+    }
+
+    public function getDatabase(\Doctrine\DBAL\Connection $conn)
+    {
+        $params = $conn->getParams();
+        return $params['user'];
+    }
+}

+ 164 - 0
main/inc/lib/symfony/Doctrine/DBAL/Driver/OCI8/OCI8Connection.php

@@ -0,0 +1,164 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Driver\OCI8;
+
+/**
+ * OCI8 implementation of the Connection interface.
+ *
+ * @since 2.0
+ */
+class OCI8Connection implements \Doctrine\DBAL\Driver\Connection
+{
+    protected $_dbh;
+
+    protected $_executeMode = OCI_COMMIT_ON_SUCCESS;
+
+    /**
+     * Create a Connection to an Oracle Database using oci8 extension.
+     *
+     * @param string $username
+     * @param string $password
+     * @param string $db
+     */
+    public function __construct($username, $password, $db, $charset = null, $sessionMode = OCI_DEFAULT)
+    {
+        if (!defined('OCI_NO_AUTO_COMMIT')) {
+            define('OCI_NO_AUTO_COMMIT', 0);
+        }
+
+        $this->_dbh = @oci_connect($username, $password, $db, $charset, $sessionMode);
+        if (!$this->_dbh) {
+            throw OCI8Exception::fromErrorInfo(oci_error());
+        }
+    }
+
+    /**
+     * Create a non-executed prepared statement.
+     *
+     * @param  string $prepareString
+     * @return OCI8Statement
+     */
+    public function prepare($prepareString)
+    {
+        return new OCI8Statement($this->_dbh, $prepareString, $this->_executeMode);
+    }
+
+    /**
+     * @param string $sql
+     * @return OCI8Statement
+     */
+    public function query()
+    {
+        $args = func_get_args();
+        $sql = $args[0];
+        //$fetchMode = $args[1];
+        $stmt = $this->prepare($sql);
+        $stmt->execute();
+        return $stmt;
+    }
+
+    /**
+     * Quote input value.
+     *
+     * @param mixed $input
+     * @param int $type PDO::PARAM*
+     * @return mixed
+     */
+    public function quote($value, $type=\PDO::PARAM_STR)
+    {
+        if (is_int($value) || is_float($value)) {
+            return $value;
+        }
+        $value = str_replace("'", "''", $value);
+        return "'" . addcslashes($value, "\000\n\r\\\032") . "'";
+    }
+
+    /**
+     *
+     * @param  string $statement
+     * @return int
+     */
+    public function exec($statement)
+    {
+        $stmt = $this->prepare($statement);
+        $stmt->execute();
+        return $stmt->rowCount();
+    }
+
+    public function lastInsertId($name = null)
+    {
+        //TODO: throw exception or support sequences?
+    }
+
+    /**
+     * Start a transactiom
+     *
+     * Oracle has to explicitly set the autocommit mode off. That means
+     * after connection, a commit or rollback there is always automatically
+     * opened a new transaction.
+     *
+     * @return bool
+     */
+    public function beginTransaction()
+    {
+        $this->_executeMode = OCI_NO_AUTO_COMMIT;
+        return true;
+    }
+
+    /**
+     * @throws OCI8Exception
+     * @return bool
+     */
+    public function commit()
+    {
+        if (!oci_commit($this->_dbh)) {
+            throw OCI8Exception::fromErrorInfo($this->errorInfo());
+        }
+        $this->_executeMode = OCI_COMMIT_ON_SUCCESS;
+        return true;
+    }
+
+    /**
+     * @throws OCI8Exception
+     * @return bool
+     */
+    public function rollBack()
+    {
+        if (!oci_rollback($this->_dbh)) {
+            throw OCI8Exception::fromErrorInfo($this->errorInfo());
+        }
+        $this->_executeMode = OCI_COMMIT_ON_SUCCESS;
+        return true;
+    }
+
+    public function errorCode()
+    {
+        $error = oci_error($this->_dbh);
+        if ($error !== false) {
+            $error = $error['code'];
+        }
+        return $error;
+    }
+
+    public function errorInfo()
+    {
+        return oci_error($this->_dbh);
+    }
+}

+ 30 - 0
main/inc/lib/symfony/Doctrine/DBAL/Driver/OCI8/OCI8Exception.php

@@ -0,0 +1,30 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+*/
+
+namespace Doctrine\DBAL\Driver\OCI8;
+
+class OCI8Exception extends \Exception
+{
+    static public function fromErrorInfo($error)
+    {
+        return new self($error['message'], $error['code']);
+    }
+}

+ 252 - 0
main/inc/lib/symfony/Doctrine/DBAL/Driver/OCI8/OCI8Statement.php

@@ -0,0 +1,252 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Driver\OCI8;
+
+use PDO;
+use IteratorAggregate;
+use Doctrine\DBAL\Driver\Statement;
+
+/**
+ * The OCI8 implementation of the Statement interface.
+ *
+ * @since 2.0
+ * @author Roman Borschel <roman@code-factory.org>
+ */
+class OCI8Statement implements \IteratorAggregate, Statement
+{
+    /** Statement handle. */
+    protected $_dbh;
+    protected $_sth;
+    protected $_executeMode;
+    protected static $_PARAM = ':param';
+    protected static $fetchStyleMap = array(
+        PDO::FETCH_BOTH => OCI_BOTH,
+        PDO::FETCH_ASSOC => OCI_ASSOC,
+        PDO::FETCH_NUM => OCI_NUM,
+        PDO::PARAM_LOB => OCI_B_BLOB,
+    );
+    protected $_defaultFetchStyle = PDO::FETCH_BOTH;
+    protected $_paramMap = array();
+
+    /**
+     * Creates a new OCI8Statement that uses the given connection handle and SQL statement.
+     *
+     * @param resource $dbh The connection handle.
+     * @param string $statement The SQL statement.
+     */
+    public function __construct($dbh, $statement, $executeMode)
+    {
+        list($statement, $paramMap) = self::convertPositionalToNamedPlaceholders($statement);
+        $this->_sth = oci_parse($dbh, $statement);
+        $this->_dbh = $dbh;
+        $this->_paramMap = $paramMap;
+        $this->_executeMode = $executeMode;
+    }
+
+    /**
+     * Convert positional (?) into named placeholders (:param<num>)
+     *
+     * Oracle does not support positional parameters, hence this method converts all
+     * positional parameters into artificially named parameters. Note that this conversion
+     * is not perfect. All question marks (?) in the original statement are treated as
+     * placeholders and converted to a named parameter.
+     *
+     * The algorithm uses a state machine with two possible states: InLiteral and NotInLiteral.
+     * Question marks inside literal strings are therefore handled correctly by this method.
+     * This comes at a cost, the whole sql statement has to be looped over.
+     *
+     * @todo extract into utility class in Doctrine\DBAL\Util namespace
+     * @todo review and test for lost spaces. we experienced missing spaces with oci8 in some sql statements.
+     * @param string $statement The SQL statement to convert.
+     * @return string
+     */
+    static public function convertPositionalToNamedPlaceholders($statement)
+    {
+        $count = 1;
+        $inLiteral = false; // a valid query never starts with quotes
+        $stmtLen = strlen($statement);
+        $paramMap = array();
+        for ($i = 0; $i < $stmtLen; $i++) {
+            if ($statement[$i] == '?' && !$inLiteral) {
+                // real positional parameter detected
+                $paramMap[$count] = ":param$count";
+                $len = strlen($paramMap[$count]);
+                $statement = substr_replace($statement, ":param$count", $i, 1);
+                $i += $len-1; // jump ahead
+                $stmtLen = strlen($statement); // adjust statement length
+                ++$count;
+            } else if ($statement[$i] == "'" || $statement[$i] == '"') {
+                $inLiteral = ! $inLiteral; // switch state!
+            }
+        }
+
+        return array($statement, $paramMap);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function bindValue($param, $value, $type = null)
+    {
+        return $this->bindParam($param, $value, $type);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function bindParam($column, &$variable, $type = null)
+    {
+        $column = isset($this->_paramMap[$column]) ? $this->_paramMap[$column] : $column;
+
+        if ($type == \PDO::PARAM_LOB) {
+            $lob = oci_new_descriptor($this->_dbh, OCI_D_LOB);
+            $lob->writeTemporary($variable, OCI_TEMP_BLOB);
+
+            return oci_bind_by_name($this->_sth, $column, $lob, -1, OCI_B_BLOB);
+        } else {
+            return oci_bind_by_name($this->_sth, $column, $variable);
+        }
+    }
+
+    /**
+     * Closes the cursor, enabling the statement to be executed again.
+     *
+     * @return boolean              Returns TRUE on success or FALSE on failure.
+     */
+    public function closeCursor()
+    {
+        return oci_free_statement($this->_sth);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function columnCount()
+    {
+        return oci_num_fields($this->_sth);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function errorCode()
+    {
+        $error = oci_error($this->_sth);
+        if ($error !== false) {
+            $error = $error['code'];
+        }
+        return $error;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function errorInfo()
+    {
+        return oci_error($this->_sth);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function execute($params = null)
+    {
+        if ($params) {
+            $hasZeroIndex = array_key_exists(0, $params);
+            foreach ($params as $key => $val) {
+                if ($hasZeroIndex && is_numeric($key)) {
+                    $this->bindValue($key + 1, $val);
+                } else {
+                    $this->bindValue($key, $val);
+                }
+            }
+        }
+
+        $ret = @oci_execute($this->_sth, $this->_executeMode);
+        if ( ! $ret) {
+            throw OCI8Exception::fromErrorInfo($this->errorInfo());
+        }
+        return $ret;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function setFetchMode($fetchStyle = PDO::FETCH_BOTH)
+    {
+        $this->_defaultFetchStyle = $fetchStyle;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getIterator()
+    {
+        $data = $this->fetchAll($this->_defaultFetchStyle);
+        return new \ArrayIterator($data);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function fetch($fetchStyle = null)
+    {
+        $fetchStyle = $fetchStyle ?: $this->_defaultFetchStyle;
+        if ( ! isset(self::$fetchStyleMap[$fetchStyle])) {
+            throw new \InvalidArgumentException("Invalid fetch style: " . $fetchStyle);
+        }
+
+        return oci_fetch_array($this->_sth, self::$fetchStyleMap[$fetchStyle] | OCI_RETURN_NULLS | OCI_RETURN_LOBS);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function fetchAll($fetchStyle = null)
+    {
+        $fetchStyle = $fetchStyle ?: $this->_defaultFetchStyle;
+        if ( ! isset(self::$fetchStyleMap[$fetchStyle])) {
+            throw new \InvalidArgumentException("Invalid fetch style: " . $fetchStyle);
+        }
+
+        $result = array();
+        oci_fetch_all($this->_sth, $result, 0, -1,
+            self::$fetchStyleMap[$fetchStyle] | OCI_RETURN_NULLS | OCI_FETCHSTATEMENT_BY_ROW | OCI_RETURN_LOBS);
+
+        return $result;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function fetchColumn($columnIndex = 0)
+    {
+        $row = oci_fetch_array($this->_sth, OCI_NUM | OCI_RETURN_NULLS | OCI_RETURN_LOBS);
+        return $row[$columnIndex];
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function rowCount()
+    {
+        return oci_num_rows($this->_sth);
+    }
+}

+ 40 - 0
main/inc/lib/symfony/Doctrine/DBAL/Driver/PDOConnection.php

@@ -0,0 +1,40 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Driver;
+
+use \PDO;
+
+/**
+ * PDO implementation of the Connection interface.
+ * Used by all PDO-based drivers.
+ *
+ * @since 2.0
+ */
+class PDOConnection extends PDO implements Connection
+{
+    public function __construct($dsn, $user = null, $password = null, array $options = null)
+    {
+        parent::__construct($dsn, $user, $password, $options);
+        $this->setAttribute(PDO::ATTR_STATEMENT_CLASS, array('Doctrine\DBAL\Driver\PDOStatement', array()));
+        $this->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
+    }
+}

+ 126 - 0
main/inc/lib/symfony/Doctrine/DBAL/Driver/PDOIbm/Driver.php

@@ -0,0 +1,126 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+*/
+
+namespace Doctrine\DBAL\Driver\PDOIbm;
+
+use Doctrine\DBAL\Connection;
+
+/**
+ * Driver for the PDO IBM extension
+ *
+ * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link        www.doctrine-project.com
+ * @since       1.0
+ * @version     $Revision$
+ * @author      Benjamin Eberlei <kontakt@beberlei.de>
+ * @author      Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author      Jonathan Wage <jonwage@gmail.com>
+ * @author      Roman Borschel <roman@code-factory.org>
+ */
+class Driver implements \Doctrine\DBAL\Driver
+{
+    /**
+     * Attempts to establish a connection with the underlying driver.
+     *
+     * @param array $params
+     * @param string $username
+     * @param string $password
+     * @param array $driverOptions
+     * @return Doctrine\DBAL\Driver\Connection
+     */
+    public function connect(array $params, $username = null, $password = null, array $driverOptions = array())
+    {
+        $conn = new \Doctrine\DBAL\Driver\PDOConnection(
+            $this->_constructPdoDsn($params),
+            $username,
+            $password,
+            $driverOptions
+        );
+        return $conn;
+    }
+
+    /**
+     * Constructs the MySql PDO DSN.
+     *
+     * @return string  The DSN.
+     */
+    private function _constructPdoDsn(array $params)
+    {
+        $dsn = 'ibm:';
+        if (isset($params['host'])) {
+            $dsn .= 'HOSTNAME=' . $params['host'] . ';';
+        }
+        if (isset($params['port'])) {
+            $dsn .= 'PORT=' . $params['port'] . ';';
+        }
+        $dsn .= 'PROTOCOL=TCPIP;';
+        if (isset($params['dbname'])) {
+            $dsn .= 'DATABASE=' . $params['dbname'] . ';';
+        }
+
+        return $dsn;
+    }
+
+    /**
+     * Gets the DatabasePlatform instance that provides all the metadata about
+     * the platform this driver connects to.
+     *
+     * @return Doctrine\DBAL\Platforms\AbstractPlatform The database platform.
+     */
+    public function getDatabasePlatform()
+    {
+        return new \Doctrine\DBAL\Platforms\DB2Platform;
+    }
+
+    /**
+     * Gets the SchemaManager that can be used to inspect and change the underlying
+     * database schema of the platform this driver connects to.
+     *
+     * @param  Doctrine\DBAL\Connection $conn
+     * @return Doctrine\DBAL\SchemaManager
+     */
+    public function getSchemaManager(Connection $conn)
+    {
+        return new \Doctrine\DBAL\Schema\DB2SchemaManager($conn);
+    }
+
+    /**
+     * Gets the name of the driver.
+     *
+     * @return string The name of the driver.
+     */
+    public function getName()
+    {
+        return 'pdo_ibm';
+    }
+
+    /**
+     * Get the name of the database connected to for this driver.
+     *
+     * @param  Doctrine\DBAL\Connection $conn
+     * @return string $database
+     */
+    public function getDatabase(\Doctrine\DBAL\Connection $conn)
+    {
+        $params = $conn->getParams();
+        return $params['dbname'];
+    }
+}

+ 102 - 0
main/inc/lib/symfony/Doctrine/DBAL/Driver/PDOMySql/Driver.php

@@ -0,0 +1,102 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Driver\PDOMySql;
+
+use Doctrine\DBAL\Connection;
+
+/**
+ * PDO MySql driver.
+ *
+ * @since 2.0
+ */
+class Driver implements \Doctrine\DBAL\Driver
+{
+    /**
+     * Attempts to establish a connection with the underlying driver.
+     *
+     * @param array $params
+     * @param string $username
+     * @param string $password
+     * @param array $driverOptions
+     * @return Doctrine\DBAL\Driver\Connection
+     */
+    public function connect(array $params, $username = null, $password = null, array $driverOptions = array())
+    {
+        $conn = new \Doctrine\DBAL\Driver\PDOConnection(
+            $this->_constructPdoDsn($params),
+            $username,
+            $password,
+            $driverOptions
+        );
+        return $conn;
+    }
+
+    /**
+     * Constructs the MySql PDO DSN.
+     *
+     * @return string  The DSN.
+     */
+    private function _constructPdoDsn(array $params)
+    {
+        $dsn = 'mysql:';
+        if (isset($params['host']) && $params['host'] != '') {
+            $dsn .= 'host=' . $params['host'] . ';';
+        }
+        if (isset($params['port'])) {
+            $dsn .= 'port=' . $params['port'] . ';';
+        }
+        if (isset($params['dbname'])) {
+            $dsn .= 'dbname=' . $params['dbname'] . ';';
+        }
+        if (isset($params['unix_socket'])) {
+            $dsn .= 'unix_socket=' . $params['unix_socket'] . ';';
+        }
+        if (isset($params['charset'])) {
+            $dsn .= 'charset=' . $params['charset'] . ';';
+        }
+
+        return $dsn;
+    }
+
+    public function getDatabasePlatform()
+    {
+        return new \Doctrine\DBAL\Platforms\MySqlPlatform();
+    }
+
+    public function getSchemaManager(\Doctrine\DBAL\Connection $conn)
+    {
+        return new \Doctrine\DBAL\Schema\MySqlSchemaManager($conn);
+    }
+
+    public function getName()
+    {
+        return 'pdo_mysql';
+    }
+
+    public function getDatabase(\Doctrine\DBAL\Connection $conn)
+    {
+        $params = $conn->getParams();
+
+        if (isset($params['dbname'])) {
+            return $params['dbname'];
+        }
+        return $conn->query('SELECT DATABASE()')->fetchColumn();
+    }
+}

+ 98 - 0
main/inc/lib/symfony/Doctrine/DBAL/Driver/PDOOracle/Driver.php

@@ -0,0 +1,98 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\DBAL\Driver\PDOOracle;
+
+use Doctrine\DBAL\Platforms;
+
+/**
+ * PDO Oracle driver
+ *
+ * WARNING: This driver gives us segfauls in our testsuites on CLOB and other
+ * stuff. PDO Oracle is not maintained by Oracle or anyone in the PHP community,
+ * which leads us to the recommendation to use the "oci8" driver to connect
+ * to Oracle instead.
+ */
+class Driver implements \Doctrine\DBAL\Driver
+{
+    public function connect(array $params, $username = null, $password = null, array $driverOptions = array())
+    {
+        return new \Doctrine\DBAL\Driver\PDOConnection(
+            $this->_constructPdoDsn($params),
+            $username,
+            $password,
+            $driverOptions
+        );
+    }
+
+    /**
+     * Constructs the Oracle PDO DSN.
+     *
+     * @return string  The DSN.
+     */
+    private function _constructPdoDsn(array $params)
+    {
+        $dsn = 'oci:';
+        if (isset($params['host'])) {
+            $dsn .= 'dbname=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)' .
+                   '(HOST=' . $params['host'] . ')';
+
+            if (isset($params['port'])) {
+                $dsn .= '(PORT=' . $params['port'] . ')';
+            } else {
+                $dsn .= '(PORT=1521)';
+            }
+
+            if (isset($params['service']) && $params['service'] == true) {
+                $dsn .= '))(CONNECT_DATA=(SERVICE_NAME=' . $params['dbname'] . ')))';
+            } else {
+                $dsn .= '))(CONNECT_DATA=(SID=' . $params['dbname'] . ')))';
+            }
+        } else {
+            $dsn .= 'dbname=' . $params['dbname'];
+        }
+
+        if (isset($params['charset'])) {
+            $dsn .= ';charset=' . $params['charset'];
+        }
+
+        return $dsn;
+    }
+
+    public function getDatabasePlatform()
+    {
+        return new \Doctrine\DBAL\Platforms\OraclePlatform();
+    }
+
+    public function getSchemaManager(\Doctrine\DBAL\Connection $conn)
+    {
+        return new \Doctrine\DBAL\Schema\OracleSchemaManager($conn);
+    }
+
+    public function getName()
+    {
+        return 'pdo_oracle';
+    }
+
+    public function getDatabase(\Doctrine\DBAL\Connection $conn)
+    {
+        $params = $conn->getParams();
+        return $params['user'];
+    }
+}

+ 70 - 0
main/inc/lib/symfony/Doctrine/DBAL/Driver/PDOPgSql/Driver.php

@@ -0,0 +1,70 @@
+<?php
+
+namespace Doctrine\DBAL\Driver\PDOPgSql;
+
+use Doctrine\DBAL\Platforms;
+
+/**
+ * Driver that connects through pdo_pgsql.
+ *
+ * @since 2.0
+ */
+class Driver implements \Doctrine\DBAL\Driver
+{
+    /**
+     * Attempts to connect to the database and returns a driver connection on success.
+     *
+     * @return Doctrine\DBAL\Driver\Connection
+     */
+    public function connect(array $params, $username = null, $password = null, array $driverOptions = array())
+    {
+        return new \Doctrine\DBAL\Driver\PDOConnection(
+            $this->_constructPdoDsn($params),
+            $username,
+            $password,
+            $driverOptions
+        );
+    }
+
+    /**
+     * Constructs the Postgres PDO DSN.
+     *
+     * @return string The DSN.
+     */
+    private function _constructPdoDsn(array $params)
+    {
+        $dsn = 'pgsql:';
+        if (isset($params['host']) && $params['host'] != '') {
+            $dsn .= 'host=' . $params['host'] . ' ';
+        }
+        if (isset($params['port']) && $params['port'] != '') {
+            $dsn .= 'port=' . $params['port'] . ' ';
+        }
+        if (isset($params['dbname'])) {
+            $dsn .= 'dbname=' . $params['dbname'] . ' ';
+        }
+
+        return $dsn;
+    }
+
+    public function getDatabasePlatform()
+    {
+        return new \Doctrine\DBAL\Platforms\PostgreSqlPlatform();
+    }
+
+    public function getSchemaManager(\Doctrine\DBAL\Connection $conn)
+    {
+        return new \Doctrine\DBAL\Schema\PostgreSqlSchemaManager($conn);
+    }
+
+    public function getName()
+    {
+        return 'pdo_pgsql';
+    }
+
+    public function getDatabase(\Doctrine\DBAL\Connection $conn)
+    {
+        $params = $conn->getParams();
+        return $params['dbname'];
+    }
+}

Daži faili netika attēloti, jo izmaiņu fails ir pārāk liels