瀏覽代碼

adding vendors see BT#6613

Julio Montoya 11 年之前
父節點
當前提交
08130773c4
共有 100 個文件被更改,包括 7927 次插入0 次删除
  1. 5 0
      composer.json
  2. 11 0
      vendor/alchemy/binary-driver/.travis.yml
  3. 61 0
      vendor/alchemy/binary-driver/CHANGELOG.md
  4. 21 0
      vendor/alchemy/binary-driver/LICENSE
  5. 190 0
      vendor/alchemy/binary-driver/README.md
  6. 38 0
      vendor/alchemy/binary-driver/composer.json
  7. 31 0
      vendor/alchemy/binary-driver/phpunit.xml.dist
  8. 220 0
      vendor/alchemy/binary-driver/src/Alchemy/BinaryDriver/AbstractBinary.php
  9. 76 0
      vendor/alchemy/binary-driver/src/Alchemy/BinaryDriver/BinaryDriverTestCase.php
  10. 66 0
      vendor/alchemy/binary-driver/src/Alchemy/BinaryDriver/BinaryInterface.php
  11. 107 0
      vendor/alchemy/binary-driver/src/Alchemy/BinaryDriver/Configuration.php
  12. 29 0
      vendor/alchemy/binary-driver/src/Alchemy/BinaryDriver/ConfigurationAwareInterface.php
  13. 58 0
      vendor/alchemy/binary-driver/src/Alchemy/BinaryDriver/ConfigurationInterface.php
  14. 16 0
      vendor/alchemy/binary-driver/src/Alchemy/BinaryDriver/Exception/ExceptionInterface.php
  15. 16 0
      vendor/alchemy/binary-driver/src/Alchemy/BinaryDriver/Exception/ExecutableNotFoundException.php
  16. 16 0
      vendor/alchemy/binary-driver/src/Alchemy/BinaryDriver/Exception/ExecutionFailureException.php
  17. 16 0
      vendor/alchemy/binary-driver/src/Alchemy/BinaryDriver/Exception/InvalidArgumentException.php
  18. 58 0
      vendor/alchemy/binary-driver/src/Alchemy/BinaryDriver/Listeners/DebugListener.php
  19. 32 0
      vendor/alchemy/binary-driver/src/Alchemy/BinaryDriver/Listeners/ListenerInterface.php
  20. 88 0
      vendor/alchemy/binary-driver/src/Alchemy/BinaryDriver/Listeners/Listeners.php
  21. 177 0
      vendor/alchemy/binary-driver/src/Alchemy/BinaryDriver/ProcessBuilderFactory.php
  22. 29 0
      vendor/alchemy/binary-driver/src/Alchemy/BinaryDriver/ProcessBuilderFactoryAwareInterface.php
  23. 65 0
      vendor/alchemy/binary-driver/src/Alchemy/BinaryDriver/ProcessBuilderFactoryInterface.php
  24. 104 0
      vendor/alchemy/binary-driver/src/Alchemy/BinaryDriver/ProcessRunner.php
  25. 29 0
      vendor/alchemy/binary-driver/src/Alchemy/BinaryDriver/ProcessRunnerAwareInterface.php
  26. 33 0
      vendor/alchemy/binary-driver/src/Alchemy/BinaryDriver/ProcessRunnerInterface.php
  27. 297 0
      vendor/alchemy/binary-driver/tests/Alchemy/Tests/BinaryDriver/AbstractBinaryTest.php
  28. 97 0
      vendor/alchemy/binary-driver/tests/Alchemy/Tests/BinaryDriver/AbstractProcessBuilderFactoryTest.php
  29. 78 0
      vendor/alchemy/binary-driver/tests/Alchemy/Tests/BinaryDriver/ConfigurationTest.php
  30. 66 0
      vendor/alchemy/binary-driver/tests/Alchemy/Tests/BinaryDriver/LTSProcessBuilderFactoryTest.php
  31. 33 0
      vendor/alchemy/binary-driver/tests/Alchemy/Tests/BinaryDriver/Listeners/DebugListenerTest.php
  32. 92 0
      vendor/alchemy/binary-driver/tests/Alchemy/Tests/BinaryDriver/Listeners/ListenersTest.php
  33. 15 0
      vendor/alchemy/binary-driver/tests/Alchemy/Tests/BinaryDriver/NONLTSProcessBuilderFactoryTest.php
  34. 208 0
      vendor/alchemy/binary-driver/tests/Alchemy/Tests/BinaryDriver/ProcessRunnerTest.php
  35. 4 0
      vendor/alchemy/binary-driver/tests/bootstrap.php
  36. 7 0
      vendor/autoload.php
  37. 246 0
      vendor/composer/ClassLoader.php
  38. 9 0
      vendor/composer/autoload_classmap.php
  39. 16 0
      vendor/composer/autoload_namespaces.php
  40. 43 0
      vendor/composer/autoload_real.php
  41. 397 0
      vendor/composer/installed.json
  42. 9 0
      vendor/doctrine/cache/.travis.yml
  43. 19 0
      vendor/doctrine/cache/LICENSE
  44. 9 0
      vendor/doctrine/cache/README.md
  45. 29 0
      vendor/doctrine/cache/composer.json
  46. 91 0
      vendor/doctrine/cache/lib/Doctrine/Common/Cache/ApcCache.php
  47. 93 0
      vendor/doctrine/cache/lib/Doctrine/Common/Cache/ArrayCache.php
  48. 111 0
      vendor/doctrine/cache/lib/Doctrine/Common/Cache/Cache.php
  49. 240 0
      vendor/doctrine/cache/lib/Doctrine/Common/Cache/CacheProvider.php
  50. 121 0
      vendor/doctrine/cache/lib/Doctrine/Common/Cache/CouchbaseCache.php
  51. 158 0
      vendor/doctrine/cache/lib/Doctrine/Common/Cache/FileCache.php
  52. 113 0
      vendor/doctrine/cache/lib/Doctrine/Common/Cache/FilesystemCache.php
  53. 121 0
      vendor/doctrine/cache/lib/Doctrine/Common/Cache/MemcacheCache.php
  54. 124 0
      vendor/doctrine/cache/lib/Doctrine/Common/Cache/MemcachedCache.php
  55. 107 0
      vendor/doctrine/cache/lib/Doctrine/Common/Cache/PhpFileCache.php
  56. 130 0
      vendor/doctrine/cache/lib/Doctrine/Common/Cache/RedisCache.php
  57. 250 0
      vendor/doctrine/cache/lib/Doctrine/Common/Cache/RiakCache.php
  58. 91 0
      vendor/doctrine/cache/lib/Doctrine/Common/Cache/WinCacheCache.php
  59. 109 0
      vendor/doctrine/cache/lib/Doctrine/Common/Cache/XcacheCache.php
  60. 83 0
      vendor/doctrine/cache/lib/Doctrine/Common/Cache/ZendDataCache.php
  61. 31 0
      vendor/doctrine/cache/phpunit.xml.dist
  62. 20 0
      vendor/doctrine/cache/tests/Doctrine/Tests/Common/Cache/ApcCacheTest.php
  63. 21 0
      vendor/doctrine/cache/tests/Doctrine/Tests/Common/Cache/ArrayCacheTest.php
  64. 103 0
      vendor/doctrine/cache/tests/Doctrine/Tests/Common/Cache/CacheTest.php
  65. 47 0
      vendor/doctrine/cache/tests/Doctrine/Tests/Common/Cache/CouchbaseCacheTest.php
  66. 107 0
      vendor/doctrine/cache/tests/Doctrine/Tests/Common/Cache/FileCacheTest.php
  67. 102 0
      vendor/doctrine/cache/tests/Doctrine/Tests/Common/Cache/FilesystemCacheTest.php
  68. 45 0
      vendor/doctrine/cache/tests/Doctrine/Tests/Common/Cache/MemcacheCacheTest.php
  69. 48 0
      vendor/doctrine/cache/tests/Doctrine/Tests/Common/Cache/MemcachedCacheTest.php
  70. 154 0
      vendor/doctrine/cache/tests/Doctrine/Tests/Common/Cache/PhpFileCacheTest.php
  71. 30 0
      vendor/doctrine/cache/tests/Doctrine/Tests/Common/Cache/RedisCacheTest.php
  72. 64 0
      vendor/doctrine/cache/tests/Doctrine/Tests/Common/Cache/RiakCacheTest.php
  73. 20 0
      vendor/doctrine/cache/tests/Doctrine/Tests/Common/Cache/WinCacheCacheTest.php
  74. 20 0
      vendor/doctrine/cache/tests/Doctrine/Tests/Common/Cache/XcacheCacheTest.php
  75. 28 0
      vendor/doctrine/cache/tests/Doctrine/Tests/Common/Cache/ZendDataCacheTest.php
  76. 10 0
      vendor/doctrine/cache/tests/Doctrine/Tests/DoctrineTestCase.php
  77. 23 0
      vendor/doctrine/cache/tests/Doctrine/Tests/TestInit.php
  78. 11 0
      vendor/evenement/evenement/.travis.yml
  79. 19 0
      vendor/evenement/evenement/LICENSE
  80. 74 0
      vendor/evenement/evenement/README.md
  81. 20 0
      vendor/evenement/evenement/composer.json
  82. 25 0
      vendor/evenement/evenement/phpunit.xml.dist
  83. 73 0
      vendor/evenement/evenement/src/Evenement/EventEmitter.php
  84. 114 0
      vendor/evenement/evenement/src/Evenement/EventEmitter2.php
  85. 22 0
      vendor/evenement/evenement/src/Evenement/EventEmitterInterface.php
  86. 160 0
      vendor/evenement/evenement/tests/Evenement/Tests/EventEmitter2Test.php
  87. 236 0
      vendor/evenement/evenement/tests/Evenement/Tests/EventEmitterTest.php
  88. 38 0
      vendor/evenement/evenement/tests/Evenement/Tests/Listener.php
  89. 28 0
      vendor/evenement/evenement/tests/bootstrap.php
  90. 110 0
      vendor/monolog/monolog/CHANGELOG.mdown
  91. 19 0
      vendor/monolog/monolog/LICENSE
  92. 248 0
      vendor/monolog/monolog/README.mdown
  93. 39 0
      vendor/monolog/monolog/composer.json
  94. 76 0
      vendor/monolog/monolog/doc/extending.md
  95. 37 0
      vendor/monolog/monolog/doc/sockets.md
  96. 158 0
      vendor/monolog/monolog/doc/usage.md
  97. 15 0
      vendor/monolog/monolog/phpunit.xml.dist
  98. 209 0
      vendor/monolog/monolog/src/Monolog/ErrorHandler.php
  99. 79 0
      vendor/monolog/monolog/src/Monolog/Formatter/ChromePHPFormatter.php
  100. 36 0
      vendor/monolog/monolog/src/Monolog/Formatter/FormatterInterface.php

+ 5 - 0
composer.json

@@ -0,0 +1,5 @@
+{
+    "require": {
+            "php-ffmpeg/php-ffmpeg": "0.3.x-dev@dev"
+    }
+}

+ 11 - 0
vendor/alchemy/binary-driver/.travis.yml

@@ -0,0 +1,11 @@
+language: php
+
+before_script:
+  - composer self-update
+  - composer install --dev --prefer-source
+
+php:
+  - 5.3.3
+  - 5.3
+  - 5.4
+  - 5.5

+ 61 - 0
vendor/alchemy/binary-driver/CHANGELOG.md

@@ -0,0 +1,61 @@
+CHANGELOG
+---------
+
+* 1.5.0 (2013-06-21)
+
+  * BC Break : ConfigurationInterface::get does not throw exceptions anymore
+    in case the key does not exist. Second argument is a default value to return
+    in case the key does not exist.
+
+* 1.4.1 (2013-05-23)
+
+  * Add third parameter to BinaryInterface::command method to pass a listener or
+    an array of listener that will be registered just the time of the command.
+
+* 1.4.0 (2013-05-11)
+
+  * Extract process run management to ProcessRunner.
+  * Add support for process listeners.
+  * Provides bundled DebugListener.
+  * Add BinaryInterface::command method.
+  * BC break : ProcessRunnerInterface::run now takes an SplObjectStorage containing
+    listeners as second argument.
+  * BC break : BinaryInterface no longer implements LoggerAwareInterface
+    as it is now supported by ProcessRunner.
+
+* 1.3.4 (2013-04-26)
+
+  * Add BinaryDriver::run method.
+
+* 1.3.3 (2013-04-26)
+
+  * Add BinaryDriver::createProcessMock method.
+
+* 1.3.2 (2013-04-26)
+
+  * Add BinaryDriverTestCase for testing BinaryDriver implementations.
+
+* 1.3.1 (2013-04-24)
+
+  * Add timeouts handling
+
+* 1.3.0 (2013-04-24)
+
+  * Add BinaryInterface and AbstractBinary
+
+* 1.2.1 (2013-04-24)
+
+  * Add ConfigurationAwareInterface
+  * Add ProcessBuilderAwareInterface
+
+* 1.2.0 (2013-04-24)
+
+  * Add BinaryDriver\Configuration
+
+* 1.1.0 (2013-04-24)
+
+  * Add support for timeouts via `setTimeout` method
+
+* 1.0.0 (2013-04-23)
+
+  * First stable version.

+ 21 - 0
vendor/alchemy/binary-driver/LICENSE

@@ -0,0 +1,21 @@
+BinaryDriver is released with MIT License :
+
+Copyright (c) 2013 Alchemy
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+IN THE SOFTWARE.

+ 190 - 0
vendor/alchemy/binary-driver/README.md

@@ -0,0 +1,190 @@
+# Binary Driver
+
+Binary-Driver is a set of PHP tools to build binary drivers.
+
+[![Build Status](https://travis-ci.org/alchemy-fr/BinaryDriver.png?branch=master)](https://travis-ci.org/alchemy-fr/BinaryDriver)
+
+## Why ?
+
+You may wonder *Why building a library while I can use `exec` or
+[symfony/process](https://github.com/symfony/Process) ?*.
+
+Here is a simple answer :
+
+ - If you use `exec`, `passthru`, `system`, `proc_open` or any low level process
+   handling in PHP, you should have a look to [symfony/process](https://github.com/symfony/Process)
+   component that will provide an OO portable, testable and secure interface to
+   deal with this. It seems easy at first approach, but if you look at this
+   component [unit tests](https://github.com/symfony/Process/tree/master/Tests),
+   you will see that handling process in a simple interface can easily become a
+   nightmare.
+
+ - If you already use symfony/process, and want to build binary drivers, you
+   will always have the same common set of methods and objects to configure, log,
+   debug, and generate processes.
+   This library is a base to implement any binary driver with this common set of
+   needs.
+
+## AbstractBinary
+
+`AbstractBinary` provides an abstract class to build a binary driver. It implements
+`BinaryInterface`.
+
+Implementation example :
+
+```php
+use Alchemy\BinaryDriver\AbstractBinary;
+
+class LsDriver extends AbstractBinary
+{
+    public function getName()
+    {
+        return 'ls driver';
+    }
+}
+
+$parser = new LsParser();
+
+$driver = Driver::load('ls');
+// will return the output of `ls -a -l`
+$parser->parse($driver->command(array('-a', '-l')));
+```
+
+### Binary detection troubleshooting
+
+If you are using Nginx with PHP-fpm, executable detection may not work because of an empty `$_ENV['path']`. 
+To avoid having an empty `PATH` environment variable, add the following line to your `fastcgi_params` 
+config file (replace `/your/current/path/` with the output of `printenv PATH`) :
+
+```
+fastcgi_param    PATH    /your/current/path
+```
+
+## Logging
+
+You can log events with a `Psr\Log\LoggerInterface` by passing it in the load
+method as second argument :
+
+```php
+$logger = new Monolog\Logger('driver');
+$driver = Driver::load('ls', $logger);
+```
+
+## Listeners
+
+You can add custom listeners on processes.
+Listeners are built on top of [Evenement](https://github.com/igorw/evenement)
+and must implement `Alchemy\BinaryDriver\ListenerInterface`.
+
+```php
+use Symfony\Component\Process\Process;
+
+class DebugListener extends EventEmitter implements ListenerInterface
+{
+    public function handle($type, $data)
+    {
+        foreach (explode(PHP_EOL, $data) as $line) {
+            $this->emit($type === Process::ERR ? 'error' : 'out', array($line));
+        }
+    }
+
+    public function forwardedEvents()
+    {
+        // forward 'error' events to the BinaryInterface
+        return array('error');
+    }
+}
+
+$listener = new DebugListener();
+
+$driver = CustomImplementation::load('php');
+
+// adds listener
+$driver->listen($listener);
+
+$driver->on('error', function ($line) {
+    echo '[ERROR] ' . $line . PHP_EOL;
+});
+
+// removes listener
+$driver->unlisten($listener);
+```
+
+### Bundled listeners
+
+The debug listener is a simple listener to catch `stderr` and `stdout` outputs ;
+read the implementation for customization.
+
+```php
+use Alchemy\BinaryDriver\Listeners\DebugListener;
+
+$driver = CustomImplementation::load('php');
+$driver->listen(new DebugListener());
+
+$driver->on('debug', function ($line) {
+    echo $line;
+});
+```
+
+## ProcessBuilderFactory
+
+ProcessBuilderFactory ease spawning processes by generating Symfony [Process]
+(http://symfony.com/doc/master/components/process.html) objects.
+
+```php
+use Alchemy\BinaryDriver\ProcessBuilderFactory;
+
+$factory = new ProcessBuilderFactory('/usr/bin/php');
+
+// return a Symfony\Component\Process\Process
+$process = $factory->create('-v');
+
+// echoes '/usr/bin/php' '-v'
+echo $process->getCommandLine();
+
+$process = $factory->create(array('-r', 'echo "Hello !";'));
+
+// echoes '/usr/bin/php' '-r' 'echo "Hello !";'
+echo $process->getCommandLine();
+```
+
+## Configuration
+
+A simple configuration object, providing an `ArrayAccess` and `IteratorAggregate`
+interface.
+
+```php
+use Alchemy\BinaryDriver\Configuration;
+
+$conf = new Configuration(array('timeout' => 0));
+
+echo $conf->get('timeout');
+
+if ($conf->has('param')) {
+    $conf->remove('param');
+}
+
+$conf->set('timeout', 20);
+
+$conf->all();
+```
+
+Same example using the `ArrayAccess` interface :
+
+```php
+use Alchemy\BinaryDriver\Configuration;
+
+$conf = new Configuration(array('timeout' => 0));
+
+echo $conf['timeout'];
+
+if (isset($conf['param'])) {
+    unset($conf['param']);
+}
+
+$conf['timeout'] = 20;
+```
+
+## License
+
+This project is released under the MIT license.

+ 38 - 0
vendor/alchemy/binary-driver/composer.json

@@ -0,0 +1,38 @@
+{
+    "name": "alchemy/binary-driver",
+    "type": "library",
+    "description": "A set of tools to build binary drivers",
+    "keywords": ["binary", "driver"],
+    "license": "MIT",
+    "authors": [
+        {
+            "name": "Nicolas Le Goff",
+            "email": "legoff.n@gmail.com"
+        },
+        {
+            "name": "Romain Neutron",
+            "email": "imprec@gmail.com",
+            "homepage": "http://www.lickmychip.com/"
+        },
+        {
+            "name": "Phraseanet Team",
+            "email": "info@alchemy.fr",
+            "homepage": "http://www.phraseanet.com/"
+        }
+    ],
+    "require": {
+        "php"                 : ">=5.3.3",
+        "evenement/evenement" : "~1.0",
+        "monolog/monolog"     : "~1.3",
+        "psr/log"             : "~1.0",
+        "symfony/process"     : "~2.0"
+    },
+    "require-dev": {
+        "phpunit/phpunit"     : "~3.7"
+    },
+    "autoload": {
+        "psr-0": {
+            "Alchemy": "src"
+        }
+    }
+}

+ 31 - 0
vendor/alchemy/binary-driver/phpunit.xml.dist

@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<phpunit backupGlobals="false"
+         backupStaticAttributes="false"
+         colors="true"
+         convertErrorsToExceptions="true"
+         convertNoticesToExceptions="true"
+         convertWarningsToExceptions="true"
+         processIsolation="false"
+         stopOnFailure="false"
+         syntaxCheck="true"
+         verbose="false"
+         bootstrap="tests/bootstrap.php"
+>
+    <php>
+      <ini name="display_errors" value="on"/>
+    </php>
+
+    <testsuites>
+        <testsuite>
+            <directory>tests</directory>
+        </testsuite>
+    </testsuites>
+    <filter>
+      <blacklist>
+        <directory>vendor</directory>
+        <directory>tests</directory>
+      </blacklist>
+    </filter>
+
+</phpunit>
+

+ 220 - 0
vendor/alchemy/binary-driver/src/Alchemy/BinaryDriver/AbstractBinary.php

@@ -0,0 +1,220 @@
+<?php
+
+/*
+ * This file is part of Alchemy\BinaryDriver.
+ *
+ * (c) Alchemy <info@alchemy.fr>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Alchemy\BinaryDriver;
+
+use Alchemy\BinaryDriver\Exception\ExecutableNotFoundException;
+use Alchemy\BinaryDriver\Exception\ExecutionFailureException;
+use Alchemy\BinaryDriver\Listeners\Listeners;
+use Alchemy\BinaryDriver\Listeners\ListenerInterface;
+use Evenement\EventEmitter;
+use Monolog\Logger;
+use Monolog\Handler\NullHandler;
+use Psr\Log\LoggerInterface;
+use Symfony\Component\Process\ExecutableFinder;
+use Symfony\Component\Process\Process;
+
+abstract class AbstractBinary extends EventEmitter implements BinaryInterface
+{
+    /** @var ConfigurationInterface */
+    protected $configuration;
+
+    /** @var ProcessBuilderFactoryInterface */
+    protected $factory;
+
+    /** @var ProcessRunner */
+    private $processRunner;
+
+    /** @var Listeners */
+    private $listenersManager;
+
+    public function __construct(ProcessBuilderFactoryInterface $factory, LoggerInterface $logger, ConfigurationInterface $configuration)
+    {
+        $this->factory = $factory;
+        $this->configuration = $configuration;
+        $this->processRunner = new ProcessRunner($logger, $this->getName());
+        $this->listenersManager = new Listeners();
+        $this->applyProcessConfiguration();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function listen(ListenerInterface $listener)
+    {
+        $this->listenersManager->register($listener, $this);
+
+        return $this;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function unlisten(ListenerInterface $listener)
+    {
+        $this->listenersManager->unregister($listener, $this);
+
+        return $this;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getConfiguration()
+    {
+        return $this->configuration;
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return BinaryInterface
+     */
+    public function setConfiguration(ConfigurationInterface $configuration)
+    {
+        $this->configuration = $configuration;
+        $this->applyProcessConfiguration();
+
+        return $this;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getProcessBuilderFactory()
+    {
+        return $this->factory;
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return BinaryInterface
+     */
+    public function setProcessBuilderFactory(ProcessBuilderFactoryInterface $factory)
+    {
+        $this->factory = $factory;
+        $this->applyProcessConfiguration();
+
+        return $this;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getProcessRunner()
+    {
+        return $this->processRunner;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function setProcessRunner(ProcessRunnerInterface $runner)
+    {
+        $this->processRunner = $runner;
+
+        return $this;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function command($command, $bypassErrors = false, $listeners = null)
+    {
+        if (!is_array($command)) {
+            $command = array($command);
+        }
+
+        return $this->run($this->factory->create($command), $bypassErrors, $listeners);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public static function load($binaries, LoggerInterface $logger = null, $configuration = array())
+    {
+        $finder = new ExecutableFinder();
+        $binary = null;
+        $binaries = is_array($binaries) ? $binaries : array($binaries);
+
+        foreach ($binaries as $candidate) {
+            if (file_exists($candidate) && is_executable($candidate)) {
+                $binary = $candidate;
+                break;
+            }
+            if (null !== $binary = $finder->find($candidate)) {
+                break;
+            }
+        }
+
+        if (null === $binary) {
+            throw new ExecutableNotFoundException(sprintf(
+                'Executable not found, proposed : %s', implode(', ', $binaries)
+            ));
+        }
+
+        if (null === $logger) {
+            $logger = new Logger(__NAMESPACE__ . ' logger');
+            $logger->pushHandler(new NullHandler());
+        }
+
+        $configuration = $configuration instanceof ConfigurationInterface ? $configuration : new Configuration($configuration);
+
+        return new static(new ProcessBuilderFactory($binary), $logger, $configuration);
+    }
+
+    /**
+     * Returns the name of the driver
+     *
+     * @return string
+     */
+    abstract public function getName();
+
+    /**
+     * Executes a process, logs events
+     *
+     * @param Process                 $process
+     * @param Boolean                 $bypassErrors Set to true to disable throwing ExecutionFailureExceptions
+     * @param ListenerInterface|array $listeners    A listener or an array of listener to register for this unique run
+     *
+     * @return string The Process output
+     *
+     * @throws ExecutionFailureException in case of process failure.
+     */
+    protected function run(Process $process, $bypassErrors = false, $listeners = null)
+    {
+        if (null !== $listeners) {
+            if (!is_array($listeners)) {
+                $listeners = array($listeners);
+            }
+
+            $listenersManager = clone $this->listenersManager;
+
+            foreach ($listeners as $listener) {
+                $listenersManager->register($listener, $this);
+            }
+        } else {
+            $listenersManager = $this->listenersManager;
+        }
+
+        return $this->processRunner->run($process, $listenersManager->storage, $bypassErrors);
+    }
+
+    private function applyProcessConfiguration()
+    {
+        if ($this->configuration->has('timeout')) {
+            $this->factory->setTimeout($this->configuration->get('timeout'));
+        }
+
+        return $this;
+    }
+}

+ 76 - 0
vendor/alchemy/binary-driver/src/Alchemy/BinaryDriver/BinaryDriverTestCase.php

@@ -0,0 +1,76 @@
+<?php
+
+namespace Alchemy\BinaryDriver;
+
+use Psr\Log\LoggerInterface;
+use Symfony\Component\Process\Process;
+
+/**
+ * Convenient PHPUnit methods for testing BinaryDriverInterface implementations.
+ */
+class BinaryDriverTestCase extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @return ProcessBuilderFactoryInterface
+     */
+    public function createProcessBuilderFactoryMock()
+    {
+        return $this->getMock('Alchemy\BinaryDriver\ProcessBuilderFactoryInterface');
+    }
+
+    /**
+     * @param integer $runs        The number of runs expected
+     * @param Boolean $success     True if the process expects to be successfull
+     * @param string  $commandLine The commandline executed
+     * @param string  $output      The process output
+     * @param string  $error       The process error output
+     *
+     * @return Process
+     */
+    public function createProcessMock($runs = 1, $success = true, $commandLine = null, $output = null, $error = null, $callback = false)
+    {
+        $process = $this->getMockBuilder('Symfony\Component\Process\Process')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $builder = $process->expects($this->exactly($runs))
+            ->method('run');
+
+        if (true === $callback) {
+            $builder->with($this->isInstanceOf('Closure'));
+        }
+
+        $process->expects($this->any())
+            ->method('isSuccessful')
+            ->will($this->returnValue($success));
+
+        foreach (array(
+            'getOutput' => $output,
+            'getErrorOutput' => $error,
+            'getCommandLine' => $commandLine,
+        ) as $command => $value) {
+            $process
+                ->expects($this->any())
+                ->method($command)
+                ->will($this->returnValue($value));
+        }
+
+        return $process;
+    }
+
+    /**
+     * @return LoggerInterface
+     */
+    public function createLoggerMock()
+    {
+        return $this->getMock('Psr\Log\LoggerInterface');
+    }
+
+    /**
+     * @return ConfigurationInterface
+     */
+    public function createConfigurationMock()
+    {
+        return $this->getMock('Alchemy\BinaryDriver\ConfigurationInterface');
+    }
+}

+ 66 - 0
vendor/alchemy/binary-driver/src/Alchemy/BinaryDriver/BinaryInterface.php

@@ -0,0 +1,66 @@
+<?php
+
+/*
+ * This file is part of Alchemy\BinaryDriver.
+ *
+ * (c) Alchemy <info@alchemy.fr>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Alchemy\BinaryDriver;
+
+use Alchemy\BinaryDriver\Exception\ExecutableNotFoundException;
+use Alchemy\BinaryDriver\Listeners\ListenerInterface;
+use Psr\Log\LoggerInterface;
+use Evenement\EventEmitterInterface;
+
+interface BinaryInterface extends ConfigurationAwareInterface, ProcessBuilderFactoryAwareInterface, ProcessRunnerAwareInterface, EventEmitterInterface
+{
+    /**
+     * Adds a listener to the binary driver
+     *
+     * @param ListenerInterface $listener
+     *
+     * @return BinaryInterface
+     */
+    public function listen(ListenerInterface $listener);
+
+    /**
+     * Removes a listener from the binary driver
+     *
+     * @param ListenerInterface $listener
+     *
+     * @return BinaryInterface
+     */
+    public function unlisten(ListenerInterface $listener);
+
+    /**
+     * Runs a command against the driver.
+     *
+     * Calling this method on a `ls` driver with the command `-a` would run `ls -a`.
+     *
+     * @param array|string            $command      A command or an array of command
+     * @param Boolean                 $bypassErrors If set to true, an erronous process will not throw an exception
+     * @param ListenerInterface|array $listeners    A listener or an array of listeners to register for this unique run
+     *
+     * @return string The command output
+     *
+     * @throws ExecutionFailureException in case of process failure.
+     */
+    public function command($command, $bypassErrors = false, $listeners = null);
+
+    /**
+     * Loads a binary
+     *
+     * @param string|array                 $binaries      A binary name or an array of binary names
+     * @param null||LoggerInterface        $logger        A Logger
+     * @param array|ConfigurationInterface $configuration The configuration
+     *
+     * @throws ExecutableNotFoundException In case none of the binaries were found
+     *
+     * @return BinaryInterface
+     */
+    public static function load($binaries, LoggerInterface $logger = null, $configuration = array());
+}

+ 107 - 0
vendor/alchemy/binary-driver/src/Alchemy/BinaryDriver/Configuration.php

@@ -0,0 +1,107 @@
+<?php
+
+/*
+ * This file is part of Alchemy\BinaryDriver.
+ *
+ * (c) Alchemy <info@alchemy.fr>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Alchemy\BinaryDriver;
+
+class Configuration implements ConfigurationInterface
+{
+    private $data;
+
+    public function __construct(array $data = array())
+    {
+        $this->data = $data;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getIterator()
+    {
+        return new \ArrayIterator($this->data);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function get($key, $default = null)
+    {
+        return isset($this->data[$key]) ? $this->data[$key] : $default;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function set($key, $value)
+    {
+        $this->data[$key] = $value;
+
+        return $this;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function has($key)
+    {
+        return array_key_exists($key, $this->data);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function remove($key)
+    {
+        $value = $this->get($key);
+        unset($this->data[$key]);
+
+        return $value;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function all()
+    {
+        return $this->data;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function offsetExists($offset)
+    {
+        return $this->has($offset);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function offsetGet($offset)
+    {
+        return $this->get($offset);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function offsetSet($offset, $value)
+    {
+        $this->set($offset, $value);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function offsetUnset($offset)
+    {
+        $this->remove($offset);
+    }
+}

+ 29 - 0
vendor/alchemy/binary-driver/src/Alchemy/BinaryDriver/ConfigurationAwareInterface.php

@@ -0,0 +1,29 @@
+<?php
+
+/*
+ * This file is part of Alchemy\BinaryDriver.
+ *
+ * (c) Alchemy <info@alchemy.fr>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Alchemy\BinaryDriver;
+
+interface ConfigurationAwareInterface
+{
+    /**
+     * Returns the configuration
+     *
+     * @return ConfigurationInterface
+     */
+    public function getConfiguration();
+
+    /**
+     * Set the configuration
+     *
+     * @param ConfigurationInterface $configuration
+     */
+    public function setConfiguration(ConfigurationInterface $configuration);
+}

+ 58 - 0
vendor/alchemy/binary-driver/src/Alchemy/BinaryDriver/ConfigurationInterface.php

@@ -0,0 +1,58 @@
+<?php
+
+/*
+ * This file is part of Alchemy\BinaryDriver.
+ *
+ * (c) Alchemy <info@alchemy.fr>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Alchemy\BinaryDriver;
+
+interface ConfigurationInterface extends \ArrayAccess, \IteratorAggregate
+{
+    /**
+     * Returns the value given a key from configuration
+     *
+     * @param string $key
+     * @param mixed  $default The default value in case the key does not exist
+     *
+     * @return mixed
+     */
+    public function get($key, $default = null);
+
+    /**
+     * Set a value to configuration
+     *
+     * @param string $key   The key
+     * @param mixed  $value The value corresponding to the key
+     */
+    public function set($key, $value);
+
+    /**
+     * Tells if Configuration contains `$key`
+     *
+     * @param string $key
+     *
+     * @return Boolean
+     */
+    public function has($key);
+
+    /**
+     * Removes a value given a key
+     *
+     * @param string $key
+     *
+     * @return mixed The previous value
+     */
+    public function remove($key);
+
+    /**
+     * Returns all values set in the configuration
+     *
+     * @return array
+     */
+    public function all();
+}

+ 16 - 0
vendor/alchemy/binary-driver/src/Alchemy/BinaryDriver/Exception/ExceptionInterface.php

@@ -0,0 +1,16 @@
+<?php
+
+/*
+ * This file is part of Alchemy\BinaryDriver.
+ *
+ * (c) Alchemy <info@alchemy.fr>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Alchemy\BinaryDriver\Exception;
+
+interface ExceptionInterface
+{
+}

+ 16 - 0
vendor/alchemy/binary-driver/src/Alchemy/BinaryDriver/Exception/ExecutableNotFoundException.php

@@ -0,0 +1,16 @@
+<?php
+
+/*
+ * This file is part of Alchemy\BinaryDriver.
+ *
+ * (c) Alchemy <info@alchemy.fr>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Alchemy\BinaryDriver\Exception;
+
+class ExecutableNotFoundException extends \RuntimeException implements ExceptionInterface
+{
+}

+ 16 - 0
vendor/alchemy/binary-driver/src/Alchemy/BinaryDriver/Exception/ExecutionFailureException.php

@@ -0,0 +1,16 @@
+<?php
+
+/*
+ * This file is part of Alchemy\BinaryDriver.
+ *
+ * (c) Alchemy <info@alchemy.fr>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Alchemy\BinaryDriver\Exception;
+
+class ExecutionFailureException extends \RuntimeException implements ExceptionInterface
+{
+}

+ 16 - 0
vendor/alchemy/binary-driver/src/Alchemy/BinaryDriver/Exception/InvalidArgumentException.php

@@ -0,0 +1,16 @@
+<?php
+
+/*
+ * This file is part of Alchemy\BinaryDriver.
+ *
+ * (c) Alchemy <info@alchemy.fr>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Alchemy\BinaryDriver\Exception;
+
+class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface
+{
+}

+ 58 - 0
vendor/alchemy/binary-driver/src/Alchemy/BinaryDriver/Listeners/DebugListener.php

@@ -0,0 +1,58 @@
+<?php
+
+/*
+ * This file is part of Alchemy\BinaryDriver.
+ *
+ * (c) Alchemy <info@alchemy.fr>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Alchemy\BinaryDriver\Listeners;
+
+use Evenement\EventEmitter;
+use Symfony\Component\Process\Process;
+
+class DebugListener extends EventEmitter implements ListenerInterface
+{
+    private $prefixOut;
+    private $prefixErr;
+    private $eventOut;
+    private $eventErr;
+
+    public function __construct($prefixOut = '[OUT] ', $prefixErr = '[ERROR] ', $eventOut = 'debug', $eventErr = 'debug')
+    {
+        $this->prefixOut = $prefixOut;
+        $this->prefixErr = $prefixErr;
+        $this->eventOut = $eventOut;
+        $this->eventErr = $eventErr;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function handle($type, $data)
+    {
+        if (Process::ERR === $type) {
+            $this->emitLines($this->eventErr, $this->prefixErr, $data);
+        } elseif (Process::OUT === $type) {
+            $this->emitLines($this->eventOut, $this->prefixOut, $data);
+        }
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function forwardedEvents()
+    {
+        return array_unique(array($this->eventErr, $this->eventOut));
+    }
+
+    private function emitLines($event, $prefix, $lines)
+    {
+        foreach (explode("\n", $lines) as $line) {
+            $this->emit($event, array($prefix . $line));
+        }
+    }
+}

+ 32 - 0
vendor/alchemy/binary-driver/src/Alchemy/BinaryDriver/Listeners/ListenerInterface.php

@@ -0,0 +1,32 @@
+<?php
+
+/*
+ * This file is part of Alchemy\BinaryDriver.
+ *
+ * (c) Alchemy <info@alchemy.fr>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Alchemy\BinaryDriver\Listeners;
+
+use Evenement\EventEmitterInterface;
+
+interface ListenerInterface extends EventEmitterInterface
+{
+    /**
+     * Handle the output of a ProcessRunner
+     *
+     * @param string $type The data type, one of Process::ERR, Process::OUT constants
+     * @param string $data The output
+     */
+    public function handle($type, $data);
+
+    /**
+     * An array of events that should be forwarded to BinaryInterface
+     *
+     * @return array
+     */
+    public function forwardedEvents();
+}

+ 88 - 0
vendor/alchemy/binary-driver/src/Alchemy/BinaryDriver/Listeners/Listeners.php

@@ -0,0 +1,88 @@
+<?php
+
+namespace Alchemy\BinaryDriver\Listeners;
+
+use SplObjectStorage;
+use Evenement\EventEmitter;
+
+class Listeners extends EventEmitter
+{
+    /** @var SplObjectStorage */
+    public $storage;
+
+    public function __construct()
+    {
+        $this->storage = new SplObjectStorage();
+    }
+
+    public function __clone()
+    {
+        $storage = $this->storage;
+        $this->storage = new SplObjectStorage();
+        $this->storage->addAll($storage);
+    }
+
+    /**
+     * Registers a listener, pass the listener events to the target.
+     *
+     * @param ListenerInterface $listener
+     * @param null|EventEmitter $target
+     *
+     * @return ListenersInterface
+     */
+    public function register(ListenerInterface $listener, EventEmitter $target = null)
+    {
+        $EElisteners = array();
+
+        if (null !== $target) {
+            $EElisteners = $this->forwardEvents($listener, $target, $listener->forwardedEvents());
+        }
+
+        $this->storage->attach($listener, $EElisteners);
+
+        return $this;
+    }
+
+    /**
+     * Unregisters a listener, removes the listener events from the target.
+     *
+     * @param ListenerInterface $listener
+     *
+     * @return ListenersInterface
+     *
+     * @throws InvalidArgumentException In case the listener is not registered
+     */
+    public function unregister(ListenerInterface $listener)
+    {
+        if (!isset($this->storage[$listener])) {
+            throw new InvalidArgumentException('Listener is not registered.');
+        }
+
+        foreach ($this->storage[$listener] as $event => $EElistener) {
+            $listener->removeListener($event, $EElistener);
+        }
+
+        $this->storage->detach($listener);
+
+        return $this;
+    }
+
+    private function forwardEvents($source, $target, array $events)
+    {
+        $EElisteners = array();
+
+        foreach ($events as $event) {
+            $listener = $this->createListener($event, $target);
+            $source->on($event, $EElisteners[$event] = $listener);
+        }
+
+        return $EElisteners;
+    }
+
+    private function createListener($event, $target)
+    {
+        return function () use ($event, $target) {
+            $target->emit($event, func_get_args());
+        };
+    }
+}

+ 177 - 0
vendor/alchemy/binary-driver/src/Alchemy/BinaryDriver/ProcessBuilderFactory.php

@@ -0,0 +1,177 @@
+<?php
+
+/*
+ * This file is part of Alchemy\BinaryDriver.
+ *
+ * (c) Alchemy <info@alchemy.fr>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Alchemy\BinaryDriver;
+
+use Alchemy\BinaryDriver\Exception\InvalidArgumentException;
+use Symfony\Component\Process\ProcessBuilder;
+
+class ProcessBuilderFactory implements ProcessBuilderFactoryInterface
+{
+    /**
+     * The binary path
+     *
+     * @var String
+     */
+    protected $binary;
+
+    /**
+     * The timeout for the generated processes
+     *
+     * @var integer|float
+     */
+    private $timeout;
+
+    /**
+     * An internal ProcessBuilder.
+     *
+     * Note that this one is used only if Symfony ProcessBuilder has method
+     * setPrefix (2.3)
+     *
+     * @var ProcessBuilder
+     */
+    private $builder;
+
+    /**
+     * Tells whether Symfony LTS ProcessBuilder should be emulated or not.
+     *
+     * This symfony version provided a brand new ::setPrefix method.
+     *
+     * @var Boolean
+     */
+    public static $emulateSfLTS;
+
+    /**
+     * Constructor
+     *
+     * @param String $binary The path to the binary
+     *
+     * @throws InvalidArgumentException In case binary path is invalid
+     */
+    public function __construct($binary)
+    {
+        $this->detectEmulation();
+
+        if (!self::$emulateSfLTS) {
+            $this->builder = new ProcessBuilder();
+        }
+
+        $this->useBinary($binary);
+    }
+
+    /**
+     * Covenient method for unit testing
+     *
+     * @return type
+     */
+    public function getBuilder()
+    {
+        return $this->builder;
+    }
+
+    /**
+     * Covenient method for unit testing
+     *
+     * @param  ProcessBuilder        $builder
+     * @return ProcessBuilderFactory
+     */
+    public function setBuilder(ProcessBuilder $builder)
+    {
+        $this->builder = $builder;
+
+        return $this;
+    }
+
+    /**
+     * @inheritdoc
+     */
+    public function getBinary()
+    {
+        return $this->binary;
+    }
+
+    /**
+     * @inheritdoc
+     */
+    public function useBinary($binary)
+    {
+        if (!is_executable($binary)) {
+            throw new InvalidArgumentException(sprintf('`%s` is not an executable binary', $binary));
+        }
+
+        $this->binary = $binary;
+
+        if (!static::$emulateSfLTS) {
+            $this->builder->setPrefix($binary);
+        }
+
+        return $this;
+    }
+
+    /**
+     * @inheritdoc
+     */
+    public function setTimeout($timeout)
+    {
+        $this->timeout = $timeout;
+
+        if (!static::$emulateSfLTS) {
+            $this->builder->setTimeout($this->timeout);
+        }
+
+        return $this;
+    }
+
+    /**
+     * @inheritdoc
+     */
+    public function getTimeout()
+    {
+        return $this->timeout;
+    }
+
+    /**
+     * @inheritdoc
+     */
+    public function create($arguments = array())
+    {
+        if (null === $this->binary) {
+            throw new InvalidArgumentException('No binary set');
+        }
+
+        if (!is_array($arguments)) {
+            $arguments = array($arguments);
+        }
+
+        if (static::$emulateSfLTS) {
+            array_unshift($arguments, $this->binary);
+
+            return ProcessBuilder::create($arguments)
+                ->setTimeout($this->timeout)
+                ->getProcess();
+        } else {
+            return $this->builder
+                ->setArguments($arguments)
+                ->getProcess();
+        }
+    }
+
+    private function detectEmulation()
+    {
+        if (null !== static::$emulateSfLTS) {
+            return $this;
+        }
+
+        static::$emulateSfLTS = !method_exists('Symfony\Component\Process\ProcessBuilder', 'setPrefix');
+
+        return $this;
+    }
+}

+ 29 - 0
vendor/alchemy/binary-driver/src/Alchemy/BinaryDriver/ProcessBuilderFactoryAwareInterface.php

@@ -0,0 +1,29 @@
+<?php
+
+/*
+ * This file is part of Alchemy\BinaryDriver.
+ *
+ * (c) Alchemy <info@alchemy.fr>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Alchemy\BinaryDriver;
+
+interface ProcessBuilderFactoryAwareInterface
+{
+    /**
+     * Returns the current process builder factory
+     *
+     * @return ProcessBuilderFactoryInterface
+     */
+    public function getProcessBuilderFactory();
+
+    /**
+     * Set a process builder factory
+     *
+     * @param ProcessBuilderFactoryInterface $factory
+     */
+    public function setProcessBuilderFactory(ProcessBuilderFactoryInterface $factory);
+}

+ 65 - 0
vendor/alchemy/binary-driver/src/Alchemy/BinaryDriver/ProcessBuilderFactoryInterface.php

@@ -0,0 +1,65 @@
+<?php
+
+/*
+ * This file is part of Alchemy\BinaryDriver.
+ *
+ * (c) Alchemy <info@alchemy.fr>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Alchemy\BinaryDriver;
+
+use Alchemy\BinaryDriver\Exception\InvalidArgumentException;
+use Symfony\Component\Process\Process;
+
+interface ProcessBuilderFactoryInterface
+{
+    /**
+     * Returns a new instance of Symfony Process
+     *
+     * @param string|array $arguments An argument or an array of arguments
+     *
+     * @return Process
+     *
+     * @throws InvalidArgumentException
+     */
+    public function create($arguments = array());
+
+    /**
+     * Returns the path to the binary that is used
+     *
+     * @return String
+     */
+    public function getBinary();
+
+    /**
+     * Sets the path to the binary
+     *
+     * @param String $binary A path to a binary
+     *
+     * @return ProcessBuilderFactoryInterface
+     *
+     * @throws InvalidArgumentException In case binary is not executable
+     */
+    public function useBinary($binary);
+
+    /**
+     * Set the default timeout to apply on created processes.
+     *
+     * @param integer|float $timeout
+     *
+     * @return ProcessBuilderFactoryInterface
+     *
+     * @throws InvalidArgumentException In case the timeout is not valid
+     */
+    public function setTimeout($timeout);
+
+    /**
+     * Returns the current timeout applied to the created processes.
+     *
+     * @return integer|float
+     */
+    public function getTimeout();
+}

+ 104 - 0
vendor/alchemy/binary-driver/src/Alchemy/BinaryDriver/ProcessRunner.php

@@ -0,0 +1,104 @@
+<?php
+
+/*
+ * This file is part of Alchemy\BinaryDriver.
+ *
+ * (c) Alchemy <info@alchemy.fr>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Alchemy\BinaryDriver;
+
+use Alchemy\BinaryDriver\Exception\ExecutionFailureException;
+use Psr\Log\LoggerInterface;
+use SplObjectStorage;
+use Symfony\Component\Process\Exception\RuntimeException;
+use Symfony\Component\Process\Process;
+
+class ProcessRunner implements ProcessRunnerInterface
+{
+    /** @var LoggerInterface */
+    private $logger;
+
+    /** @var string */
+    private $name;
+
+    public function __construct(LoggerInterface $logger, $name)
+    {
+        $this->logger = $logger;
+        $this->name = $name;
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @return ProcessRunner
+     */
+    public function setLogger(LoggerInterface $logger)
+    {
+        $this->logger = $logger;
+
+        return $this;
+    }
+
+    /**
+     * @return LoggerInterface
+     */
+    public function getLogger()
+    {
+        return $this->logger;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function run(Process $process, SplObjectStorage $listeners, $bypassErrors)
+    {
+        $this->logger->info(sprintf(
+            '%s running command %s', $this->name, $process->getCommandLine()
+        ));
+
+        try {
+            $process->run($this->buildCallback($listeners));
+        } catch (RuntimeException $e) {
+            if (!$bypassErrors) {
+                $this->doExecutionFailure($process->getCommandLine(), $e);
+            }
+        }
+
+        if (!$bypassErrors && !$process->isSuccessful()) {
+            $this->doExecutionFailure($process->getCommandLine());
+        } elseif (!$process->isSuccessful()) {
+            $this->logger->error(sprintf(
+                '%s failed to execute command %s', $this->name, $process->getCommandLine()
+            ));
+
+            return;
+        } else {
+            $this->logger->info(sprintf('%s executed command successfully', $this->name));
+
+            return $process->getOutput();
+        }
+    }
+
+    private function buildCallback(SplObjectStorage $listeners)
+    {
+        return function ($type, $data) use ($listeners) {
+            foreach ($listeners as $listener) {
+                $listener->handle($type, $data);
+            }
+        };
+    }
+
+    private function doExecutionFailure($command, \Exception $e = null)
+    {
+        $this->logger->error(sprintf(
+            '%s failed to execute command %s', $this->name, $command
+        ));
+        throw new ExecutionFailureException(sprintf(
+            '%s failed to execute command %s', $this->name, $command
+        ), $e ? $e->getCode() : null, $e ?: null);
+    }
+}

+ 29 - 0
vendor/alchemy/binary-driver/src/Alchemy/BinaryDriver/ProcessRunnerAwareInterface.php

@@ -0,0 +1,29 @@
+<?php
+
+/*
+ * This file is part of Alchemy\BinaryDriver.
+ *
+ * (c) Alchemy <info@alchemy.fr>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Alchemy\BinaryDriver;
+
+interface ProcessRunnerAwareInterface
+{
+    /**
+     * Returns the current process runner
+     *
+     * @return ProcessRunnerInterface
+     */
+    public function getProcessRunner();
+
+    /**
+     * Sets a process runner
+     *
+     * @param ProcessRunnerInterface $runner
+     */
+    public function setProcessRunner(ProcessRunnerInterface $runner);
+}

+ 33 - 0
vendor/alchemy/binary-driver/src/Alchemy/BinaryDriver/ProcessRunnerInterface.php

@@ -0,0 +1,33 @@
+<?php
+
+/*
+ * This file is part of Alchemy\BinaryDriver.
+ *
+ * (c) Alchemy <info@alchemy.fr>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Alchemy\BinaryDriver;
+
+use Alchemy\BinaryDriver\Exception\ExecutionFailureException;
+use Psr\Log\LoggerAwareInterface;
+use SplObjectStorage;
+use Symfony\Component\Process\Process;
+
+interface ProcessRunnerInterface extends LoggerAwareInterface
+{
+    /**
+     * Executes a process, logs events
+     *
+     * @param Process          $process
+     * @param SplObjectStorage $listeners    Some listeners
+     * @param Boolean          $bypassErrors Set to true to disable throwing ExecutionFailureExceptions
+     *
+     * @return string The Process output
+     *
+     * @throws ExecutionFailureException in case of process failure.
+     */
+    public function run(Process $process, SplObjectStorage $listeners, $bypassErrors);
+}

+ 297 - 0
vendor/alchemy/binary-driver/tests/Alchemy/Tests/BinaryDriver/AbstractBinaryTest.php

@@ -0,0 +1,297 @@
+<?php
+
+namespace Alchemy\Tests\BinaryDriver;
+
+use Alchemy\BinaryDriver\AbstractBinary;
+use Alchemy\BinaryDriver\BinaryDriverTestCase;
+use Alchemy\BinaryDriver\Configuration;
+use Symfony\Component\Process\ExecutableFinder;
+
+class AbstractBinaryTest extends BinaryDriverTestCase
+{
+    protected function getPhpBinary()
+    {
+        $finder = new ExecutableFinder();
+        $php = $finder->find('php');
+
+        if (null === $php) {
+            $this->markTestSkipped('Unable to find a php binary');
+        }
+
+        return $php;
+    }
+
+    public function testSimpleLoadWithBinaryPath()
+    {
+        $php = $this->getPhpBinary();
+        $imp = Implementation::load($php);
+        $this->assertInstanceOf('Alchemy\Tests\BinaryDriver\Implementation', $imp);
+
+        $this->assertEquals($php, $imp->getProcessBuilderFactory()->getBinary());
+    }
+
+    public function testMultipleLoadWithBinaryPath()
+    {
+        $php = $this->getPhpBinary();
+        $imp = Implementation::load(array('/zz/path/to/unexisting/command', $php));
+        $this->assertInstanceOf('Alchemy\Tests\BinaryDriver\Implementation', $imp);
+
+        $this->assertEquals($php, $imp->getProcessBuilderFactory()->getBinary());
+    }
+
+    public function testSimpleLoadWithBinaryName()
+    {
+        $php = $this->getPhpBinary();
+        $imp = Implementation::load('php');
+        $this->assertInstanceOf('Alchemy\Tests\BinaryDriver\Implementation', $imp);
+
+        $this->assertEquals($php, $imp->getProcessBuilderFactory()->getBinary());
+    }
+
+    public function testMultipleLoadWithBinaryName()
+    {
+        $php = $this->getPhpBinary();
+        $imp = Implementation::load(array('bachibouzouk', 'php'));
+        $this->assertInstanceOf('Alchemy\Tests\BinaryDriver\Implementation', $imp);
+
+        $this->assertEquals($php, $imp->getProcessBuilderFactory()->getBinary());
+    }
+
+    /**
+     * @expectedException Alchemy\BinaryDriver\Exception\ExecutableNotFoundException
+     */
+    public function testLoadWithMultiplePathExpectingAFailure()
+    {
+        Implementation::load(array('bachibouzouk', 'moribon'));
+    }
+
+    /**
+     * @expectedException Alchemy\BinaryDriver\Exception\ExecutableNotFoundException
+     */
+    public function testLoadWithUniquePathExpectingAFailure()
+    {
+        Implementation::load('bachibouzouk');
+    }
+
+    public function testLoadWithCustomLogger()
+    {
+        $logger = $this->getMock('Psr\Log\LoggerInterface');
+        $imp = Implementation::load('php', $logger);
+
+        $this->assertEquals($logger, $imp->getProcessRunner()->getLogger());
+    }
+
+    public function testLoadWithCustomConfigurationAsArray()
+    {
+        $conf = array('timeout' => 200);
+        $imp = Implementation::load('php', null, $conf);
+
+        $this->assertEquals($conf, $imp->getConfiguration()->all());
+    }
+
+    public function testLoadWithCustomConfigurationAsObject()
+    {
+        $conf = $this->getMock('Alchemy\BinaryDriver\ConfigurationInterface');
+        $imp = Implementation::load('php', null, $conf);
+
+        $this->assertEquals($conf, $imp->getConfiguration());
+    }
+
+    public function testProcessBuilderFactoryGetterAndSetters()
+    {
+        $imp = Implementation::load('php');
+        $factory = $this->getMock('Alchemy\BinaryDriver\ProcessBuilderFactoryInterface');
+
+        $imp->setProcessBuilderFactory($factory);
+        $this->assertEquals($factory, $imp->getProcessBuilderFactory());
+    }
+
+    public function testConfigurationGetterAndSetters()
+    {
+        $imp = Implementation::load('php');
+        $conf = $this->getMock('Alchemy\BinaryDriver\ConfigurationInterface');
+
+        $imp->setConfiguration($conf);
+        $this->assertEquals($conf, $imp->getConfiguration());
+    }
+
+    public function testTimeoutIsSetOnConstruction()
+    {
+        $imp = Implementation::load('php', null, array('timeout' => 42));
+        $this->assertEquals(42, $imp->getProcessBuilderFactory()->getTimeout());
+    }
+
+    public function testTimeoutIsSetOnConfigurationSetting()
+    {
+        $imp = Implementation::load('php', null);
+        $imp->setConfiguration(new Configuration(array('timeout' => 42)));
+        $this->assertEquals(42, $imp->getProcessBuilderFactory()->getTimeout());
+    }
+
+    public function testTimeoutIsSetOnProcessBuilderSetting()
+    {
+        $imp = Implementation::load('php', null, array('timeout' => 42));
+
+        $factory = $this->getMock('Alchemy\BinaryDriver\ProcessBuilderFactoryInterface');
+        $factory->expects($this->once())
+            ->method('setTimeout')
+            ->with(42);
+
+        $imp->setProcessBuilderFactory($factory);
+    }
+
+    public function testListenRegistersAListener()
+    {
+        $imp = Implementation::load('php');
+
+        $listeners = $this->getMockBuilder('Alchemy\BinaryDriver\Listeners\Listeners')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $listener = $this->getMock('Alchemy\BinaryDriver\Listeners\ListenerInterface');
+
+        $listeners->expects($this->once())
+            ->method('register')
+            ->with($this->equalTo($listener), $this->equalTo($imp));
+
+        $reflexion = new \ReflectionClass('Alchemy\BinaryDriver\AbstractBinary');
+        $prop = $reflexion->getProperty('listenersManager');
+        $prop->setAccessible(true);
+        $prop->setValue($imp, $listeners);
+
+        $imp->listen($listener);
+    }
+
+    /**
+     * @dataProvider provideCommandParameters
+     */
+    public function testCommandRunsAProcess($parameters, $bypassErrors, $expectedParameters, $output)
+    {
+        $imp = Implementation::load('php');
+        $factory = $this->getMock('Alchemy\BinaryDriver\ProcessBuilderFactoryInterface');
+        $processRunner = $this->getMock('Alchemy\BinaryDriver\ProcessRunnerInterface');
+
+        $process = $this->getMockBuilder('Symfony\Component\Process\Process')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $processRunner->expects($this->once())
+            ->method('run')
+            ->with($this->equalTo($process), $this->isInstanceOf('SplObjectStorage'), $this->equalTo($bypassErrors))
+            ->will($this->returnValue($output));
+
+        $factory->expects($this->once())
+            ->method('create')
+            ->with($expectedParameters)
+            ->will($this->returnValue($process));
+
+        $imp->setProcessBuilderFactory($factory);
+        $imp->setProcessRunner($processRunner);
+
+        $this->assertEquals($output, $imp->command($parameters, $bypassErrors));
+    }
+
+    /**
+     * @dataProvider provideCommandWithListenersParameters
+     */
+    public function testCommandWithTemporaryListeners($parameters, $bypassErrors, $expectedParameters, $output, $count, $listeners)
+    {
+        $imp = Implementation::load('php');
+        $factory = $this->getMock('Alchemy\BinaryDriver\ProcessBuilderFactoryInterface');
+        $processRunner = $this->getMock('Alchemy\BinaryDriver\ProcessRunnerInterface');
+
+        $process = $this->getMockBuilder('Symfony\Component\Process\Process')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $firstStorage = $secondStorage = null;
+
+        $processRunner->expects($this->exactly(2))
+            ->method('run')
+            ->with($this->equalTo($process), $this->isInstanceOf('SplObjectStorage'), $this->equalTo($bypassErrors))
+            ->will($this->returnCallback(function ($process, $storage, $errors) use ($output, &$firstStorage, &$secondStorage) {
+                if (null === $firstStorage) {
+                    $firstStorage = $storage;
+                } else {
+                    $secondStorage = $storage;
+                }
+
+                return $output;
+            }));
+
+        $factory->expects($this->exactly(2))
+            ->method('create')
+            ->with($expectedParameters)
+            ->will($this->returnValue($process));
+
+        $imp->setProcessBuilderFactory($factory);
+        $imp->setProcessRunner($processRunner);
+
+        $this->assertEquals($output, $imp->command($parameters, $bypassErrors, $listeners));
+        $this->assertCount($count, $firstStorage);
+        $this->assertEquals($output, $imp->command($parameters, $bypassErrors));
+        $this->assertCount(0, $secondStorage);
+    }
+
+    public function provideCommandWithListenersParameters()
+    {
+        $listener = $this->getMock('Alchemy\BinaryDriver\Listeners\ListenerInterface');
+        $listener->expects($this->any())
+            ->method('forwardedEvents')
+            ->will($this->returnValue(array()));
+
+        $listener2 = $this->getMock('Alchemy\BinaryDriver\Listeners\ListenerInterface');
+        $listener2->expects($this->any())
+            ->method('forwardedEvents')
+            ->will($this->returnValue(array()));
+
+        return array(
+            array('-a', false, array('-a'), 'loubda', 2, array($listener, $listener2)),
+            array('-a', false, array('-a'), 'loubda', 1, array($listener)),
+            array('-a', false, array('-a'), 'loubda', 1, $listener),
+            array('-a', false, array('-a'), 'loubda', 0, array()),
+        );
+    }
+
+    public function provideCommandParameters()
+    {
+        return array(
+            array('-a', false, array('-a'), 'loubda'),
+            array('-a', true, array('-a'), 'loubda'),
+            array('-a -b', false, array('-a -b'), 'loubda'),
+            array(array('-a'), false, array('-a'), 'loubda'),
+            array(array('-a'), true, array('-a'), 'loubda'),
+            array(array('-a', '-b'), false, array('-a', '-b'), 'loubda'),
+        );
+    }
+
+    public function testUnlistenUnregistersAListener()
+    {
+        $imp = Implementation::load('php');
+
+        $listeners = $this->getMockBuilder('Alchemy\BinaryDriver\Listeners\Listeners')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $listener = $this->getMock('Alchemy\BinaryDriver\Listeners\ListenerInterface');
+
+        $listeners->expects($this->once())
+            ->method('unregister')
+            ->with($this->equalTo($listener), $this->equalTo($imp));
+
+        $reflexion = new \ReflectionClass('Alchemy\BinaryDriver\AbstractBinary');
+        $prop = $reflexion->getProperty('listenersManager');
+        $prop->setAccessible(true);
+        $prop->setValue($imp, $listeners);
+
+        $imp->unlisten($listener);
+    }
+}
+
+class Implementation extends AbstractBinary
+{
+    public function getName()
+    {
+        return 'Implementation';
+    }
+}

+ 97 - 0
vendor/alchemy/binary-driver/tests/Alchemy/Tests/BinaryDriver/AbstractProcessBuilderFactoryTest.php

@@ -0,0 +1,97 @@
+<?php
+
+namespace Alchemy\Tests\BinaryDriver;
+
+use Symfony\Component\Process\ExecutableFinder;
+use Alchemy\BinaryDriver\ProcessBuilderFactory;
+
+abstract class AbstractProcessBuilderFactoryTest extends \PHPUnit_Framework_TestCase
+{
+    public static $phpBinary;
+
+    private $original;
+    /**
+     * @return ProcessBuilderFactory
+     */
+    abstract protected function getProcessBuilderFactory($binary);
+
+    public function setUp()
+    {
+        ProcessBuilderFactory::$emulateSfLTS = null;
+        if (null === static::$phpBinary) {
+            $this->markTestSkipped('Unable to detect php binary, skipping');
+        }
+    }
+
+    public static function setUpBeforeClass()
+    {
+        $finder = new ExecutableFinder();
+        static::$phpBinary = $finder->find('php');
+    }
+
+    public function testThatBinaryIsSetOnConstruction()
+    {
+        $factory = $this->getProcessBuilderFactory(static::$phpBinary);
+        $this->assertEquals(static::$phpBinary, $factory->getBinary());
+    }
+
+    public function testGetSetBinary()
+    {
+        $finder = new ExecutableFinder();
+        $phpUnit = $finder->find('phpunit');
+
+        if (null === $phpUnit) {
+            $this->markTestSkipped('Unable to detect phpunit binary, skipping');
+        }
+
+        $factory = $this->getProcessBuilderFactory(static::$phpBinary);
+        $factory->useBinary($phpUnit);
+        $this->assertEquals($phpUnit, $factory->getBinary());
+    }
+
+    /**
+     * @expectedException Alchemy\BinaryDriver\Exception\InvalidArgumentException
+     */
+    public function testUseNonExistantBinary()
+    {
+        $factory = $this->getProcessBuilderFactory(static::$phpBinary);
+        $factory->useBinary('itissureitdoesnotexist');
+    }
+
+    public function testCreateShouldReturnAProcess()
+    {
+        $factory = $this->getProcessBuilderFactory(static::$phpBinary);
+        $process = $factory->create();
+
+        $this->assertInstanceOf('Symfony\Component\Process\Process', $process);
+        $this->assertEquals("'".static::$phpBinary."'", $process->getCommandLine());
+    }
+
+    public function testCreateWithStringArgument()
+    {
+        $factory = $this->getProcessBuilderFactory(static::$phpBinary);
+        $process = $factory->create('-v');
+
+        $this->assertInstanceOf('Symfony\Component\Process\Process', $process);
+        $this->assertEquals("'".static::$phpBinary."' '-v'", $process->getCommandLine());
+    }
+
+    public function testCreateWithArrayArgument()
+    {
+        $factory = $this->getProcessBuilderFactory(static::$phpBinary);
+        $process = $factory->create(array('-r', 'echo "Hello !";'));
+
+        $this->assertInstanceOf('Symfony\Component\Process\Process', $process);
+        $this->assertEquals("'".static::$phpBinary."' '-r' 'echo \"Hello !\";'", $process->getCommandLine());
+    }
+
+    public function testCreateWithTimeout()
+    {
+        $factory = $this->getProcessBuilderFactory(static::$phpBinary);
+        $factory->setTimeout(200);
+        $process = $factory->create(array('-i'));
+
+        $this->assertInstanceOf('Symfony\Component\Process\Process', $process);
+        $this->assertEquals(200, $process->getTimeout());
+    }
+}

+ 78 - 0
vendor/alchemy/binary-driver/tests/Alchemy/Tests/BinaryDriver/ConfigurationTest.php

@@ -0,0 +1,78 @@
+<?php
+
+namespace Alchemy\Tests\BinaryDriver;
+
+use Alchemy\BinaryDriver\Configuration;
+
+class ConfigurationTest extends \PHPUnit_Framework_TestCase
+{
+    public function testArrayAccessImplementation()
+    {
+        $configuration = new Configuration(array('key' => 'value'));
+
+        $this->assertTrue(isset($configuration['key']));
+        $this->assertEquals('value', $configuration['key']);
+
+        $this->assertFalse(isset($configuration['key2']));
+        unset($configuration['key']);
+        $this->assertFalse(isset($configuration['key']));
+
+        $configuration['key2'] = 'value2';
+        $this->assertTrue(isset($configuration['key2']));
+        $this->assertEquals('value2', $configuration['key2']);
+    }
+
+    public function testGetOnNonExistentKeyShouldReturnDefaultValue()
+    {
+        $conf = new Configuration();
+        $this->assertEquals('booba', $conf->get('hooba', 'booba'));
+        $this->assertEquals(null, $conf->get('hooba'));
+    }
+
+    public function testSetHasGetRemove()
+    {
+        $configuration = new Configuration(array('key' => 'value'));
+
+        $this->assertTrue($configuration->has('key'));
+        $this->assertEquals('value', $configuration->get('key'));
+
+        $this->assertFalse($configuration->has('key2'));
+        $configuration->remove('key');
+        $this->assertFalse($configuration->has('key'));
+
+        $configuration->set('key2', 'value2');
+        $this->assertTrue($configuration->has('key2'));
+        $this->assertEquals('value2', $configuration->get('key2'));
+    }
+
+    public function testIterator()
+    {
+        $data = array(
+            'key1' => 'value1',
+            'key2' => 'value2',
+            'key3' => 'value3',
+        );
+
+        $captured = array();
+        $conf = new Configuration($data);
+
+        foreach ($conf as $key => $value) {
+            $captured[$key] = $value;
+        }
+
+        $this->assertEquals($data, $captured);
+    }
+
+    public function testAll()
+    {
+        $data = array(
+            'key1' => 'value1',
+            'key2' => 'value2',
+            'key3' => 'value3',
+        );
+
+        $conf = new Configuration($data);
+        $this->assertEquals($data, $conf->all());
+    }
+
+}

+ 66 - 0
vendor/alchemy/binary-driver/tests/Alchemy/Tests/BinaryDriver/LTSProcessBuilderFactoryTest.php

@@ -0,0 +1,66 @@
+<?php
+
+namespace Alchemy\Tests\BinaryDriver;
+
+use Symfony\Component\Process\ProcessBuilder;
+use Alchemy\BinaryDriver\ProcessBuilderFactory;
+use Symfony\Component\Process\Process;
+
+class LTSProcessBuilderFactoryTest extends AbstractProcessBuilderFactoryTest
+{
+    protected function getProcessBuilderFactory($binary)
+    {
+        $factory = new ProcessBuilderFactory($binary);
+        $factory->setBuilder(new LTSProcessBuilder());
+        ProcessBuilderFactory::$emulateSfLTS = false;
+        $factory->useBinary($binary);
+
+        return $factory;
+    }
+}
+
+class LTSProcessBuilder extends ProcessBuilder
+{
+    private $arguments;
+    private $prefix;
+    private $timeout;
+
+    public function __construct(array $arguments = array())
+    {
+        $this->arguments = $arguments;
+        parent::__construct($arguments);
+    }
+
+    public function setArguments(array $arguments)
+    {
+        $this->arguments = $arguments;
+
+        return $this;
+    }
+
+    public function setPrefix($prefix)
+    {
+        $this->prefix = $prefix;
+
+        return $this;
+    }
+
+    public function setTimeout($timeout)
+    {
+        $this->timeout = $timeout;
+
+        return $this;
+    }
+
+    public function getProcess()
+    {
+        if (!$this->prefix && !count($this->arguments)) {
+            throw new LogicException('You must add() command arguments before calling getProcess().');
+        }
+
+        $args = $this->prefix ? array_merge(array($this->prefix), $this->arguments) : $this->arguments;
+        $script = implode(' ', array_map('escapeshellarg', $args));
+
+        return new Process($script, null, null, null, $this->timeout);
+    }
+}

+ 33 - 0
vendor/alchemy/binary-driver/tests/Alchemy/Tests/BinaryDriver/Listeners/DebugListenerTest.php

@@ -0,0 +1,33 @@
+<?php
+
+namespace Alchemy\Tests\BinaryDriver\Listeners;
+
+use Alchemy\BinaryDriver\Listeners\DebugListener;
+use Symfony\Component\Process\Process;
+
+class DebugListenerTest extends \PHPUnit_Framework_TestCase
+{
+    public function testHandle()
+    {
+        $listener = new DebugListener();
+
+        $lines = array();
+        $listener->on('debug', function ($line) use (&$lines) {
+            $lines[] = $line;
+        });
+        $listener->handle(Process::ERR, "first line\nsecond line");
+        $listener->handle(Process::OUT, "cool output");
+        $listener->handle('unknown', "lalala");
+        $listener->handle(Process::OUT, "another output\n");
+
+        $expected = array(
+            '[ERROR] first line',
+            '[ERROR] second line',
+            '[OUT] cool output',
+            '[OUT] another output',
+            '[OUT] ',
+        );
+
+        $this->assertEquals($expected, $lines);
+    }
+}

+ 92 - 0
vendor/alchemy/binary-driver/tests/Alchemy/Tests/BinaryDriver/Listeners/ListenersTest.php

@@ -0,0 +1,92 @@
+<?php
+
+namespace Alchemy\Tests\BinaryDriver\Listeners;
+
+use Alchemy\BinaryDriver\Listeners\Listeners;
+use Evenement\EventEmitter;
+use Alchemy\BinaryDriver\Listeners\ListenerInterface;
+
+class ListenersTest extends \PHPUnit_Framework_TestCase
+{
+    public function testRegister()
+    {
+        $listener = new TestListener();
+
+        $listeners = new Listeners();
+        $listeners->register($listener);
+
+        $n = 0;
+        $listener->on('received', function ($type, $data) use (&$n, &$capturedType, &$capturedData) {
+            $n++;
+            $capturedData = $data;
+            $capturedType = $type;
+        });
+
+        $type = 'type';
+        $data = 'data';
+
+        $listener->handle($type, $data);
+        $listener->handle($type, $data);
+
+        $listeners->unregister($listener);
+
+        $listener->handle($type, $data);
+
+        $this->assertEquals(3, $n);
+        $this->assertEquals($type, $capturedType);
+        $this->assertEquals($data, $capturedData);
+    }
+
+    public function testRegisterAndForwardThenUnregister()
+    {
+        $listener = new TestListener();
+        $target = new EventEmitter();
+
+        $n = 0;
+        $target->on('received', function ($type, $data) use (&$n, &$capturedType, &$capturedData) {
+            $n++;
+            $capturedData = $data;
+            $capturedType = $type;
+        });
+
+        $m = 0;
+        $listener->on('received', function ($type, $data) use (&$m, &$capturedType2, &$capturedData2) {
+            $m++;
+            $capturedData2 = $data;
+            $capturedType2 = $type;
+        });
+
+        $listeners = new Listeners();
+        $listeners->register($listener, $target);
+
+        $type = 'type';
+        $data = 'data';
+
+        $listener->handle($type, $data);
+        $listener->handle($type, $data);
+
+        $listeners->unregister($listener, $target);
+
+        $listener->handle($type, $data);
+
+        $this->assertEquals(2, $n);
+        $this->assertEquals(3, $m);
+        $this->assertEquals($type, $capturedType);
+        $this->assertEquals($data, $capturedData);
+        $this->assertEquals($type, $capturedType2);
+        $this->assertEquals($data, $capturedData2);
+    }
+}
+
+class TestListener extends EventEmitter implements ListenerInterface
+{
+    public function handle($type, $data)
+    {
+        $this->emit('received', array($type, $data));
+    }
+
+    public function forwardedEvents()
+    {
+        return array('received');
+    }
+}

+ 15 - 0
vendor/alchemy/binary-driver/tests/Alchemy/Tests/BinaryDriver/NONLTSProcessBuilderFactoryTest.php

@@ -0,0 +1,15 @@
+<?php
+
+namespace Alchemy\Tests\BinaryDriver;
+
+use Alchemy\BinaryDriver\ProcessBuilderFactory;
+
+class NONLTSProcessBuilderFactoryTest extends AbstractProcessBuilderFactoryTest
+{
+    protected function getProcessBuilderFactory($binary)
+    {
+        ProcessBuilderFactory::$emulateSfLTS = true;
+
+        return new ProcessBuilderFactory($binary);
+    }
+}

+ 208 - 0
vendor/alchemy/binary-driver/tests/Alchemy/Tests/BinaryDriver/ProcessRunnerTest.php

@@ -0,0 +1,208 @@
+<?php
+
+/*
+ * This file is part of Alchemy\BinaryDriver.
+ *
+ * (c) Alchemy <info@alchemy.fr>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Alchemy\Tests\BinaryDriver;
+
+use Alchemy\BinaryDriver\ProcessRunner;
+use Alchemy\BinaryDriver\BinaryDriverTestCase;
+use Alchemy\BinaryDriver\Exception\ExecutionFailureException;
+use Alchemy\BinaryDriver\Listeners\ListenerInterface;
+use Evenement\EventEmitter;
+use Symfony\Component\Process\Exception\RuntimeException as ProcessRuntimeException;
+
+class ProcessRunnerTest extends BinaryDriverTestCase
+{
+    public function getProcessRunner($logger)
+    {
+        return new ProcessRunner($logger, 'test-runner');
+    }
+
+    public function testRunSuccessFullProcess()
+    {
+        $logger = $this->createLoggerMock();
+        $runner = $this->getProcessRunner($logger);
+
+        $process = $this->createProcessMock(1, true, '--helloworld--', "Kikoo Romain", null, true);
+
+        $logger
+            ->expects($this->never())
+            ->method('error');
+        $logger
+            ->expects($this->exactly(2))
+            ->method('info');
+
+        $this->assertEquals('Kikoo Romain', $runner->run($process, new \SplObjectStorage(), false));
+    }
+
+    public function testRunSuccessFullProcessBypassingErrors()
+    {
+        $logger = $this->createLoggerMock();
+        $runner = $this->getProcessRunner($logger);
+
+        $process = $this->createProcessMock(1, true, '--helloworld--', "Kikoo Romain", null, true);
+
+        $logger
+            ->expects($this->never())
+            ->method('error');
+        $logger
+            ->expects($this->exactly(2))
+            ->method('info');
+
+        $this->assertEquals('Kikoo Romain', $runner->run($process, new \SplObjectStorage(), true));
+    }
+
+    public function testRunFailingProcess()
+    {
+        $logger = $this->createLoggerMock();
+        $runner = $this->getProcessRunner($logger);
+
+        $process = $this->createProcessMock(1, false, '--helloworld--', null, null, true);
+
+        $logger
+            ->expects($this->once())
+            ->method('error');
+        $logger
+            ->expects($this->once())
+            ->method('info');
+
+        try {
+            $runner->run($process, new \SplObjectStorage(), false);
+            $this->fail('An exception should have been raised');
+        } catch (ExecutionFailureException $e) {
+
+        }
+    }
+
+    public function testRunFailingProcessWithException()
+    {
+        $logger = $this->createLoggerMock();
+        $runner = $this->getProcessRunner($logger);
+
+        $exception = new ProcessRuntimeException('Process Failed');
+        $process = $this->getMockBuilder('Symfony\Component\Process\Process')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $process->expects($this->once())
+            ->method('run')
+            ->will($this->throwException($exception));
+
+        $logger
+            ->expects($this->once())
+            ->method('error');
+        $logger
+            ->expects($this->once())
+            ->method('info');
+
+        try {
+            $runner->run($process, new \SplObjectStorage(), false);
+            $this->fail('An exception should have been raised');
+        } catch (ExecutionFailureException $e) {
+            $this->assertEquals($exception, $e->getPrevious());
+        }
+    }
+
+    public function testRunfailingProcessBypassingErrors()
+    {
+        $logger = $this->createLoggerMock();
+        $runner = $this->getProcessRunner($logger);
+
+        $process = $this->createProcessMock(1, false, '--helloworld--', 'Hello output', null, true);
+
+        $logger
+            ->expects($this->once())
+            ->method('error');
+        $logger
+            ->expects($this->once())
+            ->method('info');
+
+        $this->assertNull($runner->run($process, new \SplObjectStorage(), true));
+    }
+
+    public function testRunFailingProcessWithExceptionBypassingErrors()
+    {
+        $logger = $this->createLoggerMock();
+        $runner = $this->getProcessRunner($logger);
+
+        $exception = new ProcessRuntimeException('Process Failed');
+        $process = $this->getMockBuilder('Symfony\Component\Process\Process')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $process->expects($this->once())
+            ->method('run')
+            ->will($this->throwException($exception));
+
+        $logger
+            ->expects($this->once())
+            ->method('error');
+        $logger
+            ->expects($this->once())
+            ->method('info');
+
+        $this->assertNull($runner->run($process, new \SplObjectStorage(), true));
+    }
+
+    public function testRunSuccessFullProcessWithHandlers()
+    {
+        $logger = $this->createLoggerMock();
+        $runner = $this->getProcessRunner($logger);
+
+        $capturedCallback = null;
+
+        $process = $this->createProcessMock(1, true, '--helloworld--', "Kikoo Romain", null, true);
+        $process->expects($this->once())
+            ->method('run')
+            ->with($this->isInstanceOf('Closure'))
+            ->will($this->returnCallback(function ($callback) use (&$capturedCallback) {
+                $capturedCallback = $callback;
+            }));
+
+        $logger
+            ->expects($this->never())
+            ->method('error');
+        $logger
+            ->expects($this->exactly(2))
+            ->method('info');
+
+        $listener = new TestListener();
+        $storage = new \SplObjectStorage();
+        $storage->attach($listener);
+
+        $capturedType = $capturedData = null;
+
+        $listener->on('received', function ($type, $data) use (&$capturedType, &$capturedData) {
+            $capturedData = $data;
+            $capturedType = $type;
+        });
+
+        $this->assertEquals('Kikoo Romain', $runner->run($process, $storage, false));
+
+        $type = 'err';
+        $data = 'data';
+
+        $capturedCallback($type, $data);
+
+        $this->assertEquals($data, $capturedData);
+        $this->assertEquals($type, $capturedType);
+    }
+}
+
+class TestListener extends EventEmitter implements ListenerInterface
+{
+    public function handle($type, $data)
+    {
+        return $this->emit('received', array($type, $data));
+    }
+
+    public function forwardedEvents()
+    {
+        return array();
+    }
+}

+ 4 - 0
vendor/alchemy/binary-driver/tests/bootstrap.php

@@ -0,0 +1,4 @@
+<?php
+
+$loader = require __DIR__.'/../vendor/autoload.php';
+$loader->add('Alchemy\Tests', __DIR__);

+ 7 - 0
vendor/autoload.php

@@ -0,0 +1,7 @@
+<?php
+
+// autoload.php generated by Composer
+
+require_once __DIR__ . '/composer' . '/autoload_real.php';
+
+return ComposerAutoloaderInit75f7ea26a11f6be21d13acba7a2d0249::getLoader();

+ 246 - 0
vendor/composer/ClassLoader.php

@@ -0,0 +1,246 @@
+<?php
+
+/*
+ * This file is part of Composer.
+ *
+ * (c) Nils Adermann <naderman@naderman.de>
+ *     Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Composer\Autoload;
+
+/**
+ * ClassLoader implements a PSR-0 class loader
+ *
+ * See https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md
+ *
+ *     $loader = new \Composer\Autoload\ClassLoader();
+ *
+ *     // register classes with namespaces
+ *     $loader->add('Symfony\Component', __DIR__.'/component');
+ *     $loader->add('Symfony',           __DIR__.'/framework');
+ *
+ *     // activate the autoloader
+ *     $loader->register();
+ *
+ *     // to enable searching the include path (eg. for PEAR packages)
+ *     $loader->setUseIncludePath(true);
+ *
+ * In this example, if you try to use a class in the Symfony\Component
+ * namespace or one of its children (Symfony\Component\Console for instance),
+ * the autoloader will first look for the class under the component/
+ * directory, and it will then fallback to the framework/ directory if not
+ * found before giving up.
+ *
+ * This class is loosely based on the Symfony UniversalClassLoader.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ * @author Jordi Boggiano <j.boggiano@seld.be>
+ */
+class ClassLoader
+{
+    private $prefixes = array();
+    private $fallbackDirs = array();
+    private $useIncludePath = false;
+    private $classMap = array();
+
+    public function getPrefixes()
+    {
+        return call_user_func_array('array_merge', $this->prefixes);
+    }
+
+    public function getFallbackDirs()
+    {
+        return $this->fallbackDirs;
+    }
+
+    public function getClassMap()
+    {
+        return $this->classMap;
+    }
+
+    /**
+     * @param array $classMap Class to filename map
+     */
+    public function addClassMap(array $classMap)
+    {
+        if ($this->classMap) {
+            $this->classMap = array_merge($this->classMap, $classMap);
+        } else {
+            $this->classMap = $classMap;
+        }
+    }
+
+    /**
+     * Registers a set of classes, merging with any others previously set.
+     *
+     * @param string       $prefix  The classes prefix
+     * @param array|string $paths   The location(s) of the classes
+     * @param bool         $prepend Prepend the location(s)
+     */
+    public function add($prefix, $paths, $prepend = false)
+    {
+        if (!$prefix) {
+            if ($prepend) {
+                $this->fallbackDirs = array_merge(
+                    (array) $paths,
+                    $this->fallbackDirs
+                );
+            } else {
+                $this->fallbackDirs = array_merge(
+                    $this->fallbackDirs,
+                    (array) $paths
+                );
+            }
+
+            return;
+        }
+
+        $first = $prefix[0];
+        if (!isset($this->prefixes[$first][$prefix])) {
+            $this->prefixes[$first][$prefix] = (array) $paths;
+
+            return;
+        }
+        if ($prepend) {
+            $this->prefixes[$first][$prefix] = array_merge(
+                (array) $paths,
+                $this->prefixes[$first][$prefix]
+            );
+        } else {
+            $this->prefixes[$first][$prefix] = array_merge(
+                $this->prefixes[$first][$prefix],
+                (array) $paths
+            );
+        }
+    }
+
+    /**
+     * Registers a set of classes, replacing any others previously set.
+     *
+     * @param string       $prefix The classes prefix
+     * @param array|string $paths  The location(s) of the classes
+     */
+    public function set($prefix, $paths)
+    {
+        if (!$prefix) {
+            $this->fallbackDirs = (array) $paths;
+
+            return;
+        }
+        $this->prefixes[substr($prefix, 0, 1)][$prefix] = (array) $paths;
+    }
+
+    /**
+     * Turns on searching the include path for class files.
+     *
+     * @param bool $useIncludePath
+     */
+    public function setUseIncludePath($useIncludePath)
+    {
+        $this->useIncludePath = $useIncludePath;
+    }
+
+    /**
+     * Can be used to check if the autoloader uses the include path to check
+     * for classes.
+     *
+     * @return bool
+     */
+    public function getUseIncludePath()
+    {
+        return $this->useIncludePath;
+    }
+
+    /**
+     * Registers this instance as an autoloader.
+     *
+     * @param bool $prepend Whether to prepend the autoloader or not
+     */
+    public function register($prepend = false)
+    {
+        spl_autoload_register(array($this, 'loadClass'), true, $prepend);
+    }
+
+    /**
+     * Unregisters this instance as an autoloader.
+     */
+    public function unregister()
+    {
+        spl_autoload_unregister(array($this, 'loadClass'));
+    }
+
+    /**
+     * Loads the given class or interface.
+     *
+     * @param  string    $class The name of the class
+     * @return bool|null True if loaded, null otherwise
+     */
+    public function loadClass($class)
+    {
+        if ($file = $this->findFile($class)) {
+            include $file;
+
+            return true;
+        }
+    }
+
+    /**
+     * Finds the path to the file where the class is defined.
+     *
+     * @param string $class The name of the class
+     *
+     * @return string|false The path if found, false otherwise
+     */
+    public function findFile($class)
+    {
+        // work around for PHP 5.3.0 - 5.3.2 https://bugs.php.net/50731
+        if ('\\' == $class[0]) {
+            $class = substr($class, 1);
+        }
+
+        if (isset($this->classMap[$class])) {
+            return $this->classMap[$class];
+        }
+
+        if (false !== $pos = strrpos($class, '\\')) {
+            // namespaced class name
+            $classPath = strtr(substr($class, 0, $pos), '\\', DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
+            $className = substr($class, $pos + 1);
+        } else {
+            // PEAR-like class name
+            $classPath = null;
+            $className = $class;
+        }
+
+        $classPath .= strtr($className, '_', DIRECTORY_SEPARATOR) . '.php';
+
+        $first = $class[0];
+        if (isset($this->prefixes[$first])) {
+            foreach ($this->prefixes[$first] as $prefix => $dirs) {
+                if (0 === strpos($class, $prefix)) {
+                    foreach ($dirs as $dir) {
+                        if (file_exists($dir . DIRECTORY_SEPARATOR . $classPath)) {
+                            return $dir . DIRECTORY_SEPARATOR . $classPath;
+                        }
+                    }
+                }
+            }
+        }
+
+        foreach ($this->fallbackDirs as $dir) {
+            if (file_exists($dir . DIRECTORY_SEPARATOR . $classPath)) {
+                return $dir . DIRECTORY_SEPARATOR . $classPath;
+            }
+        }
+
+        if ($this->useIncludePath && $file = stream_resolve_include_path($classPath)) {
+            return $file;
+        }
+
+        return $this->classMap[$class] = false;
+    }
+}

+ 9 - 0
vendor/composer/autoload_classmap.php

@@ -0,0 +1,9 @@
+<?php
+
+// autoload_classmap.php generated by Composer
+
+$vendorDir = dirname(dirname(__FILE__));
+$baseDir = dirname($vendorDir);
+
+return array(
+);

+ 16 - 0
vendor/composer/autoload_namespaces.php

@@ -0,0 +1,16 @@
+<?php
+
+// autoload_namespaces.php generated by Composer
+
+$vendorDir = dirname(dirname(__FILE__));
+$baseDir = dirname($vendorDir);
+
+return array(
+    'Symfony\\Component\\Process\\' => array($vendorDir . '/symfony/process'),
+    'Psr\\Log\\' => array($vendorDir . '/psr/log'),
+    'Monolog' => array($vendorDir . '/monolog/monolog/src'),
+    'FFMpeg' => array($vendorDir . '/php-ffmpeg/php-ffmpeg/src'),
+    'Evenement' => array($vendorDir . '/evenement/evenement/src'),
+    'Doctrine\\Common\\Cache\\' => array($vendorDir . '/doctrine/cache/lib'),
+    'Alchemy' => array($vendorDir . '/alchemy/binary-driver/src'),
+);

+ 43 - 0
vendor/composer/autoload_real.php

@@ -0,0 +1,43 @@
+<?php
+
+// autoload_real.php generated by Composer
+
+class ComposerAutoloaderInit75f7ea26a11f6be21d13acba7a2d0249
+{
+    private static $loader;
+
+    public static function loadClassLoader($class)
+    {
+        if ('Composer\Autoload\ClassLoader' === $class) {
+            require __DIR__ . '/ClassLoader.php';
+        }
+    }
+
+    public static function getLoader()
+    {
+        if (null !== self::$loader) {
+            return self::$loader;
+        }
+
+        spl_autoload_register(array('ComposerAutoloaderInit75f7ea26a11f6be21d13acba7a2d0249', 'loadClassLoader'), true, true);
+        self::$loader = $loader = new \Composer\Autoload\ClassLoader();
+        spl_autoload_unregister(array('ComposerAutoloaderInit75f7ea26a11f6be21d13acba7a2d0249', 'loadClassLoader'));
+
+        $vendorDir = dirname(__DIR__);
+        $baseDir = dirname($vendorDir);
+
+        $map = require __DIR__ . '/autoload_namespaces.php';
+        foreach ($map as $namespace => $path) {
+            $loader->set($namespace, $path);
+        }
+
+        $classMap = require __DIR__ . '/autoload_classmap.php';
+        if ($classMap) {
+            $loader->addClassMap($classMap);
+        }
+
+        $loader->register(true);
+
+        return $loader;
+    }
+}

+ 397 - 0
vendor/composer/installed.json

@@ -0,0 +1,397 @@
+[
+    {
+        "name": "evenement/evenement",
+        "version": "v1.0.0",
+        "version_normalized": "1.0.0.0",
+        "source": {
+            "type": "git",
+            "url": "https://github.com/igorw/evenement.git",
+            "reference": "fa966683e7df3e5dd5929d984a44abfbd6bafe8d"
+        },
+        "dist": {
+            "type": "zip",
+            "url": "https://api.github.com/repos/igorw/evenement/zipball/fa966683e7df3e5dd5929d984a44abfbd6bafe8d",
+            "reference": "fa966683e7df3e5dd5929d984a44abfbd6bafe8d",
+            "shasum": ""
+        },
+        "require": {
+            "php": ">=5.3.0"
+        },
+        "time": "2012-05-30 15:01:08",
+        "type": "library",
+        "installation-source": "dist",
+        "autoload": {
+            "psr-0": {
+                "Evenement": "src"
+            }
+        },
+        "notification-url": "https://packagist.org/downloads/",
+        "license": [
+            "MIT"
+        ],
+        "authors": [
+            {
+                "name": "Igor Wiedler",
+                "email": "igor@wiedler.ch",
+                "homepage": "http://wiedler.ch/igor/"
+            }
+        ],
+        "description": "Événement is a very simple event dispatching library for PHP 5.3",
+        "keywords": [
+            "event-dispatcher"
+        ]
+    },
+    {
+        "name": "doctrine/cache",
+        "version": "v1.1",
+        "version_normalized": "1.1.0.0",
+        "source": {
+            "type": "git",
+            "url": "https://github.com/doctrine/cache.git",
+            "reference": "2c9761ff1d13e188d5f7378066c1ce2882d7a336"
+        },
+        "dist": {
+            "type": "zip",
+            "url": "https://api.github.com/repos/doctrine/cache/zipball/2c9761ff1d13e188d5f7378066c1ce2882d7a336",
+            "reference": "2c9761ff1d13e188d5f7378066c1ce2882d7a336",
+            "shasum": ""
+        },
+        "require": {
+            "php": ">=5.3.2"
+        },
+        "conflict": {
+            "doctrine/common": ">2.2,<2.4"
+        },
+        "time": "2013-08-07 16:04:25",
+        "type": "library",
+        "extra": {
+            "branch-alias": {
+                "dev-master": "1.0.x-dev"
+            }
+        },
+        "installation-source": "dist",
+        "autoload": {
+            "psr-0": {
+                "Doctrine\\Common\\Cache\\": "lib/"
+            }
+        },
+        "notification-url": "https://packagist.org/downloads/",
+        "license": [
+            "MIT"
+        ],
+        "authors": [
+            {
+                "name": "Jonathan Wage",
+                "email": "jonwage@gmail.com",
+                "homepage": "http://www.jwage.com/"
+            },
+            {
+                "name": "Guilherme Blanco",
+                "email": "guilhermeblanco@gmail.com",
+                "homepage": "http://www.instaclick.com"
+            },
+            {
+                "name": "Roman Borschel",
+                "email": "roman@code-factory.org"
+            },
+            {
+                "name": "Benjamin Eberlei",
+                "email": "kontakt@beberlei.de"
+            },
+            {
+                "name": "Johannes Schmitt",
+                "email": "schmittjoh@gmail.com",
+                "homepage": "http://jmsyst.com",
+                "role": "Developer of wrapped JMSSerializerBundle"
+            }
+        ],
+        "description": "Caching library offering an object-oriented API for many cache backends",
+        "homepage": "http://www.doctrine-project.org",
+        "keywords": [
+            "cache",
+            "caching"
+        ]
+    },
+    {
+        "name": "psr/log",
+        "version": "1.0.0",
+        "version_normalized": "1.0.0.0",
+        "source": {
+            "type": "git",
+            "url": "https://github.com/php-fig/log.git",
+            "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b"
+        },
+        "dist": {
+            "type": "zip",
+            "url": "https://api.github.com/repos/php-fig/log/zipball/fe0936ee26643249e916849d48e3a51d5f5e278b",
+            "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b",
+            "shasum": ""
+        },
+        "time": "2012-12-21 11:40:51",
+        "type": "library",
+        "installation-source": "dist",
+        "autoload": {
+            "psr-0": {
+                "Psr\\Log\\": ""
+            }
+        },
+        "notification-url": "https://packagist.org/downloads/",
+        "license": [
+            "MIT"
+        ],
+        "authors": [
+            {
+                "name": "PHP-FIG",
+                "homepage": "http://www.php-fig.org/"
+            }
+        ],
+        "description": "Common interface for logging libraries",
+        "keywords": [
+            "log",
+            "psr",
+            "psr-3"
+        ]
+    },
+    {
+        "name": "symfony/process",
+        "version": "v2.3.4",
+        "version_normalized": "2.3.4.0",
+        "target-dir": "Symfony/Component/Process",
+        "source": {
+            "type": "git",
+            "url": "https://github.com/symfony/Process.git",
+            "reference": "1e91553e1cedd0b8fb1da6ea4f89b02e21713d5b"
+        },
+        "dist": {
+            "type": "zip",
+            "url": "https://api.github.com/repos/symfony/Process/zipball/1e91553e1cedd0b8fb1da6ea4f89b02e21713d5b",
+            "reference": "1e91553e1cedd0b8fb1da6ea4f89b02e21713d5b",
+            "shasum": ""
+        },
+        "require": {
+            "php": ">=5.3.3"
+        },
+        "time": "2013-08-22 06:42:25",
+        "type": "library",
+        "extra": {
+            "branch-alias": {
+                "dev-master": "2.3-dev"
+            }
+        },
+        "installation-source": "dist",
+        "autoload": {
+            "psr-0": {
+                "Symfony\\Component\\Process\\": ""
+            }
+        },
+        "notification-url": "https://packagist.org/downloads/",
+        "license": [
+            "MIT"
+        ],
+        "authors": [
+            {
+                "name": "Fabien Potencier",
+                "email": "fabien@symfony.com"
+            },
+            {
+                "name": "Symfony Community",
+                "homepage": "http://symfony.com/contributors"
+            }
+        ],
+        "description": "Symfony Process Component",
+        "homepage": "http://symfony.com"
+    },
+    {
+        "name": "monolog/monolog",
+        "version": "1.6.0",
+        "version_normalized": "1.6.0.0",
+        "source": {
+            "type": "git",
+            "url": "https://github.com/Seldaek/monolog.git",
+            "reference": "f72392d0e6eb855118f5a84e89ac2d257c704abd"
+        },
+        "dist": {
+            "type": "zip",
+            "url": "https://api.github.com/repos/Seldaek/monolog/zipball/f72392d0e6eb855118f5a84e89ac2d257c704abd",
+            "reference": "f72392d0e6eb855118f5a84e89ac2d257c704abd",
+            "shasum": ""
+        },
+        "require": {
+            "php": ">=5.3.0",
+            "psr/log": "~1.0"
+        },
+        "require-dev": {
+            "doctrine/couchdb": "dev-master",
+            "mlehner/gelf-php": "1.0.*",
+            "raven/raven": "0.5.*"
+        },
+        "suggest": {
+            "doctrine/couchdb": "Allow sending log messages to a CouchDB server",
+            "ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)",
+            "ext-mongo": "Allow sending log messages to a MongoDB server",
+            "mlehner/gelf-php": "Allow sending log messages to a GrayLog2 server",
+            "raven/raven": "Allow sending log messages to a Sentry server"
+        },
+        "time": "2013-07-28 22:38:30",
+        "type": "library",
+        "extra": {
+            "branch-alias": {
+                "dev-master": "1.6.x-dev"
+            }
+        },
+        "installation-source": "dist",
+        "autoload": {
+            "psr-0": {
+                "Monolog": "src/"
+            }
+        },
+        "notification-url": "https://packagist.org/downloads/",
+        "license": [
+            "MIT"
+        ],
+        "authors": [
+            {
+                "name": "Jordi Boggiano",
+                "email": "j.boggiano@seld.be",
+                "homepage": "http://seld.be",
+                "role": "Developer"
+            }
+        ],
+        "description": "Sends your logs to files, sockets, inboxes, databases and various web services",
+        "homepage": "http://github.com/Seldaek/monolog",
+        "keywords": [
+            "log",
+            "logging",
+            "psr-3"
+        ]
+    },
+    {
+        "name": "alchemy/binary-driver",
+        "version": "1.5.0",
+        "version_normalized": "1.5.0.0",
+        "source": {
+            "type": "git",
+            "url": "https://github.com/alchemy-fr/BinaryDriver.git",
+            "reference": "b32c03d4b56ce29f783051eac55887adae654b41"
+        },
+        "dist": {
+            "type": "zip",
+            "url": "https://api.github.com/repos/alchemy-fr/BinaryDriver/zipball/b32c03d4b56ce29f783051eac55887adae654b41",
+            "reference": "b32c03d4b56ce29f783051eac55887adae654b41",
+            "shasum": ""
+        },
+        "require": {
+            "evenement/evenement": "~1.0",
+            "monolog/monolog": "~1.3",
+            "php": ">=5.3.3",
+            "psr/log": "~1.0",
+            "symfony/process": "~2.0"
+        },
+        "require-dev": {
+            "phpunit/phpunit": "~3.7"
+        },
+        "time": "2013-06-21 15:51:20",
+        "type": "library",
+        "installation-source": "dist",
+        "autoload": {
+            "psr-0": {
+                "Alchemy": "src"
+            }
+        },
+        "notification-url": "https://packagist.org/downloads/",
+        "license": [
+            "MIT"
+        ],
+        "authors": [
+            {
+                "name": "Romain Neutron",
+                "email": "imprec@gmail.com",
+                "homepage": "http://www.lickmychip.com/"
+            },
+            {
+                "name": "Nicolas Le Goff",
+                "email": "legoff.n@gmail.com"
+            },
+            {
+                "name": "Phraseanet Team",
+                "email": "info@alchemy.fr",
+                "homepage": "http://www.phraseanet.com/"
+            }
+        ],
+        "description": "A set of tools to build binary drivers",
+        "keywords": [
+            "binary",
+            "driver"
+        ]
+    },
+    {
+        "name": "php-ffmpeg/php-ffmpeg",
+        "version": "0.3.x-dev",
+        "version_normalized": "0.3.9999999.9999999-dev",
+        "source": {
+            "type": "git",
+            "url": "https://github.com/alchemy-fr/PHP-FFmpeg.git",
+            "reference": "9fcb485d497872e674cb14eb3df1386dbda9169b"
+        },
+        "dist": {
+            "type": "zip",
+            "url": "https://api.github.com/repos/alchemy-fr/PHP-FFmpeg/zipball/9fcb485d497872e674cb14eb3df1386dbda9169b",
+            "reference": "9fcb485d497872e674cb14eb3df1386dbda9169b",
+            "shasum": ""
+        },
+        "require": {
+            "alchemy/binary-driver": "~1.5",
+            "doctrine/cache": "~1.0",
+            "evenement/evenement": "~1.0",
+            "php": ">=5.3.3"
+        },
+        "require-dev": {
+            "phpunit/phpunit": "~3.7",
+            "sami/sami": "~1.0",
+            "silex/silex": "~1.0"
+        },
+        "suggest": {
+            "php-ffmpeg/extras": "A compilation of common audio & video drivers for PHP-FFMpeg"
+        },
+        "time": "2013-08-08 10:15:15",
+        "type": "library",
+        "extra": {
+            "branch-alias": {
+                "dev-master": "0.4-dev"
+            }
+        },
+        "installation-source": "source",
+        "autoload": {
+            "psr-0": {
+                "FFMpeg": "src"
+            }
+        },
+        "notification-url": "https://packagist.org/downloads/",
+        "license": [
+            "MIT"
+        ],
+        "authors": [
+            {
+                "name": "Romain Neutron",
+                "email": "imprec@gmail.com",
+                "homepage": "http://www.lickmychip.com/"
+            },
+            {
+                "name": "Phraseanet Team",
+                "email": "info@alchemy.fr",
+                "homepage": "http://www.phraseanet.com/"
+            }
+        ],
+        "description": "FFMpeg PHP, an Object Oriented library to communicate with AVconv / ffmpeg",
+        "keywords": [
+            "audio",
+            "audio processing",
+            "avconv",
+            "avprobe",
+            "ffmpeg",
+            "ffprobe",
+            "video",
+            "video processing"
+        ]
+    }
+]

+ 9 - 0
vendor/doctrine/cache/.travis.yml

@@ -0,0 +1,9 @@
+language: php
+
+php:
+  - 5.3
+  - 5.4
+  - 5.5
+
+before_script:
+    - composer --prefer-source --dev install

+ 19 - 0
vendor/doctrine/cache/LICENSE

@@ -0,0 +1,19 @@
+Copyright (c) 2006-2012 Doctrine Project
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.

+ 9 - 0
vendor/doctrine/cache/README.md

@@ -0,0 +1,9 @@
+# Doctrine Cache
+
+Cache component extracted from the Doctrine Common project.
+
+## Changelog
+
+### v1.1
+
+* Added support for MongoDB as Cache Provider

+ 29 - 0
vendor/doctrine/cache/composer.json

@@ -0,0 +1,29 @@
+{
+    "name": "doctrine/cache",
+    "type": "library",
+    "description": "Caching library offering an object-oriented API for many cache backends",
+    "keywords": ["cache", "caching"],
+    "homepage": "http://www.doctrine-project.org",
+    "license": "MIT",
+    "authors": [
+        {"name": "Guilherme Blanco", "email": "guilhermeblanco@gmail.com"},
+        {"name": "Roman Borschel", "email": "roman@code-factory.org"},
+        {"name": "Benjamin Eberlei", "email": "kontakt@beberlei.de"},
+        {"name": "Jonathan Wage", "email": "jonwage@gmail.com"},
+        {"name": "Johannes Schmitt", "email": "schmittjoh@gmail.com"}
+    ],
+    "require": {
+        "php": ">=5.3.2"
+    },
+    "conflict": {
+        "doctrine/common": ">2.2,<2.4"
+    },
+    "autoload": {
+        "psr-0": { "Doctrine\\Common\\Cache\\": "lib/" }
+    },
+    "extra": {
+        "branch-alias": {
+            "dev-master": "1.0.x-dev"
+        }
+    }
+}

+ 91 - 0
vendor/doctrine/cache/lib/Doctrine/Common/Cache/ApcCache.php

@@ -0,0 +1,91 @@
+<?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 MIT license. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Cache;
+
+/**
+ * APC cache provider.
+ *
+ * @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)
+    {
+        return apc_exists($id);
+    }
+
+    /**
+     * {@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_AVAILABLE => $sma['avail_mem'],
+        );
+    }
+}

+ 93 - 0
vendor/doctrine/cache/lib/Doctrine/Common/Cache/ArrayCache.php

@@ -0,0 +1,93 @@
+<?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 MIT license. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Cache;
+
+/**
+ * Array cache driver.
+ *
+ * @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;
+    }
+}

+ 111 - 0
vendor/doctrine/cache/lib/Doctrine/Common/Cache/Cache.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 MIT license. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Cache;
+
+/**
+ * Interface for cache drivers.
+ *
+ * @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_AVAILABLE = 'memory_available';
+    /**
+     * Only for backward compatibility (may be removed in next major release)
+     *
+     * @deprecated
+     */
+    const STATS_MEMORY_AVAILIABLE = 'memory_available';
+
+    /**
+     * Fetches an entry from the cache.
+     *
+     * @param string $id The id of the cache entry to fetch.
+     *
+     * @return mixed The cached data or FALSE, if no cache entry exists for the given id.
+     */
+    function fetch($id);
+
+    /**
+     * Tests if an entry exists in the cache.
+     *
+     * @param string $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 mixed  $data     The cache entry/data.
+     * @param int    $lifeTime The cache 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 The cache id.
+     *
+     * @return boolean TRUE if the cache entry was successfully deleted, FALSE otherwise.
+     */
+    function delete($id);
+
+    /**
+     * Retrieves cached information from the 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
+     *
+     * @return array|null An associative array with server's statistics if available, NULL otherwise.
+     */
+    function getStats();
+}

+ 240 - 0
vendor/doctrine/cache/lib/Doctrine/Common/Cache/CacheProvider.php

@@ -0,0 +1,240 @@
+<?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 MIT license. 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]';
+
+    /**
+     * The namespace to prefix all cache ids with.
+     *
+     * @var string
+     */
+    private $namespace = '';
+
+    /**
+     * The namespace version.
+     *
+     * @var string
+     */
+    private $namespaceVersion;
+
+    /**
+     * Sets the namespace to prefix all cache ids with.
+     *
+     * @param string $namespace
+     *
+     * @return void
+     */
+    public function setNamespace($namespace)
+    {
+        $this->namespace = (string) $namespace;
+    }
+
+    /**
+     * Retrieves 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();
+    }
+
+    /**
+     * Flushes all cache entries.
+     *
+     * @return boolean TRUE if the cache entries were successfully flushed, FALSE otherwise.
+     */
+    public function flushAll()
+    {
+        return $this->doFlush();
+    }
+
+    /**
+     * Deletes all cache entries.
+     *
+     * @return boolean TRUE if the cache entries were successfully deleted, FALSE otherwise.
+     */
+    public function deleteAll()
+    {
+        $namespaceCacheKey = $this->getNamespaceCacheKey();
+        $namespaceVersion  = $this->getNamespaceVersion() + 1;
+
+        $this->namespaceVersion = $namespaceVersion;
+
+        return $this->doSave($namespaceCacheKey, $namespaceVersion);
+    }
+
+    /**
+     * Prefixes the passed id with the configured namespace value.
+     *
+     * @param string $id The id to namespace.
+     *
+     * @return string The namespaced id.
+     */
+    private function getNamespacedId($id)
+    {
+        $namespaceVersion  = $this->getNamespaceVersion();
+
+        return sprintf('%s[%s][%s]', $this->namespace, $id, $namespaceVersion);
+    }
+
+    /**
+     * Returns the namespace cache key.
+     *
+     * @return string
+     */
+    private function getNamespaceCacheKey()
+    {
+        return sprintf(self::DOCTRINE_NAMESPACE_CACHEKEY, $this->namespace);
+    }
+
+    /**
+     * Returns the namespace version.
+     *
+     * @return string
+     */
+    private function getNamespaceVersion()
+    {
+        if (null !== $this->namespaceVersion) {
+            return $this->namespaceVersion;
+        }
+
+        $namespaceCacheKey = $this->getNamespaceCacheKey();
+        $namespaceVersion = $this->doFetch($namespaceCacheKey);
+
+        if (false === $namespaceVersion) {
+            $namespaceVersion = 1;
+
+            $this->doSave($namespaceCacheKey, $namespaceVersion);
+        }
+
+        $this->namespaceVersion = $namespaceVersion;
+
+        return $this->namespaceVersion;
+    }
+
+    /**
+     * Fetches an entry from the cache.
+     *
+     * @param string $id The id of the cache entry to fetch.
+     *
+     * @return string|bool The cached data or FALSE, if no cache entry exists for the given id.
+     */
+    abstract protected function doFetch($id);
+
+    /**
+     * Tests if an entry exists in the cache.
+     *
+     * @param string $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 != 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.
+     */
+    abstract protected function doSave($id, $data, $lifeTime = 0);
+
+    /**
+     * Deletes a cache entry.
+     *
+     * @param string $id The cache id.
+     *
+     * @return boolean TRUE if the cache entry was successfully deleted, FALSE otherwise.
+     */
+    abstract protected function doDelete($id);
+
+    /**
+     * Flushes all cache entries.
+     *
+     * @return boolean TRUE if the cache entry was successfully deleted, FALSE otherwise.
+     */
+    abstract protected function doFlush();
+
+    /**
+     * Retrieves cached information from the data store.
+     *
+     * @since 2.2
+     *
+     * @return array|null An associative array with server's statistics if available, NULL otherwise.
+     */
+    abstract protected function doGetStats();
+}

+ 121 - 0
vendor/doctrine/cache/lib/Doctrine/Common/Cache/CouchbaseCache.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 MIT license. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Cache;
+
+use \Couchbase;
+
+/**
+ * Couchbase cache provider.
+ *
+ * @link   www.doctrine-project.org
+ * @since  2.4
+ * @author Michael Nitschinger <michael@nitschinger.at>
+ */
+class CouchbaseCache extends CacheProvider
+{
+    /**
+     * @var Couchbase|null
+     */
+    private $couchbase;
+
+    /**
+     * Sets the Couchbase instance to use.
+     *
+     * @param Couchbase $couchbase
+     *
+     * @return void
+     */
+    public function setCouchbase(Couchbase $couchbase)
+    {
+        $this->couchbase = $couchbase;
+    }
+
+    /**
+     * Gets the Couchbase instance used by the cache.
+     *
+     * @return Couchbase|null
+     */
+    public function getCouchbase()
+    {
+        return $this->couchbase;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doFetch($id)
+    {
+        return $this->couchbase->get($id) ?: false;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doContains($id)
+    {
+        return (null !== $this->couchbase->get($id));
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doSave($id, $data, $lifeTime = 0)
+    {
+        if ($lifeTime > 30 * 24 * 3600) {
+            $lifeTime = time() + $lifeTime;
+        }
+        return $this->couchbase->set($id, $data, (int) $lifeTime);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doDelete($id)
+    {
+        return $this->couchbase->delete($id);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doFlush()
+    {
+        return $this->couchbase->flush();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doGetStats()
+    {
+        $stats   = $this->couchbase->getStats();
+        $servers = $this->couchbase->getServers();
+        $server  = explode(":", $servers[0]);
+        $key     = $server[0] . ":" . "11210";
+        $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_AVAILABLE => $stats['limit_maxbytes'],
+        );
+    }
+}

+ 158 - 0
vendor/doctrine/cache/lib/Doctrine/Common/Cache/FileCache.php

@@ -0,0 +1,158 @@
+<?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 MIT license. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Cache;
+
+/**
+ * Base file cache driver.
+ *
+ * @since  2.3
+ * @author Fabio B. Silva <fabio.bat.silva@gmail.com>
+ */
+abstract class FileCache extends CacheProvider
+{
+    /**
+     * The cache directory.
+     *
+     * @var string
+     */
+    protected $directory;
+
+    /**
+     * The cache file extension.
+     *
+     * @var string|null
+     */
+    protected $extension;
+
+    /**
+     * Constructor.
+     *
+     * @param string      $directory The cache directory.
+     * @param string|null $extension The cache file extension.
+     *
+     * @throws \InvalidArgumentException
+     */
+    public function __construct($directory, $extension = null)
+    {
+        if ( ! is_dir($directory) && ! @mkdir($directory, 0777, true)) {
+            throw new \InvalidArgumentException(sprintf(
+                'The directory "%s" does not exist and could not be created.',
+                $directory
+            ));
+        }
+
+        if ( ! is_writable($directory)) {
+            throw new \InvalidArgumentException(sprintf(
+                'The directory "%s" is not writable.',
+                $directory
+            ));
+        }
+
+        $this->directory = realpath($directory);
+        $this->extension = $extension ?: $this->extension;
+    }
+
+    /**
+     * Gets the cache directory.
+     *
+     * @return string
+     */
+    public function getDirectory()
+    {
+        return $this->directory;
+    }
+
+    /**
+     * Gets the cache file extension.
+     *
+     * @return string|null
+     */
+    public function getExtension()
+    {
+        return $this->extension;
+    }
+
+    /**
+     * @param string $id
+     *
+     * @return string
+     */
+    protected function getFilename($id)
+    {
+        $hash = hash('sha256', $id);
+        $path = implode(str_split($hash, 16), DIRECTORY_SEPARATOR);
+        $path = $this->directory . DIRECTORY_SEPARATOR . $path;
+        $id   = preg_replace('@[\\\/:"*?<>|]+@', '', $id);
+
+        return $path . DIRECTORY_SEPARATOR . $id . $this->extension;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doDelete($id)
+    {
+        return @unlink($this->getFilename($id));
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doFlush()
+    {
+        foreach ($this->getIterator() as $name => $file) {
+            @unlink($name);
+        }
+
+        return true;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doGetStats()
+    {
+        $usage = 0;
+        foreach ($this->getIterator() as $name => $file) {
+            $usage += $file->getSize();
+        }
+
+        $free = disk_free_space($this->directory);
+
+        return array(
+            Cache::STATS_HITS               => null,
+            Cache::STATS_MISSES             => null,
+            Cache::STATS_UPTIME             => null,
+            Cache::STATS_MEMORY_USAGE       => $usage,
+            Cache::STATS_MEMORY_AVAILABLE   => $free,
+        );
+    }
+
+    /**
+     * @return \Iterator
+     */
+    private function getIterator()
+    {
+        $pattern = '/^.+\\' . $this->extension . '$/i';
+        $iterator = new \RecursiveDirectoryIterator($this->directory);
+        $iterator = new \RecursiveIteratorIterator($iterator);
+        return new \RegexIterator($iterator, $pattern);
+    }
+}

+ 113 - 0
vendor/doctrine/cache/lib/Doctrine/Common/Cache/FilesystemCache.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 MIT license. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Cache;
+
+/**
+ * Filesystem cache driver.
+ *
+ * @since  2.3
+ * @author Fabio B. Silva <fabio.bat.silva@gmail.com>
+ */
+class FilesystemCache extends FileCache
+{
+    const EXTENSION = '.doctrinecache.data';
+
+    /**
+     * {@inheritdoc}
+     */
+    protected $extension = self::EXTENSION;
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doFetch($id)
+    {
+        $data     = '';
+        $lifetime = -1;
+        $filename = $this->getFilename($id);
+
+        if ( ! is_file($filename)) {
+            return false;
+        }
+
+        $resource = fopen($filename, "r");
+
+        if (false !== ($line = fgets($resource))) {
+            $lifetime = (integer) $line;
+        }
+
+        if ($lifetime !== 0 && $lifetime < time()) {
+            fclose($resource);
+
+            return false;
+        }
+
+        while (false !== ($line = fgets($resource))) {
+            $data .= $line;
+        }
+
+        fclose($resource);
+
+        return unserialize($data);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doContains($id)
+    {
+        $lifetime = -1;
+        $filename = $this->getFilename($id);
+
+        if ( ! is_file($filename)) {
+            return false;
+        }
+
+        $resource = fopen($filename, "r");
+
+        if (false !== ($line = fgets($resource))) {
+            $lifetime = (integer) $line;
+        }
+
+        fclose($resource);
+
+        return $lifetime === 0 || $lifetime > time();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doSave($id, $data, $lifeTime = 0)
+    {
+        if ($lifeTime > 0) {
+            $lifeTime = time() + $lifeTime;
+        }
+
+        $data       = serialize($data);
+        $filename   = $this->getFilename($id);
+        $filepath   = pathinfo($filename, PATHINFO_DIRNAME);
+
+        if ( ! is_dir($filepath)) {
+            mkdir($filepath, 0777, true);
+        }
+
+        return file_put_contents($filename, $lifeTime . PHP_EOL . $data);
+    }
+}

+ 121 - 0
vendor/doctrine/cache/lib/Doctrine/Common/Cache/MemcacheCache.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 MIT license. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Cache;
+
+use \Memcache;
+
+/**
+ * Memcache cache provider.
+ *
+ * @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|null
+     */
+    private $memcache;
+
+    /**
+     * Sets the memcache instance to use.
+     *
+     * @param Memcache $memcache
+     *
+     * @return void
+     */
+    public function setMemcache(Memcache $memcache)
+    {
+        $this->memcache = $memcache;
+    }
+
+    /**
+     * Gets the memcache instance used by the cache.
+     *
+     * @return Memcache|null
+     */
+    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)
+    {
+        if ($lifeTime > 30 * 24 * 3600) {
+            $lifeTime = time() + $lifeTime;
+        }
+        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_AVAILABLE => $stats['limit_maxbytes'],
+        );
+    }
+}

+ 124 - 0
vendor/doctrine/cache/lib/Doctrine/Common/Cache/MemcachedCache.php

@@ -0,0 +1,124 @@
+<?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 MIT license. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Cache;
+
+use \Memcached;
+
+/**
+ * Memcached cache provider.
+ *
+ * @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|null
+     */
+    private $memcached;
+
+    /**
+     * Sets the memcache instance to use.
+     *
+     * @param Memcached $memcached
+     *
+     * @return void
+     */
+    public function setMemcached(Memcached $memcached)
+    {
+        $this->memcached = $memcached;
+    }
+
+    /**
+     * Gets the memcached instance used by the cache.
+     *
+     * @return Memcached|null
+     */
+    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)
+    {
+        if ($lifeTime > 30 * 24 * 3600) {
+            $lifeTime = time() + $lifeTime;
+        }
+        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_AVAILABLE => $stats['limit_maxbytes'],
+        );
+    }
+}

+ 107 - 0
vendor/doctrine/cache/lib/Doctrine/Common/Cache/PhpFileCache.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 MIT license. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Cache;
+
+/**
+ * Php file cache driver.
+ *
+ * @since  2.3
+ * @author Fabio B. Silva <fabio.bat.silva@gmail.com>
+ */
+class PhpFileCache extends FileCache
+{
+    const EXTENSION = '.doctrinecache.php';
+
+     /**
+     * {@inheritdoc}
+     */
+    protected $extension = self::EXTENSION;
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doFetch($id)
+    {
+        $filename = $this->getFilename($id);
+
+        if ( ! is_file($filename)) {
+            return false;
+        }
+
+        $value = include $filename;
+
+        if ($value['lifetime'] !== 0 && $value['lifetime'] < time()) {
+            return false;
+        }
+
+        return $value['data'];
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doContains($id)
+    {
+        $filename = $this->getFilename($id);
+
+        if ( ! is_file($filename)) {
+            return false;
+        }
+
+        $value = include $filename;
+
+        return $value['lifetime'] === 0 || $value['lifetime'] > time();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doSave($id, $data, $lifeTime = 0)
+    {
+        if ($lifeTime > 0) {
+            $lifeTime = time() + $lifeTime;
+        }
+
+        if (is_object($data) && ! method_exists($data, '__set_state')) {
+            throw new \InvalidArgumentException(
+                "Invalid argument given, PhpFileCache only allows objects that implement __set_state() " .
+                "and fully support var_export(). You can use the FilesystemCache to save arbitrary object " .
+                "graphs using serialize()/deserialize()."
+            );
+        }
+
+        $filename   = $this->getFilename($id);
+        $filepath   = pathinfo($filename, PATHINFO_DIRNAME);
+
+        if ( ! is_dir($filepath)) {
+            mkdir($filepath, 0777, true);
+        }
+
+        $value = array(
+            'lifetime'  => $lifeTime,
+            'data'      => $data
+        );
+
+        $value  = var_export($value, true);
+        $code   = sprintf('<?php return %s;', $value);
+
+        return file_put_contents($filename, $code);
+    }
+}

+ 130 - 0
vendor/doctrine/cache/lib/Doctrine/Common/Cache/RedisCache.php

@@ -0,0 +1,130 @@
+<?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 MIT license. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Cache;
+
+use Redis;
+
+/**
+ * Redis cache provider.
+ *
+ * @link   www.doctrine-project.org
+ * @since  2.2
+ * @author Osman Ungur <osmanungur@gmail.com>
+ */
+class RedisCache extends CacheProvider
+{
+    /**
+     * @var Redis|null
+     */
+    private $redis;
+
+    /**
+     * Sets the redis instance to use.
+     *
+     * @param Redis $redis
+     *
+     * @return void
+     */
+    public function setRedis(Redis $redis)
+    {
+        $redis->setOption(Redis::OPT_SERIALIZER, $this->getSerializerValue());
+        $this->redis = $redis;
+    }
+
+    /**
+     * Gets the redis instance used by the cache.
+     *
+     * @return Redis|null
+     */
+    public function getRedis()
+    {
+        return $this->redis;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doFetch($id)
+    {
+        return $this->redis->get($id);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doContains($id)
+    {
+        return $this->redis->exists($id);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doSave($id, $data, $lifeTime = 0)
+    {
+        if ($lifeTime > 0) {
+            return $this->redis->setex($id, $lifeTime, $data);
+        }
+        return $this->redis->set($id, $data);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doDelete($id)
+    {
+        return $this->redis->delete($id);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doFlush()
+    {
+        return $this->redis->flushDB();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doGetStats()
+    {
+        $info = $this->redis->info();
+        return array(
+            Cache::STATS_HITS   => false,
+            Cache::STATS_MISSES => false,
+            Cache::STATS_UPTIME => $info['uptime_in_seconds'],
+            Cache::STATS_MEMORY_USAGE      => $info['used_memory'],
+            Cache::STATS_MEMORY_AVAILABLE  => false
+        );
+    }
+
+    /**
+     * Returns the serializer constant to use. If Redis is compiled with
+     * igbinary support, that is used. Otherwise the default PHP serializer is
+     * used.
+     *
+     * @return integer One of the Redis::SERIALIZER_* constants
+     */
+    protected function getSerializerValue()
+    {
+        return defined('Redis::SERIALIZER_IGBINARY') ? Redis::SERIALIZER_IGBINARY : Redis::SERIALIZER_PHP;
+    }
+}

+ 250 - 0
vendor/doctrine/cache/lib/Doctrine/Common/Cache/RiakCache.php

@@ -0,0 +1,250 @@
+<?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 MIT license. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Cache;
+
+use Riak\Bucket;
+use Riak\Connection;
+use Riak\Input;
+use Riak\Exception;
+use Riak\Object;
+
+/**
+ * Riak cache provider.
+ *
+ * @link   www.doctrine-project.org
+ * @since  1.1
+ * @author Guilherme Blanco <guilhermeblanco@hotmail.com>
+ */
+class RiakCache extends CacheProvider
+{
+    const EXPIRES_HEADER = 'X-Riak-Meta-Expires';
+
+    /**
+     * @var \Riak\Bucket
+     */
+    private $bucket;
+
+    /**
+     * Sets the riak bucket instance to use.
+     *
+     * @param \Riak\Bucket $bucket
+     */
+    public function __construct(Bucket $bucket)
+    {
+        $this->bucket = $bucket;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doFetch($id)
+    {
+        try {
+            $response = $this->bucket->get(urlencode($id));
+
+            // No objects found
+            if ( ! $response->hasObject()) {
+                return false;
+            }
+
+            // Check for attempted siblings
+            $object = ($response->hasSiblings())
+                ? $this->resolveConflict($id, $response->getVClock(), $response->getObjectList())
+                : $response->getFirstObject();
+
+            // Check for expired object
+            if ($this->isExpired($object)) {
+                $this->bucket->delete($object);
+
+                return false;
+            }
+
+            return unserialize($object->getContent());
+        } catch (Exception\RiakException $e) {
+            // Covers:
+            // - Riak\ConnectionException
+            // - Riak\CommunicationException
+            // - Riak\UnexpectedResponseException
+            // - Riak\NotFoundException
+        }
+
+        return false;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doContains($id)
+    {
+        try {
+            // We only need the HEAD, not the entire object
+            $input = new Input\GetInput();
+
+            $input->setReturnHead(true);
+
+            $response = $this->bucket->get(urlencode($id), $input);
+
+            // No objects found
+            if ( ! $response->hasObject()) {
+                return false;
+            }
+
+            $object = $response->getFirstObject();
+
+            // Check for expired object
+            if ($this->isExpired($object)) {
+                $this->bucket->delete($object);
+
+                return false;
+            }
+
+            return true;
+        } catch (Exception\RiakException $e) {
+            // Do nothing
+        }
+
+        return false;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doSave($id, $data, $lifeTime = 0)
+    {
+        try {
+            $object = new Object(urlencode($id));
+
+            $object->setContent(serialize($data));
+
+            if ($lifeTime > 0) {
+                $object->addMetadata(self::EXPIRES_HEADER, (string) (time() + $lifeTime));
+            }
+
+            $this->bucket->put($object);
+
+            return true;
+        } catch (Exception\RiakException $e) {
+            // Do nothing
+        }
+
+        return false;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doDelete($id)
+    {
+        try {
+            $this->bucket->delete(urlencode($id));
+
+            return true;
+        } catch (Exception\BadArgumentsException $e) {
+            // Key did not exist on cluster already
+        } catch (Exception\RiakException $e) {
+            // Covers:
+            // - Riak\Exception\ConnectionException
+            // - Riak\Exception\CommunicationException
+            // - Riak\Exception\UnexpectedResponseException
+        }
+
+        return false;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doFlush()
+    {
+        try {
+            $keyList = $this->bucket->getKeyList();
+
+            foreach ($keyList as $key) {
+                $this->bucket->delete($key);
+            }
+
+            return true;
+        } catch (Exception\RiakException $e) {
+            // Do nothing
+        }
+
+        return false;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function doGetStats()
+    {
+        // Only exposed through HTTP stats API, not Protocol Buffers API
+        return null;
+    }
+
+    /**
+     * Check if a given Riak Object have expired.
+     *
+     * @param \Riak\Object $object
+     *
+     * @return boolean
+     */
+    private function isExpired(Object $object)
+    {
+        $metadataMap = $object->getMetadataMap();
+
+        return isset($metadataMap[self::EXPIRES_HEADER])
+            && $metadataMap[self::EXPIRES_HEADER] < time();
+    }
+
+    /**
+     * On-read conflict resolution. Applied approach here is last write wins.
+     * Specific needs may override this method to apply alternate conflict resolutions.
+     *
+     * {@internal Riak does not attempt to resolve a write conflict, and store
+     * it as sibling of conflicted one. By following this approach, it is up to
+     * the next read to resolve the conflict. When this happens, your fetched
+     * object will have a list of siblings (read as a list of objects).
+     * In our specific case, we do not care about the intermediate ones since
+     * they are all the same read from storage, and we do apply a last sibling
+     * (last write) wins logic.
+     * If by any means our resolution generates another conflict, it'll up to
+     * next read to properly solve it.}
+     *
+     * @param string $id
+     * @param string $vClock
+     * @param array  $objectList
+     *
+     * @return \Riak\Object
+     */
+    protected function resolveConflict($id, $vClock, array $objectList)
+    {
+        // Our approach here is last-write wins
+        $winner = $objectList[count($objectList)];
+
+        $putInput = new Input\PutInput();
+        $putInput->setVClock($vClock);
+
+        $mergedObject = new Object(urlencode($id));
+        $mergedObject->setContent($winner->getContent());
+
+        $this->bucket->put($mergedObject, $putInput);
+
+        return $mergedObject;
+    }
+}

+ 91 - 0
vendor/doctrine/cache/lib/Doctrine/Common/Cache/WinCacheCache.php

@@ -0,0 +1,91 @@
+<?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 MIT license. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Cache;
+
+/**
+ * WinCache cache provider.
+ *
+ * @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_AVAILABLE => $meminfo['memory_free'],
+        );
+    }
+}

+ 109 - 0
vendor/doctrine/cache/lib/Doctrine/Common/Cache/XcacheCache.php

@@ -0,0 +1,109 @@
+<?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 MIT license. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Cache;
+
+/**
+ * Xcache cache driver.
+ *
+ * @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.
+     *
+     * @return void
+     *
+     * @throws \BadMethodCallException When xcache.admin.enable_auth is On.
+     */
+    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_AVAILABLE  => $info['avail'],
+        );
+    }
+}

+ 83 - 0
vendor/doctrine/cache/lib/Doctrine/Common/Cache/ZendDataCache.php

@@ -0,0 +1,83 @@
+<?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 MIT license. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\Common\Cache;
+
+/**
+ * Zend Data Cache cache driver.
+ *
+ * @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;
+    }
+}

+ 31 - 0
vendor/doctrine/cache/phpunit.xml.dist

@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<phpunit backupGlobals="false"
+         backupStaticAttributes="false"
+         colors="true"
+         convertErrorsToExceptions="true"
+         convertNoticesToExceptions="true"
+         convertWarningsToExceptions="true"
+         processIsolation="false"
+         stopOnFailure="false"
+         syntaxCheck="false"
+         bootstrap="./tests/Doctrine/Tests/TestInit.php"
+>
+    <testsuites>
+        <testsuite name="Doctrine Cache Test Suite">
+            <directory>./tests/Doctrine/</directory>
+        </testsuite>
+    </testsuites>
+
+    <filter>
+        <whitelist>
+            <directory>./lib/Doctrine/</directory>
+        </whitelist>
+    </filter>
+    
+    <groups>
+        <exclude>
+            <group>performance</group>
+        </exclude>
+    </groups>
+</phpunit>

+ 20 - 0
vendor/doctrine/cache/tests/Doctrine/Tests/Common/Cache/ApcCacheTest.php

@@ -0,0 +1,20 @@
+<?php
+
+namespace Doctrine\Tests\Common\Cache;
+
+use Doctrine\Common\Cache\ApcCache;
+
+class ApcCacheTest extends CacheTest
+{
+    public function setUp()
+    {
+        if ( ! extension_loaded('apc') || false === @apc_cache_info()) {
+            $this->markTestSkipped('The ' . __CLASS__ .' requires the use of APC');
+        }
+    }
+
+    protected function _getCacheDriver()
+    {
+        return new ApcCache();
+    }
+}

+ 21 - 0
vendor/doctrine/cache/tests/Doctrine/Tests/Common/Cache/ArrayCacheTest.php

@@ -0,0 +1,21 @@
+<?php
+
+namespace Doctrine\Tests\Common\Cache;
+
+use Doctrine\Common\Cache\ArrayCache;
+
+class ArrayCacheTest extends CacheTest
+{
+    protected function _getCacheDriver()
+    {
+        return new ArrayCache();
+    }
+
+    public function testGetStats()
+    {
+        $cache = $this->_getCacheDriver();
+        $stats = $cache->getStats();
+
+        $this->assertNull($stats);
+    }
+}

+ 103 - 0
vendor/doctrine/cache/tests/Doctrine/Tests/Common/Cache/CacheTest.php

@@ -0,0 +1,103 @@
+<?php
+
+namespace Doctrine\Tests\Common\Cache;
+
+use Doctrine\Common\Cache\Cache;
+
+abstract class CacheTest extends \Doctrine\Tests\DoctrineTestCase
+{
+    public function testBasics()
+    {
+        $cache = $this->_getCacheDriver();
+
+        // Test save
+        $cache->save('test_key', 'testing this out');
+
+        // Test contains to test that save() worked
+        $this->assertTrue($cache->contains('test_key'));
+
+        // Test fetch
+        $this->assertEquals('testing this out', $cache->fetch('test_key'));
+
+        // Test delete
+        $cache->save('test_key2', 'test2');
+        $cache->delete('test_key2');
+        $this->assertFalse($cache->contains('test_key2'));
+    }
+
+    public function testObjects()
+    {
+        $cache = $this->_getCacheDriver();
+
+        // Fetch/save test with objects (Is cache driver serializes/unserializes objects correctly ?)
+        $cache->save('test_object_key', new \ArrayObject());
+        $this->assertTrue($cache->fetch('test_object_key') instanceof \ArrayObject);
+    }
+
+    public function testDeleteAll()
+    {
+        $cache = $this->_getCacheDriver();
+        $cache->save('test_key1', '1');
+        $cache->save('test_key2', '2');
+        $cache->deleteAll();
+
+        $this->assertFalse($cache->contains('test_key1'));
+        $this->assertFalse($cache->contains('test_key2'));
+    }
+
+    public function testFlushAll()
+    {
+        $cache = $this->_getCacheDriver();
+        $cache->save('test_key1', '1');
+        $cache->save('test_key2', '2');
+        $cache->flushAll();
+
+        $this->assertFalse($cache->contains('test_key1'));
+        $this->assertFalse($cache->contains('test_key2'));
+    }
+
+    public function testNamespace()
+    {
+        $cache = $this->_getCacheDriver();
+        $cache->setNamespace('test_');
+        $cache->save('key1', 'test');
+
+        $this->assertTrue($cache->contains('key1'));
+
+        $cache->setNamespace('test2_');
+
+        $this->assertFalse($cache->contains('key1'));
+    }
+
+    /**
+     * @group DCOM-43
+     */
+    public function testGetStats()
+    {
+        $cache = $this->_getCacheDriver();
+        $stats = $cache->getStats();
+
+        $this->assertArrayHasKey(Cache::STATS_HITS,   $stats);
+        $this->assertArrayHasKey(Cache::STATS_MISSES, $stats);
+        $this->assertArrayHasKey(Cache::STATS_UPTIME, $stats);
+        $this->assertArrayHasKey(Cache::STATS_MEMORY_USAGE, $stats);
+        $this->assertArrayHasKey(Cache::STATS_MEMORY_AVAILABLE, $stats);
+    }
+
+    /**
+     * Make sure that all supported caches return "false" instead of "null" to be compatible
+     * with ORM integration.
+     */
+    public function testFalseOnFailedFetch()
+    {
+        $cache = $this->_getCacheDriver();
+        $result = $cache->fetch('nonexistent_key');
+        $this->assertFalse($result);
+        $this->assertNotNull($result);
+    }
+
+    /**
+     * @return \Doctrine\Common\Cache\CacheProvider
+     */
+    abstract protected function _getCacheDriver();
+}

+ 47 - 0
vendor/doctrine/cache/tests/Doctrine/Tests/Common/Cache/CouchbaseCacheTest.php

@@ -0,0 +1,47 @@
+<?php
+
+namespace Doctrine\Tests\Common\Cache;
+
+use Couchbase;
+use Doctrine\Common\Cache\CouchbaseCache;
+
+class CouchbaseCacheTest extends CacheTest
+{
+    private $couchbase;
+
+    public function setUp()
+    {
+        if (extension_loaded('couchbase')) {
+            try {
+                $this->couchbase = new Couchbase('127.0.0.1', 'Administrator', 'password', 'default');
+            } catch(Exception $ex) {
+                 $this->markTestSkipped('Could not instantiate the Couchbase cache because of: ' . $ex);   
+            }
+        } else {
+            $this->markTestSkipped('The ' . __CLASS__ .' requires the use of the couchbase extension');
+        }
+    }
+
+    public function testNoExpire() 
+    {
+        $cache = $this->_getCacheDriver();
+        $cache->save('noexpire', 'value', 0);
+        sleep(1);
+        $this->assertTrue($cache->contains('noexpire'), 'Couchbase provider should support no-expire');
+    }
+
+    public function testLongLifetime()
+    {
+        $cache = $this->_getCacheDriver();
+        $cache->save('key', 'value', 30 * 24 * 3600 + 1);
+
+        $this->assertTrue($cache->contains('key'), 'Couchbase provider should support TTL > 30 days');
+    }
+
+    protected function _getCacheDriver()
+    {
+        $driver = new CouchbaseCache();
+        $driver->setCouchbase($this->couchbase);
+        return $driver;
+    }
+}

+ 107 - 0
vendor/doctrine/cache/tests/Doctrine/Tests/Common/Cache/FileCacheTest.php

@@ -0,0 +1,107 @@
+<?php
+
+namespace Doctrine\Tests\Common\Cache;
+
+/**
+ * @group DCOM-101
+ */
+class FileCacheTest extends \Doctrine\Tests\DoctrineTestCase
+{
+    /**
+     * @var \Doctrine\Common\Cache\FileCache
+     */
+    private $driver;
+
+    protected function setUp()
+    {
+        $this->driver = $this->getMock(
+            'Doctrine\Common\Cache\FileCache',
+            array('doFetch', 'doContains', 'doSave'),
+            array(), '', false
+        );
+    }
+
+    public function getProviderFileName()
+    {
+         return array(
+            //The characters :\/<>"*?| are not valid in Windows filenames.
+            array('key:1', 'key1'),
+            array('key\2', 'key2'),
+            array('key/3', 'key3'),
+            array('key<4', 'key4'),
+            array('key>5', 'key5'),
+            array('key"6', 'key6'),
+            array('key*7', 'key7'),
+            array('key?8', 'key8'),
+            array('key|9', 'key9'),
+            array('key[0]','key[0]'),
+        );
+    }
+
+    /**
+     * @dataProvider getProviderFileName
+     */
+    public function testInvalidFilename($key, $expected)
+    {
+        $cache  = $this->driver;
+        $method = new \ReflectionMethod($cache, 'getFilename');
+
+        $method->setAccessible(true);
+
+        $value  = $method->invoke($cache, $key);
+        $actual = pathinfo($value, PATHINFO_FILENAME);
+
+        $this->assertEquals($expected, $actual);
+    }
+
+    public function testFilenameCollision()
+    {
+        $data['key:0']  = 'key0';
+        $data['key\0']  = 'key0';
+        $data['key/0']  = 'key0';
+        $data['key<0']  = 'key0';
+        $data['key>0']  = 'key0';
+        $data['key"0']  = 'key0';
+        $data['key*0']  = 'key0';
+        $data['key?0']  = 'key0';
+        $data['key|0']  = 'key0';
+
+        $paths  = array();
+        $cache  = $this->driver;
+        $method = new \ReflectionMethod($cache, 'getFilename');
+
+        $method->setAccessible(true);
+
+        foreach ($data as $key => $expected) {
+            $path   = $method->invoke($cache, $key);
+            $actual = pathinfo($path, PATHINFO_FILENAME);
+
+            $this->assertNotContains($path, $paths);
+            $this->assertEquals($expected, $actual);
+
+            $paths[] = $path;
+        }
+    }
+
+    public function testFilenameShouldCreateThePathWithFourSubDirectories()
+    {
+        $cache          = $this->driver;
+        $method         = new \ReflectionMethod($cache, 'getFilename');
+        $key            = 'item-key';
+        $expectedDir[]  = '84e0e2e893febb73';
+        $expectedDir[]  = '7a0fee0c89d53f4b';
+        $expectedDir[]  = 'b7fcb44c57cdf3d3';
+        $expectedDir[]  = '2ce7363f5d597760';
+        $expectedDir    = implode(DIRECTORY_SEPARATOR, $expectedDir);
+
+        $method->setAccessible(true);
+
+        $path       = $method->invoke($cache, $key);
+        $filename   = pathinfo($path, PATHINFO_FILENAME);
+        $dirname    = pathinfo($path, PATHINFO_DIRNAME);
+
+        $this->assertEquals('item-key', $filename);
+        $this->assertEquals(DIRECTORY_SEPARATOR . $expectedDir, $dirname);
+        $this->assertEquals(DIRECTORY_SEPARATOR . $expectedDir . DIRECTORY_SEPARATOR . $key, $path);
+    }
+}

+ 102 - 0
vendor/doctrine/cache/tests/Doctrine/Tests/Common/Cache/FilesystemCacheTest.php

@@ -0,0 +1,102 @@
+<?php
+
+namespace Doctrine\Tests\Common\Cache;
+
+use Doctrine\Common\Cache\Cache;
+use Doctrine\Common\Cache\FilesystemCache;
+
+/**
+ * @group DCOM-101
+ */
+class FilesystemCacheTest extends CacheTest
+{
+    /**
+     * @var \Doctrine\Common\Cache\FilesystemCache
+     */
+    private $driver;
+
+    protected function _getCacheDriver()
+    {
+        $dir = sys_get_temp_dir() . "/doctrine_cache_". uniqid();
+        $this->assertFalse(is_dir($dir));
+
+        $this->driver = new FilesystemCache($dir);
+        $this->assertTrue(is_dir($dir));
+
+        return $this->driver;
+    }
+
+    public function testLifetime()
+    {
+        $cache = $this->_getCacheDriver();
+
+        // Test save
+        $cache->save('test_key', 'testing this out', 10);
+
+        // Test contains to test that save() worked
+        $this->assertTrue($cache->contains('test_key'));
+
+        // Test fetch
+        $this->assertEquals('testing this out', $cache->fetch('test_key'));
+
+        // access private methods
+        $getFilename        = new \ReflectionMethod($cache, 'getFilename');
+        $getNamespacedId    = new \ReflectionMethod($cache, 'getNamespacedId');
+
+        $getFilename->setAccessible(true);
+        $getNamespacedId->setAccessible(true);
+
+        $id         = $getNamespacedId->invoke($cache, 'test_key');
+        $filename   = $getFilename->invoke($cache, $id);
+
+        $data       = '';
+        $lifetime   = 0;
+        $resource   = fopen($filename, "r");
+
+        if (false !== ($line = fgets($resource))) {
+            $lifetime = (integer) $line;
+        }
+
+        while (false !== ($line = fgets($resource))) {
+            $data .= $line;
+        }
+
+        $this->assertNotEquals(0, $lifetime, "previous lifetime could not be loaded");
+
+        // update lifetime
+        $lifetime = $lifetime - 20;
+        file_put_contents($filename, $lifetime . PHP_EOL . $data);
+
+        // test expired data
+        $this->assertFalse($cache->contains('test_key'));
+        $this->assertFalse($cache->fetch('test_key'));
+    }
+
+    public function testGetStats()
+    {
+        $cache = $this->_getCacheDriver();
+        $stats = $cache->getStats();
+
+        $this->assertNull($stats[Cache::STATS_HITS]);
+        $this->assertNull($stats[Cache::STATS_MISSES]);
+        $this->assertNull($stats[Cache::STATS_UPTIME]);
+        $this->assertEquals(0, $stats[Cache::STATS_MEMORY_USAGE]);
+        $this->assertGreaterThan(0, $stats[Cache::STATS_MEMORY_AVAILABLE]);
+    }
+
+    public function tearDown()
+    {
+        $dir        = $this->driver->getDirectory();
+        $ext        = $this->driver->getExtension();
+        $iterator   = new \RecursiveDirectoryIterator($dir);
+
+        foreach (new \RecursiveIteratorIterator($iterator, \RecursiveIteratorIterator::CHILD_FIRST) as $file) {
+            if ($file->isFile()) {
+                @unlink($file->getRealPath());
+            } else {
+                @rmdir($file->getRealPath());
+            }
+        }
+    }
+
+}

+ 45 - 0
vendor/doctrine/cache/tests/Doctrine/Tests/Common/Cache/MemcacheCacheTest.php

@@ -0,0 +1,45 @@
+<?php
+
+namespace Doctrine\Tests\Common\Cache;
+
+use Doctrine\Common\Cache\MemcacheCache;
+
+class MemcacheCacheTest extends CacheTest
+{
+    private $_memcache;
+
+    public function setUp()
+    {
+        if (extension_loaded('memcache')) {
+            $this->_memcache = new \Memcache;
+            $ok = @$this->_memcache->connect('localhost', 11211);
+            if (!$ok) {
+                $this->markTestSkipped('The ' . __CLASS__ .' requires the use of memcache');
+            }
+        } else {
+            $this->markTestSkipped('The ' . __CLASS__ .' requires the use of memcache');
+        }
+    }
+
+    public function testNoExpire() {
+        $cache = $this->_getCacheDriver();
+        $cache->save('noexpire', 'value', 0);
+        sleep(1);
+        $this->assertTrue($cache->contains('noexpire'), 'Memcache provider should support no-expire');
+    }
+
+    public function testLongLifetime()
+    {
+        $cache = $this->_getCacheDriver();
+        $cache->save('key', 'value', 30 * 24 * 3600 + 1);
+        $this->assertTrue($cache->contains('key'), 'Memcache provider should support TTL > 30 days');
+    }
+
+    protected function _getCacheDriver()
+    {
+        $driver = new MemcacheCache();
+        $driver->setMemcache($this->_memcache);
+        return $driver;
+    }
+
+}

+ 48 - 0
vendor/doctrine/cache/tests/Doctrine/Tests/Common/Cache/MemcachedCacheTest.php

@@ -0,0 +1,48 @@
+<?php
+
+namespace Doctrine\Tests\Common\Cache;
+
+use Doctrine\Common\Cache\MemcachedCache;
+
+class MemcachedCacheTest extends CacheTest
+{
+    private $memcached;
+
+    public function setUp()
+    {
+        if (extension_loaded('memcached')) {
+            $this->memcached = new \Memcached();
+            $this->memcached->setOption(\Memcached::OPT_COMPRESSION, false);
+            $this->memcached->addServer('127.0.0.1', 11211);
+
+            $fh = @fsockopen('127.0.0.1', 11211);
+            if (!$fh) {
+                $this->markTestSkipped('The ' . __CLASS__ .' requires the use of memcache');
+            }
+        } else {
+            $this->markTestSkipped('The ' . __CLASS__ .' requires the use of memcache');
+        }
+    }
+
+    public function testNoExpire() {
+        $cache = $this->_getCacheDriver();
+        $cache->save('noexpire', 'value', 0);
+        sleep(1);
+        $this->assertTrue($cache->contains('noexpire'), 'Memcache provider should support no-expire');
+    }
+
+    public function testLongLifetime()
+    {
+        $cache = $this->_getCacheDriver();
+        $cache->save('key', 'value', 30 * 24 * 3600 + 1);
+
+        $this->assertTrue($cache->contains('key'), 'Memcached provider should support TTL > 30 days');
+    }
+
+    protected function _getCacheDriver()
+    {
+        $driver = new MemcachedCache();
+        $driver->setMemcached($this->memcached);
+        return $driver;
+    }
+}

+ 154 - 0
vendor/doctrine/cache/tests/Doctrine/Tests/Common/Cache/PhpFileCacheTest.php

@@ -0,0 +1,154 @@
+<?php
+
+namespace Doctrine\Tests\Common\Cache;
+
+use Doctrine\Common\Cache\Cache;
+use Doctrine\Common\Cache\PhpFileCache;
+
+/**
+ * @group DCOM-101
+ */
+class PhpFileCacheTest extends CacheTest
+{
+    /**
+     * @var \Doctrine\Common\Cache\PhpFileCache
+     */
+    private $driver;
+
+    protected function _getCacheDriver()
+    {
+        $dir = sys_get_temp_dir() . "/doctrine_cache_". uniqid();
+        $this->assertFalse(is_dir($dir));
+
+        $this->driver = new PhpFileCache($dir);
+        $this->assertTrue(is_dir($dir));
+
+        return $this->driver;
+    }
+
+    public function testObjects()
+    {
+        $this->markTestSkipped('PhpFileCache does not support saving objects that dont implement __set_state()');
+    }
+
+    public function testLifetime()
+    {
+        $cache = $this->_getCacheDriver();
+
+        // Test save
+        $cache->save('test_key', 'testing this out', 10);
+
+        // Test contains to test that save() worked
+        $this->assertTrue($cache->contains('test_key'));
+
+        // Test fetch
+        $this->assertEquals('testing this out', $cache->fetch('test_key'));
+
+        // access private methods
+        $getFilename        = new \ReflectionMethod($cache, 'getFilename');
+        $getNamespacedId    = new \ReflectionMethod($cache, 'getNamespacedId');
+
+        $getFilename->setAccessible(true);
+        $getNamespacedId->setAccessible(true);
+
+        $id     = $getNamespacedId->invoke($cache, 'test_key');
+        $path   = $getFilename->invoke($cache, $id);
+        $value  = include $path;
+
+        // update lifetime
+        $value['lifetime'] = $value['lifetime'] - 20;
+        file_put_contents($path, '<?php return unserialize(' . var_export(serialize($value), true) . ');');
+
+        // test expired data
+        $this->assertFalse($cache->contains('test_key'));
+        $this->assertFalse($cache->fetch('test_key'));
+    }
+
+    public function testImplementsSetState()
+    {
+        $cache = $this->_getCacheDriver();
+
+        // Test save
+        $cache->save('test_set_state', new SetStateClass(array(1,2,3)));
+
+        //Test __set_state call
+        $this->assertCount(0, SetStateClass::$values);
+
+        // Test fetch
+        $value = $cache->fetch('test_set_state');
+        $this->assertInstanceOf('Doctrine\Tests\Common\Cache\SetStateClass', $value);
+        $this->assertEquals(array(1,2,3), $value->getValue());
+
+        //Test __set_state call
+        $this->assertCount(1, SetStateClass::$values);
+
+        // Test contains
+        $this->assertTrue($cache->contains('test_set_state'));
+    }
+
+    public function testNotImplementsSetState()
+    {
+        $cache = $this->_getCacheDriver();
+
+        $this->setExpectedException('InvalidArgumentException');
+        $cache->save('test_not_set_state', new NotSetStateClass(array(1,2,3)));
+    }
+
+    public function testGetStats()
+    {
+        $cache = $this->_getCacheDriver();
+        $stats = $cache->getStats();
+
+        $this->assertNull($stats[Cache::STATS_HITS]);
+        $this->assertNull($stats[Cache::STATS_MISSES]);
+        $this->assertNull($stats[Cache::STATS_UPTIME]);
+        $this->assertEquals(0, $stats[Cache::STATS_MEMORY_USAGE]);
+        $this->assertGreaterThan(0, $stats[Cache::STATS_MEMORY_AVAILABLE]);
+    }
+
+    public function tearDown()
+    {
+        if (!$this->driver) {
+            return;
+        }
+
+        $dir        = $this->driver->getDirectory();
+        $ext        = $this->driver->getExtension();
+        $iterator   = new \RecursiveDirectoryIterator($dir);
+
+        foreach (new \RecursiveIteratorIterator($iterator, \RecursiveIteratorIterator::CHILD_FIRST) as $file) {
+            if ($file->isFile()) {
+                @unlink($file->getRealPath());
+            } else {
+                @rmdir($file->getRealPath());
+            }
+        }
+    }
+
+}
+
+class NotSetStateClass
+{
+    private $value;
+
+    public function __construct($value)
+    {
+        $this->value = $value;
+    }
+
+    public function getValue()
+    {
+        return $this->value;
+    }
+}
+
+class SetStateClass extends NotSetStateClass
+{
+    public static $values = array();
+
+    public static function __set_state($data)
+    {
+        self::$values = $data;
+        return new self($data['value']);
+    }
+}

+ 30 - 0
vendor/doctrine/cache/tests/Doctrine/Tests/Common/Cache/RedisCacheTest.php

@@ -0,0 +1,30 @@
+<?php
+
+namespace Doctrine\Tests\Common\Cache;
+
+use Doctrine\Common\Cache\RedisCache;
+
+class RedisCacheTest extends CacheTest
+{
+    private $_redis;
+
+    public function setUp()
+    {
+        if (extension_loaded('redis')) {
+            $this->_redis = new \Redis();
+            $ok = @$this->_redis->connect('127.0.0.1');
+            if (!$ok) {
+                $this->markTestSkipped('The ' . __CLASS__ .' requires the use of redis');
+            }
+        } else {
+            $this->markTestSkipped('The ' . __CLASS__ .' requires the use of redis');
+        }
+    }
+
+    protected function _getCacheDriver()
+    {
+        $driver = new RedisCache();
+        $driver->setRedis($this->_redis);
+        return $driver;
+    }
+}

+ 64 - 0
vendor/doctrine/cache/tests/Doctrine/Tests/Common/Cache/RiakCacheTest.php

@@ -0,0 +1,64 @@
+<?php
+
+namespace Doctrine\Tests\Common\Cache;
+
+use Riak\Bucket;
+use Riak\Connection;
+use Riak\Exception;
+use Doctrine\Common\Cache\RiakCache;
+
+/**
+ * RiakCache test
+ *
+ * @group Riak
+ */
+class RiakCacheTest extends CacheTest
+{
+    /**
+     * @var \Riak\Connection
+     */
+    private $connection;
+
+    /**
+     * @var \Riak\Bucket
+     */
+    private $bucket;
+
+    /**
+     * {@inheritdoc}
+     */
+    public function setUp()
+    {
+        if ( ! extension_loaded('riak')) {
+            $this->markTestSkipped('The ' . __CLASS__ .' requires the use of Riak');
+        }
+
+        try {
+            $this->connection = new Connection('127.0.0.1', 8087);
+            $this->bucket     = new Bucket($this->connection, 'test');
+        } catch (Exception\RiakException $e) {
+            $this->markTestSkipped('The ' . __CLASS__ .' requires the use of Riak');
+        }
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function testGetStats()
+    {
+        $cache = $this->_getCacheDriver();
+        $stats = $cache->getStats();
+
+        $this->assertNull($stats);
+    }
+
+    /**
+     * Retrieve RiakCache instance.
+     *
+     * @return \Doctrine\Common\Cache\RiakCache
+     */
+    protected function _getCacheDriver()
+    {
+        return new RiakCache($this->bucket);
+    }
+}

+ 20 - 0
vendor/doctrine/cache/tests/Doctrine/Tests/Common/Cache/WinCacheCacheTest.php

@@ -0,0 +1,20 @@
+<?php
+
+namespace Doctrine\Tests\Common\Cache;
+
+use Doctrine\Common\Cache\WincacheCache;
+
+class WincacheCacheTest extends CacheTest
+{
+    public function setUp()
+    {
+        if ( ! extension_loaded('wincache') || ! function_exists('wincache_ucache_info')) {
+            $this->markTestSkipped('The ' . __CLASS__ .' requires the use of Wincache');
+        }
+    }
+
+    protected function _getCacheDriver()
+    {
+        return new WincacheCache();
+    }
+}

+ 20 - 0
vendor/doctrine/cache/tests/Doctrine/Tests/Common/Cache/XcacheCacheTest.php

@@ -0,0 +1,20 @@
+<?php
+
+namespace Doctrine\Tests\Common\Cache;
+
+use Doctrine\Common\Cache\XcacheCache;
+
+class XcacheCacheTest extends CacheTest
+{
+    public function setUp()
+    {
+        if ( ! extension_loaded('xcache')) {
+            $this->markTestSkipped('The ' . __CLASS__ .' requires the use of xcache');
+        }
+    }
+
+    protected function _getCacheDriver()
+    {
+        return new XcacheCache();
+    }
+}

+ 28 - 0
vendor/doctrine/cache/tests/Doctrine/Tests/Common/Cache/ZendDataCacheTest.php

@@ -0,0 +1,28 @@
+<?php
+
+namespace Doctrine\Tests\Common\Cache;
+
+use Doctrine\Common\Cache\ZendDataCache;
+
+class ZendDataCacheTest extends CacheTest
+{
+    public function setUp()
+    {
+        if (!function_exists('zend_shm_cache_fetch') || (php_sapi_name() != 'apache2handler')) {
+            $this->markTestSkipped('The ' . __CLASS__ .' requires the use of Zend Data Cache which only works in apache2handler SAPI');
+        }
+    }
+
+    public function testGetStats()
+    {
+        $cache = $this->_getCacheDriver();
+        $stats = $cache->getStats();
+
+        $this->assertNull($stats);
+    }
+
+    protected function _getCacheDriver()
+    {
+        return new ZendDataCache();
+    }
+}

+ 10 - 0
vendor/doctrine/cache/tests/Doctrine/Tests/DoctrineTestCase.php

@@ -0,0 +1,10 @@
+<?php
+
+namespace Doctrine\Tests;
+
+/**
+ * Base testcase class for all Doctrine testcases.
+ */
+abstract class DoctrineTestCase extends \PHPUnit_Framework_TestCase
+{
+}

+ 23 - 0
vendor/doctrine/cache/tests/Doctrine/Tests/TestInit.php

@@ -0,0 +1,23 @@
+<?php
+/*
+ * This file bootstraps the test environment.
+ */
+namespace Doctrine\Tests;
+
+error_reporting(E_ALL | E_STRICT);
+
+// register silently failing autoloader
+spl_autoload_register(function($class)
+{
+    if (0 === strpos($class, 'Doctrine\Tests\\')) {
+        $path = __DIR__.'/../../'.strtr($class, '\\', '/').'.php';
+        if (is_file($path) && is_readable($path)) {
+            require_once $path;
+
+            return true;
+        }
+    }
+});
+
+require_once __DIR__ . "/../../../vendor/autoload.php";
+

+ 11 - 0
vendor/evenement/evenement/.travis.yml

@@ -0,0 +1,11 @@
+language: php
+
+php:
+  - 5.3
+  - 5.4
+
+before_script:
+  - wget http://getcomposer.org/composer.phar
+  - php composer.phar install
+
+script: phpunit --coverage-text

+ 19 - 0
vendor/evenement/evenement/LICENSE

@@ -0,0 +1,19 @@
+Copyright (c) 2011 Igor Wiedler
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.

+ 74 - 0
vendor/evenement/evenement/README.md

@@ -0,0 +1,74 @@
+# Événement
+
+Événement is a very simple event dispatching library for PHP 5.3.
+
+It has the same design goals as [Silex](http://silex-project.org) and
+[Pimple](http://pimple-project.org), to empower the user while staying concise
+and simple.
+
+It is very strongly inspired by the EventEmitter API found in
+[node.js](http://nodejs.org). It includes an implementation of
+[EventEmitter2](https://github.com/hij1nx/EventEmitter2), that extends
+the original EventEmitter.
+
+[![Build Status](https://secure.travis-ci.org/igorw/evenement.png)](http://travis-ci.org/igorw/evenement)
+
+## Fetch
+
+The recommended way to install Événement is [through composer](http://getcomposer.org).
+
+Just create a composer.json file for your project:
+
+```JSON
+{
+    "require": {
+        "evenement/evenement": "dev-master"
+    }
+}
+```
+
+And run these two commands to install it:
+
+    $ curl -s http://getcomposer.org/installer | php
+    $ php composer.phar install
+
+Now you can add the autoloader, and you will have access to the library:
+
+```php
+<?php
+require 'vendor/autoload.php';
+```
+
+## Usage
+
+### Creating an Emitter
+
+```php
+<?php
+$emitter = new Evenement\EventEmitter();
+```
+
+### Adding Listeners
+
+```php
+<?php
+$emitter->on('user.create', function (User $user) use ($logger) {
+    $logger->log(sprintf("User '%s' was created.", $user->getLogin()));
+});
+```
+
+### Emitting Events
+
+```php
+<?php
+$emitter->emit('user.create', array($user));
+```
+
+Tests
+-----
+
+    $ phpunit
+
+License
+-------
+MIT, see LICENSE.

+ 20 - 0
vendor/evenement/evenement/composer.json

@@ -0,0 +1,20 @@
+{
+    "name": "evenement/evenement",
+    "description": "Événement is a very simple event dispatching library for PHP 5.3",
+    "keywords": ["event-dispatcher"],
+    "license": "MIT",
+    "authors": [
+        {
+            "name": "Igor Wiedler",
+            "email": "igor@wiedler.ch"
+        }
+    ],
+    "require": {
+        "php": ">=5.3.0"
+    },
+    "autoload": {
+        "psr-0": {
+            "Evenement": "src"
+        }
+    }
+}

+ 25 - 0
vendor/evenement/evenement/phpunit.xml.dist

@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<phpunit backupGlobals="false"
+         backupStaticAttributes="false"
+         colors="true"
+         convertErrorsToExceptions="true"
+         convertNoticesToExceptions="true"
+         convertWarningsToExceptions="true"
+         processIsolation="false"
+         stopOnFailure="false"
+         syntaxCheck="false"
+         bootstrap="tests/bootstrap.php"
+>
+    <testsuites>
+        <testsuite name="Evenement Test Suite">
+            <directory>./tests/Evenement/</directory>
+        </testsuite>
+    </testsuites>
+
+    <filter>
+        <whitelist>
+            <directory>./src/</directory>
+        </whitelist>
+    </filter>
+</phpunit>

+ 73 - 0
vendor/evenement/evenement/src/Evenement/EventEmitter.php

@@ -0,0 +1,73 @@
+<?php
+
+/*
+ * This file is part of Evenement.
+ *
+ * (c) Igor Wiedler <igor@wiedler.ch>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Evenement;
+
+class EventEmitter implements EventEmitterInterface
+{
+    protected $listeners = array();
+
+    public function on($event, $listener)
+    {
+        if (!is_callable($listener)) {
+            throw new \InvalidArgumentException('The provided listener was not a valid callable.');
+        }
+
+        if (!isset($this->listeners[$event])) {
+            $this->listeners[$event] = array();
+        }
+
+        $this->listeners[$event][] = $listener;
+    }
+
+    public function once($event, $listener)
+    {
+        $that = $this;
+
+        $onceListener = function () use ($that, &$onceListener, $event, $listener) {
+            $that->removeListener($event, $onceListener);
+
+            call_user_func_array($listener, func_get_args());
+        };
+
+        $this->on($event, $onceListener);
+    }
+
+    public function removeListener($event, $listener)
+    {
+        if (isset($this->listeners[$event])) {
+            if (false !== $index = array_search($listener, $this->listeners[$event], true)) {
+                unset($this->listeners[$event][$index]);
+            }
+        }
+    }
+
+    public function removeAllListeners($event = null)
+    {
+        if ($event !== null) {
+            unset($this->listeners[$event]);
+        } else {
+            $this->listeners = array();
+        }
+    }
+
+    public function listeners($event)
+    {
+        return isset($this->listeners[$event]) ? $this->listeners[$event] : array();
+    }
+
+    public function emit($event, array $arguments = array())
+    {
+        foreach ($this->listeners($event) as $listener) {
+            call_user_func_array($listener, $arguments);
+        }
+    }
+}

+ 114 - 0
vendor/evenement/evenement/src/Evenement/EventEmitter2.php

@@ -0,0 +1,114 @@
+<?php
+
+/*
+ * This file is part of Evenement.
+ *
+ * (c) Igor Wiedler <igor@wiedler.ch>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Evenement;
+
+class EventEmitter2 extends EventEmitter
+{
+    protected $options;
+    protected $anyListeners = array();
+
+    public function __construct(array $options = array())
+    {
+        $this->options = array_merge(array(
+            'delimiter' => '.',
+        ), $options);
+    }
+
+    public function onAny($listener)
+    {
+        $this->anyListeners[] = $listener;
+    }
+
+    public function offAny($listener)
+    {
+        if (false !== $index = array_search($listener, $this->anyListeners, true)) {
+            unset($this->anyListeners[$index]);
+        }
+    }
+
+    public function many($event, $timesToListen, $listener)
+    {
+        $that = $this;
+
+        $timesListened = 0;
+
+        if ($timesToListen == 0) {
+            return;
+        }
+
+        if ($timesToListen < 0) {
+            throw new \OutOfRangeException('You cannot listen less than zero times.');
+        }
+
+        $manyListener = function () use ($that, &$timesListened, &$manyListener, $event, $timesToListen, $listener) {
+            if (++$timesListened == $timesToListen) {
+                $that->removeListener($event, $manyListener);
+            }
+
+            call_user_func_array($listener, func_get_args());
+        };
+
+        $this->on($event, $manyListener);
+    }
+
+    public function emit($event, array $arguments = array())
+    {
+        foreach ($this->anyListeners as $listener) {
+            call_user_func_array($listener, $arguments);
+        }
+
+        parent::emit($event, $arguments);
+    }
+
+    public function listeners($event)
+    {
+        $matchedListeners = array();
+
+        foreach ($this->listeners as $name => $listeners) {
+            foreach ($listeners as $listener) {
+                if ($this->matchEventName($event, $name)) {
+                    $matchedListeners[] = $listener;
+                }
+            }
+        }
+
+        return $matchedListeners;
+    }
+
+    protected function matchEventName($matchPattern, $eventName)
+    {
+        $patternParts = explode($this->options['delimiter'], $matchPattern);
+        $nameParts = explode($this->options['delimiter'], $eventName);
+
+        if (count($patternParts) != count($nameParts)) {
+            return false;
+        }
+
+        $size = min(count($patternParts), count($nameParts));
+        for ($i = 0; $i < $size; $i++) {
+            $patternPart = $patternParts[$i];
+            $namePart = $nameParts[$i];
+
+            if ('*' === $patternPart || '*' === $namePart) {
+                continue;
+            }
+
+            if ($namePart === $patternPart) {
+                continue;
+            }
+
+            return false;
+        }
+
+        return true;
+    }
+}

+ 22 - 0
vendor/evenement/evenement/src/Evenement/EventEmitterInterface.php

@@ -0,0 +1,22 @@
+<?php
+
+/*
+ * This file is part of Evenement.
+ *
+ * (c) Igor Wiedler <igor@wiedler.ch>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Evenement;
+
+interface EventEmitterInterface
+{
+    public function on($event, $listener);
+    public function once($event, $listener);
+    public function removeListener($event, $listener);
+    public function removeAllListeners($event = null);
+    public function listeners($event);
+    public function emit($event, array $arguments = array());
+}

+ 160 - 0
vendor/evenement/evenement/tests/Evenement/Tests/EventEmitter2Test.php

@@ -0,0 +1,160 @@
+<?php
+
+/*
+ * This file is part of Evenement.
+ *
+ * Copyright (c) 2011 Igor Wiedler
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is furnished
+ * to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+namespace Evenement\Tests;
+
+use Evenement\EventEmitter2;
+
+class EventEmitter2Test extends \PHPUnit_Framework_TestCase
+{
+    private $emitter;
+
+    public function setUp()
+    {
+        $this->emitter = new EventEmitter2();
+    }
+
+    // matching tests from
+    // test/wildcardEvents/addListener.js
+
+    public function testWildcardMatching7()
+    {
+        $listenerCalled = 0;
+
+        $listener = function () use (&$listenerCalled) {
+            $listenerCalled++;
+        };
+
+        $this->emitter->on('*.test', $listener);
+        $this->emitter->on('*.*', $listener);
+        $this->emitter->on('*', $listener);
+
+        $this->emitter->emit('other.emit');
+        $this->emitter->emit('foo.test');
+
+        $this->assertSame(3, $listenerCalled);
+    }
+
+    public function testWildcardMatching8()
+    {
+        $listenerCalled = 0;
+
+        $listener = function () use (&$listenerCalled) {
+            $listenerCalled++;
+        };
+
+        $this->emitter->on('foo.test', $listener);
+        $this->emitter->on('*.*', $listener);
+        $this->emitter->on('*', $listener);
+
+        $this->emitter->emit('*.*');
+        $this->emitter->emit('foo.test');
+        $this->emitter->emit('*');
+
+        $this->assertSame(5, $listenerCalled);
+    }
+
+    public function testOnAny()
+    {
+        $this->emitter->onAny(function () {});
+    }
+
+    public function testOnAnyWithEmit()
+    {
+        $listenerCalled = 0;
+
+        $this->emitter->onAny(function () use (&$listenerCalled) {
+            $listenerCalled++;
+        });
+
+        $this->assertSame(0, $listenerCalled);
+
+        $this->emitter->emit('foo');
+
+        $this->assertSame(1, $listenerCalled);
+
+        $this->emitter->emit('bar');
+
+        $this->assertSame(2, $listenerCalled);
+    }
+
+    public function testoffAnyWithEmit()
+    {
+        $listenerCalled = 0;
+
+        $listener = function () use (&$listenerCalled) {
+            $listenerCalled++;
+        };
+
+        $this->emitter->onAny($listener);
+        $this->emitter->offAny($listener);
+
+        $this->assertSame(0, $listenerCalled);
+        $this->emitter->emit('foo');
+        $this->assertSame(0, $listenerCalled);
+    }
+
+    /**
+     * @dataProvider provideMany
+     */
+    public function testMany($amount)
+    {
+        $listenerCalled = 0;
+
+        $this->emitter->many('foo', $amount, function () use (&$listenerCalled) {
+            $listenerCalled++;
+        });
+
+        for ($i = 0; $i < $amount; $i++) {
+            $this->assertSame($i, $listenerCalled);
+            $this->emitter->emit('foo');
+        }
+
+        $this->emitter->emit('foo');
+        $this->assertSame($amount, $listenerCalled);
+    }
+
+    public function provideMany()
+    {
+        return array(
+            array(0),
+            array(1),
+            array(2),
+            array(3),
+            array(4),
+            array(400),
+        );
+    }
+
+    /**
+     * @expectedException OutOfRangeException
+     */
+    public function testManyWithLessThanZeroTtl()
+    {
+        $this->emitter->many('foo', -1, function () {});
+        $this->emitter->emit('foo');
+    }
+}

+ 236 - 0
vendor/evenement/evenement/tests/Evenement/Tests/EventEmitterTest.php

@@ -0,0 +1,236 @@
+<?php
+
+/*
+ * This file is part of Evenement.
+ *
+ * Copyright (c) 2011 Igor Wiedler
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is furnished
+ * to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+namespace Evenement\Tests;
+
+use Evenement\EventEmitter;
+
+class EventEmitterTest extends \PHPUnit_Framework_TestCase
+{
+    private $emitter;
+
+    public function setUp()
+    {
+        $this->emitter = new EventEmitter();
+    }
+
+    public function testAddListenerWithLambda()
+    {
+        $this->emitter->on('foo', function () {});
+    }
+
+    public function testAddListenerWithMethod()
+    {
+        $listener = new Listener();
+        $this->emitter->on('foo', array($listener, 'onFoo'));
+    }
+
+    public function testAddListenerWithStaticMethod()
+    {
+        $this->emitter->on('bar', array('Evenement\Tests\Listener', 'onBar'));
+    }
+
+    /**
+     * @expectedException InvalidArgumentException
+     */
+    public function testAddListenerWithInvalidListener()
+    {
+        $this->emitter->on('foo', 'not a callable');
+    }
+
+    public function testOnce()
+    {
+        $listenerCalled = 0;
+
+        $this->emitter->once('foo', function () use (&$listenerCalled) {
+            $listenerCalled++;
+        });
+
+        $this->assertSame(0, $listenerCalled);
+
+        $this->emitter->emit('foo');
+
+        $this->assertSame(1, $listenerCalled);
+
+        $this->emitter->emit('foo');
+
+        $this->assertSame(1, $listenerCalled);
+    }
+
+    public function testEmitWithoutArguments()
+    {
+        $listenerCalled = false;
+
+        $this->emitter->on('foo', function () use (&$listenerCalled) {
+            $listenerCalled = true;
+        });
+
+        $this->assertSame(false, $listenerCalled);
+        $this->emitter->emit('foo');
+        $this->assertSame(true, $listenerCalled);
+    }
+
+    public function testEmitWithOneArgument()
+    {
+        $test = $this;
+
+        $listenerCalled = false;
+
+        $this->emitter->on('foo', function ($value) use (&$listenerCalled, $test) {
+            $listenerCalled = true;
+
+            $test->assertSame('bar', $value);
+        });
+
+        $this->assertSame(false, $listenerCalled);
+        $this->emitter->emit('foo', array('bar'));
+        $this->assertSame(true, $listenerCalled);
+    }
+
+    public function testEmitWithTwoArguments()
+    {
+        $test = $this;
+
+        $listenerCalled = false;
+
+        $this->emitter->on('foo', function ($arg1, $arg2) use (&$listenerCalled, $test) {
+            $listenerCalled = true;
+
+            $test->assertSame('bar', $arg1);
+            $test->assertSame('baz', $arg2);
+        });
+
+        $this->assertSame(false, $listenerCalled);
+        $this->emitter->emit('foo', array('bar', 'baz'));
+        $this->assertSame(true, $listenerCalled);
+    }
+
+    public function testEmitWithNoListeners()
+    {
+        $this->emitter->emit('foo');
+        $this->emitter->emit('foo', array('bar'));
+        $this->emitter->emit('foo', array('bar', 'baz'));
+    }
+
+    public function testEmitWithTwoListeners()
+    {
+        $listenersCalled = 0;
+
+        $this->emitter->on('foo', function () use (&$listenersCalled) {
+            $listenersCalled++;
+        });
+
+        $this->emitter->on('foo', function () use (&$listenersCalled) {
+            $listenersCalled++;
+        });
+
+        $this->assertSame(0, $listenersCalled);
+        $this->emitter->emit('foo');
+        $this->assertSame(2, $listenersCalled);
+    }
+
+    public function testRemoveListenerMatching()
+    {
+        $listenersCalled = 0;
+
+        $listener = function () use (&$listenersCalled) {
+            $listenersCalled++;
+        };
+
+        $this->emitter->on('foo', $listener);
+        $this->emitter->removeListener('foo', $listener);
+
+        $this->assertSame(0, $listenersCalled);
+        $this->emitter->emit('foo');
+        $this->assertSame(0, $listenersCalled);
+    }
+
+    public function testRemoveListenerNotMatching()
+    {
+        $listenersCalled = 0;
+
+        $listener = function () use (&$listenersCalled) {
+            $listenersCalled++;
+        };
+
+        $this->emitter->on('foo', $listener);
+        $this->emitter->removeListener('bar', $listener);
+
+        $this->assertSame(0, $listenersCalled);
+        $this->emitter->emit('foo');
+        $this->assertSame(1, $listenersCalled);
+    }
+
+    public function testRemoveAllListenersMatching()
+    {
+        $listenersCalled = 0;
+
+        $this->emitter->on('foo', function () use (&$listenersCalled) {
+            $listenersCalled++;
+        });
+
+        $this->emitter->removeAllListeners('foo');
+
+        $this->assertSame(0, $listenersCalled);
+        $this->emitter->emit('foo');
+        $this->assertSame(0, $listenersCalled);
+    }
+
+    public function testRemoveAllListenersNotMatching()
+    {
+        $listenersCalled = 0;
+
+        $this->emitter->on('foo', function () use (&$listenersCalled) {
+            $listenersCalled++;
+        });
+
+        $this->emitter->removeAllListeners('bar');
+
+        $this->assertSame(0, $listenersCalled);
+        $this->emitter->emit('foo');
+        $this->assertSame(1, $listenersCalled);
+    }
+
+    public function testRemoveAllListenersWithoutArguments()
+    {
+        $listenersCalled = 0;
+
+        $this->emitter->on('foo', function () use (&$listenersCalled) {
+            $listenersCalled++;
+        });
+
+        $this->emitter->on('bar', function () use (&$listenersCalled) {
+            $listenersCalled++;
+        });
+
+        $this->emitter->removeAllListeners();
+
+        $this->assertSame(0, $listenersCalled);
+        $this->emitter->emit('foo');
+        $this->emitter->emit('bar');
+        $this->assertSame(0, $listenersCalled);
+    }
+}

+ 38 - 0
vendor/evenement/evenement/tests/Evenement/Tests/Listener.php

@@ -0,0 +1,38 @@
+<?php
+
+/*
+ * This file is part of Evenement.
+ *
+ * Copyright (c) 2011 Igor Wiedler
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is furnished
+ * to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+namespace Evenement\Tests;
+
+class Listener
+{
+    public function onFoo()
+    {
+    }
+
+    public static function onBar()
+    {
+    }
+}

+ 28 - 0
vendor/evenement/evenement/tests/bootstrap.php

@@ -0,0 +1,28 @@
+<?php
+
+/*
+ * This file is part of Evenement.
+ *
+ * Copyright (c) 2011 Igor Wiedler
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is furnished
+ * to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+$loader = require __DIR__.'/../vendor/autoload.php';
+$loader->add('Evenement\Tests', __DIR__);

+ 110 - 0
vendor/monolog/monolog/CHANGELOG.mdown

@@ -0,0 +1,110 @@
+### 1.6.0 (2013-07-29)
+
+  * Added HipChatHandler to send logs to a HipChat chat room
+  * Added ErrorLogHandler to send logs to PHP's error_log function
+  * Added NewRelicHandler to send logs to NewRelic's service
+  * Added Monolog\ErrorHandler helper class to register a Logger as exception/error/fatal handler
+  * Added ChannelLevelActivationStrategy for the FingersCrossedHandler to customize levels by channel
+  * Added stack traces output when normalizing exceptions (json output & co)
+  * Added Monolog\Logger::API constant (currently 1)
+  * Added support for ChromePHP's v4.0 extension
+  * Added support for message priorities in PushoverHandler, see $highPriorityLevel and $emergencyLevel
+  * Added support for sending messages to multiple users at once with the PushoverHandler
+  * Fixed RavenHandler's support for batch sending of messages (when behind a Buffer or FingersCrossedHandler)
+  * Fixed normalization of Traversables with very large data sets, only the first 1000 items are shown now
+  * Fixed issue in RotatingFileHandler when an open_basedir restriction is active
+  * Fixed minor issues in RavenHandler and bumped the API to Raven 0.5.0
+  * Fixed SyslogHandler issue when many were used concurrently with different facilities
+
+### 1.5.0 (2013-04-23)
+
+  * Added ProcessIdProcessor to inject the PID in log records
+  * Added UidProcessor to inject a unique identifier to all log records of one request/run
+  * Added support for previous exceptions in the LineFormatter exception serialization
+  * Added Monolog\Logger::getLevels() to get all available levels
+  * Fixed ChromePHPHandler so it avoids sending headers larger than Chrome can handle
+
+### 1.4.1 (2013-04-01)
+
+  * Fixed exception formatting in the LineFormatter to be more minimalistic
+  * Fixed RavenHandler's handling of context/extra data, requires Raven client >0.1.0
+  * Fixed log rotation in RotatingFileHandler to work with long running scripts spanning multiple days
+  * Fixed WebProcessor array access so it checks for data presence
+  * Fixed Buffer, Group and FingersCrossed handlers to make use of their processors
+
+### 1.4.0 (2013-02-13)
+
+  * Added RedisHandler to log to Redis via the Predis library or the phpredis extension
+  * Added ZendMonitorHandler to log to the Zend Server monitor
+  * Added the possibility to pass arrays of handlers and processors directly in the Logger constructor
+  * Added `$useSSL` option to the PushoverHandler which is enabled by default
+  * Fixed ChromePHPHandler and FirePHPHandler issue when multiple instances are used simultaneously
+  * Fixed header injection capability in the NativeMailHandler
+
+### 1.3.1 (2013-01-11)
+
+  * Fixed LogstashFormatter to be usable with stream handlers
+  * Fixed GelfMessageFormatter levels on Windows
+
+### 1.3.0 (2013-01-08)
+
+  * Added PSR-3 compliance, the `Monolog\Logger` class is now an instance of `Psr\Log\LoggerInterface`
+  * Added PsrLogMessageProcessor that you can selectively enable for full PSR-3 compliance
+  * Added LogstashFormatter (combine with SocketHandler or StreamHandler to send logs to Logstash)
+  * Added PushoverHandler to send mobile notifications
+  * Added CouchDBHandler and DoctrineCouchDBHandler
+  * Added RavenHandler to send data to Sentry servers
+  * Added support for the new MongoClient class in MongoDBHandler
+  * Added microsecond precision to log records' timestamps
+  * Added `$flushOnOverflow` param to BufferHandler to flush by batches instead of losing
+    the oldest entries
+  * Fixed normalization of objects with cyclic references
+
+### 1.2.1 (2012-08-29)
+
+  * Added new $logopts arg to SyslogHandler to provide custom openlog options
+  * Fixed fatal error in SyslogHandler
+
+### 1.2.0 (2012-08-18)
+
+  * Added AmqpHandler (for use with AMQP servers)
+  * Added CubeHandler
+  * Added NativeMailerHandler::addHeader() to send custom headers in mails
+  * Added the possibility to specify more than one recipient in NativeMailerHandler
+  * Added the possibility to specify float timeouts in SocketHandler
+  * Added NOTICE and EMERGENCY levels to conform with RFC 5424
+  * Fixed the log records to use the php default timezone instead of UTC
+  * Fixed BufferHandler not being flushed properly on PHP fatal errors
+  * Fixed normalization of exotic resource types
+  * Fixed the default format of the SyslogHandler to avoid duplicating datetimes in syslog
+
+### 1.1.0 (2012-04-23)
+
+  * Added Monolog\Logger::isHandling() to check if a handler will
+    handle the given log level
+  * Added ChromePHPHandler
+  * Added MongoDBHandler
+  * Added GelfHandler (for use with Graylog2 servers)
+  * Added SocketHandler (for use with syslog-ng for example)
+  * Added NormalizerFormatter
+  * Added the possibility to change the activation strategy of the FingersCrossedHandler
+  * Added possibility to show microseconds in logs
+  * Added `server` and `referer` to WebProcessor output
+
+### 1.0.2 (2011-10-24)
+
+  * Fixed bug in IE with large response headers and FirePHPHandler
+
+### 1.0.1 (2011-08-25)
+
+  * Added MemoryPeakUsageProcessor and MemoryUsageProcessor
+  * Added Monolog\Logger::getName() to get a logger's channel name
+
+### 1.0.0 (2011-07-06)
+
+  * Added IntrospectionProcessor to get info from where the logger was called
+  * Fixed WebProcessor in CLI
+
+### 1.0.0-RC1 (2011-07-01)
+
+  * Initial release

+ 19 - 0
vendor/monolog/monolog/LICENSE

@@ -0,0 +1,19 @@
+Copyright (c) Jordi Boggiano
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.

+ 248 - 0
vendor/monolog/monolog/README.mdown

@@ -0,0 +1,248 @@
+Monolog - Logging for PHP 5.3+ [![Build Status](https://secure.travis-ci.org/Seldaek/monolog.png)](http://travis-ci.org/Seldaek/monolog)
+==============================
+
+[![Total Downloads](https://poser.pugx.org/monolog/monolog/downloads.png)](https://packagist.org/packages/monolog/monolog)
+[![Latest Stable Version](https://poser.pugx.org/monolog/monolog/v/stable.png)](https://packagist.org/packages/monolog/monolog)
+
+
+Monolog sends your logs to files, sockets, inboxes, databases and various
+web services. See the complete list of handlers below. Special handlers
+allow you to build advanced logging strategies.
+
+This library implements the [PSR-3](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md)
+interface that you can type-hint against in your own libraries to keep
+a maximum of interoperability. You can also use it in your applications to
+make sure you can always use another compatible logger at a later time.
+
+Usage
+-----
+
+```php
+<?php
+
+use Monolog\Logger;
+use Monolog\Handler\StreamHandler;
+
+// create a log channel
+$log = new Logger('name');
+$log->pushHandler(new StreamHandler('path/to/your.log', Logger::WARNING));
+
+// add records to the log
+$log->addWarning('Foo');
+$log->addError('Bar');
+```
+
+Core Concepts
+-------------
+
+Every `Logger` instance has a channel (name) and a stack of handlers. Whenever
+you add a record to the logger, it traverses the handler stack. Each handler
+decides whether it handled fully the record, and if so, the propagation of the
+record ends there.
+
+This allows for flexible logging setups, for example having a `StreamHandler` at
+the bottom of the stack that will log anything to disk, and on top of that add
+a `MailHandler` that will send emails only when an error message is logged.
+Handlers also have a `$bubble` property which defines whether they block the
+record or not if they handled it. In this example, setting the `MailHandler`'s
+`$bubble` argument to true means that all records will propagate to the
+`StreamHandler`, even the errors that are handled by the `MailHandler`.
+
+You can create many `Logger`s, each defining a channel (e.g.: db, request,
+router, ..) and each of them combining various handlers, which can be shared
+or not. The channel is reflected in the logs and allows you to easily see or
+filter records.
+
+Each Handler also has a Formatter, a default one with settings that make sense
+will be created if you don't set one. The formatters normalize and format
+incoming records so that they can be used by the handlers to output useful
+information.
+
+Custom severity levels are not available. Only the eight
+[RFC 5424](http://tools.ietf.org/html/rfc5424) levels (debug, info, notice,
+warning, error, critical, alert, emergency) are present for basic filtering
+purposes, but for sorting and other use cases that would require
+flexibility, you should add Processors to the Logger that can add extra
+information (tags, user ip, ..) to the records before they are handled.
+
+Log Levels
+----------
+
+Monolog supports all 8 logging levels defined in
+[RFC 5424](http://tools.ietf.org/html/rfc5424), but unless you specifically
+need syslog compatibility, it is advised to only use DEBUG, INFO, WARNING,
+ERROR, CRITICAL, ALERT.
+
+- **DEBUG** (100): Detailed debug information.
+
+- **INFO** (200): Interesting events. Examples: User logs in, SQL logs.
+
+- NOTICE (250): Normal but significant events.
+
+- **WARNING** (300): Exceptional occurrences that are not errors. Examples:
+  Use of deprecated APIs, poor use of an API, undesirable things that are not
+  necessarily wrong.
+
+- **ERROR** (400): Runtime errors that do not require immediate action but
+  should typically be logged and monitored.
+
+- **CRITICAL** (500): Critical conditions. Example: Application component
+  unavailable, unexpected exception.
+
+- **ALERT** (550): Action must be taken immediately. Example: Entire website
+  down, database unavailable, etc. This should trigger the SMS alerts and wake
+  you up.
+
+- EMERGENCY (600): Emergency: system is unusable.
+
+Docs
+====
+
+**See the `doc` directory for more detailed documentation.
+The following is only a list of all parts that come with Monolog.**
+
+Handlers
+--------
+
+### Log to files and syslog
+
+- _StreamHandler_: Logs records into any PHP stream, use this for log files.
+- _RotatingFileHandler_: Logs records to a file and creates one logfile per day.
+  It will also delete files older than `$maxFiles`. You should use
+  [logrotate](http://linuxcommand.org/man_pages/logrotate8.html) for high profile
+  setups though, this is just meant as a quick and dirty solution.
+- _SyslogHandler_: Logs records to the syslog.
+- _ErrorLogHandler_: Logs records to PHP's
+  [`error_log()`](http://docs.php.net/manual/en/function.error-log.php) function.
+
+### Send alerts and emails
+
+- _NativeMailerHandler_: Sends emails using PHP's
+  [`mail()`](http://php.net/manual/en/function.mail.php) function.
+- _SwiftMailerHandler_: Sends emails using a [`Swift_Mailer`](http://swiftmailer.org/) instance.
+- _PushoverHandler_: Sends mobile notifications via the [Pushover](https://www.pushover.net/) API.
+- _HipChatHandler_: Logs records to a [HipChat](http://hipchat.com) chat room using its API.
+
+### Log specific servers and networked logging
+
+- _SocketHandler_: Logs records to [sockets](http://php.net/fsockopen), use this
+  for UNIX and TCP sockets. See an [example](https://github.com/Seldaek/monolog/blob/master/doc/sockets.md).
+- _AmqpHandler_: Logs records to an [amqp](http://www.amqp.org/) compatible
+  server. Requires the [php-amqp](http://pecl.php.net/package/amqp) extension (1.0+).
+- _GelfHandler_: Logs records to a [Graylog2](http://www.graylog2.org) server.
+- _CubeHandler_: Logs records to a [Cube](http://square.github.com/cube/) server.
+- _RavenHandler_: Logs records to a [Sentry](http://getsentry.com/) server using
+  [raven](https://packagist.org/packages/raven/raven).
+- _ZendMonitorHandler_: Logs records to the Zend Monitor present in Zend Server.
+- _NewRelicHandler_: Logs records to a [NewRelic](http://newrelic.com/) application.
+
+### Logging in development
+
+- _FirePHPHandler_: Handler for [FirePHP](http://www.firephp.org/), providing
+  inline `console` messages within [FireBug](http://getfirebug.com/).
+- _ChromePHPHandler_: Handler for [ChromePHP](http://www.chromephp.com/), providing
+  inline `console` messages within Chrome.
+
+### Log to databases
+
+- _RedisHandler_: Logs records to a [redis](http://redis.io) server.
+- _MongoDBHandler_: Handler to write records in MongoDB via a
+  [Mongo](http://pecl.php.net/package/mongo) extension connection.
+- _CouchDBHandler_: Logs records to a CouchDB server.
+- _DoctrineCouchDBHandler_: Logs records to a CouchDB server via the Doctrine CouchDB ODM.
+
+### Wrappers / Special Handlers
+
+- _FingersCrossedHandler_: A very interesting wrapper. It takes a logger as
+  parameter and will accumulate log records of all levels until a record
+  exceeds the defined severity level. At which point it delivers all records,
+  including those of lower severity, to the handler it wraps. This means that
+  until an error actually happens you will not see anything in your logs, but
+  when it happens you will have the full information, including debug and info
+  records. This provides you with all the information you need, but only when
+  you need it.
+- _NullHandler_: Any record it can handle will be thrown away. This can be used
+  to put on top of an existing handler stack to disable it temporarily.
+- _BufferHandler_: This handler will buffer all the log records it receives
+  until `close()` is called at which point it will call `handleBatch()` on the
+  handler it wraps with all the log messages at once. This is very useful to
+  send an email with all records at once for example instead of having one mail
+  for every log record.
+- _GroupHandler_: This handler groups other handlers. Every record received is
+  sent to all the handlers it is configured with.
+- _TestHandler_: Used for testing, it records everything that is sent to it and
+  has accessors to read out the information.
+
+Formatters
+----------
+
+- _LineFormatter_: Formats a log record into a one-line string.
+- _NormalizerFormatter_: Normalizes objects/resources down to strings so a record can easily be serialized/encoded.
+- _JsonFormatter_: Encodes a log record into json.
+- _WildfireFormatter_: Used to format log records into the Wildfire/FirePHP protocol, only useful for the FirePHPHandler.
+- _ChromePHPFormatter_: Used to format log records into the ChromePHP format, only useful for the ChromePHPHandler.
+- _GelfFormatter_: Used to format log records into Gelf message instances, only useful for the GelfHandler.
+- _LogstashFormatter_: Used to format log records into [logstash](http://logstash.net/) event json, useful for any handler listed under inputs [here](http://logstash.net/docs/1.1.5/).
+
+Processors
+----------
+
+- _IntrospectionProcessor_: Adds the line/file/class/method from which the log call originated.
+- _WebProcessor_: Adds the current request URI, request method and client IP to a log record.
+- _MemoryUsageProcessor_: Adds the current memory usage to a log record.
+- _MemoryPeakUsageProcessor_: Adds the peak memory usage to a log record.
+- _ProcessIdProcessor_: Adds the process id to a log record.
+- _UidProcessor_: Adds a unique identifier to a log record.
+
+Utilities
+---------
+
+- _ErrorHandler_: The `Monolog\ErrorHandler` class allows you to easily register
+  a Logger instance as an exception handler, error handler or fatal error handler.
+- _ErrorLevelActivationStrategy_: Activates a FingersCrossedHandler when a certain log
+  level is reached.
+- _ChannelLevelActivationStrategy_: Activates a FingersCrossedHandler when a certain
+  log level is reached, depending on which channel received the log record.
+
+About
+=====
+
+Requirements
+------------
+
+- Any flavor of PHP 5.3 or above should do
+- [optional] PHPUnit 3.5+ to execute the test suite (phpunit --version)
+
+Submitting bugs and feature requests
+------------------------------------
+
+Bugs and feature request are tracked on [GitHub](https://github.com/Seldaek/monolog/issues)
+
+Frameworks Integration
+----------------------
+
+- Frameworks and libraries using [PSR-3](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md)
+  can be used very easily with Monolog since it implements the interface.
+- [Symfony2](http://symfony.com) comes out of the box with Monolog.
+- [Silex](http://silex.sensiolabs.org/) comes out of the box with Monolog.
+- [Laravel4](http://laravel.com/) comes out of the box with Monolog.
+- [PPI](http://www.ppi.io/) comes out of the box with Monolog.
+- [CakePHP](http://cakephp.org/) is usable with Monolog via the [cakephp-monolog](https://github.com/jadb/cakephp-monolog) plugin.
+- [Slim](http://www.slimframework.com/) is usable with Monolog via the [Slim-Monolog](https://github.com/Flynsarmy/Slim-Monolog) log writer.
+
+Author
+------
+
+Jordi Boggiano - <j.boggiano@seld.be> - <http://twitter.com/seldaek><br />
+See also the list of [contributors](https://github.com/Seldaek/monolog/contributors) which participated in this project.
+
+License
+-------
+
+Monolog is licensed under the MIT License - see the `LICENSE` file for details
+
+Acknowledgements
+----------------
+
+This library is heavily inspired by Python's [Logbook](http://packages.python.org/Logbook/)
+library, although most concepts have been adjusted to fit to the PHP world.

+ 39 - 0
vendor/monolog/monolog/composer.json

@@ -0,0 +1,39 @@
+{
+    "name": "monolog/monolog",
+    "description": "Sends your logs to files, sockets, inboxes, databases and various web services",
+    "keywords": ["log", "logging", "psr-3"],
+    "homepage": "http://github.com/Seldaek/monolog",
+    "type": "library",
+    "license": "MIT",
+    "authors": [
+        {
+            "name": "Jordi Boggiano",
+            "email": "j.boggiano@seld.be",
+            "homepage": "http://seld.be"
+        }
+    ],
+    "require": {
+        "php": ">=5.3.0",
+        "psr/log": "~1.0"
+    },
+    "require-dev": {
+        "mlehner/gelf-php": "1.0.*",
+        "raven/raven": "0.5.*",
+        "doctrine/couchdb": "dev-master"
+    },
+    "suggest": {
+        "mlehner/gelf-php": "Allow sending log messages to a GrayLog2 server",
+        "raven/raven": "Allow sending log messages to a Sentry server",
+        "doctrine/couchdb": "Allow sending log messages to a CouchDB server",
+        "ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)",
+        "ext-mongo": "Allow sending log messages to a MongoDB server"
+    },
+    "autoload": {
+        "psr-0": {"Monolog": "src/"}
+    },
+    "extra": {
+        "branch-alias": {
+            "dev-master": "1.6.x-dev"
+        }
+    }
+}

+ 76 - 0
vendor/monolog/monolog/doc/extending.md

@@ -0,0 +1,76 @@
+Extending Monolog
+=================
+
+Monolog is fully extensible, allowing you to adapt your logger to your needs.
+
+Writing your own handler
+------------------------
+
+Monolog provides many built-in handlers. But if the one you need does not
+exist, you can write it and use it in your logger. The only requirement is
+to implement `Monolog\Handler\HandlerInterface`.
+
+Let's write a PDOHandler to log records to a database. We will extend the
+abstract class provided by Monolog to keep things DRY.
+
+```php
+<?php
+
+use Monolog\Logger;
+use Monolog\Handler\AbstractProcessingHandler;
+
+class PDOHandler extends AbstractProcessingHandler
+{
+    private $initialized = false;
+    private $pdo;
+    private $statement;
+
+    public function __construct(PDO $pdo, $level = Logger::DEBUG, $bubble = true)
+    {
+        $this->pdo = $pdo;
+        parent::__construct($level, $bubble);
+    }
+
+    protected function write(array $record)
+    {
+        if (!$this->initialized) {
+            $this->initialize();
+        }
+
+        $this->statement->execute(array(
+            'channel' => $record['channel'],
+            'level' => $record['level'],
+            'message' => $record['formatted'],
+            'time' => $record['datetime']->format('U'),
+        ));
+    }
+
+    private function initialize()
+    {
+        $this->pdo->exec(
+            'CREATE TABLE IF NOT EXISTS monolog '
+            .'(channel VARCHAR(255), level INTEGER, message LONGTEXT, time INTEGER UNSIGNED)'
+        );
+        $this->statement = $this->pdo->prepare(
+            'INSERT INTO monolog (channel, level, message, time) VALUES (:channel, :level, :message, :time)'
+        );
+
+        $this->initialized = true;
+    }
+}
+```
+
+You can now use this handler in your logger:
+
+```php
+<?php
+
+$logger->pushHandler(new PDOHandler(new PDO('sqlite:logs.sqlite'));
+
+// You can now use your logger
+$logger->addInfo('My logger is now ready');
+```
+
+The `Monolog\Handler\AbstractProcessingHandler` class provides most of the
+logic needed for the handler, including the use of processors and the formatting
+of the record (which is why we use ``$record['formatted']`` instead of ``$record['message']``).

+ 37 - 0
vendor/monolog/monolog/doc/sockets.md

@@ -0,0 +1,37 @@
+Sockets Handler
+===============
+
+This handler allows you to write your logs to sockets using [fsockopen](http://php.net/fsockopen)
+or [pfsockopen](http://php.net/pfsockopen).
+
+Persistent sockets are mainly useful in web environments where you gain some performance not closing/opening
+the connections between requests.
+
+Basic Example
+-------------
+
+```php
+<?php
+
+use Monolog\Logger;
+use Monolog\Handler\SocketHandler;
+
+// Create the logger
+$logger = new Logger('my_logger');
+
+// Create the handler
+$handler = new SocketHandler('unix:///var/log/httpd_app_log.socket');
+$handler->setPersistent(true);
+
+// Now add the handler
+$logger->pushHandler($handler, Logger::DEBUG);
+
+// You can now use your logger
+$logger->addInfo('My logger is now ready');
+
+```
+
+In this example, using syslog-ng, you should see the log on the log server:
+
+    cweb1 [2012-02-26 00:12:03] my_logger.INFO: My logger is now ready [] []
+

+ 158 - 0
vendor/monolog/monolog/doc/usage.md

@@ -0,0 +1,158 @@
+Using Monolog
+=============
+
+Installation
+------------
+
+Monolog is available on Packagist ([monolog/monolog](http://packagist.org/packages/monolog/monolog))
+and as such installable via [Composer](http://getcomposer.org/).
+
+If you do not use Composer, you can grab the code from GitHub, and use any
+PSR-0 compatible autoloader (e.g. the [Symfony2 ClassLoader component](https://github.com/symfony/ClassLoader))
+to load Monolog classes.
+
+Configuring a logger
+--------------------
+
+Here is a basic setup to log to a file and to firephp on the DEBUG level:
+
+```php
+<?php
+
+use Monolog\Logger;
+use Monolog\Handler\StreamHandler;
+use Monolog\Handler\FirePHPHandler;
+
+// Create the logger
+$logger = new Logger('my_logger');
+// Now add some handlers
+$logger->pushHandler(new StreamHandler(__DIR__.'/my_app.log', Logger::DEBUG));
+$logger->pushHandler(new FirePHPHandler());
+
+// You can now use your logger
+$logger->addInfo('My logger is now ready');
+```
+
+Let's explain it. The first step is to create the logger instance which will
+be used in your code. The argument is a channel name, which is useful when
+you use several loggers (see below for more details about it).
+
+The logger itself does not know how to handle a record. It delegates it to
+some handlers. The code above registers two handlers in the stack to allow
+handling records in two different ways.
+
+Note that the FirePHPHandler is called first as it is added on top of the
+stack. This allows you to temporarily add a logger with bubbling disabled if
+you want to override other configured loggers.
+
+Adding extra data in the records
+--------------------------------
+
+Monolog provides two different ways to add extra informations along the simple
+textual message.
+
+### Using the logging context
+
+The first way is the context, allowing to pass an array of data along the
+record:
+
+```php
+<?php
+
+$logger->addInfo('Adding a new user', array('username' => 'Seldaek'));
+```
+
+Simple handlers (like the StreamHandler for instance) will simply format
+the array to a string but richer handlers can take advantage of the context
+(FirePHP is able to display arrays in pretty way for instance).
+
+### Using processors
+
+The second way is to add extra data for all records by using a processor.
+Processors can be any callable. They will get the record as parameter and
+must return it after having eventually changed the `extra` part of it. Let's
+write a processor adding some dummy data in the record:
+
+```php
+<?php
+
+$logger->pushProcessor(function ($record) {
+    $record['extra']['dummy'] = 'Hello world!';
+
+    return $record;
+});
+```
+
+Monolog provides some built-in processors that can be used in your project.
+Look at the README file for the list.
+
+> Tip: processors can also be registered on a specific handler instead of
+  the logger to apply only for this handler.
+
+Leveraging channels
+-------------------
+
+Channels are a great way to identify to which part of the application a record
+is related. This is useful in big applications (and is leveraged by
+MonologBundle in Symfony2).
+
+Picture two loggers sharing a handler that writes to a single log file.
+Channels would allow you to identify the logger that issued every record.
+You can easily grep through the log files filtering this or that channel.
+
+```php
+<?php
+
+use Monolog\Logger;
+use Monolog\Handler\StreamHandler;
+use Monolog\Handler\FirePHPHandler;
+
+// Create some handlers
+$stream = new StreamHandler(__DIR__.'/my_app.log', Logger::DEBUG);
+$firephp = new FirePHPHandler();
+
+// Create the main logger of the app
+$logger = new Logger('my_logger');
+$logger->pushHandler($stream);
+$logger->pushHandler($firephp);
+
+// Create a logger for the security-related stuff with a different channel
+$securityLogger = new Logger('security');
+$securityLogger->pushHandler($stream);
+$securityLogger->pushHandler($firephp);
+```
+
+Customizing log format
+----------------------
+
+In Monolog it's easy to customize the format of the logs written into files,
+sockets, mails, databases and other handlers. Most of the handlers use the
+
+```php
+$record['formatted']
+```
+
+value to be automatically put into the log device. This value depends on the
+formatter settings. You can choose between predefined formatter classes or
+write your own (e.g. a multiline text file for human-readable output).
+
+To configure a predefined formatter class, just set it as the handler's field:
+
+```php
+// the default date format is "Y-m-d H:i:s"
+$dateFormat = "Y n j, g:i a";
+// the default output format is "[%datetime%] %channel%.%level_name%: %message% %context% %extra%\n"
+$output = "%datetime% > %level_name% > %message% %context% %extra%\n";
+// finally, create a formatter
+$formatter = new LineFormatter($output, $dateFormat);
+
+// Create a handler
+$stream = new StreamHandler(__DIR__.'/my_app.log', Logger::DEBUG);
+$stream->setFormatter($formatter);
+// bind it to a logger object
+$securityLogger = new Logger('security');
+$securityLogger->pushHandler($stream);
+```
+
+You may also reuse the same formatter between multiple handlers and share those
+handlers between multiple loggers.

+ 15 - 0
vendor/monolog/monolog/phpunit.xml.dist

@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<phpunit bootstrap="tests/bootstrap.php" colors="true">
+    <testsuites>
+        <testsuite name="Monolog Test Suite">
+            <directory>tests/Monolog/</directory>
+        </testsuite>
+    </testsuites>
+
+    <filter>
+        <whitelist>
+            <directory suffix=".php">src/Monolog/</directory>
+        </whitelist>
+    </filter>
+</phpunit>

+ 209 - 0
vendor/monolog/monolog/src/Monolog/ErrorHandler.php

@@ -0,0 +1,209 @@
+<?php
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog;
+
+use Psr\Log\LoggerInterface;
+use Psr\Log\LogLevel;
+
+/**
+ * Monolog error handler
+ *
+ * A facility to enable logging of runtime errors, exceptions and fatal errors.
+ *
+ * Quick setup: <code>ErrorHandler::register($logger);</code>
+ *
+ * @author Jordi Boggiano <j.boggiano@seld.be>
+ */
+class ErrorHandler
+{
+    private $logger;
+
+    private $previousExceptionHandler;
+    private $uncaughtExceptionLevel;
+
+    private $previousErrorHandler;
+    private $errorLevelMap;
+
+    private $fatalLevel;
+    private $reservedMemory;
+    private static $fatalErrors = array(E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR, E_USER_ERROR);
+
+    public function __construct(LoggerInterface $logger)
+    {
+        $this->logger = $logger;
+    }
+
+    /**
+     * Registers a new ErrorHandler for a given Logger
+     *
+     * By default it will handle errors, exceptions and fatal errors
+     *
+     * @param  LoggerInterface $logger
+     * @param  array|false     $errorLevelMap  an array of E_* constant to LogLevel::* constant mapping, or false to disable error handling
+     * @param  int|false       $exceptionLevel a LogLevel::* constant, or false to disable exception handling
+     * @param  int|false       $fatalLevel     a LogLevel::* constant, or false to disable fatal error handling
+     * @return ErrorHandler
+     */
+    public static function register(LoggerInterface $logger, $errorLevelMap = array(), $exceptionLevel = null, $fatalLevel = null)
+    {
+        $handler = new static($logger);
+        if ($errorLevelMap !== false) {
+            $handler->registerErrorHandler($errorLevelMap);
+        }
+        if ($exceptionLevel !== false) {
+            $handler->registerExceptionHandler($exceptionLevel);
+        }
+        if ($fatalLevel !== false) {
+            $handler->registerFatalHandler($fatalLevel);
+        }
+
+        return $handler;
+    }
+
+    public function registerExceptionHandler($level = null, $callPrevious = true)
+    {
+        $prev = set_exception_handler(array($this, 'handleException'));
+        $this->uncaughtExceptionLevel = $level === null ? LogLevel::ERROR : $level;
+        if ($callPrevious && $prev) {
+            $this->previousExceptionHandler = $prev;
+        }
+    }
+
+    public function registerErrorHandler(array $levelMap = array(), $callPrevious = true, $errorTypes = -1)
+    {
+        $prev = set_error_handler(array($this, 'handleError'), $errorTypes);
+        $this->errorLevelMap = $this->defaultErrorLevelMap();
+        // merging the map into the defaults by hand because array_merge
+        // trips up on numeric keys
+        foreach ($levelMap as $key => $val) {
+            $this->errorLevelMap[$key] = $val;
+        }
+        if ($callPrevious) {
+            $this->previousErrorHandler = $prev ?: true;
+        }
+    }
+
+    public function registerFatalHandler($level = null, $reservedMemorySize = 20)
+    {
+        register_shutdown_function(array($this, 'handleFatalError'));
+
+        $this->reservedMemory = str_repeat(' ', 1024 * $reservedMemorySize);
+        $this->fatalLevel = $level === null ? LogLevel::ALERT : $level;
+    }
+
+    protected function defaultErrorLevelMap()
+    {
+        return array(
+            E_ERROR             => LogLevel::CRITICAL,
+            E_WARNING           => LogLevel::WARNING,
+            E_PARSE             => LogLevel::ALERT,
+            E_NOTICE            => LogLevel::NOTICE,
+            E_CORE_ERROR        => LogLevel::CRITICAL,
+            E_CORE_WARNING      => LogLevel::WARNING,
+            E_COMPILE_ERROR     => LogLevel::ALERT,
+            E_COMPILE_WARNING   => LogLevel::WARNING,
+            E_USER_ERROR        => LogLevel::ERROR,
+            E_USER_WARNING      => LogLevel::WARNING,
+            E_USER_NOTICE       => LogLevel::NOTICE,
+            E_STRICT            => LogLevel::NOTICE,
+            E_RECOVERABLE_ERROR => LogLevel::ERROR,
+            E_DEPRECATED        => LogLevel::NOTICE,
+            E_USER_DEPRECATED   => LogLevel::NOTICE,
+        );
+    }
+
+    /**
+     * @private
+     */
+    public function handleException(\Exception $e)
+    {
+        $this->logger->log($this->uncaughtExceptionLevel, 'Uncaught exception', array('exception' => $e));
+
+        if ($this->previousExceptionHandler) {
+            call_user_func($this->previousExceptionHandler, $e);
+        }
+    }
+
+    /**
+     * @private
+     */
+    public function handleError($code, $message, $file = '', $line = 0, $context = array())
+    {
+        if (!(error_reporting() & $code)) {
+            return;
+        }
+
+        $level = isset($this->errorLevelMap[$code]) ? $this->errorLevelMap[$code] : LogLevel::CRITICAL;
+        $this->logger->log($level, self::codeToString($code).': '.$message, array('file' => $file, 'line' => $line));
+
+        if ($this->previousErrorHandler === true) {
+            return false;
+        } elseif ($this->previousErrorHandler) {
+            return call_user_func($this->previousErrorHandler, $code, $message, $file, $line, $context);
+        }
+    }
+
+    /**
+     * @private
+     */
+    public function handleFatalError()
+    {
+        $this->reservedMemory = null;
+
+        $lastError = error_get_last();
+        if ($lastError && in_array($lastError['type'], self::$fatalErrors)) {
+            $this->logger->log(
+                $this->fatalLevel,
+                'Fatal Error ('.self::codeToString($lastError['type']).'): '.$lastError['message'],
+                array('file' => $lastError['file'], 'line' => $lastError['line'])
+            );
+        }
+    }
+
+    private static function codeToString($code)
+    {
+        switch ($code) {
+            case E_ERROR:
+                return 'E_ERROR';
+            case E_WARNING:
+                return 'E_WARNING';
+            case E_PARSE:
+                return 'E_PARSE';
+            case E_NOTICE:
+                return 'E_NOTICE';
+            case E_CORE_ERROR:
+                return 'E_CORE_ERROR';
+            case E_CORE_WARNING:
+                return 'E_CORE_WARNING';
+            case E_COMPILE_ERROR:
+                return 'E_COMPILE_ERROR';
+            case E_COMPILE_WARNING:
+                return 'E_COMPILE_WARNING';
+            case E_USER_ERROR:
+                return 'E_USER_ERROR';
+            case E_USER_WARNING:
+                return 'E_USER_WARNING';
+            case E_USER_NOTICE:
+                return 'E_USER_NOTICE';
+            case E_STRICT:
+                return 'E_STRICT';
+            case E_RECOVERABLE_ERROR:
+                return 'E_RECOVERABLE_ERROR';
+            case E_DEPRECATED:
+                return 'E_DEPRECATED';
+            case E_USER_DEPRECATED:
+                return 'E_USER_DEPRECATED';
+        }
+
+        return 'Unknown PHP error';
+    }
+}

+ 79 - 0
vendor/monolog/monolog/src/Monolog/Formatter/ChromePHPFormatter.php

@@ -0,0 +1,79 @@
+<?php
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Formatter;
+
+use Monolog\Logger;
+
+/**
+ * Formats a log message according to the ChromePHP array format
+ *
+ * @author Christophe Coevoet <stof@notk.org>
+ */
+class ChromePHPFormatter implements FormatterInterface
+{
+    /**
+     * Translates Monolog log levels to Wildfire levels.
+     */
+    private $logLevels = array(
+        Logger::DEBUG     => 'log',
+        Logger::INFO      => 'info',
+        Logger::NOTICE    => 'info',
+        Logger::WARNING   => 'warn',
+        Logger::ERROR     => 'error',
+        Logger::CRITICAL  => 'error',
+        Logger::ALERT     => 'error',
+        Logger::EMERGENCY => 'error',
+    );
+
+    /**
+     * {@inheritdoc}
+     */
+    public function format(array $record)
+    {
+        // Retrieve the line and file if set and remove them from the formatted extra
+        $backtrace = 'unknown';
+        if (isset($record['extra']['file']) && isset($record['extra']['line'])) {
+            $backtrace = $record['extra']['file'].' : '.$record['extra']['line'];
+            unset($record['extra']['file']);
+            unset($record['extra']['line']);
+        }
+
+        $message = array('message' => $record['message']);
+        if ($record['context']) {
+            $message['context'] = $record['context'];
+        }
+        if ($record['extra']) {
+            $message['extra'] = $record['extra'];
+        }
+        if (count($message) === 1) {
+            $message = reset($message);
+        }
+
+        return array(
+            $record['channel'],
+            $message,
+            $backtrace,
+            $this->logLevels[$record['level']],
+        );
+    }
+
+    public function formatBatch(array $records)
+    {
+        $formatted = array();
+
+        foreach ($records as $record) {
+            $formatted[] = $this->format($record);
+        }
+
+        return $formatted;
+    }
+}

+ 36 - 0
vendor/monolog/monolog/src/Monolog/Formatter/FormatterInterface.php

@@ -0,0 +1,36 @@
+<?php
+
+/*
+ * This file is part of the Monolog package.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Monolog\Formatter;
+
+/**
+ * Interface for formatters
+ *
+ * @author Jordi Boggiano <j.boggiano@seld.be>
+ */
+interface FormatterInterface
+{
+    /**
+     * Formats a log record.
+     *
+     * @param  array $record A record to format
+     * @return mixed The formatted record
+     */
+    public function format(array $record);
+
+    /**
+     * Formats a set of log records.
+     *
+     * @param  array $records A set of records to format
+     * @return mixed The formatted set of records
+     */
+    public function formatBatch(array $records);
+}

Some files were not shown because too many files changed in this diff