Quellcode durchsuchen

Added Silex framework

git-svn-id: http://svn.code.sf.net/p/itop/code/trunk@3855 a333f486-631f-4898-b8df-5754b55c2be0
glajarige vor 9 Jahren
Ursprung
Commit
fddde8b17d
100 geänderte Dateien mit 10646 neuen und 0 gelöschten Zeilen
  1. 6 0
      lib/silex/composer.json
  2. 567 0
      lib/silex/composer.lock
  3. 7 0
      lib/silex/vendor/autoload.php
  4. 413 0
      lib/silex/vendor/composer/ClassLoader.php
  5. 21 0
      lib/silex/vendor/composer/LICENSE
  6. 10 0
      lib/silex/vendor/composer/autoload_classmap.php
  7. 18 0
      lib/silex/vendor/composer/autoload_namespaces.php
  8. 9 0
      lib/silex/vendor/composer/autoload_psr4.php
  9. 50 0
      lib/silex/vendor/composer/autoload_real.php
  10. 568 0
      lib/silex/vendor/composer/installed.json
  11. 1 0
      lib/silex/vendor/pimple/pimple/.gitignore
  12. 19 0
      lib/silex/vendor/pimple/pimple/LICENSE
  13. 159 0
      lib/silex/vendor/pimple/pimple/README.rst
  14. 25 0
      lib/silex/vendor/pimple/pimple/composer.json
  15. 214 0
      lib/silex/vendor/pimple/pimple/lib/Pimple.php
  16. 1 0
      lib/silex/vendor/psr/log/.gitignore
  17. 19 0
      lib/silex/vendor/psr/log/LICENSE
  18. 120 0
      lib/silex/vendor/psr/log/Psr/Log/AbstractLogger.php
  19. 7 0
      lib/silex/vendor/psr/log/Psr/Log/InvalidArgumentException.php
  20. 18 0
      lib/silex/vendor/psr/log/Psr/Log/LogLevel.php
  21. 17 0
      lib/silex/vendor/psr/log/Psr/Log/LoggerAwareInterface.php
  22. 22 0
      lib/silex/vendor/psr/log/Psr/Log/LoggerAwareTrait.php
  23. 114 0
      lib/silex/vendor/psr/log/Psr/Log/LoggerInterface.php
  24. 131 0
      lib/silex/vendor/psr/log/Psr/Log/LoggerTrait.php
  25. 27 0
      lib/silex/vendor/psr/log/Psr/Log/NullLogger.php
  26. 116 0
      lib/silex/vendor/psr/log/Psr/Log/Test/LoggerInterfaceTest.php
  27. 45 0
      lib/silex/vendor/psr/log/README.md
  28. 17 0
      lib/silex/vendor/psr/log/composer.json
  29. 5 0
      lib/silex/vendor/silex/silex/.gitignore
  30. 19 0
      lib/silex/vendor/silex/silex/LICENSE
  31. 63 0
      lib/silex/vendor/silex/silex/README.rst
  32. 67 0
      lib/silex/vendor/silex/silex/bin/build
  33. 9 0
      lib/silex/vendor/silex/silex/bin/compile
  34. 23 0
      lib/silex/vendor/silex/silex/bin/skeleton/fat_composer.json
  35. 11 0
      lib/silex/vendor/silex/silex/bin/skeleton/index.php
  36. 5 0
      lib/silex/vendor/silex/silex/bin/skeleton/slim_composer.json
  37. 62 0
      lib/silex/vendor/silex/silex/composer.json
  38. 259 0
      lib/silex/vendor/silex/silex/doc/changelog.rst
  39. 17 0
      lib/silex/vendor/silex/silex/doc/conf.py
  40. 55 0
      lib/silex/vendor/silex/silex/doc/contributing.rst
  41. 66 0
      lib/silex/vendor/silex/silex/doc/cookbook/assets.rst
  42. 47 0
      lib/silex/vendor/silex/silex/doc/cookbook/error_handler.rst
  43. 35 0
      lib/silex/vendor/silex/silex/doc/cookbook/form_no_csrf.rst
  44. 43 0
      lib/silex/vendor/silex/silex/doc/cookbook/index.rst
  45. 95 0
      lib/silex/vendor/silex/silex/doc/cookbook/json_request_body.rst
  46. 71 0
      lib/silex/vendor/silex/silex/doc/cookbook/multiple_loggers.rst
  47. 92 0
      lib/silex/vendor/silex/silex/doc/cookbook/session_storage.rst
  48. 177 0
      lib/silex/vendor/silex/silex/doc/cookbook/sub_requests.rst
  49. 20 0
      lib/silex/vendor/silex/silex/doc/cookbook/translating_validation_messages.rst
  50. 35 0
      lib/silex/vendor/silex/silex/doc/cookbook/validator_yaml.rst
  51. 20 0
      lib/silex/vendor/silex/silex/doc/index.rst
  52. 85 0
      lib/silex/vendor/silex/silex/doc/internals.rst
  53. 67 0
      lib/silex/vendor/silex/silex/doc/intro.rst
  54. 163 0
      lib/silex/vendor/silex/silex/doc/middlewares.rst
  55. 73 0
      lib/silex/vendor/silex/silex/doc/organizing_controllers.rst
  56. 109 0
      lib/silex/vendor/silex/silex/doc/phar.rst
  57. 214 0
      lib/silex/vendor/silex/silex/doc/providers.rst
  58. 141 0
      lib/silex/vendor/silex/silex/doc/providers/doctrine.rst
  59. 194 0
      lib/silex/vendor/silex/silex/doc/providers/form.rst
  60. 132 0
      lib/silex/vendor/silex/silex/doc/providers/http_cache.rst
  61. 74 0
      lib/silex/vendor/silex/silex/doc/providers/http_fragment.rst
  62. 21 0
      lib/silex/vendor/silex/silex/doc/providers/index.rst
  63. 105 0
      lib/silex/vendor/silex/silex/doc/providers/monolog.rst
  64. 69 0
      lib/silex/vendor/silex/silex/doc/providers/remember_me.rst
  65. 646 0
      lib/silex/vendor/silex/silex/doc/providers/security.rst
  66. 76 0
      lib/silex/vendor/silex/silex/doc/providers/serializer.rst
  67. 116 0
      lib/silex/vendor/silex/silex/doc/providers/service_controller.rst
  68. 102 0
      lib/silex/vendor/silex/silex/doc/providers/session.rst
  69. 135 0
      lib/silex/vendor/silex/silex/doc/providers/swiftmailer.rst
  70. 185 0
      lib/silex/vendor/silex/silex/doc/providers/translation.rst
  71. 161 0
      lib/silex/vendor/silex/silex/doc/providers/twig.rst
  72. 79 0
      lib/silex/vendor/silex/silex/doc/providers/url_generator.rst
  73. 221 0
      lib/silex/vendor/silex/silex/doc/providers/validator.rst
  74. 271 0
      lib/silex/vendor/silex/silex/doc/services.rst
  75. 220 0
      lib/silex/vendor/silex/silex/doc/testing.rst
  76. 768 0
      lib/silex/vendor/silex/silex/doc/usage.rst
  77. 158 0
      lib/silex/vendor/silex/silex/doc/web_servers.rst
  78. 24 0
      lib/silex/vendor/silex/silex/phpunit.xml.dist
  79. 561 0
      lib/silex/vendor/silex/silex/src/Silex/Application.php
  80. 35 0
      lib/silex/vendor/silex/silex/src/Silex/Application/FormTrait.php
  81. 36 0
      lib/silex/vendor/silex/silex/src/Silex/Application/MonologTrait.php
  82. 58 0
      lib/silex/vendor/silex/silex/src/Silex/Application/SecurityTrait.php
  83. 33 0
      lib/silex/vendor/silex/silex/src/Silex/Application/SwiftmailerTrait.php
  84. 51 0
      lib/silex/vendor/silex/silex/src/Silex/Application/TranslationTrait.php
  85. 65 0
      lib/silex/vendor/silex/silex/src/Silex/Application/TwigTrait.php
  86. 48 0
      lib/silex/vendor/silex/silex/src/Silex/Application/UrlGeneratorTrait.php
  87. 70 0
      lib/silex/vendor/silex/silex/src/Silex/CallbackResolver.php
  88. 87 0
      lib/silex/vendor/silex/silex/src/Silex/ConstraintValidatorFactory.php
  89. 118 0
      lib/silex/vendor/silex/silex/src/Silex/Controller.php
  90. 202 0
      lib/silex/vendor/silex/silex/src/Silex/ControllerCollection.php
  91. 29 0
      lib/silex/vendor/silex/silex/src/Silex/ControllerProviderInterface.php
  92. 52 0
      lib/silex/vendor/silex/silex/src/Silex/ControllerResolver.php
  93. 66 0
      lib/silex/vendor/silex/silex/src/Silex/EventListener/ConverterListener.php
  94. 42 0
      lib/silex/vendor/silex/silex/src/Silex/EventListener/LocaleListener.php
  95. 128 0
      lib/silex/vendor/silex/silex/src/Silex/EventListener/LogListener.php
  96. 96 0
      lib/silex/vendor/silex/silex/src/Silex/EventListener/MiddlewareListener.php
  97. 51 0
      lib/silex/vendor/silex/silex/src/Silex/EventListener/StringToResponseListener.php
  98. 21 0
      lib/silex/vendor/silex/silex/src/Silex/Exception/ControllerFrozenException.php
  99. 58 0
      lib/silex/vendor/silex/silex/src/Silex/ExceptionHandler.php
  100. 93 0
      lib/silex/vendor/silex/silex/src/Silex/ExceptionListenerWrapper.php

+ 6 - 0
lib/silex/composer.json

@@ -0,0 +1,6 @@
+{
+    "require": {
+        "silex/silex": "~1.1",
+        "twig/twig": "1.21.*"
+    }
+}

+ 567 - 0
lib/silex/composer.lock

@@ -0,0 +1,567 @@
+{
+    "_readme": [
+        "This file locks the dependencies of your project to a known state",
+        "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
+        "This file is @generated automatically"
+    ],
+    "hash": "0cef8e455a5b99f76246934c54fb0b18",
+    "content-hash": "bcccad4b8962ec6793031384b3b2fc97",
+    "packages": [
+        {
+            "name": "pimple/pimple",
+            "version": "v1.1.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/silexphp/Pimple.git",
+                "reference": "2019c145fe393923f3441b23f29bbdfaa5c58c4d"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/silexphp/Pimple/zipball/2019c145fe393923f3441b23f29bbdfaa5c58c4d",
+                "reference": "2019c145fe393923f3441b23f29bbdfaa5c58c4d",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.3.0"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.1.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-0": {
+                    "Pimple": "lib/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Fabien Potencier",
+                    "email": "fabien@symfony.com"
+                }
+            ],
+            "description": "Pimple is a simple Dependency Injection Container for PHP 5.3",
+            "homepage": "http://pimple.sensiolabs.org",
+            "keywords": [
+                "container",
+                "dependency injection"
+            ],
+            "time": "2013-11-22 08:30:29"
+        },
+        {
+            "name": "psr/log",
+            "version": "1.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": ""
+            },
+            "type": "library",
+            "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"
+            ],
+            "time": "2012-12-21 11:40:51"
+        },
+        {
+            "name": "silex/silex",
+            "version": "v1.2.5",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/silexphp/Silex.git",
+                "reference": "ce75b98d82d4c509802e63005c618392db17afef"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/silexphp/Silex/zipball/ce75b98d82d4c509802e63005c618392db17afef",
+                "reference": "ce75b98d82d4c509802e63005c618392db17afef",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.3.3",
+                "pimple/pimple": "~1.0",
+                "symfony/event-dispatcher": "~2.3,<2.7",
+                "symfony/http-foundation": "~2.3,<2.7",
+                "symfony/http-kernel": "~2.3,<2.7",
+                "symfony/routing": "~2.3,<2.7"
+            },
+            "require-dev": {
+                "doctrine/dbal": "~2.2",
+                "monolog/monolog": "~1.4,>=1.4.1",
+                "swiftmailer/swiftmailer": "5.*",
+                "symfony/browser-kit": "~2.3,<2.7",
+                "symfony/config": "~2.3,<2.7",
+                "symfony/css-selector": "~2.3,<2.7",
+                "symfony/debug": "~2.3,<2.7",
+                "symfony/dom-crawler": "~2.3,<2.7",
+                "symfony/finder": "~2.3,<2.7",
+                "symfony/form": "~2.3,<2.7",
+                "symfony/locale": "~2.3,<2.7",
+                "symfony/monolog-bridge": "~2.3,<2.7",
+                "symfony/options-resolver": "~2.3,<2.7",
+                "symfony/process": "~2.3,<2.7",
+                "symfony/security": "~2.3,<2.7",
+                "symfony/serializer": "~2.3,<2.7",
+                "symfony/translation": "~2.3,<2.7",
+                "symfony/twig-bridge": "~2.3,<2.7",
+                "symfony/validator": "~2.3,<2.7",
+                "twig/twig": ">=1.8.0,<2.0-dev"
+            },
+            "suggest": {
+                "symfony/browser-kit": "~2.3",
+                "symfony/css-selector": "~2.3",
+                "symfony/dom-crawler": "~2.3",
+                "symfony/form": "~2.3"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.2.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-0": {
+                    "Silex": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Fabien Potencier",
+                    "email": "fabien@symfony.com"
+                },
+                {
+                    "name": "Igor Wiedler",
+                    "email": "igor@wiedler.ch"
+                }
+            ],
+            "description": "The PHP micro-framework based on the Symfony2 Components",
+            "homepage": "http://silex.sensiolabs.org",
+            "keywords": [
+                "microframework"
+            ],
+            "time": "2015-06-04 21:24:58"
+        },
+        {
+            "name": "symfony/debug",
+            "version": "v2.6.12",
+            "target-dir": "Symfony/Component/Debug",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/debug.git",
+                "reference": "fca5696e0c9787722baa8f2ad6940dfd7a6a6941"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/debug/zipball/fca5696e0c9787722baa8f2ad6940dfd7a6a6941",
+                "reference": "fca5696e0c9787722baa8f2ad6940dfd7a6a6941",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.3.3",
+                "psr/log": "~1.0"
+            },
+            "conflict": {
+                "symfony/http-kernel": ">=2.3,<2.3.24|~2.4.0|>=2.5,<2.5.9|>=2.6,<2.6.2"
+            },
+            "require-dev": {
+                "symfony/class-loader": "~2.2",
+                "symfony/http-foundation": "~2.1",
+                "symfony/http-kernel": "~2.3.24|~2.5.9|~2.6,>=2.6.2",
+                "symfony/phpunit-bridge": "~2.7"
+            },
+            "suggest": {
+                "symfony/http-foundation": "",
+                "symfony/http-kernel": ""
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "2.6-dev"
+                }
+            },
+            "autoload": {
+                "psr-0": {
+                    "Symfony\\Component\\Debug\\": ""
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Fabien Potencier",
+                    "email": "fabien@symfony.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Symfony Debug Component",
+            "homepage": "https://symfony.com",
+            "time": "2015-07-08 05:59:48"
+        },
+        {
+            "name": "symfony/event-dispatcher",
+            "version": "v2.6.12",
+            "target-dir": "Symfony/Component/EventDispatcher",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/event-dispatcher.git",
+                "reference": "672593bc4b0043a0acf91903bb75a1c82d8f2e02"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/672593bc4b0043a0acf91903bb75a1c82d8f2e02",
+                "reference": "672593bc4b0043a0acf91903bb75a1c82d8f2e02",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.3.3"
+            },
+            "require-dev": {
+                "psr/log": "~1.0",
+                "symfony/config": "~2.0,>=2.0.5",
+                "symfony/dependency-injection": "~2.6",
+                "symfony/expression-language": "~2.6",
+                "symfony/phpunit-bridge": "~2.7",
+                "symfony/stopwatch": "~2.3"
+            },
+            "suggest": {
+                "symfony/dependency-injection": "",
+                "symfony/http-kernel": ""
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "2.6-dev"
+                }
+            },
+            "autoload": {
+                "psr-0": {
+                    "Symfony\\Component\\EventDispatcher\\": ""
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Fabien Potencier",
+                    "email": "fabien@symfony.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Symfony EventDispatcher Component",
+            "homepage": "https://symfony.com",
+            "time": "2015-05-02 15:18:45"
+        },
+        {
+            "name": "symfony/http-foundation",
+            "version": "v2.6.12",
+            "target-dir": "Symfony/Component/HttpFoundation",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/http-foundation.git",
+                "reference": "e8fd1b73ac1c3de1f76c73801ddf1a8ecb1c1c9c"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/http-foundation/zipball/e8fd1b73ac1c3de1f76c73801ddf1a8ecb1c1c9c",
+                "reference": "e8fd1b73ac1c3de1f76c73801ddf1a8ecb1c1c9c",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.3.3"
+            },
+            "require-dev": {
+                "symfony/expression-language": "~2.4",
+                "symfony/phpunit-bridge": "~2.7"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "2.6-dev"
+                }
+            },
+            "autoload": {
+                "psr-0": {
+                    "Symfony\\Component\\HttpFoundation\\": ""
+                },
+                "classmap": [
+                    "Symfony/Component/HttpFoundation/Resources/stubs"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Fabien Potencier",
+                    "email": "fabien@symfony.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Symfony HttpFoundation Component",
+            "homepage": "https://symfony.com",
+            "time": "2015-07-22 10:08:40"
+        },
+        {
+            "name": "symfony/http-kernel",
+            "version": "v2.6.12",
+            "target-dir": "Symfony/Component/HttpKernel",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/http-kernel.git",
+                "reference": "498866a8ca0bcbcd3f3824b1520fa568ff7ca3b6"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/http-kernel/zipball/498866a8ca0bcbcd3f3824b1520fa568ff7ca3b6",
+                "reference": "498866a8ca0bcbcd3f3824b1520fa568ff7ca3b6",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.3.3",
+                "psr/log": "~1.0",
+                "symfony/debug": "~2.6,>=2.6.2",
+                "symfony/event-dispatcher": "~2.6,>=2.6.7",
+                "symfony/http-foundation": "~2.5,>=2.5.4"
+            },
+            "require-dev": {
+                "symfony/browser-kit": "~2.3",
+                "symfony/class-loader": "~2.1",
+                "symfony/config": "~2.0,>=2.0.5",
+                "symfony/console": "~2.3",
+                "symfony/css-selector": "~2.0,>=2.0.5",
+                "symfony/dependency-injection": "~2.2",
+                "symfony/dom-crawler": "~2.0,>=2.0.5",
+                "symfony/expression-language": "~2.4",
+                "symfony/finder": "~2.0,>=2.0.5",
+                "symfony/phpunit-bridge": "~2.7",
+                "symfony/process": "~2.0,>=2.0.5",
+                "symfony/routing": "~2.2",
+                "symfony/stopwatch": "~2.3",
+                "symfony/templating": "~2.2",
+                "symfony/translation": "~2.0,>=2.0.5",
+                "symfony/var-dumper": "~2.6"
+            },
+            "suggest": {
+                "symfony/browser-kit": "",
+                "symfony/class-loader": "",
+                "symfony/config": "",
+                "symfony/console": "",
+                "symfony/dependency-injection": "",
+                "symfony/finder": "",
+                "symfony/var-dumper": ""
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "2.6-dev"
+                }
+            },
+            "autoload": {
+                "psr-0": {
+                    "Symfony\\Component\\HttpKernel\\": ""
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Fabien Potencier",
+                    "email": "fabien@symfony.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Symfony HttpKernel Component",
+            "homepage": "https://symfony.com",
+            "time": "2015-11-23 11:37:53"
+        },
+        {
+            "name": "symfony/routing",
+            "version": "v2.6.12",
+            "target-dir": "Symfony/Component/Routing",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/routing.git",
+                "reference": "0a1764d41bbb54f3864808c50569ac382b44d128"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/routing/zipball/0a1764d41bbb54f3864808c50569ac382b44d128",
+                "reference": "0a1764d41bbb54f3864808c50569ac382b44d128",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.3.3"
+            },
+            "require-dev": {
+                "doctrine/annotations": "~1.0",
+                "doctrine/common": "~2.2",
+                "psr/log": "~1.0",
+                "symfony/config": "~2.2",
+                "symfony/expression-language": "~2.4",
+                "symfony/http-foundation": "~2.3",
+                "symfony/phpunit-bridge": "~2.7",
+                "symfony/yaml": "~2.0,>=2.0.5"
+            },
+            "suggest": {
+                "doctrine/annotations": "For using the annotation loader",
+                "symfony/config": "For using the all-in-one router or any loader",
+                "symfony/expression-language": "For using expression matching",
+                "symfony/yaml": "For using the YAML loader"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "2.6-dev"
+                }
+            },
+            "autoload": {
+                "psr-0": {
+                    "Symfony\\Component\\Routing\\": ""
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Fabien Potencier",
+                    "email": "fabien@symfony.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Symfony Routing Component",
+            "homepage": "https://symfony.com",
+            "keywords": [
+                "router",
+                "routing",
+                "uri",
+                "url"
+            ],
+            "time": "2015-07-09 16:02:48"
+        },
+        {
+            "name": "twig/twig",
+            "version": "v1.21.2",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/twigphp/Twig.git",
+                "reference": "ddce1136beb8db29b9cd7dffa8ab518b978c9db3"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/twigphp/Twig/zipball/ddce1136beb8db29b9cd7dffa8ab518b978c9db3",
+                "reference": "ddce1136beb8db29b9cd7dffa8ab518b978c9db3",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.2.7"
+            },
+            "require-dev": {
+                "symfony/debug": "~2.7",
+                "symfony/phpunit-bridge": "~2.7"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.21-dev"
+                }
+            },
+            "autoload": {
+                "psr-0": {
+                    "Twig_": "lib/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Fabien Potencier",
+                    "email": "fabien@symfony.com",
+                    "homepage": "http://fabien.potencier.org",
+                    "role": "Lead Developer"
+                },
+                {
+                    "name": "Armin Ronacher",
+                    "email": "armin.ronacher@active-4.com",
+                    "role": "Project Founder"
+                },
+                {
+                    "name": "Twig Team",
+                    "homepage": "http://twig.sensiolabs.org/contributors",
+                    "role": "Contributors"
+                }
+            ],
+            "description": "Twig, the flexible, fast, and secure template language for PHP",
+            "homepage": "http://twig.sensiolabs.org",
+            "keywords": [
+                "templating"
+            ],
+            "time": "2015-09-09 05:28:51"
+        }
+    ],
+    "packages-dev": [],
+    "aliases": [],
+    "minimum-stability": "stable",
+    "stability-flags": [],
+    "prefer-stable": false,
+    "prefer-lowest": false,
+    "platform": [],
+    "platform-dev": []
+}

+ 7 - 0
lib/silex/vendor/autoload.php

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

+ 413 - 0
lib/silex/vendor/composer/ClassLoader.php

@@ -0,0 +1,413 @@
+<?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
+{
+    // PSR-4
+    private $prefixLengthsPsr4 = array();
+    private $prefixDirsPsr4 = array();
+    private $fallbackDirsPsr4 = array();
+
+    // PSR-0
+    private $prefixesPsr0 = array();
+    private $fallbackDirsPsr0 = array();
+
+    private $useIncludePath = false;
+    private $classMap = array();
+
+    private $classMapAuthoritative = false;
+
+    public function getPrefixes()
+    {
+        if (!empty($this->prefixesPsr0)) {
+            return call_user_func_array('array_merge', $this->prefixesPsr0);
+        }
+
+        return array();
+    }
+
+    public function getPrefixesPsr4()
+    {
+        return $this->prefixDirsPsr4;
+    }
+
+    public function getFallbackDirs()
+    {
+        return $this->fallbackDirsPsr0;
+    }
+
+    public function getFallbackDirsPsr4()
+    {
+        return $this->fallbackDirsPsr4;
+    }
+
+    public function getClassMap()
+    {
+        return $this->classMap;
+    }
+
+    /**
+     * @param array $classMap Class to filename map
+     */
+    public function addClassMap(array $classMap)
+    {
+        if ($this->classMap) {
+            $this->classMap = array_merge($this->classMap, $classMap);
+        } else {
+            $this->classMap = $classMap;
+        }
+    }
+
+    /**
+     * Registers a set of PSR-0 directories for a given prefix, either
+     * appending or prepending to the ones previously set for this prefix.
+     *
+     * @param string       $prefix  The prefix
+     * @param array|string $paths   The PSR-0 root directories
+     * @param bool         $prepend Whether to prepend the directories
+     */
+    public function add($prefix, $paths, $prepend = false)
+    {
+        if (!$prefix) {
+            if ($prepend) {
+                $this->fallbackDirsPsr0 = array_merge(
+                    (array) $paths,
+                    $this->fallbackDirsPsr0
+                );
+            } else {
+                $this->fallbackDirsPsr0 = array_merge(
+                    $this->fallbackDirsPsr0,
+                    (array) $paths
+                );
+            }
+
+            return;
+        }
+
+        $first = $prefix[0];
+        if (!isset($this->prefixesPsr0[$first][$prefix])) {
+            $this->prefixesPsr0[$first][$prefix] = (array) $paths;
+
+            return;
+        }
+        if ($prepend) {
+            $this->prefixesPsr0[$first][$prefix] = array_merge(
+                (array) $paths,
+                $this->prefixesPsr0[$first][$prefix]
+            );
+        } else {
+            $this->prefixesPsr0[$first][$prefix] = array_merge(
+                $this->prefixesPsr0[$first][$prefix],
+                (array) $paths
+            );
+        }
+    }
+
+    /**
+     * Registers a set of PSR-4 directories for a given namespace, either
+     * appending or prepending to the ones previously set for this namespace.
+     *
+     * @param string       $prefix  The prefix/namespace, with trailing '\\'
+     * @param array|string $paths   The PSR-0 base directories
+     * @param bool         $prepend Whether to prepend the directories
+     *
+     * @throws \InvalidArgumentException
+     */
+    public function addPsr4($prefix, $paths, $prepend = false)
+    {
+        if (!$prefix) {
+            // Register directories for the root namespace.
+            if ($prepend) {
+                $this->fallbackDirsPsr4 = array_merge(
+                    (array) $paths,
+                    $this->fallbackDirsPsr4
+                );
+            } else {
+                $this->fallbackDirsPsr4 = array_merge(
+                    $this->fallbackDirsPsr4,
+                    (array) $paths
+                );
+            }
+        } elseif (!isset($this->prefixDirsPsr4[$prefix])) {
+            // Register directories for a new namespace.
+            $length = strlen($prefix);
+            if ('\\' !== $prefix[$length - 1]) {
+                throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
+            }
+            $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
+            $this->prefixDirsPsr4[$prefix] = (array) $paths;
+        } elseif ($prepend) {
+            // Prepend directories for an already registered namespace.
+            $this->prefixDirsPsr4[$prefix] = array_merge(
+                (array) $paths,
+                $this->prefixDirsPsr4[$prefix]
+            );
+        } else {
+            // Append directories for an already registered namespace.
+            $this->prefixDirsPsr4[$prefix] = array_merge(
+                $this->prefixDirsPsr4[$prefix],
+                (array) $paths
+            );
+        }
+    }
+
+    /**
+     * Registers a set of PSR-0 directories for a given prefix,
+     * replacing any others previously set for this prefix.
+     *
+     * @param string       $prefix The prefix
+     * @param array|string $paths  The PSR-0 base directories
+     */
+    public function set($prefix, $paths)
+    {
+        if (!$prefix) {
+            $this->fallbackDirsPsr0 = (array) $paths;
+        } else {
+            $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
+        }
+    }
+
+    /**
+     * Registers a set of PSR-4 directories for a given namespace,
+     * replacing any others previously set for this namespace.
+     *
+     * @param string       $prefix The prefix/namespace, with trailing '\\'
+     * @param array|string $paths  The PSR-4 base directories
+     *
+     * @throws \InvalidArgumentException
+     */
+    public function setPsr4($prefix, $paths)
+    {
+        if (!$prefix) {
+            $this->fallbackDirsPsr4 = (array) $paths;
+        } else {
+            $length = strlen($prefix);
+            if ('\\' !== $prefix[$length - 1]) {
+                throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
+            }
+            $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
+            $this->prefixDirsPsr4[$prefix] = (array) $paths;
+        }
+    }
+
+    /**
+     * Turns on searching the include path for class files.
+     *
+     * @param bool $useIncludePath
+     */
+    public function setUseIncludePath($useIncludePath)
+    {
+        $this->useIncludePath = $useIncludePath;
+    }
+
+    /**
+     * Can be used to check if the autoloader uses the include path to check
+     * for classes.
+     *
+     * @return bool
+     */
+    public function getUseIncludePath()
+    {
+        return $this->useIncludePath;
+    }
+
+    /**
+     * Turns off searching the prefix and fallback directories for classes
+     * that have not been registered with the class map.
+     *
+     * @param bool $classMapAuthoritative
+     */
+    public function setClassMapAuthoritative($classMapAuthoritative)
+    {
+        $this->classMapAuthoritative = $classMapAuthoritative;
+    }
+
+    /**
+     * Should class lookup fail if not found in the current class map?
+     *
+     * @return bool
+     */
+    public function isClassMapAuthoritative()
+    {
+        return $this->classMapAuthoritative;
+    }
+
+    /**
+     * 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)) {
+            includeFile($file);
+
+            return true;
+        }
+    }
+
+    /**
+     * Finds the path to the file where the class is defined.
+     *
+     * @param string $class The name of the class
+     *
+     * @return string|false The path if found, false otherwise
+     */
+    public function findFile($class)
+    {
+        // work around for PHP 5.3.0 - 5.3.2 https://bugs.php.net/50731
+        if ('\\' == $class[0]) {
+            $class = substr($class, 1);
+        }
+
+        // class map lookup
+        if (isset($this->classMap[$class])) {
+            return $this->classMap[$class];
+        }
+        if ($this->classMapAuthoritative) {
+            return false;
+        }
+
+        $file = $this->findFileWithExtension($class, '.php');
+
+        // Search for Hack files if we are running on HHVM
+        if ($file === null && defined('HHVM_VERSION')) {
+            $file = $this->findFileWithExtension($class, '.hh');
+        }
+
+        if ($file === null) {
+            // Remember that this class does not exist.
+            return $this->classMap[$class] = false;
+        }
+
+        return $file;
+    }
+
+    private function findFileWithExtension($class, $ext)
+    {
+        // PSR-4 lookup
+        $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
+
+        $first = $class[0];
+        if (isset($this->prefixLengthsPsr4[$first])) {
+            foreach ($this->prefixLengthsPsr4[$first] as $prefix => $length) {
+                if (0 === strpos($class, $prefix)) {
+                    foreach ($this->prefixDirsPsr4[$prefix] as $dir) {
+                        if (file_exists($file = $dir . DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $length))) {
+                            return $file;
+                        }
+                    }
+                }
+            }
+        }
+
+        // PSR-4 fallback dirs
+        foreach ($this->fallbackDirsPsr4 as $dir) {
+            if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
+                return $file;
+            }
+        }
+
+        // PSR-0 lookup
+        if (false !== $pos = strrpos($class, '\\')) {
+            // namespaced class name
+            $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
+                . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
+        } else {
+            // PEAR-like class name
+            $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
+        }
+
+        if (isset($this->prefixesPsr0[$first])) {
+            foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
+                if (0 === strpos($class, $prefix)) {
+                    foreach ($dirs as $dir) {
+                        if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
+                            return $file;
+                        }
+                    }
+                }
+            }
+        }
+
+        // PSR-0 fallback dirs
+        foreach ($this->fallbackDirsPsr0 as $dir) {
+            if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
+                return $file;
+            }
+        }
+
+        // PSR-0 include paths.
+        if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
+            return $file;
+        }
+    }
+}
+
+/**
+ * Scope isolated include.
+ *
+ * Prevents access to $this/self from included files.
+ */
+function includeFile($file)
+{
+    include $file;
+}

+ 21 - 0
lib/silex/vendor/composer/LICENSE

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

+ 10 - 0
lib/silex/vendor/composer/autoload_classmap.php

@@ -0,0 +1,10 @@
+<?php
+
+// autoload_classmap.php @generated by Composer
+
+$vendorDir = dirname(dirname(__FILE__));
+$baseDir = dirname($vendorDir);
+
+return array(
+    'SessionHandlerInterface' => $vendorDir . '/symfony/http-foundation/Symfony/Component/HttpFoundation/Resources/stubs/SessionHandlerInterface.php',
+);

+ 18 - 0
lib/silex/vendor/composer/autoload_namespaces.php

@@ -0,0 +1,18 @@
+<?php
+
+// autoload_namespaces.php @generated by Composer
+
+$vendorDir = dirname(dirname(__FILE__));
+$baseDir = dirname($vendorDir);
+
+return array(
+    'Twig_' => array($vendorDir . '/twig/twig/lib'),
+    'Symfony\\Component\\Routing\\' => array($vendorDir . '/symfony/routing'),
+    'Symfony\\Component\\HttpKernel\\' => array($vendorDir . '/symfony/http-kernel'),
+    'Symfony\\Component\\HttpFoundation\\' => array($vendorDir . '/symfony/http-foundation'),
+    'Symfony\\Component\\EventDispatcher\\' => array($vendorDir . '/symfony/event-dispatcher'),
+    'Symfony\\Component\\Debug\\' => array($vendorDir . '/symfony/debug'),
+    'Silex' => array($vendorDir . '/silex/silex/src'),
+    'Psr\\Log\\' => array($vendorDir . '/psr/log'),
+    'Pimple' => array($vendorDir . '/pimple/pimple/lib'),
+);

+ 9 - 0
lib/silex/vendor/composer/autoload_psr4.php

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

+ 50 - 0
lib/silex/vendor/composer/autoload_real.php

@@ -0,0 +1,50 @@
+<?php
+
+// autoload_real.php @generated by Composer
+
+class ComposerAutoloaderInite16e7860e9352d90241324e1bba430e8
+{
+    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('ComposerAutoloaderInite16e7860e9352d90241324e1bba430e8', 'loadClassLoader'), true, true);
+        self::$loader = $loader = new \Composer\Autoload\ClassLoader();
+        spl_autoload_unregister(array('ComposerAutoloaderInite16e7860e9352d90241324e1bba430e8', 'loadClassLoader'));
+
+        $map = require __DIR__ . '/autoload_namespaces.php';
+        foreach ($map as $namespace => $path) {
+            $loader->set($namespace, $path);
+        }
+
+        $map = require __DIR__ . '/autoload_psr4.php';
+        foreach ($map as $namespace => $path) {
+            $loader->setPsr4($namespace, $path);
+        }
+
+        $classMap = require __DIR__ . '/autoload_classmap.php';
+        if ($classMap) {
+            $loader->addClassMap($classMap);
+        }
+
+        $loader->register(true);
+
+        return $loader;
+    }
+}
+
+function composerRequiree16e7860e9352d90241324e1bba430e8($file)
+{
+    require $file;
+}

+ 568 - 0
lib/silex/vendor/composer/installed.json

@@ -0,0 +1,568 @@
+[
+    {
+        "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": "pimple/pimple",
+        "version": "v1.1.1",
+        "version_normalized": "1.1.1.0",
+        "source": {
+            "type": "git",
+            "url": "https://github.com/silexphp/Pimple.git",
+            "reference": "2019c145fe393923f3441b23f29bbdfaa5c58c4d"
+        },
+        "dist": {
+            "type": "zip",
+            "url": "https://api.github.com/repos/silexphp/Pimple/zipball/2019c145fe393923f3441b23f29bbdfaa5c58c4d",
+            "reference": "2019c145fe393923f3441b23f29bbdfaa5c58c4d",
+            "shasum": ""
+        },
+        "require": {
+            "php": ">=5.3.0"
+        },
+        "time": "2013-11-22 08:30:29",
+        "type": "library",
+        "extra": {
+            "branch-alias": {
+                "dev-master": "1.1.x-dev"
+            }
+        },
+        "installation-source": "dist",
+        "autoload": {
+            "psr-0": {
+                "Pimple": "lib/"
+            }
+        },
+        "notification-url": "https://packagist.org/downloads/",
+        "license": [
+            "MIT"
+        ],
+        "authors": [
+            {
+                "name": "Fabien Potencier",
+                "email": "fabien@symfony.com"
+            }
+        ],
+        "description": "Pimple is a simple Dependency Injection Container for PHP 5.3",
+        "homepage": "http://pimple.sensiolabs.org",
+        "keywords": [
+            "container",
+            "dependency injection"
+        ]
+    },
+    {
+        "name": "silex/silex",
+        "version": "v1.2.5",
+        "version_normalized": "1.2.5.0",
+        "source": {
+            "type": "git",
+            "url": "https://github.com/silexphp/Silex.git",
+            "reference": "ce75b98d82d4c509802e63005c618392db17afef"
+        },
+        "dist": {
+            "type": "zip",
+            "url": "https://api.github.com/repos/silexphp/Silex/zipball/ce75b98d82d4c509802e63005c618392db17afef",
+            "reference": "ce75b98d82d4c509802e63005c618392db17afef",
+            "shasum": ""
+        },
+        "require": {
+            "php": ">=5.3.3",
+            "pimple/pimple": "~1.0",
+            "symfony/event-dispatcher": "~2.3,<2.7",
+            "symfony/http-foundation": "~2.3,<2.7",
+            "symfony/http-kernel": "~2.3,<2.7",
+            "symfony/routing": "~2.3,<2.7"
+        },
+        "require-dev": {
+            "doctrine/dbal": "~2.2",
+            "monolog/monolog": "~1.4,>=1.4.1",
+            "swiftmailer/swiftmailer": "5.*",
+            "symfony/browser-kit": "~2.3,<2.7",
+            "symfony/config": "~2.3,<2.7",
+            "symfony/css-selector": "~2.3,<2.7",
+            "symfony/debug": "~2.3,<2.7",
+            "symfony/dom-crawler": "~2.3,<2.7",
+            "symfony/finder": "~2.3,<2.7",
+            "symfony/form": "~2.3,<2.7",
+            "symfony/locale": "~2.3,<2.7",
+            "symfony/monolog-bridge": "~2.3,<2.7",
+            "symfony/options-resolver": "~2.3,<2.7",
+            "symfony/process": "~2.3,<2.7",
+            "symfony/security": "~2.3,<2.7",
+            "symfony/serializer": "~2.3,<2.7",
+            "symfony/translation": "~2.3,<2.7",
+            "symfony/twig-bridge": "~2.3,<2.7",
+            "symfony/validator": "~2.3,<2.7",
+            "twig/twig": ">=1.8.0,<2.0-dev"
+        },
+        "suggest": {
+            "symfony/browser-kit": "~2.3",
+            "symfony/css-selector": "~2.3",
+            "symfony/dom-crawler": "~2.3",
+            "symfony/form": "~2.3"
+        },
+        "time": "2015-06-04 21:24:58",
+        "type": "library",
+        "extra": {
+            "branch-alias": {
+                "dev-master": "1.2.x-dev"
+            }
+        },
+        "installation-source": "dist",
+        "autoload": {
+            "psr-0": {
+                "Silex": "src/"
+            }
+        },
+        "notification-url": "https://packagist.org/downloads/",
+        "license": [
+            "MIT"
+        ],
+        "authors": [
+            {
+                "name": "Fabien Potencier",
+                "email": "fabien@symfony.com"
+            },
+            {
+                "name": "Igor Wiedler",
+                "email": "igor@wiedler.ch"
+            }
+        ],
+        "description": "The PHP micro-framework based on the Symfony2 Components",
+        "homepage": "http://silex.sensiolabs.org",
+        "keywords": [
+            "microframework"
+        ]
+    },
+    {
+        "name": "twig/twig",
+        "version": "v1.21.2",
+        "version_normalized": "1.21.2.0",
+        "source": {
+            "type": "git",
+            "url": "https://github.com/twigphp/Twig.git",
+            "reference": "ddce1136beb8db29b9cd7dffa8ab518b978c9db3"
+        },
+        "dist": {
+            "type": "zip",
+            "url": "https://api.github.com/repos/twigphp/Twig/zipball/ddce1136beb8db29b9cd7dffa8ab518b978c9db3",
+            "reference": "ddce1136beb8db29b9cd7dffa8ab518b978c9db3",
+            "shasum": ""
+        },
+        "require": {
+            "php": ">=5.2.7"
+        },
+        "require-dev": {
+            "symfony/debug": "~2.7",
+            "symfony/phpunit-bridge": "~2.7"
+        },
+        "time": "2015-09-09 05:28:51",
+        "type": "library",
+        "extra": {
+            "branch-alias": {
+                "dev-master": "1.21-dev"
+            }
+        },
+        "installation-source": "dist",
+        "autoload": {
+            "psr-0": {
+                "Twig_": "lib/"
+            }
+        },
+        "notification-url": "https://packagist.org/downloads/",
+        "license": [
+            "BSD-3-Clause"
+        ],
+        "authors": [
+            {
+                "name": "Fabien Potencier",
+                "email": "fabien@symfony.com",
+                "homepage": "http://fabien.potencier.org",
+                "role": "Lead Developer"
+            },
+            {
+                "name": "Armin Ronacher",
+                "email": "armin.ronacher@active-4.com",
+                "role": "Project Founder"
+            },
+            {
+                "name": "Twig Team",
+                "homepage": "http://twig.sensiolabs.org/contributors",
+                "role": "Contributors"
+            }
+        ],
+        "description": "Twig, the flexible, fast, and secure template language for PHP",
+        "homepage": "http://twig.sensiolabs.org",
+        "keywords": [
+            "templating"
+        ]
+    },
+    {
+        "name": "symfony/debug",
+        "version": "v2.6.12",
+        "version_normalized": "2.6.12.0",
+        "target-dir": "Symfony/Component/Debug",
+        "source": {
+            "type": "git",
+            "url": "https://github.com/symfony/debug.git",
+            "reference": "fca5696e0c9787722baa8f2ad6940dfd7a6a6941"
+        },
+        "dist": {
+            "type": "zip",
+            "url": "https://api.github.com/repos/symfony/debug/zipball/fca5696e0c9787722baa8f2ad6940dfd7a6a6941",
+            "reference": "fca5696e0c9787722baa8f2ad6940dfd7a6a6941",
+            "shasum": ""
+        },
+        "require": {
+            "php": ">=5.3.3",
+            "psr/log": "~1.0"
+        },
+        "conflict": {
+            "symfony/http-kernel": ">=2.3,<2.3.24|~2.4.0|>=2.5,<2.5.9|>=2.6,<2.6.2"
+        },
+        "require-dev": {
+            "symfony/class-loader": "~2.2",
+            "symfony/http-foundation": "~2.1",
+            "symfony/http-kernel": "~2.3.24|~2.5.9|~2.6,>=2.6.2",
+            "symfony/phpunit-bridge": "~2.7"
+        },
+        "suggest": {
+            "symfony/http-foundation": "",
+            "symfony/http-kernel": ""
+        },
+        "time": "2015-07-08 05:59:48",
+        "type": "library",
+        "extra": {
+            "branch-alias": {
+                "dev-master": "2.6-dev"
+            }
+        },
+        "installation-source": "dist",
+        "autoload": {
+            "psr-0": {
+                "Symfony\\Component\\Debug\\": ""
+            }
+        },
+        "notification-url": "https://packagist.org/downloads/",
+        "license": [
+            "MIT"
+        ],
+        "authors": [
+            {
+                "name": "Fabien Potencier",
+                "email": "fabien@symfony.com"
+            },
+            {
+                "name": "Symfony Community",
+                "homepage": "https://symfony.com/contributors"
+            }
+        ],
+        "description": "Symfony Debug Component",
+        "homepage": "https://symfony.com"
+    },
+    {
+        "name": "symfony/http-foundation",
+        "version": "v2.6.12",
+        "version_normalized": "2.6.12.0",
+        "target-dir": "Symfony/Component/HttpFoundation",
+        "source": {
+            "type": "git",
+            "url": "https://github.com/symfony/http-foundation.git",
+            "reference": "e8fd1b73ac1c3de1f76c73801ddf1a8ecb1c1c9c"
+        },
+        "dist": {
+            "type": "zip",
+            "url": "https://api.github.com/repos/symfony/http-foundation/zipball/e8fd1b73ac1c3de1f76c73801ddf1a8ecb1c1c9c",
+            "reference": "e8fd1b73ac1c3de1f76c73801ddf1a8ecb1c1c9c",
+            "shasum": ""
+        },
+        "require": {
+            "php": ">=5.3.3"
+        },
+        "require-dev": {
+            "symfony/expression-language": "~2.4",
+            "symfony/phpunit-bridge": "~2.7"
+        },
+        "time": "2015-07-22 10:08:40",
+        "type": "library",
+        "extra": {
+            "branch-alias": {
+                "dev-master": "2.6-dev"
+            }
+        },
+        "installation-source": "dist",
+        "autoload": {
+            "psr-0": {
+                "Symfony\\Component\\HttpFoundation\\": ""
+            },
+            "classmap": [
+                "Symfony/Component/HttpFoundation/Resources/stubs"
+            ]
+        },
+        "notification-url": "https://packagist.org/downloads/",
+        "license": [
+            "MIT"
+        ],
+        "authors": [
+            {
+                "name": "Fabien Potencier",
+                "email": "fabien@symfony.com"
+            },
+            {
+                "name": "Symfony Community",
+                "homepage": "https://symfony.com/contributors"
+            }
+        ],
+        "description": "Symfony HttpFoundation Component",
+        "homepage": "https://symfony.com"
+    },
+    {
+        "name": "symfony/event-dispatcher",
+        "version": "v2.6.12",
+        "version_normalized": "2.6.12.0",
+        "target-dir": "Symfony/Component/EventDispatcher",
+        "source": {
+            "type": "git",
+            "url": "https://github.com/symfony/event-dispatcher.git",
+            "reference": "672593bc4b0043a0acf91903bb75a1c82d8f2e02"
+        },
+        "dist": {
+            "type": "zip",
+            "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/672593bc4b0043a0acf91903bb75a1c82d8f2e02",
+            "reference": "672593bc4b0043a0acf91903bb75a1c82d8f2e02",
+            "shasum": ""
+        },
+        "require": {
+            "php": ">=5.3.3"
+        },
+        "require-dev": {
+            "psr/log": "~1.0",
+            "symfony/config": "~2.0,>=2.0.5",
+            "symfony/dependency-injection": "~2.6",
+            "symfony/expression-language": "~2.6",
+            "symfony/phpunit-bridge": "~2.7",
+            "symfony/stopwatch": "~2.3"
+        },
+        "suggest": {
+            "symfony/dependency-injection": "",
+            "symfony/http-kernel": ""
+        },
+        "time": "2015-05-02 15:18:45",
+        "type": "library",
+        "extra": {
+            "branch-alias": {
+                "dev-master": "2.6-dev"
+            }
+        },
+        "installation-source": "dist",
+        "autoload": {
+            "psr-0": {
+                "Symfony\\Component\\EventDispatcher\\": ""
+            }
+        },
+        "notification-url": "https://packagist.org/downloads/",
+        "license": [
+            "MIT"
+        ],
+        "authors": [
+            {
+                "name": "Fabien Potencier",
+                "email": "fabien@symfony.com"
+            },
+            {
+                "name": "Symfony Community",
+                "homepage": "https://symfony.com/contributors"
+            }
+        ],
+        "description": "Symfony EventDispatcher Component",
+        "homepage": "https://symfony.com"
+    },
+    {
+        "name": "symfony/http-kernel",
+        "version": "v2.6.12",
+        "version_normalized": "2.6.12.0",
+        "target-dir": "Symfony/Component/HttpKernel",
+        "source": {
+            "type": "git",
+            "url": "https://github.com/symfony/http-kernel.git",
+            "reference": "498866a8ca0bcbcd3f3824b1520fa568ff7ca3b6"
+        },
+        "dist": {
+            "type": "zip",
+            "url": "https://api.github.com/repos/symfony/http-kernel/zipball/498866a8ca0bcbcd3f3824b1520fa568ff7ca3b6",
+            "reference": "498866a8ca0bcbcd3f3824b1520fa568ff7ca3b6",
+            "shasum": ""
+        },
+        "require": {
+            "php": ">=5.3.3",
+            "psr/log": "~1.0",
+            "symfony/debug": "~2.6,>=2.6.2",
+            "symfony/event-dispatcher": "~2.6,>=2.6.7",
+            "symfony/http-foundation": "~2.5,>=2.5.4"
+        },
+        "require-dev": {
+            "symfony/browser-kit": "~2.3",
+            "symfony/class-loader": "~2.1",
+            "symfony/config": "~2.0,>=2.0.5",
+            "symfony/console": "~2.3",
+            "symfony/css-selector": "~2.0,>=2.0.5",
+            "symfony/dependency-injection": "~2.2",
+            "symfony/dom-crawler": "~2.0,>=2.0.5",
+            "symfony/expression-language": "~2.4",
+            "symfony/finder": "~2.0,>=2.0.5",
+            "symfony/phpunit-bridge": "~2.7",
+            "symfony/process": "~2.0,>=2.0.5",
+            "symfony/routing": "~2.2",
+            "symfony/stopwatch": "~2.3",
+            "symfony/templating": "~2.2",
+            "symfony/translation": "~2.0,>=2.0.5",
+            "symfony/var-dumper": "~2.6"
+        },
+        "suggest": {
+            "symfony/browser-kit": "",
+            "symfony/class-loader": "",
+            "symfony/config": "",
+            "symfony/console": "",
+            "symfony/dependency-injection": "",
+            "symfony/finder": "",
+            "symfony/var-dumper": ""
+        },
+        "time": "2015-11-23 11:37:53",
+        "type": "library",
+        "extra": {
+            "branch-alias": {
+                "dev-master": "2.6-dev"
+            }
+        },
+        "installation-source": "dist",
+        "autoload": {
+            "psr-0": {
+                "Symfony\\Component\\HttpKernel\\": ""
+            }
+        },
+        "notification-url": "https://packagist.org/downloads/",
+        "license": [
+            "MIT"
+        ],
+        "authors": [
+            {
+                "name": "Fabien Potencier",
+                "email": "fabien@symfony.com"
+            },
+            {
+                "name": "Symfony Community",
+                "homepage": "https://symfony.com/contributors"
+            }
+        ],
+        "description": "Symfony HttpKernel Component",
+        "homepage": "https://symfony.com"
+    },
+    {
+        "name": "symfony/routing",
+        "version": "v2.6.12",
+        "version_normalized": "2.6.12.0",
+        "target-dir": "Symfony/Component/Routing",
+        "source": {
+            "type": "git",
+            "url": "https://github.com/symfony/routing.git",
+            "reference": "0a1764d41bbb54f3864808c50569ac382b44d128"
+        },
+        "dist": {
+            "type": "zip",
+            "url": "https://api.github.com/repos/symfony/routing/zipball/0a1764d41bbb54f3864808c50569ac382b44d128",
+            "reference": "0a1764d41bbb54f3864808c50569ac382b44d128",
+            "shasum": ""
+        },
+        "require": {
+            "php": ">=5.3.3"
+        },
+        "require-dev": {
+            "doctrine/annotations": "~1.0",
+            "doctrine/common": "~2.2",
+            "psr/log": "~1.0",
+            "symfony/config": "~2.2",
+            "symfony/expression-language": "~2.4",
+            "symfony/http-foundation": "~2.3",
+            "symfony/phpunit-bridge": "~2.7",
+            "symfony/yaml": "~2.0,>=2.0.5"
+        },
+        "suggest": {
+            "doctrine/annotations": "For using the annotation loader",
+            "symfony/config": "For using the all-in-one router or any loader",
+            "symfony/expression-language": "For using expression matching",
+            "symfony/yaml": "For using the YAML loader"
+        },
+        "time": "2015-07-09 16:02:48",
+        "type": "library",
+        "extra": {
+            "branch-alias": {
+                "dev-master": "2.6-dev"
+            }
+        },
+        "installation-source": "dist",
+        "autoload": {
+            "psr-0": {
+                "Symfony\\Component\\Routing\\": ""
+            }
+        },
+        "notification-url": "https://packagist.org/downloads/",
+        "license": [
+            "MIT"
+        ],
+        "authors": [
+            {
+                "name": "Fabien Potencier",
+                "email": "fabien@symfony.com"
+            },
+            {
+                "name": "Symfony Community",
+                "homepage": "https://symfony.com/contributors"
+            }
+        ],
+        "description": "Symfony Routing Component",
+        "homepage": "https://symfony.com",
+        "keywords": [
+            "router",
+            "routing",
+            "uri",
+            "url"
+        ]
+    }
+]

+ 1 - 0
lib/silex/vendor/pimple/pimple/.gitignore

@@ -0,0 +1 @@
+phpunit.xml

+ 19 - 0
lib/silex/vendor/pimple/pimple/LICENSE

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

+ 159 - 0
lib/silex/vendor/pimple/pimple/README.rst

@@ -0,0 +1,159 @@
+Pimple
+======
+
+Pimple is a small Dependency Injection Container for PHP 5.3 that consists
+of just one file and one class (about 80 lines of code).
+
+`Download it`_, require it in your code, and you're good to go::
+
+    require_once '/path/to/Pimple.php';
+
+Creating a container is a matter of instating the ``Pimple`` class::
+
+    $container = new Pimple();
+
+As many other dependency injection containers, Pimple is able to manage two
+different kind of data: *services* and *parameters*.
+
+Defining Parameters
+-------------------
+
+Defining a parameter is as simple as using the Pimple instance as an array::
+
+    // define some parameters
+    $container['cookie_name'] = 'SESSION_ID';
+    $container['session_storage_class'] = 'SessionStorage';
+
+Defining Services
+-----------------
+
+A service is an object that does something as part of a larger system.
+Examples of services: Database connection, templating engine, mailer. Almost
+any object could be a service.
+
+Services are defined by anonymous functions that return an instance of an
+object::
+
+    // define some services
+    $container['session_storage'] = function ($c) {
+        return new $c['session_storage_class']($c['cookie_name']);
+    };
+
+    $container['session'] = function ($c) {
+        return new Session($c['session_storage']);
+    };
+
+Notice that the anonymous function has access to the current container
+instance, allowing references to other services or parameters.
+
+As objects are only created when you get them, the order of the definitions
+does not matter, and there is no performance penalty.
+
+Using the defined services is also very easy::
+
+    // get the session object
+    $session = $container['session'];
+
+    // the above call is roughly equivalent to the following code:
+    // $storage = new SessionStorage('SESSION_ID');
+    // $session = new Session($storage);
+
+Defining Shared Services
+------------------------
+
+By default, each time you get a service, Pimple returns a new instance of it.
+If you want the same instance to be returned for all calls, wrap your
+anonymous function with the ``share()`` method::
+
+    $container['session'] = $container->share(function ($c) {
+        return new Session($c['session_storage']);
+    });
+
+Protecting Parameters
+---------------------
+
+Because Pimple sees anonymous functions as service definitions, you need to
+wrap anonymous functions with the ``protect()`` method to store them as
+parameter::
+
+    $container['random'] = $container->protect(function () { return rand(); });
+
+Modifying services after creation
+---------------------------------
+
+In some cases you may want to modify a service definition after it has been
+defined. You can use the ``extend()`` method to define additional code to
+be run on your service just after it is created::
+
+    $container['mail'] = function ($c) {
+        return new \Zend_Mail();
+    };
+
+    $container['mail'] = $container->extend('mail', function($mail, $c) {
+        $mail->setFrom($c['mail.default_from']);
+        return $mail;
+    });
+
+The first argument is the name of the object, the second is a function that
+gets access to the object instance and the container. The return value is
+a service definition, so you need to re-assign it on the container.
+
+If the service you plan to extend is already shared, it's recommended that you
+re-wrap your extended service with the ``shared`` method, otherwise your extension
+code will be called every time you access the service::
+
+    $container['twig'] = $container->share(function ($c) {
+        return new Twig_Environment($c['twig.loader'], $c['twig.options']);
+    });
+
+    $container['twig'] = $container->share($container->extend('twig', function ($twig, $c) {
+        $twig->addExtension(new MyTwigExtension());
+        return $twig;
+    }));
+
+Fetching the service creation function
+--------------------------------------
+
+When you access an object, Pimple automatically calls the anonymous function
+that you defined, which creates the service object for you. If you want to get
+raw access to this function, you can use the ``raw()`` method::
+
+    $container['session'] = $container->share(function ($c) {
+        return new Session($c['session_storage']);
+    });
+
+    $sessionFunction = $container->raw('session');
+
+Packaging a Container for reusability
+-------------------------------------
+
+If you use the same libraries over and over, you might want to create reusable
+containers. Creating a reusable container is as simple as creating a class
+that extends ``Pimple``, and configuring it in the constructor::
+
+    class SomeContainer extends Pimple
+    {
+        public function __construct()
+        {
+            $this['parameter'] = 'foo';
+            $this['object'] = function () { return stdClass(); };
+        }
+    }
+
+Using this container from your own is as easy as it can get::
+
+    $container = new Pimple();
+
+    // define your project parameters and services
+    // ...
+
+    // embed the SomeContainer container
+    $container['embedded'] = $container->share(function () { return new SomeContainer(); });
+
+    // configure it
+    $container['embedded']['parameter'] = 'bar';
+
+    // use it
+    $container['embedded']['object']->...;
+
+.. _Download it: https://github.com/fabpot/Pimple

+ 25 - 0
lib/silex/vendor/pimple/pimple/composer.json

@@ -0,0 +1,25 @@
+{
+    "name": "pimple/pimple",
+    "type": "library",
+    "description": "Pimple is a simple Dependency Injection Container for PHP 5.3",
+    "keywords": ["dependency injection", "container"],
+    "homepage": "http://pimple.sensiolabs.org",
+    "license": "MIT",
+    "authors": [
+        {
+            "name": "Fabien Potencier",
+            "email": "fabien@symfony.com"
+        }
+    ],
+    "require": {
+        "php": ">=5.3.0"
+    },
+    "autoload": {
+        "psr-0": { "Pimple": "lib/" }
+    },
+    "extra": {
+        "branch-alias": {
+            "dev-master": "1.1.x-dev"
+        }
+    }
+}

+ 214 - 0
lib/silex/vendor/pimple/pimple/lib/Pimple.php

@@ -0,0 +1,214 @@
+<?php
+
+/*
+ * This file is part of Pimple.
+ *
+ * Copyright (c) 2009 Fabien Potencier
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is furnished
+ * to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+/**
+ * Pimple main class.
+ *
+ * @package pimple
+ * @author  Fabien Potencier
+ */
+class Pimple implements ArrayAccess
+{
+    protected $values = array();
+
+    /**
+     * Instantiate the container.
+     *
+     * Objects and parameters can be passed as argument to the constructor.
+     *
+     * @param array $values The parameters or objects.
+     */
+    public function __construct(array $values = array())
+    {
+        $this->values = $values;
+    }
+
+    /**
+     * Sets a parameter or an object.
+     *
+     * Objects must be defined as Closures.
+     *
+     * Allowing any PHP callable leads to difficult to debug problems
+     * as function names (strings) are callable (creating a function with
+     * the same a name as an existing parameter would break your container).
+     *
+     * @param string $id    The unique identifier for the parameter or object
+     * @param mixed  $value The value of the parameter or a closure to defined an object
+     */
+    public function offsetSet($id, $value)
+    {
+        $this->values[$id] = $value;
+    }
+
+    /**
+     * Gets a parameter or an object.
+     *
+     * @param string $id The unique identifier for the parameter or object
+     *
+     * @return mixed The value of the parameter or an object
+     *
+     * @throws InvalidArgumentException if the identifier is not defined
+     */
+    public function offsetGet($id)
+    {
+        if (!array_key_exists($id, $this->values)) {
+            throw new InvalidArgumentException(sprintf('Identifier "%s" is not defined.', $id));
+        }
+
+        $isFactory = is_object($this->values[$id]) && method_exists($this->values[$id], '__invoke');
+
+        return $isFactory ? $this->values[$id]($this) : $this->values[$id];
+    }
+
+    /**
+     * Checks if a parameter or an object is set.
+     *
+     * @param string $id The unique identifier for the parameter or object
+     *
+     * @return Boolean
+     */
+    public function offsetExists($id)
+    {
+        return array_key_exists($id, $this->values);
+    }
+
+    /**
+     * Unsets a parameter or an object.
+     *
+     * @param string $id The unique identifier for the parameter or object
+     */
+    public function offsetUnset($id)
+    {
+        unset($this->values[$id]);
+    }
+
+    /**
+     * Returns a closure that stores the result of the given service definition
+     * for uniqueness in the scope of this instance of Pimple.
+     *
+     * @param callable $callable A service definition to wrap for uniqueness
+     *
+     * @return Closure The wrapped closure
+     */
+    public static function share($callable)
+    {
+        if (!is_object($callable) || !method_exists($callable, '__invoke')) {
+            throw new InvalidArgumentException('Service definition is not a Closure or invokable object.');
+        }
+
+        return function ($c) use ($callable) {
+            static $object;
+
+            if (null === $object) {
+                $object = $callable($c);
+            }
+
+            return $object;
+        };
+    }
+
+    /**
+     * Protects a callable from being interpreted as a service.
+     *
+     * This is useful when you want to store a callable as a parameter.
+     *
+     * @param callable $callable A callable to protect from being evaluated
+     *
+     * @return Closure The protected closure
+     */
+    public static function protect($callable)
+    {
+        if (!is_object($callable) || !method_exists($callable, '__invoke')) {
+            throw new InvalidArgumentException('Callable is not a Closure or invokable object.');
+        }
+
+        return function ($c) use ($callable) {
+            return $callable;
+        };
+    }
+
+    /**
+     * Gets a parameter or the closure defining an object.
+     *
+     * @param string $id The unique identifier for the parameter or object
+     *
+     * @return mixed The value of the parameter or the closure defining an object
+     *
+     * @throws InvalidArgumentException if the identifier is not defined
+     */
+    public function raw($id)
+    {
+        if (!array_key_exists($id, $this->values)) {
+            throw new InvalidArgumentException(sprintf('Identifier "%s" is not defined.', $id));
+        }
+
+        return $this->values[$id];
+    }
+
+    /**
+     * Extends an object definition.
+     *
+     * Useful when you want to extend an existing object definition,
+     * without necessarily loading that object.
+     *
+     * @param string $id       The unique identifier for the object
+     * @param callable $callable A service definition to extend the original
+     *
+     * @return Closure The wrapped closure
+     *
+     * @throws InvalidArgumentException if the identifier is not defined or not a service definition
+     */
+    public function extend($id, $callable)
+    {
+        if (!array_key_exists($id, $this->values)) {
+            throw new InvalidArgumentException(sprintf('Identifier "%s" is not defined.', $id));
+        }
+
+        if (!is_object($this->values[$id]) || !method_exists($this->values[$id], '__invoke')) {
+            throw new InvalidArgumentException(sprintf('Identifier "%s" does not contain an object definition.', $id));
+        }
+
+        if (!is_object($callable) || !method_exists($callable, '__invoke')) {
+            throw new InvalidArgumentException('Extension service definition is not a Closure or invokable object.');
+        }
+
+        $factory = $this->values[$id];
+
+        return $this->values[$id] = function ($c) use ($callable, $factory) {
+            return $callable($factory($c), $c);
+        };
+    }
+
+    /**
+     * Returns all defined value names.
+     *
+     * @return array An array of value names
+     */
+    public function keys()
+    {
+        return array_keys($this->values);
+    }
+}

+ 1 - 0
lib/silex/vendor/psr/log/.gitignore

@@ -0,0 +1 @@
+vendor

+ 19 - 0
lib/silex/vendor/psr/log/LICENSE

@@ -0,0 +1,19 @@
+Copyright (c) 2012 PHP Framework Interoperability Group
+
+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.

+ 120 - 0
lib/silex/vendor/psr/log/Psr/Log/AbstractLogger.php

@@ -0,0 +1,120 @@
+<?php
+
+namespace Psr\Log;
+
+/**
+ * This is a simple Logger implementation that other Loggers can inherit from.
+ *
+ * It simply delegates all log-level-specific methods to the `log` method to
+ * reduce boilerplate code that a simple Logger that does the same thing with
+ * messages regardless of the error level has to implement.
+ */
+abstract class AbstractLogger implements LoggerInterface
+{
+    /**
+     * System is unusable.
+     *
+     * @param string $message
+     * @param array $context
+     * @return null
+     */
+    public function emergency($message, array $context = array())
+    {
+        $this->log(LogLevel::EMERGENCY, $message, $context);
+    }
+
+    /**
+     * Action must be taken immediately.
+     *
+     * Example: Entire website down, database unavailable, etc. This should
+     * trigger the SMS alerts and wake you up.
+     *
+     * @param string $message
+     * @param array $context
+     * @return null
+     */
+    public function alert($message, array $context = array())
+    {
+        $this->log(LogLevel::ALERT, $message, $context);
+    }
+
+    /**
+     * Critical conditions.
+     *
+     * Example: Application component unavailable, unexpected exception.
+     *
+     * @param string $message
+     * @param array $context
+     * @return null
+     */
+    public function critical($message, array $context = array())
+    {
+        $this->log(LogLevel::CRITICAL, $message, $context);
+    }
+
+    /**
+     * Runtime errors that do not require immediate action but should typically
+     * be logged and monitored.
+     *
+     * @param string $message
+     * @param array $context
+     * @return null
+     */
+    public function error($message, array $context = array())
+    {
+        $this->log(LogLevel::ERROR, $message, $context);
+    }
+
+    /**
+     * Exceptional occurrences that are not errors.
+     *
+     * Example: Use of deprecated APIs, poor use of an API, undesirable things
+     * that are not necessarily wrong.
+     *
+     * @param string $message
+     * @param array $context
+     * @return null
+     */
+    public function warning($message, array $context = array())
+    {
+        $this->log(LogLevel::WARNING, $message, $context);
+    }
+
+    /**
+     * Normal but significant events.
+     *
+     * @param string $message
+     * @param array $context
+     * @return null
+     */
+    public function notice($message, array $context = array())
+    {
+        $this->log(LogLevel::NOTICE, $message, $context);
+    }
+
+    /**
+     * Interesting events.
+     *
+     * Example: User logs in, SQL logs.
+     *
+     * @param string $message
+     * @param array $context
+     * @return null
+     */
+    public function info($message, array $context = array())
+    {
+        $this->log(LogLevel::INFO, $message, $context);
+    }
+
+    /**
+     * Detailed debug information.
+     *
+     * @param string $message
+     * @param array $context
+     * @return null
+     */
+    public function debug($message, array $context = array())
+    {
+        $this->log(LogLevel::DEBUG, $message, $context);
+    }
+}

+ 7 - 0
lib/silex/vendor/psr/log/Psr/Log/InvalidArgumentException.php

@@ -0,0 +1,7 @@
+<?php
+
+namespace Psr\Log;
+
+class InvalidArgumentException extends \InvalidArgumentException
+{
+}

+ 18 - 0
lib/silex/vendor/psr/log/Psr/Log/LogLevel.php

@@ -0,0 +1,18 @@
+<?php
+
+namespace Psr\Log;
+
+/**
+ * Describes log levels
+ */
+class LogLevel
+{
+    const EMERGENCY = 'emergency';
+    const ALERT = 'alert';
+    const CRITICAL = 'critical';
+    const ERROR = 'error';
+    const WARNING = 'warning';
+    const NOTICE = 'notice';
+    const INFO = 'info';
+    const DEBUG = 'debug';
+}

+ 17 - 0
lib/silex/vendor/psr/log/Psr/Log/LoggerAwareInterface.php

@@ -0,0 +1,17 @@
+<?php
+
+namespace Psr\Log;
+
+/**
+ * Describes a logger-aware instance
+ */
+interface LoggerAwareInterface
+{
+    /**
+     * Sets a logger instance on the object
+     *
+     * @param LoggerInterface $logger
+     * @return null
+     */
+    public function setLogger(LoggerInterface $logger);
+}

+ 22 - 0
lib/silex/vendor/psr/log/Psr/Log/LoggerAwareTrait.php

@@ -0,0 +1,22 @@
+<?php
+
+namespace Psr\Log;
+
+/**
+ * Basic Implementation of LoggerAwareInterface.
+ */
+trait LoggerAwareTrait
+{
+    /** @var LoggerInterface */
+    protected $logger;
+
+    /**
+     * Sets a logger.
+     * 
+     * @param LoggerInterface $logger
+     */
+    public function setLogger(LoggerInterface $logger)
+    {
+        $this->logger = $logger;
+    }
+}

+ 114 - 0
lib/silex/vendor/psr/log/Psr/Log/LoggerInterface.php

@@ -0,0 +1,114 @@
+<?php
+
+namespace Psr\Log;
+
+/**
+ * Describes a logger instance
+ *
+ * The message MUST be a string or object implementing __toString().
+ *
+ * The message MAY contain placeholders in the form: {foo} where foo
+ * will be replaced by the context data in key "foo".
+ *
+ * The context array can contain arbitrary data, the only assumption that
+ * can be made by implementors is that if an Exception instance is given
+ * to produce a stack trace, it MUST be in a key named "exception".
+ *
+ * See https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md
+ * for the full interface specification.
+ */
+interface LoggerInterface
+{
+    /**
+     * System is unusable.
+     *
+     * @param string $message
+     * @param array $context
+     * @return null
+     */
+    public function emergency($message, array $context = array());
+
+    /**
+     * Action must be taken immediately.
+     *
+     * Example: Entire website down, database unavailable, etc. This should
+     * trigger the SMS alerts and wake you up.
+     *
+     * @param string $message
+     * @param array $context
+     * @return null
+     */
+    public function alert($message, array $context = array());
+
+    /**
+     * Critical conditions.
+     *
+     * Example: Application component unavailable, unexpected exception.
+     *
+     * @param string $message
+     * @param array $context
+     * @return null
+     */
+    public function critical($message, array $context = array());
+
+    /**
+     * Runtime errors that do not require immediate action but should typically
+     * be logged and monitored.
+     *
+     * @param string $message
+     * @param array $context
+     * @return null
+     */
+    public function error($message, array $context = array());
+
+    /**
+     * Exceptional occurrences that are not errors.
+     *
+     * Example: Use of deprecated APIs, poor use of an API, undesirable things
+     * that are not necessarily wrong.
+     *
+     * @param string $message
+     * @param array $context
+     * @return null
+     */
+    public function warning($message, array $context = array());
+
+    /**
+     * Normal but significant events.
+     *
+     * @param string $message
+     * @param array $context
+     * @return null
+     */
+    public function notice($message, array $context = array());
+
+    /**
+     * Interesting events.
+     *
+     * Example: User logs in, SQL logs.
+     *
+     * @param string $message
+     * @param array $context
+     * @return null
+     */
+    public function info($message, array $context = array());
+
+    /**
+     * Detailed debug information.
+     *
+     * @param string $message
+     * @param array $context
+     * @return null
+     */
+    public function debug($message, array $context = array());
+
+    /**
+     * Logs with an arbitrary level.
+     *
+     * @param mixed $level
+     * @param string $message
+     * @param array $context
+     * @return null
+     */
+    public function log($level, $message, array $context = array());
+}

+ 131 - 0
lib/silex/vendor/psr/log/Psr/Log/LoggerTrait.php

@@ -0,0 +1,131 @@
+<?php
+
+namespace Psr\Log;
+
+/**
+ * This is a simple Logger trait that classes unable to extend AbstractLogger
+ * (because they extend another class, etc) can include.
+ *
+ * It simply delegates all log-level-specific methods to the `log` method to 
+ * reduce boilerplate code that a simple Logger that does the same thing with 
+ * messages regardless of the error level has to implement.
+ */
+trait LoggerTrait
+{
+    /**
+     * System is unusable.
+     *
+     * @param string $message
+     * @param array $context
+     * @return null
+     */
+    public function emergency($message, array $context = array())
+    {
+        $this->log(LogLevel::EMERGENCY, $message, $context);
+    }
+
+    /**
+     * Action must be taken immediately.
+     *
+     * Example: Entire website down, database unavailable, etc. This should
+     * trigger the SMS alerts and wake you up.
+     *
+     * @param string $message
+     * @param array $context
+     * @return null
+     */
+    public function alert($message, array $context = array())
+    {
+        $this->log(LogLevel::ALERT, $message, $context);
+    }
+
+    /**
+     * Critical conditions.
+     *
+     * Example: Application component unavailable, unexpected exception.
+     *
+     * @param string $message
+     * @param array $context
+     * @return null
+     */
+    public function critical($message, array $context = array())
+    {
+        $this->log(LogLevel::CRITICAL, $message, $context);
+    }
+
+    /**
+     * Runtime errors that do not require immediate action but should typically
+     * be logged and monitored.
+     *
+     * @param string $message
+     * @param array $context
+     * @return null
+     */
+    public function error($message, array $context = array())
+    {
+        $this->log(LogLevel::ERROR, $message, $context);
+    }
+
+    /**
+     * Exceptional occurrences that are not errors.
+     *
+     * Example: Use of deprecated APIs, poor use of an API, undesirable things
+     * that are not necessarily wrong.
+     *
+     * @param string $message
+     * @param array $context
+     * @return null
+     */
+    public function warning($message, array $context = array())
+    {
+        $this->log(LogLevel::WARNING, $message, $context);
+    }
+
+    /**
+     * Normal but significant events.
+     *
+     * @param string $message
+     * @param array $context
+     * @return null
+     */
+    public function notice($message, array $context = array())
+    {
+        $this->log(LogLevel::NOTICE, $message, $context);
+    }
+
+    /**
+     * Interesting events.
+     *
+     * Example: User logs in, SQL logs.
+     *
+     * @param string $message
+     * @param array $context
+     * @return null
+     */
+    public function info($message, array $context = array())
+    {
+        $this->log(LogLevel::INFO, $message, $context);
+    }
+
+    /**
+     * Detailed debug information.
+     *
+     * @param string $message
+     * @param array $context
+     * @return null
+     */
+    public function debug($message, array $context = array())
+    {
+        $this->log(LogLevel::DEBUG, $message, $context);
+    }
+
+    /**
+     * Logs with an arbitrary level.
+     *
+     * @param mixed $level
+     * @param string $message
+     * @param array $context
+     * @return null
+     */
+    abstract public function log($level, $message, array $context = array());
+}

+ 27 - 0
lib/silex/vendor/psr/log/Psr/Log/NullLogger.php

@@ -0,0 +1,27 @@
+<?php
+
+namespace Psr\Log;
+
+/**
+ * This Logger can be used to avoid conditional log calls
+ *
+ * Logging should always be optional, and if no logger is provided to your
+ * library creating a NullLogger instance to have something to throw logs at
+ * is a good way to avoid littering your code with `if ($this->logger) { }`
+ * blocks.
+ */
+class NullLogger extends AbstractLogger
+{
+    /**
+     * Logs with an arbitrary level.
+     *
+     * @param mixed $level
+     * @param string $message
+     * @param array $context
+     * @return null
+     */
+    public function log($level, $message, array $context = array())
+    {
+        // noop
+    }
+}

+ 116 - 0
lib/silex/vendor/psr/log/Psr/Log/Test/LoggerInterfaceTest.php

@@ -0,0 +1,116 @@
+<?php
+
+namespace Psr\Log\Test;
+
+use Psr\Log\LogLevel;
+
+/**
+ * Provides a base test class for ensuring compliance with the LoggerInterface
+ *
+ * Implementors can extend the class and implement abstract methods to run this as part of their test suite
+ */
+abstract class LoggerInterfaceTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @return LoggerInterface
+     */
+    abstract function getLogger();
+
+    /**
+     * This must return the log messages in order with a simple formatting: "<LOG LEVEL> <MESSAGE>"
+     *
+     * Example ->error('Foo') would yield "error Foo"
+     *
+     * @return string[]
+     */
+    abstract function getLogs();
+
+    public function testImplements()
+    {
+        $this->assertInstanceOf('Psr\Log\LoggerInterface', $this->getLogger());
+    }
+
+    /**
+     * @dataProvider provideLevelsAndMessages
+     */
+    public function testLogsAtAllLevels($level, $message)
+    {
+        $logger = $this->getLogger();
+        $logger->{$level}($message, array('user' => 'Bob'));
+        $logger->log($level, $message, array('user' => 'Bob'));
+
+        $expected = array(
+            $level.' message of level '.$level.' with context: Bob',
+            $level.' message of level '.$level.' with context: Bob',
+        );
+        $this->assertEquals($expected, $this->getLogs());
+    }
+
+    public function provideLevelsAndMessages()
+    {
+        return array(
+            LogLevel::EMERGENCY => array(LogLevel::EMERGENCY, 'message of level emergency with context: {user}'),
+            LogLevel::ALERT => array(LogLevel::ALERT, 'message of level alert with context: {user}'),
+            LogLevel::CRITICAL => array(LogLevel::CRITICAL, 'message of level critical with context: {user}'),
+            LogLevel::ERROR => array(LogLevel::ERROR, 'message of level error with context: {user}'),
+            LogLevel::WARNING => array(LogLevel::WARNING, 'message of level warning with context: {user}'),
+            LogLevel::NOTICE => array(LogLevel::NOTICE, 'message of level notice with context: {user}'),
+            LogLevel::INFO => array(LogLevel::INFO, 'message of level info with context: {user}'),
+            LogLevel::DEBUG => array(LogLevel::DEBUG, 'message of level debug with context: {user}'),
+        );
+    }
+
+    /**
+     * @expectedException Psr\Log\InvalidArgumentException
+     */
+    public function testThrowsOnInvalidLevel()
+    {
+        $logger = $this->getLogger();
+        $logger->log('invalid level', 'Foo');
+    }
+
+    public function testContextReplacement()
+    {
+        $logger = $this->getLogger();
+        $logger->info('{Message {nothing} {user} {foo.bar} a}', array('user' => 'Bob', 'foo.bar' => 'Bar'));
+
+        $expected = array('info {Message {nothing} Bob Bar a}');
+        $this->assertEquals($expected, $this->getLogs());
+    }
+
+    public function testObjectCastToString()
+    {
+        $dummy = $this->getMock('Psr\Log\Test\DummyTest', array('__toString'));
+        $dummy->expects($this->once())
+            ->method('__toString')
+            ->will($this->returnValue('DUMMY'));
+
+        $this->getLogger()->warning($dummy);
+    }
+
+    public function testContextCanContainAnything()
+    {
+        $context = array(
+            'bool' => true,
+            'null' => null,
+            'string' => 'Foo',
+            'int' => 0,
+            'float' => 0.5,
+            'nested' => array('with object' => new DummyTest),
+            'object' => new \DateTime,
+            'resource' => fopen('php://memory', 'r'),
+        );
+
+        $this->getLogger()->warning('Crazy context data', $context);
+    }
+
+    public function testContextExceptionKeyCanBeExceptionOrOtherValues()
+    {
+        $this->getLogger()->warning('Random message', array('exception' => 'oops'));
+        $this->getLogger()->critical('Uncaught Exception!', array('exception' => new \LogicException('Fail')));
+    }
+}
+
+class DummyTest
+{
+}

+ 45 - 0
lib/silex/vendor/psr/log/README.md

@@ -0,0 +1,45 @@
+PSR Log
+=======
+
+This repository holds all interfaces/classes/traits related to
+[PSR-3](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md).
+
+Note that this is not a logger of its own. It is merely an interface that
+describes a logger. See the specification for more details.
+
+Usage
+-----
+
+If you need a logger, you can use the interface like this:
+
+```php
+<?php
+
+use Psr\Log\LoggerInterface;
+
+class Foo
+{
+    private $logger;
+
+    public function __construct(LoggerInterface $logger = null)
+    {
+        $this->logger = $logger;
+    }
+
+    public function doSomething()
+    {
+        if ($this->logger) {
+            $this->logger->info('Doing work');
+        }
+
+        // do something useful
+    }
+}
+```
+
+You can then pick one of the implementations of the interface to get a logger.
+
+If you want to implement the interface, you can require this package and
+implement `Psr\Log\LoggerInterface` in your code. Please read the
+[specification text](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md)
+for details.

+ 17 - 0
lib/silex/vendor/psr/log/composer.json

@@ -0,0 +1,17 @@
+{
+    "name": "psr/log",
+    "description": "Common interface for logging libraries",
+    "keywords": ["psr", "psr-3", "log"],
+    "license": "MIT",
+    "authors": [
+        {
+            "name": "PHP-FIG",
+            "homepage": "http://www.php-fig.org/"
+        }
+    ],
+    "autoload": {
+        "psr-0": {
+            "Psr\\Log\\": ""
+        }
+    }
+}

+ 5 - 0
lib/silex/vendor/silex/silex/.gitignore

@@ -0,0 +1,5 @@
+/phpunit.xml
+/vendor
+/build
+/composer.lock
+

+ 19 - 0
lib/silex/vendor/silex/silex/LICENSE

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

+ 63 - 0
lib/silex/vendor/silex/silex/README.rst

@@ -0,0 +1,63 @@
+Silex, a simple Web Framework
+=============================
+
+Silex is a PHP micro-framework to develop websites based on `Symfony2
+components`_:
+
+.. code-block:: php
+
+    <?php
+
+    require_once __DIR__.'/../vendor/autoload.php';
+
+    $app = new Silex\Application();
+
+    $app->get('/hello/{name}', function ($name) use ($app) {
+      return 'Hello '.$app->escape($name);
+    });
+
+    $app->run();
+
+Silex works with PHP 5.3.3 or later.
+
+Installation
+------------
+
+The recommended way to install Silex is through `Composer`_:
+
+.. code-block:: bash
+
+    php composer.phar require silex/silex "~1.2"
+
+Alternatively, you can download the `silex.zip`_ file and extract it.
+
+More Information
+----------------
+
+Read the `documentation`_ for more information.
+
+Tests
+-----
+
+To run the test suite, you need `Composer`_ and `PHPUnit`_:
+
+.. code-block:: bash
+
+    $ composer install
+    $ phpunit
+
+Community
+---------
+
+Check out #silex-php on irc.freenode.net.
+
+License
+-------
+
+Silex is licensed under the MIT license.
+
+.. _Symfony2 components: http://symfony.com
+.. _Composer:            http://getcomposer.org
+.. _PHPUnit:             https://phpunit.de
+.. _silex.zip:           http://silex.sensiolabs.org/download
+.. _documentation:       http://silex.sensiolabs.org/documentation

+ 67 - 0
lib/silex/vendor/silex/silex/bin/build

@@ -0,0 +1,67 @@
+#!/bin/sh
+
+PHP=`which php`
+GIT=`which git`
+DIR=`$PHP -r "echo dirname(dirname(realpath('$0')));"`
+
+if [ ! -d "$DIR/build" ]; then
+    mkdir -p $DIR/build
+fi
+
+cd $DIR/build
+
+if [ ! -f "composer.phar" ]; then
+    curl -s http://getcomposer.org/installer 2>/dev/null | $PHP >/dev/null 2>/dev/null
+else
+    $PHP composer.phar self-update >/dev/null 2>/dev/null
+fi
+
+for TYPE in slim fat
+do
+    if [ -d "$DIR/build/skeleton" ]; then
+        rm -rf $DIR/build/skeleton
+    fi
+    mkdir -p $DIR/build/skeleton
+
+    cd "$DIR/build/skeleton"
+
+    mkdir -p web/
+    COMPOSER=$TYPE"_composer.json"
+    cp $DIR/bin/skeleton/$COMPOSER composer.json
+    cp $DIR/bin/skeleton/index.php web/index.php
+
+    $PHP ../composer.phar install -q
+
+    if [ -d "$DIR/build/tmp/silex" ]; then
+        rm -rf $DIR/build/tmp/silex
+    fi
+    mkdir -p $DIR/build/tmp/silex
+
+    cd "$DIR/build/tmp/silex"
+    cp -r ../../skeleton/* .
+
+    find . -name .DS_Store | xargs rm -rf -
+    find . -name .git | xargs rm -rf -
+    find . -name phpunit.xml.* | xargs rm -rf -
+    find . -type d -name Tests | xargs rm -rf -
+    find . -type d -name test* | xargs rm -rf -
+    find . -type d -name doc | xargs rm -rf -
+    find . -type d -name ext | xargs rm -rf -
+
+    export COPY_EXTENDED_ATTRIBUTES_DISABLE=true
+    export COPYFILE_DISABLE=true
+
+    cd "$DIR/build/tmp"
+
+    if [ "slim" = "$TYPE" ]; then
+        NAME="silex"
+    else
+        NAME="silex_fat"
+    fi
+
+    rm -f "$DIR/build/$NAME.*"
+    tar zcpf "$DIR/build/$NAME.tgz" silex
+    zip -rq "$DIR/build/$NAME.zip" silex
+    rm -rf "$DIR/build/tmp"
+    rm -rf "$DIR/build/skeleton"
+done

+ 9 - 0
lib/silex/vendor/silex/silex/bin/compile

@@ -0,0 +1,9 @@
+#!/usr/bin/env php
+<?php
+
+require_once __DIR__.'/../vendor/autoload.php';
+
+use Silex\Util\Compiler;
+
+$compiler = new Compiler();
+$compiler->compile();

+ 23 - 0
lib/silex/vendor/silex/silex/bin/skeleton/fat_composer.json

@@ -0,0 +1,23 @@
+{
+    "require": {
+        "silex/silex": "~1.1",
+        "symfony/browser-kit": "~2.3",
+        "symfony/console": "~2.3",
+        "symfony/config": "~2.3",
+        "symfony/css-selector": "~2.3",
+        "symfony/dom-crawler": "~2.3",
+        "symfony/filesystem": "~2.3",
+        "symfony/finder": "~2.3",
+        "symfony/form": "~2.3",
+        "symfony/locale": "~2.3",
+        "symfony/process": "~2.3",
+        "symfony/security": "~2.3",
+        "symfony/serializer": "~2.3",
+        "symfony/translation": "~2.3",
+        "symfony/validator": "~2.3",
+        "symfony/monolog-bridge": "~2.3",
+        "symfony/twig-bridge": "~2.3",
+        "doctrine/dbal": ">=2.2.0,<2.4.0-dev",
+        "swiftmailer/swiftmailer": "5.*"
+    }
+}

+ 11 - 0
lib/silex/vendor/silex/silex/bin/skeleton/index.php

@@ -0,0 +1,11 @@
+<?php
+
+require_once __DIR__.'/../vendor/autoload.php';
+
+$app = new Silex\Application();
+
+$app->get('/hello', function () {
+    return 'Hello!';
+});
+
+$app->run();

+ 5 - 0
lib/silex/vendor/silex/silex/bin/skeleton/slim_composer.json

@@ -0,0 +1,5 @@
+{
+    "require": {
+        "silex/silex": "~1.1"
+    }
+}

+ 62 - 0
lib/silex/vendor/silex/silex/composer.json

@@ -0,0 +1,62 @@
+{
+    "minimum-stability": "dev",
+    "name": "silex/silex",
+    "description": "The PHP micro-framework based on the Symfony2 Components",
+    "keywords": ["microframework"],
+    "homepage": "http://silex.sensiolabs.org",
+    "license": "MIT",
+    "authors": [
+        {
+            "name": "Fabien Potencier",
+            "email": "fabien@symfony.com"
+        },
+        {
+            "name": "Igor Wiedler",
+            "email": "igor@wiedler.ch"
+        }
+    ],
+    "require": {
+        "php": ">=5.3.3",
+        "pimple/pimple": "~1.0",
+        "symfony/event-dispatcher": "~2.3,<2.7",
+        "symfony/http-foundation": "~2.3,<2.7",
+        "symfony/http-kernel": "~2.3,<2.7",
+        "symfony/routing": "~2.3,<2.7"
+    },
+    "require-dev": {
+        "symfony/security": "~2.3,<2.7",
+        "symfony/config": "~2.3,<2.7",
+        "symfony/locale": "~2.3,<2.7",
+        "symfony/form": "~2.3,<2.7",
+        "symfony/browser-kit": "~2.3,<2.7",
+        "symfony/css-selector": "~2.3,<2.7",
+        "symfony/debug": "~2.3,<2.7",
+        "symfony/dom-crawler": "~2.3,<2.7",
+        "symfony/finder": "~2.3,<2.7",
+        "symfony/monolog-bridge": "~2.3,<2.7",
+        "symfony/options-resolver": "~2.3,<2.7",
+        "symfony/process": "~2.3,<2.7",
+        "symfony/serializer": "~2.3,<2.7",
+        "symfony/translation": "~2.3,<2.7",
+        "symfony/twig-bridge": "~2.3,<2.7",
+        "symfony/validator": "~2.3,<2.7",
+        "twig/twig": ">=1.8.0,<2.0-dev",
+        "doctrine/dbal": "~2.2",
+        "swiftmailer/swiftmailer": "5.*",
+        "monolog/monolog": "~1.4,>=1.4.1"
+    },
+    "suggest": {
+        "symfony/browser-kit": "~2.3",
+        "symfony/css-selector": "~2.3",
+        "symfony/dom-crawler": "~2.3",
+        "symfony/form": "~2.3"
+    },
+    "autoload": {
+        "psr-0": { "Silex": "src/" }
+    },
+    "extra": {
+        "branch-alias": {
+            "dev-master": "1.2.x-dev"
+        }
+    }
+}

+ 259 - 0
lib/silex/vendor/silex/silex/doc/changelog.rst

@@ -0,0 +1,259 @@
+Changelog
+=========
+
+1.2.5 (2015-06-04)
+------------------
+
+* no code changes (last version of the 1.2 branch)
+
+1.2.4 (2015-04-11)
+------------------
+
+* fixed the exception message when mounting a collection that doesn't return a ControllerCollection
+* fixed Symfony dependencies (Silex 1.2 is not compatible with Symfony 2.7)
+
+1.2.3 (2015-01-20)
+------------------
+
+* fixed remember me listener
+* fixed translation files loading when they do not exist
+* allowed global after middlewares to return responses like route specific ones
+
+1.2.2 (2014-09-26)
+------------------
+
+* fixed Translator locale management
+* added support for the $app argument in application middlewares (to make it consistent with route middlewares)
+* added form.types to the Form provider
+
+1.2.1 (2014-07-01)
+------------------
+
+* added support permissions in the Monolog provider
+* fixed Switfmailer spool where the event dispatcher is different from the other ones
+* fixed locale when changing it on the translator itself
+
+1.2.0 (2014-03-29)
+------------------
+
+* Allowed disabling the boot logic of MonologServiceProvider
+* Reverted "convert attributes on the request that actually exist"
+* [BC BREAK] Routes are now always added in the order of their registration (even for mounted routes)
+* Added run() on Route to be able to define the controller code
+* Deprecated TwigCoreExtension (register the new HttpFragmentServiceProvider instead)
+* Added HttpFragmentServiceProvider
+* Allowed a callback to be a method call on a service (before, after, finish, error, on Application; convert, before, after on Controller)
+
+1.1.3 (2013-XX-XX)
+------------------
+
+* Fixed translator locale management
+
+1.1.2 (2013-10-30)
+------------------
+
+* Added missing "security.hide_user_not_found" support in SecurityServiceProvider
+* Fixed event listeners that are registered after the boot via the on() method
+
+1.0.2 (2013-10-30)
+------------------
+
+* Fixed SecurityServiceProvider to use null as a fake controller so that routes can be dumped
+
+1.1.1 (2013-10-11)
+------------------
+
+* Removed or replaced deprecated Symfony code
+* Updated code to take advantages of 2.3 new features
+* Only convert attributes on the request that actually exist.
+
+1.1.0 (2013-07-04)
+------------------
+
+* Support for any ``Psr\Log\LoggerInterface`` as opposed to the monolog-bridge
+  one.
+* Made dispatcher proxy methods ``on``, ``before``, ``after`` and ``error``
+  lazy, so that they will not instantiate the dispatcher early.
+* Dropped support for 2.1 and 2.2 versions of Symfony.
+
+1.0.1 (2013-07-04)
+------------------
+
+* Fixed RedirectableUrlMatcher::redirect() when Silex is configured to use a logger
+* Make ``DoctrineServiceProvider`` multi-db support lazy.
+
+1.0.0 (2013-05-03)
+------------------
+
+* **2013-04-12**: Added support for validators as services.
+
+* **2013-04-01**: Added support for host matching with symfony 2.2::
+
+      $app->match('/', function() {
+          // app-specific action
+      })->host('example.com');
+
+      $app->match('/', function ($user) {
+          // user-specific action
+      })->host('{user}.example.com');
+
+* **2013-03-08**: Added support for form type extensions and guessers as
+  services.
+
+* **2013-03-08**: Added support for remember-me via the
+  ``RememberMeServiceProvider``.
+
+* **2013-02-07**: Added ``Application::sendFile()`` to ease sending
+  ``BinaryFileResponse``.
+
+* **2012-11-05**: Filters have been renamed to application middlewares in the
+  documentation.
+
+* **2012-11-05**: The ``before()``, ``after()``, ``error()``, and ``finish()``
+  listener priorities now set the priority of the underlying Symfony event
+  instead of a custom one before.
+
+* **2012-11-05**: Removing the default exception handler should now be done
+  via its ``disable()`` method:
+
+    Before:
+
+        unset($app['exception_handler']);
+
+    After:
+
+        $app['exception_handler']->disable();
+
+* **2012-07-15**: removed the ``monolog.configure`` service. Use the
+  ``extend`` method instead:
+
+    Before::
+
+        $app['monolog.configure'] = $app->protect(function ($monolog) use ($app) {
+            // do something
+        });
+
+    After::
+
+        $app['monolog'] = $app->share($app->extend('monolog', function($monolog, $app) {
+            // do something
+
+            return $monolog;
+        }));
+
+
+* **2012-06-17**: ``ControllerCollection`` now takes a required route instance
+  as a constructor argument.
+
+    Before::
+
+        $controllers = new ControllerCollection();
+
+    After::
+
+        $controllers = new ControllerCollection(new Route());
+
+        // or even better
+        $controllers = $app['controllers_factory'];
+
+* **2012-06-17**: added application traits for PHP 5.4
+
+* **2012-06-16**: renamed ``request.default_locale`` to ``locale``
+
+* **2012-06-16**: Removed the ``translator.loader`` service. See documentation
+  for how to use XLIFF or YAML-based translation files.
+
+* **2012-06-15**: removed the ``twig.configure`` service. Use the ``extend``
+  method instead:
+
+    Before::
+
+        $app['twig.configure'] = $app->protect(function ($twig) use ($app) {
+            // do something
+        });
+
+    After::
+
+        $app['twig'] = $app->share($app->extend('twig', function($twig, $app) {
+            // do something
+
+            return $twig;
+        }));
+
+* **2012-06-13**: Added a route ``before`` middleware
+
+* **2012-06-13**: Renamed the route ``middleware`` to ``before``
+
+* **2012-06-13**: Added an extension for the Symfony Security component
+
+* **2012-05-31**: Made the ``BrowserKit``, ``CssSelector``, ``DomCrawler``,
+  ``Finder`` and ``Process`` components optional dependencies. Projects that
+  depend on them (e.g. through functional tests) should add those dependencies
+  to their ``composer.json``.
+
+* **2012-05-26**: added ``boot()`` to ``ServiceProviderInterface``.
+
+* **2012-05-26**: Removed ``SymfonyBridgesServiceProvider``. It is now implicit
+  by checking the existence of the bridge.
+
+* **2012-05-26**: Removed the ``translator.messages`` parameter (use
+  ``translator.domains`` instead).
+
+* **2012-05-24**: Removed the ``autoloader`` service (use composer instead).
+  The ``*.class_path`` settings on all the built-in providers have also been
+  removed in favor of Composer.
+
+* **2012-05-21**: Changed error() to allow handling specific exceptions.
+
+* **2012-05-20**: Added a way to define settings on a controller collection.
+
+* **2012-05-20**: The Request instance is not available anymore from the
+  Application after it has been handled.
+
+* **2012-04-01**: Added ``finish`` filters.
+
+* **2012-03-20**: Added ``json`` helper::
+
+        $data = array('some' => 'data');
+        $response = $app->json($data);
+
+* **2012-03-11**: Added route middlewares.
+
+* **2012-03-02**: Switched to use Composer for dependency management.
+
+* **2012-02-27**: Updated to Symfony 2.1 session handling.
+
+* **2012-01-02**: Introduced support for streaming responses.
+
+* **2011-09-22**: ``ExtensionInterface`` has been renamed to
+  ``ServiceProviderInterface``. All built-in extensions have been renamed
+  accordingly (for instance, ``Silex\Extension\TwigExtension`` has been
+  renamed to ``Silex\Provider\TwigServiceProvider``).
+
+* **2011-09-22**: The way reusable applications work has changed. The
+  ``mount()`` method now takes an instance of ``ControllerCollection`` instead
+  of an ``Application`` one.
+
+    Before::
+
+        $app = new Application();
+        $app->get('/bar', function() { return 'foo'; });
+
+        return $app;
+
+    After::
+
+        $app = new ControllerCollection();
+        $app->get('/bar', function() { return 'foo'; });
+
+        return $app;
+
+* **2011-08-08**: The controller method configuration is now done on the Controller itself
+
+    Before::
+
+        $app->match('/', function () { echo 'foo'; }, 'GET|POST');
+
+    After::
+
+        $app->match('/', function () { echo 'foo'; })->method('GET|POST');

+ 17 - 0
lib/silex/vendor/silex/silex/doc/conf.py

@@ -0,0 +1,17 @@
+import sys, os
+from sphinx.highlighting import lexers
+from pygments.lexers.web import PhpLexer
+
+sys.path.append(os.path.abspath('_exts'))
+
+extensions = []
+master_doc = 'index'
+highlight_language = 'php'
+
+project = u'Silex'
+copyright = u'2010 Fabien Potencier'
+
+version = '0'
+release = '0.0.0'
+
+lexers['php'] = PhpLexer(startinline=True)

+ 55 - 0
lib/silex/vendor/silex/silex/doc/contributing.rst

@@ -0,0 +1,55 @@
+Contributing
+============
+
+We are open to contributions to the Silex code. If you find
+a bug or want to contribute a provider, just follow these
+steps.
+
+* Fork `the Silex repository <https://github.com/silexphp/Silex>`_
+  on github.
+
+* Make your feature addition or bug fix.
+
+* Add tests for it. This is important so we don't break it in a future version unintentionally.
+
+* Optionally, add some technical documentation.
+
+* `Send a pull request <https://help.github.com/articles/creating-a-pull-request>`_, to the correct `target branch`_. 
+  Bonus points for topic branches.
+
+If you have a big change or would like to discuss something,
+please join us on the `mailing list
+<http://groups.google.com/group/silex-php>`_.
+
+.. note::
+
+    Any code you contribute must be licensed under the MIT
+    License.
+
+Target branch
+=============
+
+Before you create a pull request for Silex, you need to determine which branch
+to submit it to. Read this section carefully first.
+
+Silex has two active branches: `1.0` and `master` (`1.1`).
+
+* **1.0**: Bugfixes and documentation fixes go into the 1.0 branch. 1.0 is
+  periodically merged into master. The 1.0 branch targets versions 2.1, 2.2 and
+  2.3 of Symfony2.
+
+* **1.1**: All new features go into the 1.1 branch. Changes cannot break
+  backward compatibility. The 1.1 branch targets the 2.3 version of Symfony2.
+
+
+Writing Documentation
+=====================
+
+The documentation is written in `reStructuredText
+<http://docutils.sourceforge.net/rst.html>`_ and can be generated using `sphinx
+<http://sphinx-doc.org>`_.
+
+.. code-block:: bash
+
+    $ cd doc
+    $ sphinx-build -b html . build

+ 66 - 0
lib/silex/vendor/silex/silex/doc/cookbook/assets.rst

@@ -0,0 +1,66 @@
+Managing Assets in Templates
+============================
+
+A Silex application is not always hosted at the web root directory. To avoid
+repeating the base path whenever you link to another page, it is highly
+recommended to use the :doc:`URL generator service provider
+</providers/url_generator>`.
+
+But what about images, stylesheets, or JavaScript files? Their URLs are not
+managed by the Silex router, but nonetheless, they need to get prefixed by the
+base path. Fortunately, the Request object contain the application base path
+that needs to be prepended::
+
+    // generate a link to the stylesheets in /css/styles.css
+    $request->getBasePath().'/css/styles.css';
+
+And doing the same in a Twig template is as easy as it can get:
+
+.. code-block:: jinja
+
+    {{ app.request.basepath }}/css/styles.css
+
+If your assets are hosted under a different host, you might want to abstract
+the path by defining a Silex parameter::
+
+    $app['asset_path'] = 'http://assets.examples.com';
+
+Using it in a template is as easy as before:
+
+.. code-block:: jinja
+
+    {{ app.asset_path }}/css/styles.css
+
+If you need to implement some logic independently of the asset, define a
+service instead::
+
+    $app['asset_path'] = $app->share(function () {
+        // implement whatever logic you need to determine the asset path
+
+        return 'http://assets.examples.com';
+    });
+
+Usage is exactly the same as before:
+
+.. code-block:: jinja
+
+    {{ app.asset_path }}/css/styles.css
+
+If the asset location depends on the asset type or path, you will need more
+abstraction; here is one way to do that with a Twig function::
+
+    $app['twig'] = $app->share($app->extend('twig', function($twig, $app) {
+        $twig->addFunction(new \Twig_SimpleFunction('asset', function ($asset) {
+            // implement whatever logic you need to determine the asset path
+
+            return sprintf('http://assets.examples.com/%s', ltrim($asset, '/'));
+        }));
+
+        return $twig;
+    }));
+
+The ``asset`` function can then be used in your templates:
+
+.. code-block:: jinja
+
+    {{ asset('/css/styles.css') }}

+ 47 - 0
lib/silex/vendor/silex/silex/doc/cookbook/error_handler.rst

@@ -0,0 +1,47 @@
+Converting Errors to Exceptions
+===============================
+
+Silex will catch exceptions that are thrown from within a request/response
+cycle. It will however *not* catch PHP errors and notices. You can catch them
+by converting them to exceptions, this recipe will tell you how.
+
+Why does Silex not do this?
+---------------------------
+
+Silex could do this automatically in theory, but there is a reason why it does
+not. Silex acts as a library, this means that it does not mess with any global
+state. Since error handlers are global in PHP, it is your responsibility as a
+user to register them.
+
+Registering the ErrorHandler
+----------------------------
+
+Fortunately, the ``Symfony/Debug`` package has an ``ErrorHandler`` class that
+solves this issue. It converts all errors to exceptions, and exceptions can be
+caught by Silex.
+
+You register it by calling the static ``register`` method::
+
+    use Symfony\Component\Debug\ErrorHandler;
+
+    ErrorHandler::register();
+
+It is recommended that you do this in your front controller, i.e.
+``web/index.php``.
+
+Handling fatal errors
+---------------------
+
+To handle fatal errors, you can additionally register a global
+``ExceptionHandler``::
+
+    use Symfony\Component\Debug\ExceptionHandler;
+
+    ExceptionHandler::register();
+
+In production you may want to disable the debug output by passing ``false`` as
+the ``$debug`` argument::
+
+    use Symfony\Component\Debug\ExceptionHandler;
+
+    ExceptionHandler::register(false);

+ 35 - 0
lib/silex/vendor/silex/silex/doc/cookbook/form_no_csrf.rst

@@ -0,0 +1,35 @@
+Disabling CSRF Protection on a Form using the FormExtension
+===========================================================
+
+The *FormExtension* provides a service for building form in your application
+with the Symfony2 Form component. By default, the *FormExtension* uses the
+CSRF Protection avoiding Cross-site request forgery, a method by which a
+malicious user attempts to make your legitimate users unknowingly submit data
+that they don't intend to submit.
+
+You can find more details about CSRF Protection and CSRF token in the
+`Symfony2 Book
+<http://symfony.com/doc/current/book/forms.html#csrf-protection>`_.
+
+In some cases (for example, when embedding a form in an html email) you might
+want not to use this protection. The easiest way to avoid this is to
+understand that it is possible to give specific options to your form builder
+through the ``createBuilder()`` function.
+
+Example
+-------
+
+.. code-block:: php
+
+    $form = $app['form.factory']->createBuilder('form', null, array('csrf_protection' => false));
+
+That's it, your form could be submitted from everywhere without CSRF Protection.
+
+Going further
+-------------
+
+This specific example showed how to change the ``csrf_protection`` in the
+``$options`` parameter of the ``createBuilder()`` function. More of them could
+be passed through this parameter, it is as simple as using the Symfony2
+``getDefaultOptions()`` method in your form classes. `See more here
+<http://symfony.com/doc/current/book/forms.html#book-form-creating-form-classes>`_.

+ 43 - 0
lib/silex/vendor/silex/silex/doc/cookbook/index.rst

@@ -0,0 +1,43 @@
+Cookbook
+========
+
+The cookbook section contains recipes for solving specific problems.
+
+.. toctree::
+    :maxdepth: 1
+    :hidden:
+
+    json_request_body
+    translating_validation_messages
+    session_storage
+    form_no_csrf
+    validator_yaml
+    sub_requests
+    error_handler
+    multiple_loggers
+    assets
+
+Recipes
+-------
+
+* :doc:`Accepting a JSON Request Body <json_request_body>` A common need when
+  building a restful API is the ability to accept a JSON encoded entity from
+  the request body.
+
+* :doc:`Translating Validation Messages<translating_validation_messages>`.
+
+* :doc:`Using PdoSessionStorage to store Sessions in the Database
+  <session_storage>`.
+
+* :doc:`Disabling the CSRF Protection on a Form using the FormExtension
+  <form_no_csrf>`.
+
+* :doc:`Using YAML to configure Validation <validator_yaml>`.
+
+* :doc:`Making sub-Requests <sub_requests>`.
+
+* :doc:`Converting Errors to Exceptions <error_handler>`.
+
+* :doc:`Using multiple Monolog Loggers <multiple_loggers>`.
+
+* :doc:`Managing Assets in Templates <assets>`.

+ 95 - 0
lib/silex/vendor/silex/silex/doc/cookbook/json_request_body.rst

@@ -0,0 +1,95 @@
+Accepting a JSON Request Body
+=============================
+
+A common need when building a restful API is the ability to accept a JSON
+encoded entity from the request body.
+
+An example for such an API could be a blog post creation.
+
+Example API
+-----------
+
+In this example we will create an API for creating a blog post. The following
+is a spec of how we want it to work.
+
+Request
+~~~~~~~
+
+In the request we send the data for the blog post as a JSON object. We also
+indicate that using the ``Content-Type`` header:
+
+.. code-block:: text
+
+    POST /blog/posts
+    Accept: application/json
+    Content-Type: application/json
+    Content-Length: 57
+
+    {"title":"Hello World!","body":"This is my first post!"}
+
+Response
+~~~~~~~~
+
+The server responds with a 201 status code, telling us that the post was
+created. It tells us the ``Content-Type`` of the response, which is also
+JSON:
+
+.. code-block:: text
+
+    HTTP/1.1 201 Created
+    Content-Type: application/json
+    Content-Length: 65
+    Connection: close
+
+    {"id":"1","title":"Hello World!","body":"This is my first post!"}
+
+Parsing the request body
+------------------------
+
+The request body should only be parsed as JSON if the ``Content-Type`` header
+begins with ``application/json``. Since we want to do this for every request,
+the easiest solution is to use an application before middleware.
+
+We simply use ``json_decode`` to parse the content of the request and then
+replace the request data on the ``$request`` object::
+
+    use Symfony\Component\HttpFoundation\Request;
+    use Symfony\Component\HttpFoundation\ParameterBag;
+
+    $app->before(function (Request $request) {
+        if (0 === strpos($request->headers->get('Content-Type'), 'application/json')) {
+            $data = json_decode($request->getContent(), true);
+            $request->request->replace(is_array($data) ? $data : array());
+        }
+    });
+
+Controller implementation
+-------------------------
+
+Our controller will create a new blog post from the data provided and will
+return the post object, including its ``id``, as JSON::
+
+    use Symfony\Component\HttpFoundation\Request;
+    use Symfony\Component\HttpFoundation\Response;
+
+    $app->post('/blog/posts', function (Request $request) use ($app) {
+        $post = array(
+            'title' => $request->request->get('title'),
+            'body'  => $request->request->get('body'),
+        );
+
+        $post['id'] = createPost($post);
+
+        return $app->json($post, 201);
+    });
+
+Manual testing
+--------------
+
+In order to manually test our API, we can use the ``curl`` command line
+utility, which allows sending HTTP requests:
+
+.. code-block:: bash
+
+    $ curl http://blog.lo/blog/posts -d '{"title":"Hello World!","body":"This is my first post!"}' -H 'Content-Type: application/json'
+    {"id":"1","title":"Hello World!","body":"This is my first post!"}

+ 71 - 0
lib/silex/vendor/silex/silex/doc/cookbook/multiple_loggers.rst

@@ -0,0 +1,71 @@
+Using multiple Monolog Loggers
+==============================
+
+Having separate instances of `Monolog` for different parts of your system is
+often desirable and allows you to configure them independently, allowing for fine
+grained control of where your logging goes and in what detail.
+
+This simple example allows you to quickly configure several monolog instances,
+using the bundled handler, but each with a different channel. 
+
+.. code-block:: php
+
+    $app['monolog.factory'] = $app->protect(function ($name) use ($app) {
+        $log = new $app['monolog.logger.class']($name);
+        $log->pushHandler($app['monolog.handler']);
+
+        return $log;
+    });
+
+    foreach (array('auth', 'payments', 'stats') as $channel) {
+        $app['monolog.'.$channel] = $app->share(function ($app) use ($channel) {
+            return $app['monolog.factory']($channel);
+        });
+    }
+
+As your application grows, or your logging needs for certain areas of the
+system become apparent, it should be straightforward to then configure that
+particular service separately, including your customizations.
+
+.. code-block:: php
+
+    use Monolog\Handler\StreamHandler;
+
+    $app['monolog.payments'] = $app->share(function ($app) {
+        $log = new $app['monolog.logger.class']('payments');
+        $handler = new StreamHandler($app['monolog.payments.logfile'], $app['monolog.payment.level']);
+        $log->pushHandler($handler);
+
+        return $log;
+    });
+
+Alternatively, you could attempt to make the factory more complicated, and rely
+on some conventions, such as checking for an array of handlers registered with
+the container with the channel name, defaulting to the bundled handler.
+
+.. code-block:: php
+
+    use Monolog\Handler\StreamHandler;
+    use Monolog\Logger;
+
+    $app['monolog.factory'] = $app->protect(function ($name) use ($app) {
+        $log = new $app['monolog.logger.class']($name);
+
+        $handlers = isset($app['monolog.'.$name.'.handlers'])
+            ? $app['monolog.'.$name.'.handlers']
+            : array($app['monolog.handler']);
+
+        foreach ($handlers as $handler) {
+            $log->pushHandler($handler);
+        }
+
+        return $log;
+    });
+
+    $app['monolog.payments.handlers'] = $app->share(function ($app) {
+        return array(
+            new StreamHandler(__DIR__.'/../payments.log', Logger::DEBUG),
+        );
+    });
+
+

+ 92 - 0
lib/silex/vendor/silex/silex/doc/cookbook/session_storage.rst

@@ -0,0 +1,92 @@
+Using PdoSessionStorage to store Sessions in the Database
+=========================================================
+
+By default, the :doc:`SessionServiceProvider </providers/session>` writes
+session information in files using Symfony2 NativeFileSessionStorage. Most
+medium to large websites use a database to store sessions instead of files,
+because databases are easier to use and scale in a multi-webserver
+environment.
+
+Symfony2's `NativeSessionStorage
+<http://api.symfony.com/master/Symfony/Component/HttpFoundation/Session/Storage/NativeSessionStorage.html>`_
+has multiple storage handlers and one of them uses PDO to store sessions,
+`PdoSessionHandler
+<http://api.symfony.com/master/Symfony/Component/HttpFoundation/Session/Storage/Handler/PdoSessionHandler.html>`_.
+To use it, replace the ``session.storage.handler`` service in your application
+like explained below.
+
+With a dedicated PDO service
+----------------------------
+
+.. code-block:: php
+
+    use Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler;
+
+    $app->register(new Silex\Provider\SessionServiceProvider());
+
+    $app['pdo.dsn'] = 'mysql:dbname=mydatabase';
+    $app['pdo.user'] = 'myuser';
+    $app['pdo.password'] = 'mypassword';
+
+    $app['session.db_options'] = array(
+        'db_table'      => 'session',
+        'db_id_col'     => 'session_id',
+        'db_data_col'   => 'session_value',
+        'db_time_col'   => 'session_time',
+    );
+
+    $app['pdo'] = $app->share(function () use ($app) {
+        return new PDO(
+            $app['pdo.dsn'],
+            $app['pdo.user'],
+            $app['pdo.password']
+        );
+    });
+
+    $app['session.storage.handler'] = $app->share(function () use ($app) {
+        return new PdoSessionHandler(
+            $app['pdo'],
+            $app['session.db_options'],
+            $app['session.storage.options']
+        );
+    });
+
+Using the DoctrineServiceProvider
+---------------------------------
+
+When using the :doc:`DoctrineServiceProvider </providers/doctrine>` You don't
+have to make another database connection, simply pass the getWrappedConnection method.
+
+.. code-block:: php
+
+    use Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler;
+
+    $app->register(new Silex\Provider\SessionServiceProvider());
+
+    $app['session.db_options'] = array(
+        'db_table'      => 'session',
+        'db_id_col'     => 'session_id',
+        'db_data_col'   => 'session_value',
+        'db_time_col'   => 'session_time',
+    );
+
+    $app['session.storage.handler'] = $app->share(function () use ($app) {
+        return new PdoSessionHandler(
+            $app['db']->getWrappedConnection(),
+            $app['session.db_options'],
+            $app['session.storage.options']
+        );
+    });
+
+Database structure
+------------------
+
+PdoSessionStorage needs a database table with 3 columns:
+
+* ``session_id``: ID column (VARCHAR(255) or larger)
+* ``session_value``: Value column (TEXT or CLOB)
+* ``session_time``: Time column (INTEGER)
+
+You can find examples of SQL statements to create the session table in the
+`Symfony2 cookbook
+<http://symfony.com/doc/current/cookbook/configuration/pdo_session_storage.html#example-sql-statements>`_

+ 177 - 0
lib/silex/vendor/silex/silex/doc/cookbook/sub_requests.rst

@@ -0,0 +1,177 @@
+Making sub-Requests
+===================
+
+Since Silex is based on the ``HttpKernelInterface``, it allows you to simulate
+requests against your application. This means that you can embed a page within
+another, it also allows you to forward a request which is essentially an
+internal redirect that does not change the URL.
+
+Basics
+------
+
+You can make a sub-request by calling the ``handle`` method on the
+``Application``. This method takes three arguments:
+
+* ``$request``: An instance of the ``Request`` class which represents the
+   HTTP request.
+
+* ``$type``: Must be either ``HttpKernelInterface::MASTER_REQUEST`` or
+  ``HttpKernelInterface::SUB_REQUEST``. Certain listeners are only executed for
+  the master request, so it's important that this is set to ``SUB_REQUEST``.
+
+* ``$catch``: Catches exceptions and turns them into a response with status code
+  ``500``. This argument defaults to ``true``. For sub-requests you will most
+  likely want to set it to ``false``.
+
+By calling ``handle``, you can make a sub-request manually. Here's an example::
+
+    use Symfony\Component\HttpFoundation\Request;
+    use Symfony\Component\HttpKernel\HttpKernelInterface;
+
+    $subRequest = Request::create('/');
+    $response = $app->handle($subRequest, HttpKernelInterface::SUB_REQUEST, false);
+
+There's some more things that you need to keep in mind though. In most cases
+you will want to forward some parts of the current master request to the
+sub-request. That includes: Cookies, server information, session.
+
+Here is a more advanced example that forwards said information (``$request``
+holds the master request)::
+
+    use Symfony\Component\HttpFoundation\Request;
+    use Symfony\Component\HttpKernel\HttpKernelInterface;
+
+    $subRequest = Request::create('/', 'GET', array(), $request->cookies->all(), array(), $request->server->all());
+    if ($request->getSession()) {
+        $subRequest->setSession($request->getSession());
+    }
+
+    $response = $app->handle($subRequest, HttpKernelInterface::SUB_REQUEST, false);
+
+To forward this response to the client, you can simply return it from a
+controller::
+
+    use Silex\Application;
+    use Symfony\Component\HttpFoundation\Request;
+    use Symfony\Component\HttpKernel\HttpKernelInterface;
+
+    $app->get('/foo', function (Application $app, Request $request) {
+        $subRequest = Request::create('/', ...);
+        $response = $app->handle($subRequest, HttpKernelInterface::SUB_REQUEST, false);
+
+        return $response;
+    });
+
+If you want to embed the response as part of a larger page you can call
+``Response::getContent``::
+
+    $header = ...;
+    $footer = ...;
+    $body = $response->getContent();
+
+    return $header.$body.$footer;
+
+Rendering pages in Twig templates
+---------------------------------
+
+The :doc:`TwigServiceProvider </providers/twig>` provides a ``render``
+function that you can use in Twig templates. It gives you a convenient way to
+embed pages.
+
+.. code-block:: jinja
+
+    {{ render('/sidebar') }}
+
+For details, refer to the :doc:`TwigServiceProvider </providers/twig>` docs.
+
+Edge Side Includes
+------------------
+
+You can use ESI either through the :doc:`HttpCacheServiceProvider
+</providers/http_cache>` or a reverse proxy cache such as Varnish. This also
+allows you to embed pages, however it also gives you the benefit of caching
+parts of the page.
+
+Here is an example of how you would embed a page via ESI:
+
+.. code-block:: jinja
+
+    <esi:include src="/sidebar" />
+
+For details, refer to the :doc:`HttpCacheServiceProvider
+</providers/http_cache>` docs.
+
+Dealing with the request base URL
+---------------------------------
+
+One thing to watch out for is the base URL. If your application is not
+hosted at the webroot of your web server, then you may have an URL like
+``http://example.org/foo/index.php/articles/42``.
+
+In this case, ``/foo/index.php`` is your request base path. Silex accounts for
+this path prefix in the routing process, it reads it from
+``$request->server``. In the context of sub-requests this can lead to issues,
+because if you do not prepend the base path the request could mistake a part
+of the path you want to match as the base path and cut it off.
+
+You can prevent that from happening by always prepending the base path when
+constructing a request::
+
+    $url = $request->getUriForPath('/');
+    $subRequest = Request::create($url, 'GET', array(), $request->cookies->all(), array(), $request->server->all());
+
+This is something to be aware of when making sub-requests by hand.
+
+Lack of container scopes
+------------------------
+
+While the sub-requests available in Silex are quite powerful, they have their
+limits. The major limitation/danger that you will run into is the lack of
+scopes on the Pimple container.
+
+The container is a concept that is global to a Silex application, since the
+application object **is** the container. Any request that is run against an
+application will re-use the same set of services. Since these services are
+mutable, code in a master request can affect the sub-requests and vice versa.
+Any services depending on the ``request`` service will store the first request
+that they get (could be master or sub-request), and keep using it, even if
+that request is already over.
+
+For example::
+
+    use Symfony\Component\HttpFoundation\Request;
+
+    class ContentFormatNegotiator
+    {
+        private $request;
+
+        public function __construct(Request $request)
+        {
+            $this->request = $request;
+        }
+
+        public function negotiateFormat(array $serverTypes)
+        {
+            $clientAcceptType = $this->request->headers->get('Accept');
+
+            ...
+
+            return $format;
+        }
+    }
+
+This example looks harmless, but it might blow up. You have no way of knowing
+what ``$request->headers->get()`` will return, because ``$request`` could be
+either the master request or a sub-request. The answer in this case is to pass
+the request as an argument to ``negotiateFormat``. Then you can pass it in
+from a location where you have safe access to the current request: a listener
+or a controller.
+
+Here are a few general approaches to working around this issue:
+
+* Use ESI with Varnish.
+
+* Do not inject the request, ever. Use listeners instead, as they can access
+  the request without storing it.
+
+* Inject the Silex Application and fetch the request from it.

+ 20 - 0
lib/silex/vendor/silex/silex/doc/cookbook/translating_validation_messages.rst

@@ -0,0 +1,20 @@
+Translating Validation Messages
+===============================
+
+When working with Symfony2 validator, a common task would be to show localized
+validation messages.
+
+In order to do that, you will need to register translator and point to
+translated resources::
+
+    $app->register(new Silex\Provider\TranslationServiceProvider(), array(
+        'locale' => 'sr_Latn',
+        'translator.domains' => array(),
+    ));
+
+    $app->before(function () use ($app) {
+        $app['translator']->addLoader('xlf', new Symfony\Component\Translation\Loader\XliffFileLoader());
+        $app['translator']->addResource('xlf', __DIR__.'/vendor/symfony/validator/Symfony/Component/Validator/Resources/translations/validators/validators.sr_Latn.xlf', 'sr_Latn', 'validators');
+    });
+
+And that's all you need to load translations from Symfony2 ``xlf`` files.

+ 35 - 0
lib/silex/vendor/silex/silex/doc/cookbook/validator_yaml.rst

@@ -0,0 +1,35 @@
+Using YAML to configure Validation
+==================================
+
+Simplicity is at the heart of Silex so there is no out of the box solution to
+use YAML files for validation. But this doesn't mean that this is not
+possible. Let's see how to do it.
+
+First, you need to install the YAML Component:
+
+.. code-block:: bash
+
+    composer require symfony/yaml
+
+Next, you need to tell the Validation Service that you are not using
+``StaticMethodLoader`` to load your class metadata but a YAML file::
+
+    $app->register(new ValidatorServiceProvider());
+
+    $app['validator.mapping.class_metadata_factory'] = new Symfony\Component\Validator\Mapping\ClassMetadataFactory(
+        new Symfony\Component\Validator\Mapping\Loader\YamlFileLoader(__DIR__.'/validation.yml')
+    );
+
+Now, we can replace the usage of the static method and move all the validation
+rules to ``validation.yml``:
+
+.. code-block:: yaml
+
+    # validation.yml
+    Post:
+      properties:
+        title:
+          - NotNull: ~
+          - NotBlank: ~
+        body:
+          - Min: 100

+ 20 - 0
lib/silex/vendor/silex/silex/doc/index.rst

@@ -0,0 +1,20 @@
+Silex
+=====
+
+.. toctree::
+    :maxdepth: 1
+
+    intro
+    usage
+    middlewares
+    organizing_controllers
+    services
+    providers
+    testing
+    cookbook/index
+    internals
+    contributing
+    providers/index
+    web_servers
+    changelog
+    phar

+ 85 - 0
lib/silex/vendor/silex/silex/doc/internals.rst

@@ -0,0 +1,85 @@
+Internals
+=========
+
+This chapter will tell you a bit about how Silex works
+internally.
+
+Silex
+-----
+
+Application
+~~~~~~~~~~~
+
+The application is the main interface to Silex. It implements Symfony2's
+`HttpKernelInterface
+<http://api.symfony.com/master/Symfony/Component/HttpKernel/HttpKernelInterface.html>`_,
+so you can pass a `Request
+<http://api.symfony.com/master/Symfony/Component/HttpFoundation/Request.html>`_
+to the ``handle`` method and it will return a `Response
+<http://api.symfony.com/master/Symfony/Component/HttpFoundation/Response.html>`_.
+
+It extends the ``Pimple`` service container, allowing for flexibility on the
+outside as well as the inside. You could replace any service, and you are also
+able to read them.
+
+The application makes strong use of the `EventDispatcher
+<http://api.symfony.com/master/Symfony/Component/EventDispatcher/EventDispatcher.html>`_
+to hook into the Symfony2 `HttpKernel
+<http://api.symfony.com/master/Symfony/Component/HttpKernel/HttpKernel.html>`_
+events. This allows fetching the ``Request``, converting string responses into
+``Response`` objects and handling Exceptions. We also use it to dispatch some
+custom events like before/after middlewares and errors.
+
+Controller
+~~~~~~~~~~
+
+The Symfony2 `Route
+<http://api.symfony.com/master/Symfony/Component/Routing/Route.html>`_ is
+actually quite powerful. Routes can be named, which allows for URL generation.
+They can also have requirements for the variable parts. In order to allow
+setting these through a nice interface, the ``match`` method (which is used by
+``get``, ``post``, etc.) returns an instance of the ``Controller``, which
+wraps a route.
+
+ControllerCollection
+~~~~~~~~~~~~~~~~~~~~
+
+One of the goals of exposing the `RouteCollection
+<http://api.symfony.com/master/Symfony/Component/Routing/RouteCollection.html>`_
+was to make it mutable, so providers could add stuff to it. The challenge here
+is the fact that routes know nothing about their name. The name only has
+meaning in context of the ``RouteCollection`` and cannot be changed.
+
+To solve this challenge we came up with a staging area for routes. The
+``ControllerCollection`` holds the controllers until ``flush`` is called, at
+which point the routes are added to the ``RouteCollection``. Also, the
+controllers are then frozen. This means that they can no longer be modified
+and will throw an Exception if you try to do so.
+
+Unfortunately no good way for flushing implicitly could be found, which is why
+flushing is now always explicit. The Application will flush, but if you want
+to read the ``ControllerCollection`` before the request takes place, you will
+have to call flush yourself.
+
+The ``Application`` provides a shortcut ``flush`` method for flushing the
+``ControllerCollection``.
+
+.. tip::
+
+    Instead of creating an instance of ``RouteCollection`` yourself, use the
+    ``$app['controllers_factory']`` factory instead.
+
+Symfony2
+--------
+
+Following Symfony2 components are used by Silex:
+
+* **HttpFoundation**: For ``Request`` and ``Response``.
+
+* **HttpKernel**: Because we need a heart.
+
+* **Routing**: For matching defined routes.
+
+* **EventDispatcher**: For hooking into the HttpKernel.
+
+For more information, `check out the Symfony website <http://symfony.com/>`_.

+ 67 - 0
lib/silex/vendor/silex/silex/doc/intro.rst

@@ -0,0 +1,67 @@
+Introduction
+============
+
+Silex is a PHP microframework for PHP 5.3. It is built on the shoulders of
+`Symfony2`_ and `Pimple`_ and also inspired by `Sinatra`_.
+
+A microframework provides the guts for building simple single-file apps. Silex
+aims to be:
+
+* *Concise*: Silex exposes an intuitive and concise API that is fun to use.
+
+* *Extensible*: Silex has an extension system based around the Pimple micro
+  service-container that makes it even easier to tie in third party libraries.
+
+* *Testable*: Silex uses Symfony2's HttpKernel which abstracts request and
+  response. This makes it very easy to test apps and the framework itself. It
+  also respects the HTTP specification and encourages its proper use.
+
+In a nutshell, you define controllers and map them to routes, all in one step.
+
+Usage
+-----
+
+.. code-block:: php
+
+    <?php
+
+    // web/index.php
+    require_once __DIR__.'/../vendor/autoload.php';
+
+    $app = new Silex\Application();
+
+    $app->get('/hello/{name}', function ($name) use ($app) {
+        return 'Hello '.$app->escape($name);
+    });
+
+    $app->run();
+
+All that is needed to get access to the Framework is to include the
+autoloader.
+
+Next a route for ``/hello/{name}`` that matches for ``GET`` requests is defined.
+When the route matches, the function is executed and the return value is sent
+back to the client.
+
+Finally, the app is run. Visit ``/hello/world`` to see the result. It's really
+that easy!
+
+Installation
+------------
+
+Installing Silex is as easy as it can get: 
+
+.. code-block:: bash
+
+    composer require silex/silex
+
+Another way is to `download`_ the archive file and extract it.
+
+All examples in the documentation relies on a well-configured web server; read
+the :doc:`webserver documentation<web_servers>` to check yours.
+
+.. _Symfony2: http://symfony.com/
+.. _Pimple: http://pimple.sensiolabs.org/
+.. _Sinatra: http://www.sinatrarb.com/
+.. _Composer: http://getcomposer.org/
+.. _`download`: http://silex.sensiolabs.org/download

+ 163 - 0
lib/silex/vendor/silex/silex/doc/middlewares.rst

@@ -0,0 +1,163 @@
+Middlewares
+===========
+
+Silex allows you to run code, that changes the default Silex behavior, at
+different stages during the handling of a request through *middlewares*:
+
+* *Application middlewares* are triggered independently of the current handled
+  request;
+
+* *Route middlewares* are triggered when their associated route is matched.
+
+Application Middlewares
+-----------------------
+
+The application middlewares are only run for the "master" Request.
+
+Before Middleware
+~~~~~~~~~~~~~~~~~
+
+A *before* application middleware allows you to tweak the Request before the
+controller is executed::
+
+    $app->before(function (Request $request, Application $app) {
+        // ...
+    });
+
+By default, the middleware is run after the routing and the security.
+
+If you want your middleware to be run even if an exception is thrown early on
+(on a 404 or 403 error for instance), then, you need to register it as an
+early event::
+
+    $app->before(function (Request $request, Application $app) {
+        // ...
+    }, Application::EARLY_EVENT);
+
+Of course, in this case, the routing and the security won't have been
+executed, and so you won't have access to the locale, the current route, or
+the security user.
+
+.. note::
+
+    The before middleware is an event registered on the Symfony *request*
+    event.
+
+After Middleware
+~~~~~~~~~~~~~~~~
+
+An *after* application middleware allows you to tweak the Response before it
+is sent to the client::
+
+    $app->after(function (Request $request, Response $response) {
+        // ...
+    });
+
+.. note::
+
+    The after middleware is an event registered on the Symfony *response*
+    event.
+
+Finish Middleware
+~~~~~~~~~~~~~~~~~
+
+A *finish* application middleware allows you to execute tasks after the
+Response has been sent to the client (like sending emails or logging)::
+
+    $app->finish(function (Request $request, Response $response) {
+        // ...
+        // Warning: modifications to the Request or Response will be ignored
+    });
+
+.. note::
+
+    The finish middleware is an event registered on the Symfony *terminate*
+    event.
+
+Route Middlewares
+-----------------
+
+Route middlewares are added to routes or route collections and they are only
+triggered when the corresponding route is matched. You can also stack them::
+
+    $app->get('/somewhere', function () {
+        // ...
+    })
+    ->before($before1)
+    ->before($before2)
+    ->after($after1)
+    ->after($after2)
+    ;
+
+Before Middleware
+~~~~~~~~~~~~~~~~~
+
+A *before* route middleware is fired just before the route callback, but after
+the *before* application middlewares::
+
+    $before = function (Request $request, Application $app) {
+        // ...
+    };
+
+    $app->get('/somewhere', function () {
+        // ...
+    })
+    ->before($before);
+
+After Middleware
+~~~~~~~~~~~~~~~~
+
+An *after* route middleware is fired just after the route callback, but before
+the application *after* application middlewares::
+
+    $after = function (Request $request, Response $response, Application $app) {
+        // ...
+    };
+
+    $app->get('/somewhere', function () {
+        // ...
+    })
+    ->after($after);
+
+Middlewares Priority
+--------------------
+
+You can add as many middlewares as you want, in which case they are triggered
+in the same order as you added them.
+
+You can explicitly control the priority of your middleware by passing an
+additional argument to the registration methods::
+
+    $app->before(function (Request $request) {
+        // ...
+    }, 32);
+
+As a convenience, two constants allow you to register an event as early as
+possible or as late as possible::
+
+    $app->before(function (Request $request) {
+        // ...
+    }, Application::EARLY_EVENT);
+
+    $app->before(function (Request $request) {
+        // ...
+    }, Application::LATE_EVENT);
+
+Short-circuiting the Controller
+-------------------------------
+
+If a before middleware returns a Response object, the Request handling is
+short-circuited (the next middlewares won't be run, nor the route
+callback), and the Response is passed to the after middlewares right away::
+
+    $app->before(function (Request $request) {
+        // redirect the user to the login screen if access to the Resource is protected
+        if (...) {
+            return new RedirectResponse('/login');
+        }
+    });
+
+.. note::
+
+    If a before middleware does not return a Response or ``null``, a
+    ``RuntimeException`` is thrown.

+ 73 - 0
lib/silex/vendor/silex/silex/doc/organizing_controllers.rst

@@ -0,0 +1,73 @@
+Organizing Controllers
+======================
+
+When your application starts to define too many controllers, you might want to
+group them logically::
+
+    // define controllers for a blog
+    $blog = $app['controllers_factory'];
+    $blog->get('/', function () {
+        return 'Blog home page';
+    });
+    // ...
+
+    // define controllers for a forum
+    $forum = $app['controllers_factory'];
+    $forum->get('/', function () {
+        return 'Forum home page';
+    });
+
+    // define "global" controllers
+    $app->get('/', function () {
+        return 'Main home page';
+    });
+
+    $app->mount('/blog', $blog);
+    $app->mount('/forum', $forum);
+
+.. note::
+
+    ``$app['controllers_factory']`` is a factory that returns a new instance
+    of ``ControllerCollection`` when used.
+
+``mount()`` prefixes all routes with the given prefix and merges them into the
+main Application. So, ``/`` will map to the main home page, ``/blog/`` to the
+blog home page, and ``/forum/`` to the forum home page.
+
+.. caution::
+
+    When mounting a route collection under ``/blog``, it is not possible to
+    define a route for the ``/blog`` URL. The shortest possible URL is
+    ``/blog/``.
+
+.. note::
+
+    When calling ``get()``, ``match()``, or any other HTTP methods on the
+    Application, you are in fact calling them on a default instance of
+    ``ControllerCollection`` (stored in ``$app['controllers']``).
+
+Another benefit is the ability to apply settings on a set of controllers very
+easily. Building on the example from the middleware section, here is how you
+would secure all controllers for the backend collection::
+
+    $backend = $app['controllers_factory'];
+
+    // ensure that all controllers require logged-in users
+    $backend->before($mustBeLogged);
+
+.. tip::
+
+    For a better readability, you can split each controller collection into a
+    separate file::
+
+        // blog.php
+        $blog = $app['controllers_factory'];
+        $blog->get('/', function () { return 'Blog home page'; });
+
+        return $blog;
+
+        // app.php
+        $app->mount('/blog', include 'blog.php');
+
+    Instead of requiring a file, you can also create a :ref:`Controller
+    provider <controller-providers>`.

+ 109 - 0
lib/silex/vendor/silex/silex/doc/phar.rst

@@ -0,0 +1,109 @@
+Phar File
+=========
+
+.. caution::
+
+    Using the Silex ``phar`` file is deprecated. You should use Composer
+    instead to install Silex and its dependencies or download one of the
+    archives.
+
+Installing
+----------
+
+Installing Silex is as easy as downloading the `phar
+<http://silex.sensiolabs.org/get/silex.phar>`_ and storing it somewhere on
+the disk. Then, require it in your script::
+
+    <?php
+
+    require_once 'phar://'.__DIR__.'/silex.phar';
+
+    $app = new Silex\Application();
+
+    $app->get('/hello/{name}', function ($name) use ($app) {
+        return 'Hello '.$app->escape($name);
+    });
+
+    $app->run();
+
+Console
+-------
+
+Silex includes a lightweight console for updating to the latest version.
+
+To find out which version of Silex you are using, invoke ``silex.phar`` on the
+command-line with ``version`` as an argument:
+
+.. code-block:: text
+
+    $ php silex.phar version
+    Silex version 0a243d3 2011-04-17 14:49:31 +0200
+
+To check that your are using the latest version, run the ``check`` command:
+
+.. code-block:: text
+
+    $ php silex.phar check
+
+To update ``silex.phar`` to the latest version, invoke the ``update``
+command:
+
+.. code-block:: text
+
+    $ php silex.phar update
+
+This will automatically download a new ``silex.phar`` from
+``silex.sensiolabs.org`` and replace the existing one.
+
+Pitfalls
+--------
+
+There are some things that can go wrong. Here we will try and outline the
+most frequent ones.
+
+PHP configuration
+~~~~~~~~~~~~~~~~~
+
+Certain PHP distributions have restrictive default Phar settings. Setting
+the following may help.
+
+.. code-block:: ini
+
+    detect_unicode = Off
+    phar.readonly = Off
+    phar.require_hash = Off
+
+If you are on Suhosin you will also have to set this:
+
+.. code-block:: ini
+
+    suhosin.executor.include.whitelist = phar
+
+.. note::
+
+    Ubuntu's PHP ships with Suhosin, so if you are using Ubuntu, you will need
+    this change.
+
+Phar-Stub bug
+~~~~~~~~~~~~~
+
+Some PHP installations have a bug that throws a ``PharException`` when trying
+to include the Phar. It will also tell you that ``Silex\Application`` could not
+be found. A workaround is using the following include line::
+
+    require_once 'phar://'.__DIR__.'/silex.phar/autoload.php';
+
+The exact cause of this issue could not be determined yet.
+
+ioncube loader bug
+~~~~~~~~~~~~~~~~~~
+
+Ioncube loader is an extension that can decode PHP encoded file.
+Unfortunately, old versions (prior to version 4.0.9) are not working well
+with phar archives.
+You must either upgrade Ioncube loader to version 4.0.9 or newer or disable it
+by commenting or removing this line in your php.ini file:
+
+.. code-block:: ini
+
+    zend_extension = /usr/lib/php5/20090626+lfs/ioncube_loader_lin_5.3.so

+ 214 - 0
lib/silex/vendor/silex/silex/doc/providers.rst

@@ -0,0 +1,214 @@
+Providers
+=========
+
+Providers allow the developer to reuse parts of an application into another
+one. Silex provides two types of providers defined by two interfaces:
+``ServiceProviderInterface`` for services and ``ControllerProviderInterface``
+for controllers.
+
+Service Providers
+-----------------
+
+Loading providers
+~~~~~~~~~~~~~~~~~
+
+In order to load and use a service provider, you must register it on the
+application::
+
+    $app = new Silex\Application();
+
+    $app->register(new Acme\DatabaseServiceProvider());
+
+You can also provide some parameters as a second argument. These will be set
+**after** the provider is registered, but **before** it is booted::
+
+    $app->register(new Acme\DatabaseServiceProvider(), array(
+        'database.dsn'      => 'mysql:host=localhost;dbname=myapp',
+        'database.user'     => 'root',
+        'database.password' => 'secret_root_password',
+    ));
+
+Conventions
+~~~~~~~~~~~
+
+You need to watch out in what order you do certain things when interacting
+with providers. Just keep to these rules:
+
+* Overriding existing services must occur **after** the provider is
+  registered.
+
+  *Reason: If the service already exists, the provider will overwrite it.*
+
+* You can set parameters any time **after** the provider is registered, but
+  **before** the service is accessed.
+
+  *Reason: Providers can set default values for parameters. Just like with
+  services, the provider will overwrite existing values.*
+
+Make sure to stick to this behavior when creating your own providers.
+
+Included providers
+~~~~~~~~~~~~~~~~~~
+
+There are a few providers that you get out of the box. All of these are within
+the ``Silex\Provider`` namespace:
+
+* :doc:`DoctrineServiceProvider <providers/doctrine>`
+* :doc:`MonologServiceProvider <providers/monolog>`
+* :doc:`SessionServiceProvider <providers/session>`
+* :doc:`SerializerServiceProvider <providers/serializer>`
+* :doc:`SwiftmailerServiceProvider <providers/swiftmailer>`
+* :doc:`TwigServiceProvider <providers/twig>`
+* :doc:`TranslationServiceProvider <providers/translation>`
+* :doc:`UrlGeneratorServiceProvider <providers/url_generator>`
+* :doc:`ValidatorServiceProvider <providers/validator>`
+* :doc:`HttpCacheServiceProvider <providers/http_cache>`
+* :doc:`FormServiceProvider <providers/form>`
+* :doc:`SecurityServiceProvider <providers/security>`
+* :doc:`RememberMeServiceProvider <providers/remember_me>`
+* :doc:`ServiceControllerServiceProvider <providers/service_controller>`
+
+Third party providers
+~~~~~~~~~~~~~~~~~~~~~
+
+Some service providers are developed by the community. Those third-party
+providers are listed on `Silex' repository wiki
+<https://github.com/silexphp/Silex/wiki/Third-Party-ServiceProviders>`_.
+
+You are encouraged to share yours.
+
+Creating a provider
+~~~~~~~~~~~~~~~~~~~
+
+Providers must implement the ``Silex\ServiceProviderInterface``::
+
+    interface ServiceProviderInterface
+    {
+        public function register(Application $app);
+
+        public function boot(Application $app);
+    }
+
+This is very straight forward, just create a new class that implements the two
+methods. In the ``register()`` method, you can define services on the
+application which then may make use of other services and parameters. In the
+``boot()`` method, you can configure the application, just before it handles a
+request.
+
+Here is an example of such a provider::
+
+    namespace Acme;
+
+    use Silex\Application;
+    use Silex\ServiceProviderInterface;
+
+    class HelloServiceProvider implements ServiceProviderInterface
+    {
+        public function register(Application $app)
+        {
+            $app['hello'] = $app->protect(function ($name) use ($app) {
+                $default = $app['hello.default_name'] ? $app['hello.default_name'] : '';
+                $name = $name ?: $default;
+
+                return 'Hello '.$app->escape($name);
+            });
+        }
+
+        public function boot(Application $app)
+        {
+        }
+    }
+
+This class provides a ``hello`` service which is a protected closure. It takes
+a ``name`` argument and will return ``hello.default_name`` if no name is
+given. If the default is also missing, it will use an empty string.
+
+You can now use this provider as follows::
+
+    $app = new Silex\Application();
+
+    $app->register(new Acme\HelloServiceProvider(), array(
+        'hello.default_name' => 'Igor',
+    ));
+
+    $app->get('/hello', function () use ($app) {
+        $name = $app['request']->get('name');
+
+        return $app['hello']($name);
+    });
+
+In this example we are getting the ``name`` parameter from the query string,
+so the request path would have to be ``/hello?name=Fabien``.
+
+.. _controller-providers:
+
+Controller Providers
+--------------------
+
+Loading providers
+~~~~~~~~~~~~~~~~~
+
+In order to load and use a controller provider, you must "mount" its
+controllers under a path::
+
+    $app = new Silex\Application();
+
+    $app->mount('/blog', new Acme\BlogControllerProvider());
+
+All controllers defined by the provider will now be available under the
+``/blog`` path.
+
+Creating a provider
+~~~~~~~~~~~~~~~~~~~
+
+Providers must implement the ``Silex\ControllerProviderInterface``::
+
+    interface ControllerProviderInterface
+    {
+        public function connect(Application $app);
+    }
+
+Here is an example of such a provider::
+
+    namespace Acme;
+
+    use Silex\Application;
+    use Silex\ControllerProviderInterface;
+
+    class HelloControllerProvider implements ControllerProviderInterface
+    {
+        public function connect(Application $app)
+        {
+            // creates a new controller based on the default route
+            $controllers = $app['controllers_factory'];
+
+            $controllers->get('/', function (Application $app) {
+                return $app->redirect('/hello');
+            });
+
+            return $controllers;
+        }
+    }
+
+The ``connect`` method must return an instance of ``ControllerCollection``.
+``ControllerCollection`` is the class where all controller related methods are
+defined (like ``get``, ``post``, ``match``, ...).
+
+.. tip::
+
+    The ``Application`` class acts in fact as a proxy for these methods.
+
+You can now use this provider as follows::
+
+    $app = new Silex\Application();
+
+    $app->mount('/blog', new Acme\HelloControllerProvider());
+
+In this example, the ``/blog/`` path now references the controller defined in
+the provider.
+
+.. tip::
+
+    You can also define a provider that implements both the service and the
+    controller provider interface and package in the same class the services
+    needed to make your controllers work.

+ 141 - 0
lib/silex/vendor/silex/silex/doc/providers/doctrine.rst

@@ -0,0 +1,141 @@
+DoctrineServiceProvider
+=======================
+
+The *DoctrineServiceProvider* provides integration with the `Doctrine DBAL
+<http://www.doctrine-project.org/projects/dbal>`_ for easy database access.
+
+.. note::
+
+    There is only a Doctrine DBAL. An ORM service is **not** supplied.
+
+Parameters
+----------
+
+* **db.options**: Array of Doctrine DBAL options.
+
+  These options are available:
+
+  * **driver**: The database driver to use, defaults to ``pdo_mysql``.
+    Can be any of: ``pdo_mysql``, ``pdo_sqlite``, ``pdo_pgsql``,
+    ``pdo_oci``, ``oci8``, ``ibm_db2``, ``pdo_ibm``, ``pdo_sqlsrv``.
+
+  * **dbname**: The name of the database to connect to.
+
+  * **host**: The host of the database to connect to. Defaults to
+    localhost.
+
+  * **user**: The user of the database to connect to. Defaults to
+    root.
+
+  * **password**: The password of the database to connect to.
+
+  * **charset**: Only relevant for ``pdo_mysql``, and ``pdo_oci/oci8``,
+    specifies the charset used when connecting to the database.
+
+  * **path**: Only relevant for ``pdo_sqlite``, specifies the path to
+    the SQLite database.
+
+  * **port**: Only relevant for ``pdo_mysql``, ``pdo_pgsql``, and ``pdo_oci/oci8``,
+    specifies the port of the database to connect to.
+
+  These and additional options are described in detail in the `Doctrine DBAL
+  configuration documentation <http://docs.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/configuration.html>`_.
+
+Services
+--------
+
+* **db**: The database connection, instance of
+  ``Doctrine\DBAL\Connection``.
+
+* **db.config**: Configuration object for Doctrine. Defaults to
+  an empty ``Doctrine\DBAL\Configuration``.
+
+* **db.event_manager**: Event Manager for Doctrine.
+
+Registering
+-----------
+
+.. code-block:: php
+
+    $app->register(new Silex\Provider\DoctrineServiceProvider(), array(
+        'db.options' => array(
+            'driver'   => 'pdo_sqlite',
+            'path'     => __DIR__.'/app.db',
+        ),
+    ));
+
+.. note::
+
+    Doctrine DBAL comes with the "fat" Silex archive but not with the regular
+    one. If you are using Composer, add it as a dependency:
+
+    .. code-block:: bash
+
+        composer require "doctrine/dbal:~2.2"
+
+Usage
+-----
+
+The Doctrine provider provides a ``db`` service. Here is a usage
+example::
+
+    $app->get('/blog/{id}', function ($id) use ($app) {
+        $sql = "SELECT * FROM posts WHERE id = ?";
+        $post = $app['db']->fetchAssoc($sql, array((int) $id));
+
+        return  "<h1>{$post['title']}</h1>".
+                "<p>{$post['body']}</p>";
+    });
+
+Using multiple databases
+------------------------
+
+The Doctrine provider can allow access to multiple databases. In order to
+configure the data sources, replace the **db.options** with **dbs.options**.
+**dbs.options** is an array of configurations where keys are connection names
+and values are options::
+
+    $app->register(new Silex\Provider\DoctrineServiceProvider(), array(
+        'dbs.options' => array (
+            'mysql_read' => array(
+                'driver'    => 'pdo_mysql',
+                'host'      => 'mysql_read.someplace.tld',
+                'dbname'    => 'my_database',
+                'user'      => 'my_username',
+                'password'  => 'my_password',
+                'charset'   => 'utf8mb4',
+            ),
+            'mysql_write' => array(
+                'driver'    => 'pdo_mysql',
+                'host'      => 'mysql_write.someplace.tld',
+                'dbname'    => 'my_database',
+                'user'      => 'my_username',
+                'password'  => 'my_password',
+                'charset'   => 'utf8mb4',
+            ),
+        ),
+    ));
+
+The first registered connection is the default and can simply be accessed as
+you would if there was only one connection. Given the above configuration,
+these two lines are equivalent::
+
+    $app['db']->fetchAll('SELECT * FROM table');
+
+    $app['dbs']['mysql_read']->fetchAll('SELECT * FROM table');
+
+Using multiple connections::
+
+    $app->get('/blog/{id}', function ($id) use ($app) {
+        $sql = "SELECT * FROM posts WHERE id = ?";
+        $post = $app['dbs']['mysql_read']->fetchAssoc($sql, array((int) $id));
+
+        $sql = "UPDATE posts SET value = ? WHERE id = ?";
+        $app['dbs']['mysql_write']->executeUpdate($sql, array('newValue', (int) $id));
+
+        return  "<h1>{$post['title']}</h1>".
+                "<p>{$post['body']}</p>";
+    });
+
+For more information, consult the `Doctrine DBAL documentation
+<http://docs.doctrine-project.org/projects/doctrine-dbal/en/latest/>`_.

+ 194 - 0
lib/silex/vendor/silex/silex/doc/providers/form.rst

@@ -0,0 +1,194 @@
+FormServiceProvider
+===================
+
+The *FormServiceProvider* provides a service for building forms in
+your application with the Symfony2 Form component.
+
+Parameters
+----------
+
+* **form.secret**: This secret value is used for generating and validating the
+  CSRF token for a specific page. It is very important for you to set this
+  value to a static randomly generated value, to prevent hijacking of your
+  forms. Defaults to ``md5(__DIR__)``.
+
+Services
+--------
+
+* **form.factory**: An instance of `FormFactory
+  <http://api.symfony.com/master/Symfony/Component/Form/FormFactory.html>`_,
+  that is used to build a form.
+
+* **form.csrf_provider**: An instance of an implementation of the
+  `CsrfProviderInterface
+  <http://api.symfony.com/master/Symfony/Component/Form/Extension/Csrf/CsrfProvider/CsrfProviderInterface.html>`_,
+  defaults to a `DefaultCsrfProvider
+  <http://api.symfony.com/master/Symfony/Component/Form/Extension/Csrf/CsrfProvider/DefaultCsrfProvider.html>`_.
+
+Registering
+-----------
+
+.. code-block:: php
+
+    use Silex\Provider\FormServiceProvider;
+
+    $app->register(new FormServiceProvider());
+
+.. note::
+
+    If you don't want to create your own form layout, it's fine: a default one
+    will be used. But you will have to register the :doc:`translation provider
+    <translation>` as the default form layout requires it.
+
+    If you want to use validation with forms, do not forget to register the
+    :doc:`Validator provider <validator>`.
+
+.. note::
+
+    The Symfony Form Component and all its dependencies (optional or not) comes
+    with the "fat" Silex archive but not with the regular one. If you are using
+    Composer, add it as a dependency:
+
+    .. code-block:: bash
+
+        composer require symfony/form
+
+    If you are going to use the validation extension with forms, you must also
+    add a dependency to the ``symfony/config`` and ``symfony/translation``
+    components:
+
+    .. code-block:: bash
+
+        composer require symfony/validator symfony/config symfony/translation
+        
+    The Symfony Security CSRF component is used to protect forms against CSRF attacks:
+
+    .. code-block:: bash
+    
+        composer require symfony/security-csrf
+
+    If you want to use forms in your Twig templates, you can also install the
+    Symfony Twig Bridge. Make sure to install, if you didn't do that already,
+    the Translation component in order for the bridge to work:
+
+    .. code-block:: bash
+
+        composer require symfony/twig-bridge symfony/translation
+
+Usage
+-----
+
+The FormServiceProvider provides a ``form.factory`` service. Here is a usage
+example::
+
+    $app->match('/form', function (Request $request) use ($app) {
+        // some default data for when the form is displayed the first time
+        $data = array(
+            'name' => 'Your name',
+            'email' => 'Your email',
+        );
+
+        $form = $app['form.factory']->createBuilder('form', $data)
+            ->add('name')
+            ->add('email')
+            ->add('gender', 'choice', array(
+                'choices' => array(1 => 'male', 2 => 'female'),
+                'expanded' => true,
+            ))
+            ->getForm();
+
+        $form->handleRequest($request);
+
+        if ($form->isValid()) {
+            $data = $form->getData();
+
+            // do something with the data
+
+            // redirect somewhere
+            return $app->redirect('...');
+        }
+
+        // display the form
+        return $app['twig']->render('index.twig', array('form' => $form->createView()));
+    });
+
+And here is the ``index.twig`` form template (requires ``symfony/twig-bridge``):
+
+.. code-block:: jinja
+
+    <form action="#" method="post">
+        {{ form_widget(form) }}
+
+        <input type="submit" name="submit" />
+    </form>
+
+If you are using the validator provider, you can also add validation to your
+form by adding constraints on the fields::
+
+    use Symfony\Component\Validator\Constraints as Assert;
+
+    $app->register(new Silex\Provider\ValidatorServiceProvider());
+    $app->register(new Silex\Provider\TranslationServiceProvider(), array(
+        'translator.domains' => array(),
+    ));
+
+    $form = $app['form.factory']->createBuilder('form')
+        ->add('name', 'text', array(
+            'constraints' => array(new Assert\NotBlank(), new Assert\Length(array('min' => 5)))
+        ))
+        ->add('email', 'text', array(
+            'constraints' => new Assert\Email()
+        ))
+        ->add('gender', 'choice', array(
+            'choices' => array(1 => 'male', 2 => 'female'),
+            'expanded' => true,
+            'constraints' => new Assert\Choice(array(1, 2)),
+        ))
+        ->getForm();
+
+You can register form types by extending ``form.types``::
+
+    $app['form.types'] = $app->share($app->extend('form.types', function ($types) use ($app) {
+        $types[] = new YourFormType();
+
+        return $types;
+    }));
+
+You can register form extensions by extending ``form.extensions``::
+
+    $app['form.extensions'] = $app->share($app->extend('form.extensions', function ($extensions) use ($app) {
+        $extensions[] = new YourTopFormExtension();
+
+        return $extensions;
+    }));
+
+
+You can register form type extensions by extending ``form.type.extensions``::
+
+    $app['form.type.extensions'] = $app->share($app->extend('form.type.extensions', function ($extensions) use ($app) {
+        $extensions[] = new YourFormTypeExtension();
+
+        return $extensions;
+    }));
+
+You can register form type guessers by extending ``form.type.guessers``::
+
+    $app['form.type.guessers'] = $app->share($app->extend('form.type.guessers', function ($guessers) use ($app) {
+        $guessers[] = new YourFormTypeGuesser();
+
+        return $guessers;
+    }));
+
+Traits
+------
+
+``Silex\Application\FormTrait`` adds the following shortcuts:
+
+* **form**: Creates a FormBuilder instance.
+
+.. code-block:: php
+
+    $app->form($data);
+
+For more information, consult the `Symfony2 Forms documentation
+<http://symfony.com/doc/2.3/book/forms.html>`_.

+ 132 - 0
lib/silex/vendor/silex/silex/doc/providers/http_cache.rst

@@ -0,0 +1,132 @@
+HttpCacheServiceProvider
+========================
+
+The *HttpCacheServiceProvider* provides support for the Symfony2 Reverse
+Proxy.
+
+Parameters
+----------
+
+* **http_cache.cache_dir**: The cache directory to store the HTTP cache data.
+
+* **http_cache.options** (optional): An array of options for the `HttpCache
+  <http://api.symfony.com/master/Symfony/Component/HttpKernel/HttpCache/HttpCache.html>`_
+  constructor.
+
+Services
+--------
+
+* **http_cache**: An instance of `HttpCache
+  <http://api.symfony.com/master/Symfony/Component/HttpKernel/HttpCache/HttpCache.html>`_.
+
+* **http_cache.esi**: An instance of `Esi
+  <http://api.symfony.com/master/Symfony/Component/HttpKernel/HttpCache/Esi.html>`_,
+  that implements the ESI capabilities to Request and Response instances.
+
+* **http_cache.store**: An instance of `Store
+  <http://api.symfony.com/master/Symfony/Component/HttpKernel/HttpCache/Store.html>`_,
+  that implements all the logic for storing cache metadata (Request and Response
+  headers).
+
+Registering
+-----------
+
+.. code-block:: php
+
+    $app->register(new Silex\Provider\HttpCacheServiceProvider(), array(
+        'http_cache.cache_dir' => __DIR__.'/cache/',
+    ));
+
+Usage
+-----
+
+Silex already supports any reverse proxy like Varnish out of the box by
+setting Response HTTP cache headers::
+
+    use Symfony\Component\HttpFoundation\Response;
+
+    $app->get('/', function() {
+        return new Response('Foo', 200, array(
+            'Cache-Control' => 's-maxage=5',
+        ));
+    });
+
+.. tip::
+
+    If you want Silex to trust the ``X-Forwarded-For*`` headers from your
+    reverse proxy at address $ip, you will need to whitelist it as documented
+    in `Trusting Proxies
+    <http://symfony.com/doc/current/components/http_foundation/trusting_proxies.html>`_.
+
+    If you would be running Varnish in front of your application on the same machine:
+    
+    .. code-block:: php
+
+        use Symfony\Component\HttpFoundation\Request;
+        
+        Request::setTrustedProxies(array('127.0.0.1', '::1'));
+        $app->run();
+
+This provider allows you to use the Symfony2 reverse proxy natively with
+Silex applications by using the ``http_cache`` service. The Symfony2 reverse proxy
+acts much like any other proxy would, so you will want to whitelist it:
+
+.. code-block:: php
+
+    use Symfony\Component\HttpFoundation\Request;
+        
+    Request::setTrustedProxies(array('127.0.0.1'));
+    $app['http_cache']->run();
+
+The provider also provides ESI support::
+
+    $app->get('/', function() {
+        $response = new Response(<<<EOF
+    <html>
+        <body>
+            Hello
+            <esi:include src="/included" />
+        </body>
+    </html>
+
+    EOF
+        , 200, array(
+            'Surrogate-Control' => 'content="ESI/1.0"',
+        ));
+
+        $response->setTtl(20);
+
+        return $response;
+    });
+
+    $app->get('/included', function() {
+        $response = new Response('Foo');
+        $response->setTtl(5);
+
+        return $response;
+    });
+
+    $app['http_cache']->run();
+
+If your application doesn't use ESI, you can disable it to slightly improve the
+overall performance::
+
+    $app->register(new Silex\Provider\HttpCacheServiceProvider(), array(
+       'http_cache.cache_dir' => __DIR__.'/cache/',
+       'http_cache.esi'       => null,
+    ));
+
+.. tip::
+
+    To help you debug caching issues, set your application ``debug`` to true.
+    Symfony automatically adds a ``X-Symfony-Cache`` header to each response
+    with useful information about cache hits and misses.
+
+    If you are *not* using the Symfony Session provider, you might want to set
+    the PHP ``session.cache_limiter`` setting to an empty value to avoid the
+    default PHP behavior.
+
+    Finally, check that your Web server does not override your caching strategy.
+
+For more information, consult the `Symfony2 HTTP Cache documentation
+<http://symfony.com/doc/current/book/http_cache.html>`_.

+ 74 - 0
lib/silex/vendor/silex/silex/doc/providers/http_fragment.rst

@@ -0,0 +1,74 @@
+HttpFragmentServiceProvider
+===========================
+
+The *HttpFragmentServiceProvider* provides support for the Symfony2 fragment
+sub-framework, which allows you to embed fragments of HTML in a template.
+
+.. warning::
+
+    This service provider only work with Symfony 2.4+.
+
+Parameters
+----------
+
+* **fragment.path**: The path to use for the URL generated for ESI and
+  HInclude URLs (``/_fragment`` by default).
+
+* **uri_signer.secret**: The secret to use for the URI signer service (used
+  for the HInclude renderer).
+
+* **fragment.renderers.hinclude.global_template**: The content or Twig
+  template to use for the default content when using the HInclude renderer.
+
+Services
+--------
+
+* **fragment.handler**: An instance of `FragmentHandler
+  <http://api.symfony.com/master/Symfony/Component/HttpKernel/Fragment/FragmentHandler.html>`_.
+
+* **fragment.renderers**: An array of fragment renderers (by default, the
+  inline, ESI, and HInclude renderers are pre-configured).
+
+Registering
+-----------
+
+.. code-block:: php
+
+    $app->register(new Silex\Provider\HttpFragmentServiceProvider());
+
+Usage
+-----
+
+.. note::
+
+    This section assumes that you are using Twig for your templates.
+
+Instead of building a page out of a single request/controller/template, the
+fragment framework allows you to build a page from several
+controllers/sub-requests/sub-templates by using **fragments**.
+
+Including "sub-pages" in the main page can be done with the Twig ``render()``
+function:
+
+.. code-block:: jinja
+
+    The main page content.
+
+    {{ render('/foo') }}
+
+    The main page content resumes here.
+
+The ``render()`` call is replaced by the content of the ``/foo`` URL
+(internally, a sub-request is handled by Silex to render the sub-page).
+
+Instead of making internal sub-requests, you can also use the ESI (the
+sub-request is handled by a reverse proxy) or the HInclude strategies (the
+sub-request is handled by a web browser):
+
+.. code-block:: jinja
+
+    {{ render(url('route_name')) }}
+
+    {{ render_esi(url('route_name')) }}
+
+    {{ render_hinclude(url('route_name')) }}

+ 21 - 0
lib/silex/vendor/silex/silex/doc/providers/index.rst

@@ -0,0 +1,21 @@
+Silex
+=====
+
+.. toctree::
+    :maxdepth: 1
+
+    doctrine
+    monolog
+    session
+    swiftmailer
+    translation
+    twig
+    url_generator
+    validator
+    form
+    http_cache
+    http_fragment
+    security
+    remember_me
+    serializer
+    service_controller

+ 105 - 0
lib/silex/vendor/silex/silex/doc/providers/monolog.rst

@@ -0,0 +1,105 @@
+MonologServiceProvider
+======================
+
+The *MonologServiceProvider* provides a default logging mechanism through
+Jordi Boggiano's `Monolog <https://github.com/Seldaek/monolog>`_ library.
+
+It will log requests and errors and allow you to add logging to your
+application. This allows you to debug and monitor the behaviour,
+even in production.
+
+Parameters
+----------
+
+* **monolog.logfile**: File where logs are written to.
+* **monolog.bubble** = (optional) Whether the messages that are handled can bubble up the stack or not.
+* **monolog.permission** = (optional) File permissions default (null), nothing change.
+
+* **monolog.level** (optional): Level of logging, defaults
+  to ``DEBUG``. Must be one of ``Logger::DEBUG``, ``Logger::INFO``,
+  ``Logger::WARNING``, ``Logger::ERROR``. ``DEBUG`` will log
+  everything, ``INFO`` will log everything except ``DEBUG``,
+  etc.
+
+  In addition to the ``Logger::`` constants, it is also possible to supply the
+  level in string form, for example: ``"DEBUG"``, ``"INFO"``, ``"WARNING"``,
+  ``"ERROR"``.
+
+* **monolog.name** (optional): Name of the monolog channel,
+  defaults to ``myapp``.
+
+Services
+--------
+
+* **monolog**: The monolog logger instance.
+
+  Example usage::
+
+    $app['monolog']->addDebug('Testing the Monolog logging.');
+
+* **monolog.listener**: An event listener to log requests, responses and errors.
+
+Registering
+-----------
+
+.. code-block:: php
+
+    $app->register(new Silex\Provider\MonologServiceProvider(), array(
+        'monolog.logfile' => __DIR__.'/development.log',
+    ));
+
+.. note::
+
+    Monolog comes with the "fat" Silex archive but not with the regular one.
+    If you are using Composer, add it as a dependency:
+
+    .. code-block:: bash
+
+        composer require monolog/monolog
+
+Usage
+-----
+
+The MonologServiceProvider provides a ``monolog`` service. You can use it to
+add log entries for any logging level through ``addDebug()``, ``addInfo()``,
+``addWarning()`` and ``addError()``::
+
+    use Symfony\Component\HttpFoundation\Response;
+
+    $app->post('/user', function () use ($app) {
+        // ...
+
+        $app['monolog']->addInfo(sprintf("User '%s' registered.", $username));
+
+        return new Response('', 201);
+    });
+
+Customization
+-------------
+
+You can configure Monolog (like adding or changing the handlers) before using
+it by extending the ``monolog`` service::
+
+    $app['monolog'] = $app->share($app->extend('monolog', function($monolog, $app) {
+        $monolog->pushHandler(...);
+
+        return $monolog;
+    }));
+
+By default, all requests, responses and errors are logged by an event listener
+registered as a service called `monolog.listener`. You can replace or remove
+this service if you want to modify or disable the informations logged.
+
+Traits
+------
+
+``Silex\Application\MonologTrait`` adds the following shortcuts:
+
+* **log**: Logs a message.
+
+.. code-block:: php
+
+    $app->log(sprintf("User '%s' registered.", $username));
+
+For more information, check out the `Monolog documentation
+<https://github.com/Seldaek/monolog>`_.

+ 69 - 0
lib/silex/vendor/silex/silex/doc/providers/remember_me.rst

@@ -0,0 +1,69 @@
+RememberMeServiceProvider
+=========================
+
+The *RememberMeServiceProvider* adds "Remember-Me" authentication to the
+*SecurityServiceProvider*.
+
+Parameters
+----------
+
+n/a
+
+Services
+--------
+
+n/a
+
+.. note::
+
+    The service provider defines many other services that are used internally
+    but rarely need to be customized.
+
+Registering
+-----------
+
+Before registering this service provider, you must register the
+*SecurityServiceProvider*::
+
+    $app->register(new Silex\Provider\SecurityServiceProvider());
+    $app->register(new Silex\Provider\RememberMeServiceProvider());
+
+    $app['security.firewalls'] = array(
+        'my-firewall' => array(
+            'pattern'     => '^/secure$',
+            'form'        => true,
+            'logout'      => true,
+            'remember_me' => array(
+                'key'                => 'Choose_A_Unique_Random_Key',
+                'always_remember_me' => true,
+                /* Other options */
+            ),
+            'users' => array( /* ... */ ),
+        ),
+    );
+
+Options
+-------
+
+* **key**: A secret key to generate tokens (you should generate a random
+  string).
+
+* **name**: Cookie name (default: ``REMEMBERME``).
+
+* **lifetime**: Cookie lifetime (default: ``31536000`` ~ 1 year).
+
+* **path**: Cookie path (default: ``/``).
+
+* **domain**: Cookie domain (default: ``null`` = request domain).
+
+* **secure**: Cookie is secure (default: ``false``).
+
+* **httponly**: Cookie is HTTP only (default: ``true``).
+
+* **always_remember_me**: Enable remember me (default: ``false``).
+
+* **remember_me_parameter**: Name of the request parameter enabling remember_me
+  on login. To add the checkbox to the login form. You can find more
+  information in the `Symfony cookbook
+  <http://symfony.com/doc/current/cookbook/security/remember_me.html>`_
+  (default: ``_remember_me``).

+ 646 - 0
lib/silex/vendor/silex/silex/doc/providers/security.rst

@@ -0,0 +1,646 @@
+SecurityServiceProvider
+=======================
+
+The *SecurityServiceProvider* manages authentication and authorization for
+your applications.
+
+Parameters
+----------
+
+* **security.hide_user_not_found** (optional): Defines whether to hide user not
+  found exception or not. Defaults to ``true``.
+
+Services
+--------
+
+* **security**: The main entry point for the security provider. Use it to get
+  the current user token.
+
+* **security.authentication_manager**: An instance of
+  `AuthenticationProviderManager
+  <http://api.symfony.com/master/Symfony/Component/Security/Core/Authentication/AuthenticationProviderManager.html>`_,
+  responsible for authentication.
+
+* **security.access_manager**: An instance of `AccessDecisionManager
+  <http://api.symfony.com/master/Symfony/Component/Security/Core/Authorization/AccessDecisionManager.html>`_,
+  responsible for authorization.
+
+* **security.session_strategy**: Define the session strategy used for
+  authentication (default to a migration strategy).
+
+* **security.user_checker**: Checks user flags after authentication.
+
+* **security.last_error**: Returns the last authentication errors when given a
+  Request object.
+
+* **security.encoder_factory**: Defines the encoding strategies for user
+  passwords (default to use a digest algorithm for all users).
+
+* **security.encoder.digest**: The encoder to use by default for all users.
+
+.. note::
+
+    The service provider defines many other services that are used internally
+    but rarely need to be customized.
+
+Registering
+-----------
+
+.. code-block:: php
+
+    $app->register(new Silex\Provider\SecurityServiceProvider(), array(
+        'security.firewalls' => // see below
+    ));
+
+.. note::
+
+    The Symfony Security Component comes with the "fat" Silex archive but not
+    with the regular one. If you are using Composer, add it as a dependency:
+
+    .. code-block:: bash
+
+        composer require symfony/security
+
+.. caution::
+
+    The security features are only available after the Application has been
+    booted. So, if you want to use it outside of the handling of a request,
+    don't forget to call ``boot()`` first::
+
+        $application->boot();
+
+.. caution::
+
+    If you're using a form to authenticate users, you need to enable
+    ``SessionServiceProvider``.
+
+Usage
+-----
+
+The Symfony Security component is powerful. To learn more about it, read the
+`Symfony2 Security documentation
+<http://symfony.com/doc/2.3/book/security.html>`_.
+
+.. tip::
+
+    When a security configuration does not behave as expected, enable logging
+    (with the Monolog extension for instance) as the Security Component logs a
+    lot of interesting information about what it does and why.
+
+Below is a list of recipes that cover some common use cases.
+
+Accessing the current User
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The current user information is stored in a token that is accessible via the
+``security`` service::
+
+    $token = $app['security']->getToken();
+
+If there is no information about the user, the token is ``null``. If the user
+is known, you can get it with a call to ``getUser()``::
+
+    if (null !== $token) {
+        $user = $token->getUser();
+    }
+
+The user can be a string, an object with a ``__toString()`` method, or an
+instance of `UserInterface
+<http://api.symfony.com/master/Symfony/Component/Security/Core/User/UserInterface.html>`_.
+
+Securing a Path with HTTP Authentication
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The following configuration uses HTTP basic authentication to secure URLs
+under ``/admin/``::
+
+    $app['security.firewalls'] = array(
+        'admin' => array(
+            'pattern' => '^/admin',
+            'http' => true,
+            'users' => array(
+                // raw password is foo
+                'admin' => array('ROLE_ADMIN', '5FZ2Z8QIkA7UTZ4BYkoC+GsReLf569mSKDsfods6LYQ8t+a8EW9oaircfMpmaLbPBh4FOBiiFyLfuZmTSUwzZg=='),
+            ),
+        ),
+    );
+
+The ``pattern`` is a regular expression (it can also be a `RequestMatcher
+<http://api.symfony.com/master/Symfony/Component/HttpFoundation/RequestMatcher.html>`_
+instance); the ``http`` setting tells the security layer to use HTTP basic
+authentication and the ``users`` entry defines valid users.
+
+Each user is defined with the following information:
+
+* The role or an array of roles for the user (roles are strings beginning with
+  ``ROLE_`` and ending with anything you want);
+
+* The user encoded password.
+
+.. caution::
+
+    All users must at least have one role associated with them.
+
+The default configuration of the extension enforces encoded passwords. To
+generate a valid encoded password from a raw password, use the
+``security.encoder_factory`` service::
+
+    // find the encoder for a UserInterface instance
+    $encoder = $app['security.encoder_factory']->getEncoder($user);
+
+    // compute the encoded password for foo
+    $password = $encoder->encodePassword('foo', $user->getSalt());
+
+When the user is authenticated, the user stored in the token is an instance of
+`User
+<http://api.symfony.com/master/Symfony/Component/Security/Core/User/User.html>`_
+
+.. caution::
+
+    If you are using php-cgi under Apache, you need to add this configuration
+    to make things work correctly:
+
+    .. code-block:: apache
+
+        RewriteEngine On
+        RewriteCond %{HTTP:Authorization} ^(.+)$
+        RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
+        RewriteCond %{REQUEST_FILENAME} !-f
+        RewriteRule ^(.*)$ app.php [QSA,L]
+
+Securing a Path with a Form
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Using a form to authenticate users is very similar to the above configuration.
+Instead of using the ``http`` setting, use the ``form`` one and define these
+two parameters:
+
+* **login_path**: The login path where the user is redirected when they are
+  accessing a secured area without being authenticated so that they can enter
+  their credentials;
+
+* **check_path**: The check URL used by Symfony to validate the credentials of
+  the user.
+
+Here is how to secure all URLs under ``/admin/`` with a form::
+
+    $app['security.firewalls'] = array(
+        'admin' => array(
+            'pattern' => '^/admin/',
+            'form' => array('login_path' => '/login', 'check_path' => '/admin/login_check'),
+            'users' => array(
+                'admin' => array('ROLE_ADMIN', '5FZ2Z8QIkA7UTZ4BYkoC+GsReLf569mSKDsfods6LYQ8t+a8EW9oaircfMpmaLbPBh4FOBiiFyLfuZmTSUwzZg=='),
+            ),
+        ),
+    );
+
+Always keep in mind the following two golden rules:
+
+* The ``login_path`` path must always be defined **outside** the secured area
+  (or if it is in the secured area, the ``anonymous`` authentication mechanism
+  must be enabled -- see below);
+
+* The ``check_path`` path must always be defined **inside** the secured area.
+
+For the login form to work, create a controller like the following::
+
+    use Symfony\Component\HttpFoundation\Request;
+
+    $app->get('/login', function(Request $request) use ($app) {
+        return $app['twig']->render('login.html', array(
+            'error'         => $app['security.last_error']($request),
+            'last_username' => $app['session']->get('_security.last_username'),
+        ));
+    });
+
+The ``error`` and ``last_username`` variables contain the last authentication
+error and the last username entered by the user in case of an authentication
+error.
+
+Create the associated template:
+
+.. code-block:: jinja
+
+    <form action="{{ path('admin_login_check') }}" method="post">
+        {{ error }}
+        <input type="text" name="_username" value="{{ last_username }}" />
+        <input type="password" name="_password" value="" />
+        <input type="submit" />
+    </form>
+
+.. note::
+
+    The ``admin_login_check`` route is automatically defined by Silex and its
+    name is derived from the ``check_path`` value (all ``/`` are replaced with
+    ``_`` and the leading ``/`` is stripped).
+
+Defining more than one Firewall
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You are not limited to define one firewall per project.
+
+Configuring several firewalls is useful when you want to secure different
+parts of your website with different authentication strategies or for
+different users (like using an HTTP basic authentication for the website API
+and a form to secure your website administration area).
+
+It's also useful when you want to secure all URLs except the login form::
+
+    $app['security.firewalls'] = array(
+        'login' => array(
+            'pattern' => '^/login$',
+        ),
+        'secured' => array(
+            'pattern' => '^.*$',
+            'form' => array('login_path' => '/login', 'check_path' => '/login_check'),
+            'users' => array(
+                'admin' => array('ROLE_ADMIN', '5FZ2Z8QIkA7UTZ4BYkoC+GsReLf569mSKDsfods6LYQ8t+a8EW9oaircfMpmaLbPBh4FOBiiFyLfuZmTSUwzZg=='),
+            ),
+        ),
+    );
+
+The order of the firewall configurations is significant as the first one to
+match wins. The above configuration first ensures that the ``/login`` URL is
+not secured (no authentication settings), and then it secures all other URLs.
+
+.. tip::
+
+    You can toggle all registered authentication mechanisms for a particular
+    area on and off with the ``security`` flag::
+
+        $app['security.firewalls'] = array(
+            'api' => array(
+                'pattern' => '^/api',
+                'security' => $app['debug'] ? false : true,
+                'wsse' => true,
+
+                // ...
+            ),
+        );
+
+Adding a Logout
+~~~~~~~~~~~~~~~
+
+When using a form for authentication, you can let users log out if you add the
+``logout`` setting, where ``logout_path`` must match the main firewall
+pattern::
+
+    $app['security.firewalls'] = array(
+        'secured' => array(
+            'pattern' => '^/admin/',
+            'form' => array('login_path' => '/login', 'check_path' => '/admin/login_check'),
+            'logout' => array('logout_path' => '/admin/logout'),
+
+            // ...
+        ),
+    );
+
+A route is automatically generated, based on the configured path (all ``/``
+are replaced with ``_`` and the leading ``/`` is stripped):
+
+.. code-block:: jinja
+
+    <a href="{{ path('admin_logout') }}">Logout</a>
+
+Allowing Anonymous Users
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+When securing only some parts of your website, the user information are not
+available in non-secured areas. To make the user accessible in such areas,
+enabled the ``anonymous`` authentication mechanism::
+
+    $app['security.firewalls'] = array(
+        'unsecured' => array(
+            'anonymous' => true,
+
+            // ...
+        ),
+    );
+
+When enabling the anonymous setting, a user will always be accessible from the
+security context; if the user is not authenticated, it returns the ``anon.``
+string.
+
+Checking User Roles
+~~~~~~~~~~~~~~~~~~~
+
+To check if a user is granted some role, use the ``isGranted()`` method on the
+security context::
+
+    if ($app['security']->isGranted('ROLE_ADMIN')) {
+        // ...
+    }
+
+You can check roles in Twig templates too:
+
+.. code-block:: jinja
+
+    {% if is_granted('ROLE_ADMIN') %}
+        <a href="/secured?_switch_user=fabien">Switch to Fabien</a>
+    {% endif %}
+
+You can check if a user is "fully authenticated" (not an anonymous user for
+instance) with the special ``IS_AUTHENTICATED_FULLY`` role:
+
+.. code-block:: jinja
+
+    {% if is_granted('IS_AUTHENTICATED_FULLY') %}
+        <a href="{{ path('logout') }}">Logout</a>
+    {% else %}
+        <a href="{{ path('login') }}">Login</a>
+    {% endif %}
+
+Of course you will need to define a ``login`` route for this to work.
+
+.. tip::
+
+    Don't use the ``getRoles()`` method to check user roles.
+
+.. caution::
+
+    ``isGranted()`` throws an exception when no authentication information is
+    available (which is the case on non-secured area).
+
+Impersonating a User
+~~~~~~~~~~~~~~~~~~~~
+
+If you want to be able to switch to another user (without knowing the user
+credentials), enable the ``switch_user`` authentication strategy::
+
+    $app['security.firewalls'] = array(
+        'unsecured' => array(
+            'switch_user' => array('parameter' => '_switch_user', 'role' => 'ROLE_ALLOWED_TO_SWITCH'),
+
+            // ...
+        ),
+    );
+
+Switching to another user is now a matter of adding the ``_switch_user`` query
+parameter to any URL when logged in as a user who has the
+``ROLE_ALLOWED_TO_SWITCH`` role:
+
+.. code-block:: jinja
+
+    {% if is_granted('ROLE_ALLOWED_TO_SWITCH') %}
+        <a href="?_switch_user=fabien">Switch to user Fabien</a>
+    {% endif %}
+
+You can check that you are impersonating a user by checking the special
+``ROLE_PREVIOUS_ADMIN``. This is useful for instance to allow the user to
+switch back to their primary account:
+
+.. code-block:: jinja
+
+    {% if is_granted('ROLE_PREVIOUS_ADMIN') %}
+        You are an admin but you've switched to another user,
+        <a href="?_switch_user=_exit"> exit</a> the switch.
+    {% endif %}
+
+Defining a Role Hierarchy
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Defining a role hierarchy allows to automatically grant users some additional
+roles::
+
+    $app['security.role_hierarchy'] = array(
+        'ROLE_ADMIN' => array('ROLE_USER', 'ROLE_ALLOWED_TO_SWITCH'),
+    );
+
+With this configuration, all users with the ``ROLE_ADMIN`` role also
+automatically have the ``ROLE_USER`` and ``ROLE_ALLOWED_TO_SWITCH`` roles.
+
+Defining Access Rules
+~~~~~~~~~~~~~~~~~~~~~
+
+Roles are a great way to adapt the behavior of your website depending on
+groups of users, but they can also be used to further secure some areas by
+defining access rules::
+
+    $app['security.access_rules'] = array(
+        array('^/admin', 'ROLE_ADMIN', 'https'),
+        array('^.*$', 'ROLE_USER'),
+    );
+
+With the above configuration, users must have the ``ROLE_ADMIN`` to access the
+``/admin`` section of the website, and ``ROLE_USER`` for everything else.
+Furthermore, the admin section can only be accessible via HTTPS (if that's not
+the case, the user will be automatically redirected).
+
+.. note::
+
+    The first argument can also be a `RequestMatcher
+    <http://api.symfony.com/master/Symfony/Component/HttpFoundation/RequestMatcher.html>`_
+    instance.
+
+Defining a custom User Provider
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Using an array of users is simple and useful when securing an admin section of
+a personal website, but you can override this default mechanism with you own.
+
+The ``users`` setting can be defined as a service that returns an instance of
+`UserProviderInterface
+<http://api.symfony.com/master/Symfony/Component/Security/Core/User/UserProviderInterface.html>`_::
+
+    'users' => $app->share(function () use ($app) {
+        return new UserProvider($app['db']);
+    }),
+
+Here is a simple example of a user provider, where Doctrine DBAL is used to
+store the users::
+
+    use Symfony\Component\Security\Core\User\UserProviderInterface;
+    use Symfony\Component\Security\Core\User\UserInterface;
+    use Symfony\Component\Security\Core\User\User;
+    use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
+    use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
+    use Doctrine\DBAL\Connection;
+
+    class UserProvider implements UserProviderInterface
+    {
+        private $conn;
+
+        public function __construct(Connection $conn)
+        {
+            $this->conn = $conn;
+        }
+
+        public function loadUserByUsername($username)
+        {
+            $stmt = $this->conn->executeQuery('SELECT * FROM users WHERE username = ?', array(strtolower($username)));
+
+            if (!$user = $stmt->fetch()) {
+                throw new UsernameNotFoundException(sprintf('Username "%s" does not exist.', $username));
+            }
+
+            return new User($user['username'], $user['password'], explode(',', $user['roles']), true, true, true, true);
+        }
+
+        public function refreshUser(UserInterface $user)
+        {
+            if (!$user instanceof User) {
+                throw new UnsupportedUserException(sprintf('Instances of "%s" are not supported.', get_class($user)));
+            }
+
+            return $this->loadUserByUsername($user->getUsername());
+        }
+
+        public function supportsClass($class)
+        {
+            return $class === 'Symfony\Component\Security\Core\User\User';
+        }
+    }
+
+In this example, instances of the default ``User`` class are created for the
+users, but you can define your own class; the only requirement is that the
+class must implement `UserInterface
+<http://api.symfony.com/master/Symfony/Component/Security/Core/User/UserInterface.html>`_
+
+And here is the code that you can use to create the database schema and some
+sample users::
+
+    use Doctrine\DBAL\Schema\Table;
+
+    $schema = $app['db']->getSchemaManager();
+    if (!$schema->tablesExist('users')) {
+        $users = new Table('users');
+        $users->addColumn('id', 'integer', array('unsigned' => true, 'autoincrement' => true));
+        $users->setPrimaryKey(array('id'));
+        $users->addColumn('username', 'string', array('length' => 32));
+        $users->addUniqueIndex(array('username'));
+        $users->addColumn('password', 'string', array('length' => 255));
+        $users->addColumn('roles', 'string', array('length' => 255));
+
+        $schema->createTable($users);
+
+        $app['db']->insert('users', array(
+          'username' => 'fabien',
+          'password' => '5FZ2Z8QIkA7UTZ4BYkoC+GsReLf569mSKDsfods6LYQ8t+a8EW9oaircfMpmaLbPBh4FOBiiFyLfuZmTSUwzZg==',
+          'roles' => 'ROLE_USER'
+        ));
+
+        $app['db']->insert('users', array(
+          'username' => 'admin',
+          'password' => '5FZ2Z8QIkA7UTZ4BYkoC+GsReLf569mSKDsfods6LYQ8t+a8EW9oaircfMpmaLbPBh4FOBiiFyLfuZmTSUwzZg==',
+          'roles' => 'ROLE_ADMIN'
+        ));
+    }
+
+.. tip::
+
+    If you are using the Doctrine ORM, the Symfony bridge for Doctrine
+    provides a user provider class that is able to load users from your
+    entities.
+
+Defining a custom Encoder
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+By default, Silex uses the ``sha512`` algorithm to encode passwords.
+Additionally, the password is encoded multiple times and converted to base64.
+You can change these defaults by overriding the ``security.encoder.digest``
+service::
+
+    use Symfony\Component\Security\Core\Encoder\MessageDigestPasswordEncoder;
+
+    $app['security.encoder.digest'] = $app->share(function ($app) {
+        // use the sha1 algorithm
+        // don't base64 encode the password
+        // use only 1 iteration
+        return new MessageDigestPasswordEncoder('sha1', false, 1);
+    });
+
+Defining a custom Authentication Provider
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The Symfony Security component provides a lot of ready-to-use authentication
+providers (form, HTTP, X509, remember me, ...), but you can add new ones
+easily. To register a new authentication provider, create a service named
+``security.authentication_listener.factory.XXX`` where ``XXX`` is the name you want to
+use in your configuration::
+
+    $app['security.authentication_listener.factory.wsse'] = $app->protect(function ($name, $options) use ($app) {
+        // define the authentication provider object
+        $app['security.authentication_provider.'.$name.'.wsse'] = $app->share(function () use ($app) {
+            return new WsseProvider($app['security.user_provider.default'], __DIR__.'/security_cache');
+        });
+
+        // define the authentication listener object
+        $app['security.authentication_listener.'.$name.'.wsse'] = $app->share(function () use ($app) {
+            return new WsseListener($app['security'], $app['security.authentication_manager']);
+        });
+
+        return array(
+            // the authentication provider id
+            'security.authentication_provider.'.$name.'.wsse',
+            // the authentication listener id
+            'security.authentication_listener.'.$name.'.wsse',
+            // the entry point id
+            null,
+            // the position of the listener in the stack
+            'pre_auth'
+        );
+    });
+
+You can now use it in your configuration like any other built-in
+authentication provider::
+
+    $app->register(new Silex\Provider\SecurityServiceProvider(), array(
+        'security.firewalls' => array(
+            'default' => array(
+                'wsse' => true,
+
+                // ...
+            ),
+        ),
+    ));
+
+Instead of ``true``, you can also define an array of options that customize
+the behavior of your authentication factory; it will be passed as the second
+argument of your authentication factory (see above).
+
+This example uses the authentication provider classes as described in the
+Symfony `cookbook`_.
+
+Stateless Authentication
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+By default, a session cookie is created to persist the security context of
+the user. However, if you use certificates, HTTP authentication, WSSE and so
+on, the credentials are sent for each request. In that case, you can turn off
+persistence by activating the ``stateless`` authentication flag::
+
+    $app['security.firewalls'] = array(
+        'default' => array(
+            'stateless' => true,
+            'wsse' => true,
+
+            // ...
+        ),
+    );
+
+Traits
+------
+
+``Silex\Application\SecurityTrait`` adds the following shortcuts:
+
+* **user**: Returns the current user.
+
+* **encodePassword**: Encode a given password.
+
+.. code-block:: php
+
+    $user = $app->user();
+
+    $encoded = $app->encodePassword($user, 'foo');
+
+``Silex\Route\SecurityTrait`` adds the following methods to the controllers:
+
+* **secure**: Secures a controller for the given roles.
+
+.. code-block:: php
+
+    $app->get('/', function () {
+        // do something but only for admins
+    })->secure('ROLE_ADMIN');
+
+.. _cookbook: http://symfony.com/doc/current/cookbook/security/custom_authentication_provider.html

+ 76 - 0
lib/silex/vendor/silex/silex/doc/providers/serializer.rst

@@ -0,0 +1,76 @@
+SerializerServiceProvider
+===========================
+
+The *SerializerServiceProvider* provides a service for serializing objects.
+
+Parameters
+----------
+
+None.
+
+Services
+--------
+
+* **serializer**: An instance of `Symfony\\Component\\Serializer\\Serializer
+  <http://api.symfony.com/master/Symfony/Component/Serializer/Serializer.html>`_.
+
+* **serializer.encoders**: `Symfony\\Component\\Serializer\\Encoder\\JsonEncoder
+  <http://api.symfony.com/master/Symfony/Component/Serializer/Encoder/JsonEncoder.html>`_
+  and `Symfony\\Component\\Serializer\\Encoder\\XmlEncoder
+  <http://api.symfony.com/master/Symfony/Component/Serializer/Encoder/XmlEncoder.html>`_.
+
+* **serializer.normalizers**: `Symfony\\Component\\Serializer\\Normalizer\\CustomNormalizer
+  <http://api.symfony.com/master/Symfony/Component/Serializer/Normalizer/CustomNormalizer.html>`_
+  and `Symfony\\Component\\Serializer\\Normalizer\\GetSetMethodNormalizer
+  <http://api.symfony.com/master/Symfony/Component/Serializer/Normalizer/GetSetMethodNormalizer.html>`_.
+
+Registering
+-----------
+
+.. code-block:: php
+
+    $app->register(new Silex\Provider\SerializerServiceProvider());
+    
+.. note::
+
+    The *SerializerServiceProvider* relies on Symfony's `Serializer Component
+    <http://symfony.com/doc/current/components/serializer.html>`_, 
+    which comes with the "fat" Silex archive but not with the regular
+    one. If you are using Composer, add it as a dependency:
+
+    .. code-block:: bash
+
+        composer require symfony/serializer
+
+Usage
+-----
+
+The ``SerializerServiceProvider`` provider provides a ``serializer`` service:
+
+.. code-block:: php
+
+    use Silex\Application;
+    use Silex\Provider\SerializerServiceProvider;
+    use Symfony\Component\HttpFoundation\Response;
+
+    $app = new Application();
+
+    $app->register(new SerializerServiceProvider());
+
+    // only accept content types supported by the serializer via the assert method.
+    $app->get("/pages/{id}.{_format}", function ($id) use ($app) {
+        // assume a page_repository service exists that returns Page objects. The
+        // object returned has getters and setters exposing the state.
+        $page = $app['page_repository']->find($id);
+        $format = $app['request']->getRequestFormat();
+
+        if (!$page instanceof Page) {
+            $app->abort("No page found for id: $id");
+        }
+
+        return new Response($app['serializer']->serialize($page, $format), 200, array(
+            "Content-Type" => $app['request']->getMimeType($format)
+        ));
+    })->assert("_format", "xml|json")
+      ->assert("id", "\d+");
+

+ 116 - 0
lib/silex/vendor/silex/silex/doc/providers/service_controller.rst

@@ -0,0 +1,116 @@
+ServiceControllerServiceProvider
+================================
+
+As your Silex application grows, you may wish to begin organizing your
+controllers in a more formal fashion. Silex can use controller classes out of
+the box, but with a bit of work, your controllers can be created as services,
+giving you the full power of dependency injection and lazy loading.
+
+.. ::todo Link above to controller classes cookbook
+
+Why would I want to do this?
+----------------------------
+
+- Dependency Injection over Service Location
+
+  Using this method, you can inject the actual dependencies required by your
+  controller and gain total inversion of control, while still maintaining the
+  lazy loading of your controllers and its dependencies. Because your
+  dependencies are clearly defined, they are easily mocked, allowing you to test
+  your controllers in isolation.
+
+- Framework Independence
+
+  Using this method, your controllers start to become more independent of the
+  framework you are using. Carefully crafted, your controllers will become
+  reusable with multiple frameworks. By keeping careful control of your
+  dependencies, your controllers could easily become compatible with Silex,
+  Symfony (full stack) and Drupal, to name just a few.
+
+Parameters
+----------
+
+There are currently no parameters for the ``ServiceControllerServiceProvider``.
+
+Services
+--------
+
+There are no extra services provided, the ``ServiceControllerServiceProvider``
+simply extends the existing **resolver** service.
+
+Registering
+-----------
+
+.. code-block:: php
+
+    $app->register(new Silex\Provider\ServiceControllerServiceProvider());
+
+Usage
+-----
+
+In this slightly contrived example of a blog API, we're going to change the
+``/posts.json`` route to use a controller, that is defined as a service.
+
+.. code-block:: php
+
+    use Silex\Application;
+    use Demo\Repository\PostRepository;
+
+    $app = new Application();
+
+    $app['posts.repository'] = $app->share(function() {
+        return new PostRepository;
+    });
+
+    $app->get('/posts.json', function() use ($app) {
+        return $app->json($app['posts.repository']->findAll());
+    });
+
+Rewriting your controller as a service is pretty simple, create a Plain Ol' PHP
+Object with your ``PostRepository`` as a dependency, along with an
+``indexJsonAction`` method to handle the request. Although not shown in the
+example below, you can use type hinting and parameter naming to get the
+parameters you need, just like with standard Silex routes.
+
+If you are a TDD/BDD fan (and you should be), you may notice that this
+controller has well defined responsibilities and dependencies, and is easily
+tested/specced. You may also notice that the only external dependency is on
+``Symfony\Component\HttpFoundation\JsonResponse``, meaning this controller could
+easily be used in a Symfony (full stack) application, or potentially with other
+applications or frameworks that know how to handle a `Symfony/HttpFoundation
+<http://symfony.com/doc/master/components/http_foundation/introduction.html>`_
+``Response`` object.
+
+.. code-block:: php
+
+    namespace Demo\Controller;
+
+    use Demo\Repository\PostRepository;
+    use Symfony\Component\HttpFoundation\JsonResponse;
+
+    class PostController
+    {
+        protected $repo;
+
+        public function __construct(PostRepository $repo)
+        {
+            $this->repo = $repo;
+        }
+
+        public function indexJsonAction()
+        {
+            return new JsonResponse($this->repo->findAll());
+        }
+    }
+
+And lastly, define your controller as a service in the application, along with
+your route. The syntax in the route definition is the name of the service,
+followed by a single colon (:), followed by the method name.
+
+.. code-block:: php
+
+    $app['posts.controller'] = $app->share(function() use ($app) {
+        return new PostController($app['posts.repository']);
+    });
+
+    $app->get('/posts.json', "posts.controller:indexJsonAction");

+ 102 - 0
lib/silex/vendor/silex/silex/doc/providers/session.rst

@@ -0,0 +1,102 @@
+SessionServiceProvider
+======================
+
+The *SessionServiceProvider* provides a service for storing data persistently
+between requests.
+
+Parameters
+----------
+
+* **session.storage.save_path** (optional): The path for the
+  ``NativeFileSessionHandler``, defaults to the value of
+  ``sys_get_temp_dir()``.
+
+* **session.storage.options**: An array of options that is passed to the
+  constructor of the ``session.storage`` service.
+
+  In case of the default `NativeSessionStorage
+  <http://api.symfony.com/master/Symfony/Component/HttpFoundation/Session/Storage/NativeSessionStorage.html>`_,
+  the most useful options are:
+
+  * **name**: The cookie name (_SESS by default)
+  * **id**: The session id (null by default)
+  * **cookie_lifetime**: Cookie lifetime
+  * **cookie_path**: Cookie path
+  * **cookie_domain**: Cookie domain
+  * **cookie_secure**: Cookie secure (HTTPS)
+  * **cookie_httponly**: Whether the cookie is http only
+
+  However, all of these are optional. Default Sessions life time is 1800
+  seconds (30 minutes). To override this, set the ``lifetime`` option.
+
+  For a full list of available options, read the `PHP
+  <http://php.net/session.configuration>`_ official documentation.
+
+* **session.test**: Whether to simulate sessions or not (useful when writing
+  functional tests).
+
+Services
+--------
+
+* **session**: An instance of Symfony2's `Session
+  <http://api.symfony.com/master/Symfony/Component/HttpFoundation/Session/Session.html>`_.
+
+* **session.storage**: A service that is used for persistence of the session
+  data.
+
+* **session.storage.handler**: A service that is used by the
+  ``session.storage`` for data access. Defaults to a `NativeFileSessionHandler
+  <http://api.symfony.com/master/Symfony/Component/HttpFoundation/Session/Storage/Handler/NativeFileSessionHandler.html>`_
+  storage handler.
+
+Registering
+-----------
+
+.. code-block:: php
+
+    $app->register(new Silex\Provider\SessionServiceProvider());
+
+Usage
+-----
+
+The Session provider provides a ``session`` service. Here is an example that
+authenticates a user and creates a session for them::
+
+    use Symfony\Component\HttpFoundation\Response;
+
+    $app->get('/login', function () use ($app) {
+        $username = $app['request']->server->get('PHP_AUTH_USER', false);
+        $password = $app['request']->server->get('PHP_AUTH_PW');
+
+        if ('igor' === $username && 'password' === $password) {
+            $app['session']->set('user', array('username' => $username));
+            return $app->redirect('/account');
+        }
+
+        $response = new Response();
+        $response->headers->set('WWW-Authenticate', sprintf('Basic realm="%s"', 'site_login'));
+        $response->setStatusCode(401, 'Please sign in.');
+        return $response;
+    });
+
+    $app->get('/account', function () use ($app) {
+        if (null === $user = $app['session']->get('user')) {
+            return $app->redirect('/login');
+        }
+
+        return "Welcome {$user['username']}!";
+    });
+
+
+Custom Session Configurations
+-----------------------------
+
+If your system is using a custom session configuration (such as a redis handler
+from a PHP extension) then you need to disable the NativeFileSessionHandler by
+setting ``session.storage.handler`` to null. You will have to configure the
+``session.save_path`` ini setting yourself in that case.
+
+.. code-block:: php
+
+    $app['session.storage.handler'] = null;
+

+ 135 - 0
lib/silex/vendor/silex/silex/doc/providers/swiftmailer.rst

@@ -0,0 +1,135 @@
+SwiftmailerServiceProvider
+==========================
+
+The *SwiftmailerServiceProvider* provides a service for sending email through
+the `Swift Mailer <http://swiftmailer.org>`_ library.
+
+You can use the ``mailer`` service to send messages easily. By default, it
+will attempt to send emails through SMTP.
+
+Parameters
+----------
+
+* **swiftmailer.use_spool**: A boolean to specify whether or not to use the
+  memory spool, defaults to true. 
+* **swiftmailer.options**: An array of options for the default SMTP-based
+  configuration.
+
+  The following options can be set:
+
+  * **host**: SMTP hostname, defaults to 'localhost'.
+  * **port**: SMTP port, defaults to 25.
+  * **username**: SMTP username, defaults to an empty string.
+  * **password**: SMTP password, defaults to an empty string.
+  * **encryption**: SMTP encryption, defaults to null. Valid values are 'tls', 'ssl', or null (indicating no encryption).
+  * **auth_mode**: SMTP authentication mode, defaults to null. Valid values are 'plain', 'login', 'cram-md5', or null.
+
+  Example usage::
+
+    $app['swiftmailer.options'] = array(
+        'host' => 'host',
+        'port' => '25',
+        'username' => 'username',
+        'password' => 'password',
+        'encryption' => null,
+        'auth_mode' => null
+    );
+
+Services
+--------
+
+* **mailer**: The mailer instance.
+
+  Example usage::
+
+    $message = \Swift_Message::newInstance();
+
+    // ...
+
+    $app['mailer']->send($message);
+
+* **swiftmailer.transport**: The transport used for e-mail
+  delivery. Defaults to a ``Swift_Transport_EsmtpTransport``.
+
+* **swiftmailer.transport.buffer**: StreamBuffer used by
+  the transport.
+
+* **swiftmailer.transport.authhandler**: Authentication
+  handler used by the transport. Will try the following
+  by default: CRAM-MD5, login, plaintext.
+
+* **swiftmailer.transport.eventdispatcher**: Internal event
+  dispatcher used by Swiftmailer.
+
+Registering
+-----------
+
+.. code-block:: php
+
+    $app->register(new Silex\Provider\SwiftmailerServiceProvider());
+
+.. note::
+
+    SwiftMailer comes with the "fat" Silex archive but not with the regular
+    one. If you are using Composer, add it as a dependency:
+
+    .. code-block:: bash
+
+        composer require swiftmailer/swiftmailer
+
+Usage
+-----
+
+The Swiftmailer provider provides a ``mailer`` service::
+
+    $app->post('/feedback', function () use ($app) {
+        $request = $app['request'];
+
+        $message = \Swift_Message::newInstance()
+            ->setSubject('[YourSite] Feedback')
+            ->setFrom(array('noreply@yoursite.com'))
+            ->setTo(array('feedback@yoursite.com'))
+            ->setBody($request->get('message'));
+
+        $app['mailer']->send($message);
+
+        return new Response('Thank you for your feedback!', 201);
+    });
+
+Usage in commands
+~~~~~~~~~~~~~~~~~
+
+By default, the Swiftmailer provider sends the emails using the ``KernelEvents::TERMINATE``
+event, which is fired after the response has been sent. However, as this event
+isn't fired for console commands, your emails won't be sent.
+
+For that reason, if you send emails using a command console, it is recommended
+that you disable the use of the memory spool (before accessing ``$app['mailer']``)::
+
+    $app['swiftmailer.use_spool'] = false;
+
+Alternatively, you can just make sure to flush the message spool by hand before
+ending the command execution. To do so, use the following code::
+
+    $app['swiftmailer.spooltransport']
+        ->getSpool()
+        ->flushQueue($app['swiftmailer.transport'])
+    ;
+
+Traits
+------
+
+``Silex\Application\SwiftmailerTrait`` adds the following shortcuts:
+
+* **mail**: Sends an email.
+
+.. code-block:: php
+
+    $app->mail(\Swift_Message::newInstance()
+        ->setSubject('[YourSite] Feedback')
+        ->setFrom(array('noreply@yoursite.com'))
+        ->setTo(array('feedback@yoursite.com'))
+        ->setBody($request->get('message')));
+
+For more information, check out the `Swift Mailer documentation
+<http://swiftmailer.org>`_.

+ 185 - 0
lib/silex/vendor/silex/silex/doc/providers/translation.rst

@@ -0,0 +1,185 @@
+TranslationServiceProvider
+==========================
+
+The *TranslationServiceProvider* provides a service for translating your
+application into different languages.
+
+Parameters
+----------
+
+* **translator.domains** (optional): A mapping of domains/locales/messages.
+  This parameter contains the translation data for all languages and domains.
+
+* **locale** (optional): The locale for the translator. You will most likely
+  want to set this based on some request parameter. Defaults to ``en``.
+
+* **locale_fallbacks** (optional): Fallback locales for the translator. It will
+  be used when the current locale has no messages set. Defaults to ``en``.
+
+Services
+--------
+
+* **translator**: An instance of `Translator
+  <http://api.symfony.com/master/Symfony/Component/Translation/Translator.html>`_,
+  that is used for translation.
+
+* **translator.loader**: An instance of an implementation of the translation
+  `LoaderInterface
+  <http://api.symfony.com/master/Symfony/Component/Translation/Loader/LoaderInterface.html>`_,
+  defaults to an `ArrayLoader
+  <http://api.symfony.com/master/Symfony/Component/Translation/Loader/ArrayLoader.html>`_.
+
+* **translator.message_selector**: An instance of `MessageSelector
+  <http://api.symfony.com/master/Symfony/Component/Translation/MessageSelector.html>`_.
+
+Registering
+-----------
+
+.. code-block:: php
+
+    $app->register(new Silex\Provider\TranslationServiceProvider(), array(
+        'locale_fallbacks' => array('en'),
+    ));
+
+.. note::
+
+    The Symfony Translation Component comes with the "fat" Silex archive but
+    not with the regular one. If you are using Composer, add it as a
+    dependency:
+
+    .. code-block:: bash
+
+        composer require symfony/translation
+
+Usage
+-----
+
+The Translation provider provides a ``translator`` service and makes use of
+the ``translator.domains`` parameter::
+
+    $app['translator.domains'] = array(
+        'messages' => array(
+            'en' => array(
+                'hello'     => 'Hello %name%',
+                'goodbye'   => 'Goodbye %name%',
+            ),
+            'de' => array(
+                'hello'     => 'Hallo %name%',
+                'goodbye'   => 'Tschüss %name%',
+            ),
+            'fr' => array(
+                'hello'     => 'Bonjour %name%',
+                'goodbye'   => 'Au revoir %name%',
+            ),
+        ),
+        'validators' => array(
+            'fr' => array(
+                'This value should be a valid number.' => 'Cette valeur doit être un nombre.',
+            ),
+        ),
+    );
+
+    $app->get('/{_locale}/{message}/{name}', function ($message, $name) use ($app) {
+        return $app['translator']->trans($message, array('%name%' => $name));
+    });
+
+The above example will result in following routes:
+
+* ``/en/hello/igor`` will return ``Hello igor``.
+
+* ``/de/hello/igor`` will return ``Hallo igor``.
+
+* ``/fr/hello/igor`` will return ``Bonjour igor``.
+
+* ``/it/hello/igor`` will return ``Hello igor`` (because of the fallback).
+
+Traits
+------
+
+``Silex\Application\TranslationTrait`` adds the following shortcuts:
+
+* **trans**: Translates the given message.
+
+* **transChoice**: Translates the given choice message by choosing a
+  translation according to a number.
+
+.. code-block:: php
+
+    $app->trans('Hello World');
+
+    $app->transChoice('Hello World');
+
+Recipes
+-------
+
+YAML-based language files
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Having your translations in PHP files can be inconvenient. This recipe will
+show you how to load translations from external YAML files.
+
+First, add the Symfony2 ``Config`` and ``Yaml`` components as dependencies:
+
+.. code-block:: bash
+
+    composer require symfony/config symfony/yaml
+
+Next, you have to create the language mappings in YAML files. A naming you can
+use is ``locales/en.yml``. Just do the mapping in this file as follows:
+
+.. code-block:: yaml
+
+    hello: Hello %name%
+    goodbye: Goodbye %name%
+
+Then, register the ``YamlFileLoader`` on the ``translator`` and add all your
+translation files::
+
+    use Symfony\Component\Translation\Loader\YamlFileLoader;
+
+    $app['translator'] = $app->share($app->extend('translator', function($translator, $app) {
+        $translator->addLoader('yaml', new YamlFileLoader());
+
+        $translator->addResource('yaml', __DIR__.'/locales/en.yml', 'en');
+        $translator->addResource('yaml', __DIR__.'/locales/de.yml', 'de');
+        $translator->addResource('yaml', __DIR__.'/locales/fr.yml', 'fr');
+
+        return $translator;
+    }));
+
+XLIFF-based language files
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Just as you would do with YAML translation files, you first need to add the
+Symfony2 ``Config`` component as a dependency (see above for details).
+
+Then, similarly, create XLIFF files in your locales directory and add them to
+the translator::
+
+    $translator->addResource('xliff', __DIR__.'/locales/en.xlf', 'en');
+    $translator->addResource('xliff', __DIR__.'/locales/de.xlf', 'de');
+    $translator->addResource('xliff', __DIR__.'/locales/fr.xlf', 'fr');
+
+.. note::
+
+    The XLIFF loader is already pre-configured by the extension.
+
+Accessing translations in Twig templates
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Once loaded, the translation service provider is available from within Twig
+templates:
+
+.. code-block:: jinja
+
+    {{ app.translator.trans('translation_key') }}
+
+Moreover, when using the Twig bridge provided by Symfony (see
+:doc:`TwigServiceProvider </providers/twig>`), you will be allowed to translate
+strings in the Twig way:
+
+.. code-block:: jinja
+
+    {{ 'translation_key'|trans }}
+    {{ 'translation_key'|transchoice }}
+    {% trans %}translation_key{% endtrans %}

+ 161 - 0
lib/silex/vendor/silex/silex/doc/providers/twig.rst

@@ -0,0 +1,161 @@
+TwigServiceProvider
+===================
+
+The *TwigServiceProvider* provides integration with the `Twig
+<http://twig.sensiolabs.org/>`_ template engine.
+
+Parameters
+----------
+
+* **twig.path** (optional): Path to the directory containing twig template
+  files (it can also be an array of paths).
+
+* **twig.templates** (optional): An associative array of template names to
+  template contents. Use this if you want to define your templates inline.
+
+* **twig.options** (optional): An associative array of twig
+  options. Check out the `twig documentation <http://twig.sensiolabs.org/doc/api.html#environment-options>`_
+  for more information.
+
+* **twig.form.templates** (optional): An array of templates used to render
+  forms (only available when the ``FormServiceProvider`` is enabled).
+
+Services
+--------
+
+* **twig**: The ``Twig_Environment`` instance. The main way of
+  interacting with Twig.
+
+* **twig.loader**: The loader for Twig templates which uses the ``twig.path``
+  and the ``twig.templates`` options. You can also replace the loader
+  completely.
+
+Registering
+-----------
+
+.. code-block:: php
+
+    $app->register(new Silex\Provider\TwigServiceProvider(), array(
+        'twig.path' => __DIR__.'/views',
+    ));
+
+.. note::
+
+    Twig comes with the "fat" Silex archive but not with the regular one. If
+    you are using Composer, add it as a dependency:
+
+    .. code-block:: bash
+
+        composer require twig/twig
+
+Symfony2 Components Integration
+-------------------------------
+
+Symfony provides a Twig bridge that provides additional integration between
+some Symfony2 components and Twig. Add it as a dependency:
+
+.. code-block:: bash
+
+    composer require symfony/twig-bridge
+
+When present, the ``TwigServiceProvider`` will provide you with the following
+additional capabilities:
+
+* **UrlGeneratorServiceProvider**: If you are using the
+  ``UrlGeneratorServiceProvider``, you will have access to the ``path()`` and
+  ``url()`` functions. You can find more information in the `Symfony2 Routing
+  documentation
+  <http://symfony.com/doc/current/book/routing.html#generating-urls-from-a-template>`_.
+
+* **TranslationServiceProvider**: If you are using the
+  ``TranslationServiceProvider``, you will get the ``trans()`` and
+  ``transchoice()`` functions for translation in Twig templates. You can find
+  more information in the `Symfony2 Translation documentation
+  <http://symfony.com/doc/current/book/translation.html#twig-templates>`_.
+
+* **FormServiceProvider**: If you are using the ``FormServiceProvider``, you
+  will get a set of helpers for working with forms in templates. You can find
+  more information in the `Symfony2 Forms reference
+  <http://symfony.com/doc/current/reference/forms/twig_reference.html>`_.
+
+* **SecurityServiceProvider**: If you are using the
+  ``SecurityServiceProvider``, you will have access to the ``is_granted()``
+  function in templates. You can find more information in the `Symfony2
+  Security documentation
+  <http://symfony.com/doc/current/book/security.html#access-control-in-templates>`_.
+
+Usage
+-----
+
+The Twig provider provides a ``twig`` service::
+
+    $app->get('/hello/{name}', function ($name) use ($app) {
+        return $app['twig']->render('hello.twig', array(
+            'name' => $name,
+        ));
+    });
+
+This will render a file named ``views/hello.twig``.
+
+In any Twig template, the ``app`` variable refers to the Application object.
+So you can access any service from within your view. For example to access
+``$app['request']->getHost()``, just put this in your template:
+
+.. code-block:: jinja
+
+    {{ app.request.host }}
+
+A ``render`` function is also registered to help you render another controller
+from a template:
+
+.. code-block:: jinja
+
+    {{ render(app.request.baseUrl ~ '/sidebar') }}
+
+    {# or if you are also using the UrlGeneratorServiceProvider #}
+    {{ render(url('sidebar')) }}
+
+.. note::
+
+    You must prepend the ``app.request.baseUrl`` to render calls to ensure
+    that the render works when deployed into a sub-directory of the docroot.
+
+Traits
+------
+
+``Silex\Application\TwigTrait`` adds the following shortcuts:
+
+* **render**: Renders a view with the given parameters and returns a Response
+  object.
+
+.. code-block:: php
+
+    return $app->render('index.html', ['name' => 'Fabien']);
+
+    $response = new Response();
+    $response->setTtl(10);
+
+    return $app->render('index.html', ['name' => 'Fabien'], $response);
+
+.. code-block:: php
+
+    // stream a view
+    use Symfony\Component\HttpFoundation\StreamedResponse;
+
+    return $app->render('index.html', ['name' => 'Fabien'], new StreamedResponse());
+
+Customization
+-------------
+
+You can configure the Twig environment before using it by extending the
+``twig`` service::
+
+    $app['twig'] = $app->share($app->extend('twig', function($twig, $app) {
+        $twig->addGlobal('pi', 3.14);
+        $twig->addFilter('levenshtein', new \Twig_Filter_Function('levenshtein'));
+
+        return $twig;
+    }));
+
+For more information, check out the `official Twig documentation
+<http://twig.sensiolabs.org>`_.

+ 79 - 0
lib/silex/vendor/silex/silex/doc/providers/url_generator.rst

@@ -0,0 +1,79 @@
+UrlGeneratorServiceProvider
+===========================
+
+The *UrlGeneratorServiceProvider* provides a service for generating URLs for
+named routes.
+
+Parameters
+----------
+
+None.
+
+Services
+--------
+
+* **url_generator**: An instance of `UrlGenerator
+  <http://api.symfony.com/master/Symfony/Component/Routing/Generator/UrlGenerator.html>`_,
+  using the `RouteCollection
+  <http://api.symfony.com/master/Symfony/Component/Routing/RouteCollection.html>`_
+  that is provided through the ``routes`` service. It has a ``generate``
+  method, which takes the route name as an argument, followed by an array of
+  route parameters.
+
+Registering
+-----------
+
+.. code-block:: php
+
+    $app->register(new Silex\Provider\UrlGeneratorServiceProvider());
+
+Usage
+-----
+
+The UrlGenerator provider provides a ``url_generator`` service::
+
+    $app->get('/', function () {
+        return 'welcome to the homepage';
+    })
+    ->bind('homepage');
+
+    $app->get('/hello/{name}', function ($name) {
+        return "Hello $name!";
+    })
+    ->bind('hello');
+
+    $app->get('/navigation', function () use ($app) {
+        return '<a href="'.$app['url_generator']->generate('homepage').'">Home</a>'.
+               ' | '.
+               '<a href="'.$app['url_generator']->generate('hello', array('name' => 'Igor')).'">Hello Igor</a>';
+    });
+
+When using Twig, the service can be used like this:
+
+.. code-block:: jinja
+
+    {{ app.url_generator.generate('homepage') }}
+
+Moreover, if you have ``twig-bridge`` as a Composer dep, you will have access
+to the ``path()`` and ``url()`` functions:
+
+.. code-block:: jinja
+
+    {{ path('homepage') }}
+    {{ url('homepage') }} {# generates the absolute url http://example.org/ #}
+    {{ path('hello', {name: 'Fabien'}) }}
+    {{ url('hello', {name: 'Fabien'}) }} {# generates the absolute url http://example.org/hello/Fabien #}
+
+Traits
+------
+
+``Silex\Application\UrlGeneratorTrait`` adds the following shortcuts:
+
+* **path**: Generates a path.
+
+* **url**: Generates an absolute URL.
+
+.. code-block:: php
+
+    $app->path('homepage');
+    $app->url('homepage');

+ 221 - 0
lib/silex/vendor/silex/silex/doc/providers/validator.rst

@@ -0,0 +1,221 @@
+ValidatorServiceProvider
+========================
+
+The *ValidatorServiceProvider* provides a service for validating data. It is
+most useful when used with the *FormServiceProvider*, but can also be used
+standalone.
+
+Parameters
+----------
+
+none
+
+Services
+--------
+
+* **validator**: An instance of `Validator
+  <http://api.symfony.com/master/Symfony/Component/Validator/Validator.html>`_.
+
+* **validator.mapping.class_metadata_factory**: Factory for metadata loaders,
+  which can read validation constraint information from classes. Defaults to
+  StaticMethodLoader--ClassMetadataFactory.
+
+  This means you can define a static ``loadValidatorMetadata`` method on your
+  data class, which takes a ClassMetadata argument. Then you can set
+  constraints on this ClassMetadata instance.
+
+* **validator.validator_factory**: Factory for ConstraintValidators. Defaults
+  to a standard ``ConstraintValidatorFactory``. Mostly used internally by the
+  Validator.
+
+Registering
+-----------
+
+.. code-block:: php
+
+    $app->register(new Silex\Provider\ValidatorServiceProvider());
+
+.. note::
+
+    The Symfony Validator Component comes with the "fat" Silex archive but not
+    with the regular one. If you are using Composer, add it as a dependency:
+
+    .. code-block:: bash
+
+        composer require symfony/validator
+
+Usage
+-----
+
+The Validator provider provides a ``validator`` service.
+
+Validating Values
+~~~~~~~~~~~~~~~~~
+
+You can validate values directly using the ``validateValue`` validator
+method::
+
+    use Symfony\Component\Validator\Constraints as Assert;
+
+    $app->get('/validate/{email}', function ($email) use ($app) {
+        $errors = $app['validator']->validateValue($email, new Assert\Email());
+
+        if (count($errors) > 0) {
+            return (string) $errors;
+        } else {
+            return 'The email is valid';
+        }
+    });
+
+Validating Associative Arrays
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Validating associative arrays is like validating simple values, with a
+collection of constraints::
+
+    use Symfony\Component\Validator\Constraints as Assert;
+
+    class Book
+    {
+        public $title;
+        public $author;
+    }
+
+    class Author
+    {
+        public $first_name;
+        public $last_name;
+    }
+
+    $book = array(
+        'title' => 'My Book',
+        'author' => array(
+            'first_name' => 'Fabien',
+            'last_name'  => 'Potencier',
+        ),
+    );
+
+    $constraint = new Assert\Collection(array(
+        'title' => new Assert\Length(array('min' => 10)),
+        'author' => new Assert\Collection(array(
+            'first_name' => array(new Assert\NotBlank(), new Assert\Length(array('min' => 10))),
+            'last_name'  => new Assert\Length(array('min' => 10)),
+        )),
+    ));
+    $errors = $app['validator']->validateValue($book, $constraint);
+
+    if (count($errors) > 0) {
+        foreach ($errors as $error) {
+            echo $error->getPropertyPath().' '.$error->getMessage()."\n";
+        }
+    } else {
+        echo 'The book is valid';
+    }
+
+Validating Objects
+~~~~~~~~~~~~~~~~~~
+
+If you want to add validations to a class, you can define the constraint for
+the class properties and getters, and then call the ``validate`` method::
+
+    use Symfony\Component\Validator\Constraints as Assert;
+
+    $author = new Author();
+    $author->first_name = 'Fabien';
+    $author->last_name = 'Potencier';
+
+    $book = new Book();
+    $book->title = 'My Book';
+    $book->author = $author;
+
+    $metadata = $app['validator.mapping.class_metadata_factory']->getMetadataFor('Author');
+    $metadata->addPropertyConstraint('first_name', new Assert\NotBlank());
+    $metadata->addPropertyConstraint('first_name', new Assert\Length(array('min' => 10)));
+    $metadata->addPropertyConstraint('last_name', new Assert\Length(array('min' => 10)));
+
+    $metadata = $app['validator.mapping.class_metadata_factory']->getMetadataFor('Book');
+    $metadata->addPropertyConstraint('title', new Assert\Length(array('min' => 10)));
+    $metadata->addPropertyConstraint('author', new Assert\Valid());
+
+    $errors = $app['validator']->validate($book);
+
+    if (count($errors) > 0) {
+        foreach ($errors as $error) {
+            echo $error->getPropertyPath().' '.$error->getMessage()."\n";
+        }
+    } else {
+        echo 'The author is valid';
+    }
+
+You can also declare the class constraint by adding a static
+``loadValidatorMetadata`` method to your classes::
+
+    use Symfony\Component\Validator\Mapping\ClassMetadata;
+    use Symfony\Component\Validator\Constraints as Assert;
+
+    class Book
+    {
+        public $title;
+        public $author;
+
+        static public function loadValidatorMetadata(ClassMetadata $metadata)
+        {
+            $metadata->addPropertyConstraint('title', new Assert\Length(array('min' => 10)));
+            $metadata->addPropertyConstraint('author', new Assert\Valid());
+        }
+    }
+
+    class Author
+    {
+        public $first_name;
+        public $last_name;
+
+        static public function loadValidatorMetadata(ClassMetadata $metadata)
+        {
+            $metadata->addPropertyConstraint('first_name', new Assert\NotBlank());
+            $metadata->addPropertyConstraint('first_name', new Assert\Length(array('min' => 10)));
+            $metadata->addPropertyConstraint('last_name', new Assert\Length(array('min' => 10)));
+        }
+    }
+
+    $app->get('/validate/{email}', function ($email) use ($app) {
+        $author = new Author();
+        $author->first_name = 'Fabien';
+        $author->last_name = 'Potencier';
+
+        $book = new Book();
+        $book->title = 'My Book';
+        $book->author = $author;
+
+        $errors = $app['validator']->validate($book);
+
+        if (count($errors) > 0) {
+            foreach ($errors as $error) {
+                echo $error->getPropertyPath().' '.$error->getMessage()."\n";
+            }
+        } else {
+            echo 'The author is valid';
+        }
+    });
+
+.. note::
+
+    Use ``addGetterConstraint()`` to add constraints on getter methods and
+    ``addConstraint()`` to add constraints on the class itself.
+
+Translation
+~~~~~~~~~~~
+
+To be able to translate the error messages, you can use the translator
+provider and register the messages under the ``validators`` domain::
+
+    $app['translator.domains'] = array(
+        'validators' => array(
+            'fr' => array(
+                'This value should be a valid number.' => 'Cette valeur doit être un nombre.',
+            ),
+        ),
+    );
+
+For more information, consult the `Symfony2 Validation documentation
+<http://symfony.com/doc/master/book/validation.html>`_.

+ 271 - 0
lib/silex/vendor/silex/silex/doc/services.rst

@@ -0,0 +1,271 @@
+Services
+========
+
+Silex is not only a microframework. It is also a micro service container. It
+does this by extending `Pimple <http://pimple.sensiolabs.org>`_ which provides
+service goodness in just 44 NCLOC.
+
+Dependency Injection
+--------------------
+
+.. note::
+
+    You can skip this if you already know what Dependency Injection is.
+
+Dependency Injection is a design pattern where you pass dependencies to
+services instead of creating them from within the service or relying on
+globals. This generally leads to code that is decoupled, re-usable, flexible
+and testable.
+
+Here is an example of a class that takes a ``User`` object and stores it as a
+file in JSON format::
+
+    class JsonUserPersister
+    {
+        private $basePath;
+
+        public function __construct($basePath)
+        {
+            $this->basePath = $basePath;
+        }
+
+        public function persist(User $user)
+        {
+            $data = $user->getAttributes();
+            $json = json_encode($data);
+            $filename = $this->basePath.'/'.$user->id.'.json';
+            file_put_contents($filename, $json, LOCK_EX);
+        }
+    }
+
+In this simple example the dependency is the ``basePath`` property. It is
+passed to the constructor. This means you can create several independent
+instances with different base paths. Of course dependencies do not have to be
+simple strings. More often they are in fact other services.
+
+Container
+~~~~~~~~~
+
+A DIC or service container is responsible for creating and storing services.
+It can recursively create dependencies of the requested services and inject
+them. It does so lazily, which means a service is only created when you
+actually need it.
+
+Most containers are quite complex and are configured through XML or YAML
+files.
+
+Pimple is different.
+
+Pimple
+------
+
+Pimple is probably the simplest service container out there. It makes strong
+use of closures and implements the ArrayAccess interface.
+
+We will start off by creating a new instance of Pimple -- and because
+``Silex\Application`` extends ``Pimple`` all of this applies to Silex as
+well::
+
+    $container = new Pimple();
+
+or::
+
+    $app = new Silex\Application();
+
+Parameters
+~~~~~~~~~~
+
+You can set parameters (which are usually strings) by setting an array key on
+the container::
+
+    $app['some_parameter'] = 'value';
+
+The array key can be anything, by convention periods are used for
+namespacing::
+
+    $app['asset.host'] = 'http://cdn.mysite.com/';
+
+Reading parameter values is possible with the same syntax::
+
+    echo $app['some_parameter'];
+
+Service definitions
+~~~~~~~~~~~~~~~~~~~
+
+Defining services is no different than defining parameters. You just set an
+array key on the container to be a closure. However, when you retrieve the
+service, the closure is executed. This allows for lazy service creation::
+
+    $app['some_service'] = function () {
+        return new Service();
+    };
+
+And to retrieve the service, use::
+
+    $service = $app['some_service'];
+
+Every time you call ``$app['some_service']``, a new instance of the service is
+created.
+
+Shared services
+~~~~~~~~~~~~~~~
+
+You may want to use the same instance of a service across all of your code. In
+order to do that you can make a *shared* service::
+
+    $app['some_service'] = $app->share(function () {
+        return new Service();
+    });
+
+This will create the service on first invocation, and then return the existing
+instance on any subsequent access.
+
+Access container from closure
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+In many cases you will want to access the service container from within a
+service definition closure. For example when fetching services the current
+service depends on.
+
+Because of this, the container is passed to the closure as an argument::
+
+    $app['some_service'] = function ($app) {
+        return new Service($app['some_other_service'], $app['some_service.config']);
+    };
+
+Here you can see an example of Dependency Injection. ``some_service`` depends
+on ``some_other_service`` and takes ``some_service.config`` as configuration
+options. The dependency is only created when ``some_service`` is accessed, and
+it is possible to replace either of the dependencies by simply overriding
+those definitions.
+
+.. note::
+
+    This also works for shared services.
+
+Going back to our initial example, here's how we could use the container
+to manage its dependencies::
+
+    $app['user.persist_path'] = '/tmp/users';
+    $app['user.persister'] = $app->share(function ($app) {
+        return new JsonUserPersister($app['user.persist_path']);
+    });
+
+
+Protected closures
+~~~~~~~~~~~~~~~~~~
+
+Because the container sees closures as factories for services, it will always
+execute them when reading them.
+
+In some cases you will however want to store a closure as a parameter, so that
+you can fetch it and execute it yourself -- with your own arguments.
+
+This is why Pimple allows you to protect your closures from being executed, by
+using the ``protect`` method::
+
+    $app['closure_parameter'] = $app->protect(function ($a, $b) {
+        return $a + $b;
+    });
+
+    // will not execute the closure
+    $add = $app['closure_parameter'];
+
+    // calling it now
+    echo $add(2, 3);
+
+Note that protected closures do not get access to the container.
+
+Core services
+-------------
+
+Silex defines a range of services which can be used or replaced. You probably
+don't want to mess with most of them.
+
+* **request**: Contains the current request object, which is an instance of
+  `Request
+  <http://api.symfony.com/master/Symfony/Component/HttpFoundation/Request.html>`_.
+  It gives you access to ``GET``, ``POST`` parameters and lots more!
+
+  Example usage::
+
+    $id = $app['request']->get('id');
+
+  This is only available when a request is being served, you can only access
+  it from within a controller, an application before/after middlewares, or an
+  error handler.
+
+* **routes**: The `RouteCollection
+  <http://api.symfony.com/master/Symfony/Component/Routing/RouteCollection.html>`_
+  that is used internally. You can add, modify, read routes.
+
+* **controllers**: The ``Silex\ControllerCollection`` that is used internally.
+  Check the *Internals* chapter for more information.
+
+* **dispatcher**: The `EventDispatcher
+  <http://api.symfony.com/master/Symfony/Component/EventDispatcher/EventDispatcher.html>`_
+  that is used internally. It is the core of the Symfony2 system and is used
+  quite a bit by Silex.
+
+* **resolver**: The `ControllerResolver
+  <http://api.symfony.com/master/Symfony/Component/HttpKernel/Controller/ControllerResolver.html>`_
+  that is used internally. It takes care of executing the controller with the
+  right arguments.
+
+* **kernel**: The `HttpKernel
+  <http://api.symfony.com/master/Symfony/Component/HttpKernel/HttpKernel.html>`_
+  that is used internally. The HttpKernel is the heart of Symfony2, it takes a
+  Request as input and returns a Response as output.
+
+* **request_context**: The request context is a simplified representation of
+  the request that is used by the Router and the UrlGenerator.
+
+* **exception_handler**: The Exception handler is the default handler that is
+  used when you don't register one via the ``error()`` method or if your handler
+  does not return a Response. Disable it with
+  ``$app['exception_handler']->disable()``.
+
+* **logger**: A ``Psr\Log\LoggerInterface`` instance. By default, logging is
+  disabled as the value is set to ``null``. To enable logging you can either use
+  the ``MonologServiceProvider`` or define your own ``logger`` service that
+  conforms to the PSR logger interface.
+
+  In versions of Silex before 1.1 this must be a
+  ``Symfony\Component\HttpKernel\Log\LoggerInterface``.
+
+.. note::
+
+    All of these Silex core services are shared.
+
+Core parameters
+---------------
+
+* **request.http_port** (optional): Allows you to override the default port
+  for non-HTTPS URLs. If the current request is HTTP, it will always use the
+  current port.
+
+  Defaults to 80.
+
+  This parameter can be used by the ``UrlGeneratorProvider``.
+
+* **request.https_port** (optional): Allows you to override the default port
+  for HTTPS URLs. If the current request is HTTPS, it will always use the
+  current port.
+
+  Defaults to 443.
+
+  This parameter can be used by the ``UrlGeneratorProvider``.
+
+* **locale** (optional): The locale of the user. When set before any request
+  handling, it defines the default locale (``en`` by default). When a request
+  is being handled, it is automatically set according to the ``_locale``
+  request attribute of the current route.
+
+* **debug** (optional): Returns whether or not the application is running in
+  debug mode.
+
+  Defaults to false.
+
+* **charset** (optional): The charset to use for Responses.
+
+  Defaults to UTF-8.

+ 220 - 0
lib/silex/vendor/silex/silex/doc/testing.rst

@@ -0,0 +1,220 @@
+Testing
+=======
+
+Because Silex is built on top of Symfony2, it is very easy to write functional
+tests for your application. Functional tests are automated software tests that
+ensure that your code is working correctly. They go through the user
+interface, using a fake browser, and mimic the actions a user would do.
+
+Why
+---
+
+If you are not familiar with software tests, you may be wondering why you
+would need this. Every time you make a change to your application, you have to
+test it. This means going through all the pages and making sure they are still
+working. Functional tests save you a lot of time, because they enable you to
+test your application in usually under a second by running a single command.
+
+For more information on functional testing, unit testing, and automated
+software tests in general, check out `PHPUnit
+<https://github.com/sebastianbergmann/phpunit>`_ and `Bulat Shakirzyanov's
+talk on Clean Code
+<http://www.slideshare.net/avalanche123/clean-code-5609451>`_.
+
+PHPUnit
+-------
+
+`PHPUnit <https://github.com/sebastianbergmann/phpunit>`_ is the de-facto
+standard testing framework for PHP. It was built for writing unit tests, but
+it can be used for functional tests too. You write tests by creating a new
+class, that extends the ``PHPUnit_Framework_TestCase``. Your test cases are
+methods prefixed with ``test``::
+
+    class ContactFormTest extends \PHPUnit_Framework_TestCase
+    {
+        public function testInitialPage()
+        {
+            ...
+        }
+    }
+
+In your test cases, you do assertions on the state of what you are testing. In
+this case we are testing a contact form, so we would want to assert that the
+page loaded correctly and contains our form::
+
+        public function testInitialPage()
+        {
+            $statusCode = ...
+            $pageContent = ...
+
+            $this->assertEquals(200, $statusCode);
+            $this->assertContains('Contact us', $pageContent);
+            $this->assertContains('<form', $pageContent);
+        }
+
+Here you see some of the available assertions. There is a full list available
+in the `Writing Tests for PHPUnit
+<https://phpunit.de/manual/current/en/writing-tests-for-phpunit.html>`_
+section of the PHPUnit documentation.
+
+WebTestCase
+-----------
+
+Symfony2 provides a WebTestCase class that can be used to write functional
+tests. The Silex version of this class is ``Silex\WebTestCase``, and you can
+use it by making your test extend it::
+
+    use Silex\WebTestCase;
+
+    class ContactFormTest extends WebTestCase
+    {
+        ...
+    }
+
+.. note::
+
+    If you want to use the Symfony2 ``WebTestCase`` class you will need to
+    explicitly install its dependencies for your project:
+
+    .. code-block:: bash
+
+        composer require --dev symfony/browser-kit symfony/css-selector
+
+For your WebTestCase, you will have to implement a ``createApplication``
+method, which returns your application. It will probably look like this::
+
+        public function createApplication()
+        {
+            return require __DIR__.'/path/to/app.php';
+        }
+
+Make sure you do **not** use ``require_once`` here, as this method will be
+executed before every test.
+
+.. tip::
+
+    By default, the application behaves in the same way as when using it from
+    a browser. But when an error occurs, it is sometimes easier to get raw
+    exceptions instead of HTML pages. It is rather simple if you tweak the
+    application configuration in the ``createApplication()`` method like
+    follows::
+
+        public function createApplication()
+        {
+            $app = require __DIR__.'/path/to/app.php';
+            $app['debug'] = true;
+            $app['exception_handler']->disable();
+
+            return $app;
+        }
+
+.. tip::
+
+    If your application use sessions, set ``session.test`` to ``true`` to
+    simulate sessions::
+
+        public function createApplication()
+        {
+            // ...
+
+            $app['session.test'] = true;
+
+            // ...
+        }
+
+The WebTestCase provides a ``createClient`` method. A client acts as a
+browser, and allows you to interact with your application. Here's how it
+works::
+
+        public function testInitialPage()
+        {
+            $client = $this->createClient();
+            $crawler = $client->request('GET', '/');
+
+            $this->assertTrue($client->getResponse()->isOk());
+            $this->assertCount(1, $crawler->filter('h1:contains("Contact us")'));
+            $this->assertCount(1, $crawler->filter('form'));
+            ...
+        }
+
+There are several things going on here. You have both a ``Client`` and a
+``Crawler``.
+
+You can also access the application through ``$this->app``.
+
+Client
+------
+
+The client represents a browser. It holds your browsing history, cookies and
+more. The ``request`` method allows you to make a request to a page on your
+application.
+
+.. note::
+
+    You can find some documentation for it in `the client section of the
+    testing chapter of the Symfony2 documentation
+    <http://symfony.com/doc/current/book/testing.html#the-test-client>`_.
+
+Crawler
+-------
+
+The crawler allows you to inspect the content of a page. You can filter it
+using CSS expressions and lots more.
+
+.. note::
+
+    You can find some documentation for it in `the crawler section of the testing
+    chapter of the Symfony2 documentation
+    <http://symfony.com/doc/current/book/testing.html#the-test-client>`_.
+
+Configuration
+-------------
+
+The suggested way to configure PHPUnit is to create a ``phpunit.xml.dist``
+file, a ``tests`` folder and your tests in
+``tests/YourApp/Tests/YourTest.php``. The ``phpunit.xml.dist`` file should
+look like this:
+
+.. code-block:: xml
+
+    <?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"
+    >
+        <testsuites>
+            <testsuite name="YourApp Test Suite">
+                <directory>./tests/</directory>
+            </testsuite>
+        </testsuites>
+    </phpunit>
+
+You can also configure a bootstrap file for autoloading and whitelisting for
+code coverage reports.
+
+Your ``tests/YourApp/Tests/YourTest.php`` should look like this::
+
+    namespace YourApp\Tests;
+
+    use Silex\WebTestCase;
+
+    class YourTest extends WebTestCase
+    {
+        public function createApplication()
+        {
+            return require __DIR__.'/../../../app.php';
+        }
+
+        public function testFooBar()
+        {
+            ...
+        }
+    }
+
+Now, when running ``phpunit`` on the command line, your tests should run.

+ 768 - 0
lib/silex/vendor/silex/silex/doc/usage.rst

@@ -0,0 +1,768 @@
+Usage
+=====
+
+This chapter describes how to use Silex.
+
+Installation
+------------
+
+If you want to get started fast, `download`_ Silex as an archive and extract
+it, you should have the following directory structure:
+
+.. code-block:: text
+
+    ├── composer.json
+    ├── composer.lock
+    ├── vendor
+    │   └── ...
+    └── web
+        └── index.php
+
+If you want more flexibility, use Composer_ instead:
+
+.. code-block:: bash
+
+    composer require silex/silex:~1.2
+
+Bootstrap
+---------
+
+To bootstrap Silex, all you need to do is require the ``vendor/autoload.php``
+file and create an instance of ``Silex\Application``. After your controller
+definitions, call the ``run`` method on your application::
+
+    // web/index.php
+    require_once __DIR__.'/../vendor/autoload.php';
+
+    $app = new Silex\Application();
+
+    // ... definitions
+
+    $app->run();
+
+Then, you have to configure your web server (read the
+:doc:`dedicated chapter <web_servers>` for more information).
+
+.. tip::
+
+    When developing a website, you might want to turn on the debug mode to
+    ease debugging::
+
+        $app['debug'] = true;
+
+.. tip::
+
+    If your application is hosted behind a reverse proxy at address ``$ip``,
+    and you want Silex to trust the ``X-Forwarded-For*`` headers, you will
+    need to run your application like this::
+
+        use Symfony\Component\HttpFoundation\Request;
+
+        Request::setTrustedProxies(array($ip));
+        $app->run();
+
+Routing
+-------
+
+In Silex you define a route and the controller that is called when that
+route is matched.
+
+A route pattern consists of:
+
+* *Pattern*: The route pattern defines a path that points to a resource. The
+  pattern can include variable parts and you are able to set RegExp
+  requirements for them.
+
+* *Method*: One of the following HTTP methods: ``GET``, ``POST``, ``PUT``,
+  ``DELETE`` or ``PATCH``. This describes the interaction with the resource.
+  Commonly only ``GET`` and ``POST`` are used, but it is possible to use the
+  others as well.
+
+The controller is defined using a closure like this::
+
+    function () {
+        // ... do something
+    }
+
+Closures are anonymous functions that may import state from outside of their
+definition. This is different from globals, because the outer state does not
+have to be global. For instance, you could define a closure in a function and
+import local variables of that function.
+
+.. note::
+
+    Closures that do not import scope are referred to as lambdas. Because all
+    anonymous functions are instances of the ``Closure`` class in PHP, the
+    documentation will not make a distinction here.
+
+The return value of the closure becomes the content of the page.
+
+Example GET Route
+~~~~~~~~~~~~~~~~~
+
+Here is an example definition of a ``GET`` route::
+
+    $blogPosts = array(
+        1 => array(
+            'date'      => '2011-03-29',
+            'author'    => 'igorw',
+            'title'     => 'Using Silex',
+            'body'      => '...',
+        ),
+    );
+
+    $app->get('/blog', function () use ($blogPosts) {
+        $output = '';
+        foreach ($blogPosts as $post) {
+            $output .= $post['title'];
+            $output .= '<br />';
+        }
+
+        return $output;
+    });
+
+Visiting ``/blog`` will return a list of blog post titles. The ``use``
+statement means something different in this context. It tells the closure to
+import the ``$blogPosts`` variable from the outer scope. This allows you to
+use it from within the closure.
+
+Dynamic Routing
+~~~~~~~~~~~~~~~
+
+Now, you can create another controller for viewing individual blog posts::
+
+    $app->get('/blog/{id}', function (Silex\Application $app, $id) use ($blogPosts) {
+        if (!isset($blogPosts[$id])) {
+            $app->abort(404, "Post $id does not exist.");
+        }
+
+        $post = $blogPosts[$id];
+
+        return  "<h1>{$post['title']}</h1>".
+                "<p>{$post['body']}</p>";
+    });
+
+This route definition has a variable ``{id}`` part which is passed to the
+closure.
+
+The current ``Application`` is automatically injected by Silex to the Closure
+thanks to the type hinting.
+
+When the post does not exist, you are using ``abort()`` to stop the request
+early. It actually throws an exception, which you will see how to handle later
+on.
+
+Example POST Route
+~~~~~~~~~~~~~~~~~~
+
+POST routes signify the creation of a resource. An example for this is a
+feedback form. You will use the ``mail`` function to send an e-mail::
+
+    use Symfony\Component\HttpFoundation\Request;
+    use Symfony\Component\HttpFoundation\Response;
+
+    $app->post('/feedback', function (Request $request) {
+        $message = $request->get('message');
+        mail('feedback@yoursite.com', '[YourSite] Feedback', $message);
+
+        return new Response('Thank you for your feedback!', 201);
+    });
+
+It is pretty straightforward.
+
+.. note::
+
+    There is a :doc:`SwiftmailerServiceProvider <providers/swiftmailer>`
+    included that you can use instead of ``mail()``.
+
+The current ``request`` is automatically injected by Silex to the Closure
+thanks to the type hinting. It is an instance of
+Request_, so you can fetch variables using the request ``get`` method.
+
+Instead of returning a string you are returning an instance of Response_.
+This allows setting an HTTP status code, in this case it is set to
+``201 Created``.
+
+.. note::
+
+    Silex always uses a ``Response`` internally, it converts strings to
+    responses with status code ``200 Ok``.
+
+Other methods
+~~~~~~~~~~~~~
+
+You can create controllers for most HTTP methods. Just call one of these
+methods on your application: ``get``, ``post``, ``put``, ``delete``::
+
+    $app->put('/blog/{id}', function ($id) {
+        // ...
+    });
+
+    $app->delete('/blog/{id}', function ($id) {
+        // ...
+    });
+
+    $app->patch('/blog/{id}', function ($id) {
+        // ...
+    });
+
+.. tip::
+
+    Forms in most web browsers do not directly support the use of other HTTP
+    methods. To use methods other than GET and POST you can utilize a special
+    form field with a name of ``_method``. The form's ``method`` attribute must
+    be set to POST when using this field:
+
+    .. code-block:: html
+
+        <form action="/my/target/route/" method="post">
+            <!-- ... -->
+            <input type="hidden" id="_method" name="_method" value="PUT" />
+        </form>
+
+    If you are using Symfony Components 2.2+, you will need to explicitly
+    enable this method override::
+
+        use Symfony\Component\HttpFoundation\Request;
+
+        Request::enableHttpMethodParameterOverride();
+        $app->run();
+
+You can also call ``match``, which will match all methods. This can be
+restricted via the ``method`` method::
+
+    $app->match('/blog', function () {
+        // ...
+    });
+
+    $app->match('/blog', function () {
+        // ...
+    })
+    ->method('PATCH');
+
+    $app->match('/blog', function () {
+        // ...
+    })
+    ->method('PUT|POST');
+
+.. note::
+
+    The order in which the routes are defined is significant. The first
+    matching route will be used, so place more generic routes at the bottom.
+
+Route Variables
+~~~~~~~~~~~~~~~
+
+As it has been shown before you can define variable parts in a route like
+this::
+
+    $app->get('/blog/{id}', function ($id) {
+        // ...
+    });
+
+It is also possible to have more than one variable part, just make sure the
+closure arguments match the names of the variable parts::
+
+    $app->get('/blog/{postId}/{commentId}', function ($postId, $commentId) {
+        // ...
+    });
+
+While it's not recommended, you could also do this (note the switched
+arguments)::
+
+    $app->get('/blog/{postId}/{commentId}', function ($commentId, $postId) {
+        // ...
+    });
+
+You can also ask for the current Request and Application objects::
+
+    $app->get('/blog/{id}', function (Application $app, Request $request, $id) {
+        // ...
+    });
+
+.. note::
+
+    Note for the Application and Request objects, Silex does the injection
+    based on the type hinting and not on the variable name::
+
+        $app->get('/blog/{id}', function (Application $foo, Request $bar, $id) {
+            // ...
+        });
+
+Route Variable Converters
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Before injecting the route variables into the controller, you can apply some
+converters::
+
+    $app->get('/user/{id}', function ($id) {
+        // ...
+    })->convert('id', function ($id) { return (int) $id; });
+
+This is useful when you want to convert route variables to objects as it
+allows to reuse the conversion code across different controllers::
+
+    $userProvider = function ($id) {
+        return new User($id);
+    };
+
+    $app->get('/user/{user}', function (User $user) {
+        // ...
+    })->convert('user', $userProvider);
+
+    $app->get('/user/{user}/edit', function (User $user) {
+        // ...
+    })->convert('user', $userProvider);
+
+The converter callback also receives the ``Request`` as its second argument::
+
+    $callback = function ($post, Request $request) {
+        return new Post($request->attributes->get('slug'));
+    };
+
+    $app->get('/blog/{id}/{slug}', function (Post $post) {
+        // ...
+    })->convert('post', $callback);
+
+A converter can also be defined as a service. For example, here is a user
+converter based on Doctrine ObjectManager::
+
+    use Doctrine\Common\Persistence\ObjectManager;
+    use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
+
+    class UserConverter
+    {
+        private $om;
+
+        public function __construct(ObjectManager $om)
+        {
+            $this->om = $om;
+        }
+
+        public function convert($id)
+        {
+            if (null === $user = $this->om->find('User', (int) $id)) {
+                throw new NotFoundHttpException(sprintf('User %d does not exist', $id));
+            }
+
+            return $user;
+        }
+    }
+
+The service will now be registered in the application, and the
+convert method will be used as converter::
+
+    $app['converter.user'] = $app->share(function () {
+        return new UserConverter();
+    });
+
+    $app->get('/user/{user}', function (User $user) {
+        // ...
+    })->convert('user', 'converter.user:convert');
+
+.. warning::
+
+    Please note that the ability to use a service method (with the `a:b` notation) will be in version 1.2
+
+Requirements
+~~~~~~~~~~~~
+
+In some cases you may want to only match certain expressions. You can define
+requirements using regular expressions by calling ``assert`` on the
+``Controller`` object, which is returned by the routing methods.
+
+The following will make sure the ``id`` argument is numeric, since ``\d+``
+matches any amount of digits::
+
+    $app->get('/blog/{id}', function ($id) {
+        // ...
+    })
+    ->assert('id', '\d+');
+
+You can also chain these calls::
+
+    $app->get('/blog/{postId}/{commentId}', function ($postId, $commentId) {
+        // ...
+    })
+    ->assert('postId', '\d+')
+    ->assert('commentId', '\d+');
+
+Default Values
+~~~~~~~~~~~~~~
+
+You can define a default value for any route variable by calling ``value`` on
+the ``Controller`` object::
+
+    $app->get('/{pageName}', function ($pageName) {
+        // ...
+    })
+    ->value('pageName', 'index');
+
+This will allow matching ``/``, in which case the ``pageName`` variable will
+have the value ``index``.
+
+Named Routes
+~~~~~~~~~~~~
+
+Some providers (such as ``UrlGeneratorProvider``) can make use of named
+routes. By default Silex will generate a route name for you, that cannot
+really be used. You can give a route a name by calling ``bind`` on the
+``Controller`` object that is returned by the routing methods::
+
+    $app->get('/', function () {
+        // ...
+    })
+    ->bind('homepage');
+
+    $app->get('/blog/{id}', function ($id) {
+        // ...
+    })
+    ->bind('blog_post');
+
+.. note::
+
+    It only makes sense to name routes if you use providers that make use of
+    the ``RouteCollection``.
+
+Controllers in Classes
+~~~~~~~~~~~~~~~~~~~~~~
+
+If you don't want to use anonymous functions, you can also define your
+controllers as methods. By using the ``ControllerClass::methodName`` syntax,
+you can tell Silex to lazily create the controller object for you::
+
+    $app->get('/', 'Acme\\Foo::bar');
+
+    use Silex\Application;
+    use Symfony\Component\HttpFoundation\Request;
+
+    namespace Acme
+    {
+        class Foo
+        {
+            public function bar(Request $request, Application $app)
+            {
+                // ...
+            }
+        }
+    }
+
+This will load the ``Acme\Foo`` class on demand, create an instance and call
+the ``bar`` method to get the response. You can use ``Request`` and
+``Silex\Application`` type hints to get ``$request`` and ``$app`` injected.
+
+For an even stronger separation between Silex and your controllers, you can
+:doc:`define your controllers as services <providers/service_controller>`.
+
+Global Configuration
+--------------------
+
+If a controller setting must be applied to all controllers (a converter, a
+middleware, a requirement, or a default value), you can configure it on
+``$app['controllers']``, which holds all application controllers::
+
+    $app['controllers']
+        ->value('id', '1')
+        ->assert('id', '\d+')
+        ->requireHttps()
+        ->method('get')
+        ->convert('id', function () { /* ... */ })
+        ->before(function () { /* ... */ })
+    ;
+
+These settings are applied to already registered controllers and they become
+the defaults for new controllers.
+
+.. note::
+
+    The global configuration does not apply to controller providers you might
+    mount as they have their own global configuration (read the
+    :doc:`dedicated chapter<organizing_controllers>` for more information).
+
+.. warning::
+
+    The converters are run for **all** registered controllers.
+
+Error Handlers
+--------------
+
+If some part of your code throws an exception you will want to display some
+kind of error page to the user. This is what error handlers do. You can also
+use them to do additional things, such as logging.
+
+To register an error handler, pass a closure to the ``error`` method which
+takes an ``Exception`` argument and returns a response::
+
+    use Symfony\Component\HttpFoundation\Response;
+
+    $app->error(function (\Exception $e, $code) {
+        return new Response('We are sorry, but something went terribly wrong.');
+    });
+
+You can also check for specific errors by using the ``$code`` argument, and
+handle them differently::
+
+    use Symfony\Component\HttpFoundation\Response;
+
+    $app->error(function (\Exception $e, $code) {
+        switch ($code) {
+            case 404:
+                $message = 'The requested page could not be found.';
+                break;
+            default:
+                $message = 'We are sorry, but something went terribly wrong.';
+        }
+
+        return new Response($message);
+    });
+
+.. note::
+
+    As Silex ensures that the Response status code is set to the most
+    appropriate one depending on the exception, setting the status on the
+    response won't work. If you want to overwrite the status code (which you
+    should not without a good reason), set the ``X-Status-Code`` header::
+
+        return new Response('Error', 404 /* ignored */, array('X-Status-Code' => 200));
+
+You can restrict an error handler to only handle some Exception classes by
+setting a more specific type hint for the Closure argument::
+
+    $app->error(function (\LogicException $e, $code) {
+        // this handler will only handle \LogicException exceptions
+        // and exceptions that extends \LogicException
+    });
+
+If you want to set up logging you can use a separate error handler for that.
+Just make sure you register it before the response error handlers, because
+once a response is returned, the following handlers are ignored.
+
+.. note::
+
+    Silex ships with a provider for Monolog_ which handles logging of errors.
+    Check out the *Providers* :doc:`chapter <providers/monolog>` for details.
+
+.. tip::
+
+    Silex comes with a default error handler that displays a detailed error
+    message with the stack trace when **debug** is true, and a simple error
+    message otherwise. Error handlers registered via the ``error()`` method
+    always take precedence but you can keep the nice error messages when debug
+    is turned on like this::
+
+        use Symfony\Component\HttpFoundation\Response;
+
+        $app->error(function (\Exception $e, $code) use ($app) {
+            if ($app['debug']) {
+                return;
+            }
+
+            // ... logic to handle the error and return a Response
+        });
+
+The error handlers are also called when you use ``abort`` to abort a request
+early::
+
+    $app->get('/blog/{id}', function (Silex\Application $app, $id) use ($blogPosts) {
+        if (!isset($blogPosts[$id])) {
+            $app->abort(404, "Post $id does not exist.");
+        }
+
+        return new Response(...);
+    });
+
+Redirects
+---------
+
+You can redirect to another page by returning a redirect response, which you
+can create by calling the ``redirect`` method::
+
+    $app->get('/', function () use ($app) {
+        return $app->redirect('/hello');
+    });
+
+This will redirect from ``/`` to ``/hello``.
+
+Forwards
+--------
+
+When you want to delegate the rendering to another controller, without a
+round-trip to the browser (as for a redirect), use an internal sub-request::
+
+    use Symfony\Component\HttpFoundation\Request;
+    use Symfony\Component\HttpKernel\HttpKernelInterface;
+
+    $app->get('/', function () use ($app) {
+        // redirect to /hello
+        $subRequest = Request::create('/hello', 'GET');
+
+        return $app->handle($subRequest, HttpKernelInterface::SUB_REQUEST);
+    });
+
+.. tip::
+
+    If you are using ``UrlGeneratorProvider``, you can also generate the URI::
+
+        $request = Request::create($app['url_generator']->generate('hello'), 'GET');
+
+There's some more things that you need to keep in mind though. In most cases you
+will want to forward some parts of the current master request to the sub-request.
+That includes: Cookies, server information, session.
+Read more on :doc:`how to make sub-requests <cookbook/sub_requests>`.
+
+JSON
+----
+
+If you want to return JSON data, you can use the ``json`` helper method.
+Simply pass it your data, status code and headers, and it will create a JSON
+response for you::
+
+    $app->get('/users/{id}', function ($id) use ($app) {
+        $user = getUser($id);
+
+        if (!$user) {
+            $error = array('message' => 'The user was not found.');
+
+            return $app->json($error, 404);
+        }
+
+        return $app->json($user);
+    });
+
+Streaming
+---------
+
+It's possible to create a streaming response, which is important in cases when
+you cannot buffer the data being sent::
+
+    $app->get('/images/{file}', function ($file) use ($app) {
+        if (!file_exists(__DIR__.'/images/'.$file)) {
+            return $app->abort(404, 'The image was not found.');
+        }
+
+        $stream = function () use ($file) {
+            readfile($file);
+        };
+
+        return $app->stream($stream, 200, array('Content-Type' => 'image/png'));
+    });
+
+If you need to send chunks, make sure you call ``ob_flush`` and ``flush``
+after every chunk::
+
+    $stream = function () {
+        $fh = fopen('http://www.example.com/', 'rb');
+        while (!feof($fh)) {
+          echo fread($fh, 1024);
+          ob_flush();
+          flush();
+        }
+        fclose($fh);
+    };
+
+Sending a file
+--------------
+
+If you want to return a file, you can use the ``sendFile`` helper method.
+It eases returning files that would otherwise not be publicly available. Simply
+pass it your file path, status code, headers and the content disposition and it
+will create a ``BinaryFileResponse`` based response for you::
+
+    $app->get('/files/{path}', function ($path) use ($app) {
+        if (!file_exists('/base/path/' . $path)) {
+            $app->abort(404);
+        }
+
+        return $app->sendFile('/base/path/' . $path);
+    });
+
+To further customize the response before returning it, check the API doc for
+`Symfony\Component\HttpFoundation\BinaryFileResponse
+<http://api.symfony.com/master/Symfony/Component/HttpFoundation/BinaryFileResponse.html>`_::
+
+    return $app
+        ->sendFile('/base/path/' . $path)
+        ->setContentDisposition(ResponseHeaderBag::DISPOSITION_ATTACHMENT, 'pic.jpg')
+    ;
+
+.. note::
+
+    HttpFoundation 2.2 or greater is required for this feature to be available.
+
+Traits
+------
+
+Silex comes with PHP traits that define shortcut methods.
+
+.. caution::
+
+    You need to use PHP 5.4 or later to benefit from this feature.
+
+Almost all built-in service providers have some corresponding PHP traits. To
+use them, define your own Application class and include the traits you want::
+
+    use Silex\Application;
+
+    class MyApplication extends Application
+    {
+        use Application\TwigTrait;
+        use Application\SecurityTrait;
+        use Application\FormTrait;
+        use Application\UrlGeneratorTrait;
+        use Application\SwiftmailerTrait;
+        use Application\MonologTrait;
+        use Application\TranslationTrait;
+    }
+
+You can also define your own Route class and use some traits::
+
+    use Silex\Route;
+
+    class MyRoute extends Route
+    {
+        use Route\SecurityTrait;
+    }
+
+To use your newly defined route, override the ``$app['route_class']``
+setting::
+
+    $app['route_class'] = 'MyRoute';
+
+Read each provider chapter to learn more about the added methods.
+
+Security
+--------
+
+Make sure to protect your application against attacks.
+
+Escaping
+~~~~~~~~
+
+When outputting any user input (either route variables GET/POST variables
+obtained from the request), you will have to make sure to escape it correctly,
+to prevent Cross-Site-Scripting attacks.
+
+* **Escaping HTML**: PHP provides the ``htmlspecialchars`` function for this.
+  Silex provides a shortcut ``escape`` method::
+
+      $app->get('/name', function (Silex\Application $app) {
+          $name = $app['request']->get('name');
+          return "You provided the name {$app->escape($name)}.";
+      });
+
+  If you use the Twig template engine you should use its escaping or even
+  auto-escaping mechanisms.
+
+* **Escaping JSON**: If you want to provide data in JSON format you should
+  use the Silex ``json`` function::
+
+      $app->get('/name.json', function (Silex\Application $app) {
+          $name = $app['request']->get('name');
+          return $app->json(array('name' => $name));
+      });
+
+.. _download: http://silex.sensiolabs.org/download
+.. _Composer: http://getcomposer.org/
+.. _Request: http://api.symfony.com/master/Symfony/Component/HttpFoundation/Request.html
+.. _Response: http://api.symfony.com/master/Symfony/Component/HttpFoundation/Response.html
+.. _Monolog: https://github.com/Seldaek/monolog

+ 158 - 0
lib/silex/vendor/silex/silex/doc/web_servers.rst

@@ -0,0 +1,158 @@
+Webserver Configuration
+=======================
+
+Apache
+------
+
+If you are using Apache, make sure ``mod_rewrite`` is enabled and use the
+following ``.htaccess`` file:
+
+.. code-block:: apache
+
+    <IfModule mod_rewrite.c>
+        Options -MultiViews
+
+        RewriteEngine On
+        #RewriteBase /path/to/app
+        RewriteCond %{REQUEST_FILENAME} !-f
+        RewriteRule ^ index.php [QSA,L]
+    </IfModule>
+
+.. note::
+
+    If your site is not at the webroot level you will have to uncomment the
+    ``RewriteBase`` statement and adjust the path to point to your directory,
+    relative from the webroot.
+
+Alternatively, if you use Apache 2.2.16 or higher, you can use the
+`FallbackResource directive`_ so make your .htaccess even easier:
+
+.. code-block:: apache
+
+    FallbackResource /index.php
+
+.. note::
+
+    If your site is not at the webroot level you will have to adjust the path to
+    point to your directory, relative from the webroot.
+
+nginx
+-----
+
+If you are using nginx, configure your vhost to forward non-existent
+resources to ``index.php``:
+
+.. code-block:: nginx
+
+    server {
+        #site root is redirected to the app boot script
+        location = / {
+            try_files @site @site;
+        }
+
+        #all other locations try other files first and go to our front controller if none of them exists
+        location / {
+            try_files $uri $uri/ @site;
+        }
+
+        #return 404 for all php files as we do have a front controller
+        location ~ \.php$ {
+            return 404;
+        }
+
+        location @site {
+            # the ubuntu default
+            fastcgi_pass   unix:/var/run/php5-fpm.sock;
+            # for running on centos
+            #fastcgi_pass   unix:/var/run/php-fpm/www.sock;
+            
+            include fastcgi_params;
+            fastcgi_param  SCRIPT_FILENAME $document_root/index.php;
+            #uncomment when running via https
+            #fastcgi_param HTTPS on;
+        }
+    }
+
+IIS
+---
+
+If you are using the Internet Information Services from Windows, you can use
+this sample ``web.config`` file:
+
+.. code-block:: xml
+
+    <?xml version="1.0"?>
+    <configuration>
+        <system.webServer>
+            <defaultDocument>
+                <files>
+                    <clear />
+                    <add value="index.php" />
+                </files>
+            </defaultDocument>
+            <rewrite>
+                <rules>
+                    <rule name="Silex Front Controller" stopProcessing="true">
+                        <match url="^(.*)$" ignoreCase="false" />
+                        <conditions logicalGrouping="MatchAll">
+                            <add input="{REQUEST_FILENAME}" matchType="IsFile" ignoreCase="false" negate="true" />
+                        </conditions>
+                        <action type="Rewrite" url="index.php" appendQueryString="true" />
+                    </rule>
+                </rules>
+            </rewrite>
+        </system.webServer>
+    </configuration>
+
+Lighttpd
+--------
+
+If you are using lighttpd, use this sample ``simple-vhost`` as a starting
+point:
+
+.. code-block:: lighttpd
+
+    server.document-root = "/path/to/app"
+
+    url.rewrite-once = (
+        # configure some static files
+        "^/assets/.+" => "$0",
+        "^/favicon\.ico$" => "$0",
+
+        "^(/[^\?]*)(\?.*)?" => "/index.php$1$2"
+    )
+
+.. _FallbackResource directive: http://www.adayinthelifeof.nl/2012/01/21/apaches-fallbackresource-your-new-htaccess-command/
+
+PHP 5.4
+-------
+
+PHP 5.4 ships with a built-in webserver for development. This server allows
+you to run silex without any configuration. However, in order to serve static
+files, you'll have to make sure your front controller returns false in that
+case::
+
+    // web/index.php
+
+    $filename = __DIR__.preg_replace('#(\?.*)$#', '', $_SERVER['REQUEST_URI']);
+    if (php_sapi_name() === 'cli-server' && is_file($filename)) {
+        return false;
+    }
+
+    $app = require __DIR__.'/../src/app.php';
+    $app->run();
+
+
+Assuming your front controller is at ``web/index.php``, you can start the
+server from the command-line with this command:
+
+.. code-block:: text
+
+    $ php -S localhost:8080 -t web web/index.php
+
+Now the application should be running at ``http://localhost:8080``.
+
+.. note::
+
+    This server is for development only. It is **not** recommended to use it
+    in production.

+ 24 - 0
lib/silex/vendor/silex/silex/phpunit.xml.dist

@@ -0,0 +1,24 @@
+<?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="Silex Test Suite">
+            <directory>./tests/Silex/</directory>
+        </testsuite>
+    </testsuites>
+    <filter>
+        <whitelist>
+            <directory>./src</directory>
+        </whitelist>
+    </filter>
+</phpunit>

+ 561 - 0
lib/silex/vendor/silex/silex/src/Silex/Application.php

@@ -0,0 +1,561 @@
+<?php
+
+/*
+ * This file is part of the Silex framework.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Silex;
+
+use Symfony\Component\HttpFoundation\BinaryFileResponse;
+use Symfony\Component\HttpKernel\HttpKernel;
+use Symfony\Component\HttpKernel\HttpKernelInterface;
+use Symfony\Component\HttpKernel\TerminableInterface;
+use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
+use Symfony\Component\HttpKernel\Event\GetResponseEvent;
+use Symfony\Component\HttpKernel\Event\PostResponseEvent;
+use Symfony\Component\HttpKernel\EventListener\ResponseListener;
+use Symfony\Component\HttpKernel\EventListener\RouterListener;
+use Symfony\Component\HttpKernel\Exception\HttpException;
+use Symfony\Component\HttpKernel\KernelEvents;
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpFoundation\RequestStack;
+use Symfony\Component\HttpFoundation\Response;
+use Symfony\Component\HttpFoundation\RedirectResponse;
+use Symfony\Component\HttpFoundation\StreamedResponse;
+use Symfony\Component\HttpFoundation\JsonResponse;
+use Symfony\Component\Routing\RouteCollection;
+use Symfony\Component\Routing\RequestContext;
+use Silex\EventListener\LocaleListener;
+use Silex\EventListener\MiddlewareListener;
+use Silex\EventListener\ConverterListener;
+use Silex\EventListener\StringToResponseListener;
+
+/**
+ * The Silex framework class.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class Application extends \Pimple implements HttpKernelInterface, TerminableInterface
+{
+    const VERSION = '1.2.5';
+
+    const EARLY_EVENT = 512;
+    const LATE_EVENT  = -512;
+
+    protected $providers = array();
+    protected $booted = false;
+
+    /**
+     * Instantiate a new Application.
+     *
+     * Objects and parameters can be passed as argument to the constructor.
+     *
+     * @param array $values The parameters or objects.
+     */
+    public function __construct(array $values = array())
+    {
+        parent::__construct();
+
+        $app = $this;
+
+        $this['logger'] = null;
+
+        $this['routes'] = $this->share(function () {
+            return new RouteCollection();
+        });
+
+        $this['controllers'] = $this->share(function () use ($app) {
+            return $app['controllers_factory'];
+        });
+
+        $this['controllers_factory'] = function () use ($app) {
+            return new ControllerCollection($app['route_factory']);
+        };
+
+        $this['route_class'] = 'Silex\\Route';
+        $this['route_factory'] = function () use ($app) {
+            return new $app['route_class']();
+        };
+
+        $this['exception_handler'] = $this->share(function () use ($app) {
+            return new ExceptionHandler($app['debug']);
+        });
+
+        $this['dispatcher_class'] = 'Symfony\\Component\\EventDispatcher\\EventDispatcher';
+        $this['dispatcher'] = $this->share(function () use ($app) {
+            $dispatcher = new $app['dispatcher_class']();
+
+            $urlMatcher = new LazyUrlMatcher(function () use ($app) {
+                return $app['url_matcher'];
+            });
+            $dispatcher->addSubscriber(new RouterListener($urlMatcher, $app['request_context'], $app['logger'], $app['request_stack']));
+            $dispatcher->addSubscriber(new LocaleListener($app, $urlMatcher, $app['request_stack']));
+            if (isset($app['exception_handler'])) {
+                $dispatcher->addSubscriber($app['exception_handler']);
+            }
+            $dispatcher->addSubscriber(new ResponseListener($app['charset']));
+            $dispatcher->addSubscriber(new MiddlewareListener($app));
+            $dispatcher->addSubscriber(new ConverterListener($app['routes'], $app['callback_resolver']));
+            $dispatcher->addSubscriber(new StringToResponseListener());
+
+            return $dispatcher;
+        });
+
+        $this['callback_resolver'] = $this->share(function () use ($app) {
+            return new CallbackResolver($app);
+        });
+
+        $this['resolver'] = $this->share(function () use ($app) {
+            return new ControllerResolver($app, $app['logger']);
+        });
+
+        $this['kernel'] = $this->share(function () use ($app) {
+            return new HttpKernel($app['dispatcher'], $app['resolver'], $app['request_stack']);
+        });
+
+        $this['request_stack'] = $this->share(function () use ($app) {
+            if (class_exists('Symfony\Component\HttpFoundation\RequestStack')) {
+                return new RequestStack();
+            }
+        });
+
+        $this['request_context'] = $this->share(function () use ($app) {
+            $context = new RequestContext();
+
+            $context->setHttpPort($app['request.http_port']);
+            $context->setHttpsPort($app['request.https_port']);
+
+            return $context;
+        });
+
+        $this['url_matcher'] = $this->share(function () use ($app) {
+            return new RedirectableUrlMatcher($app['routes'], $app['request_context']);
+        });
+
+        $this['request_error'] = $this->protect(function () {
+            throw new \RuntimeException('Accessed request service outside of request scope. Try moving that call to a before handler or controller.');
+        });
+
+        $this['request'] = $this['request_error'];
+
+        $this['request.http_port'] = 80;
+        $this['request.https_port'] = 443;
+        $this['debug'] = false;
+        $this['charset'] = 'UTF-8';
+        $this['locale'] = 'en';
+
+        foreach ($values as $key => $value) {
+            $this[$key] = $value;
+        }
+    }
+
+    /**
+     * Registers a service provider.
+     *
+     * @param ServiceProviderInterface $provider A ServiceProviderInterface instance
+     * @param array                    $values   An array of values that customizes the provider
+     *
+     * @return Application
+     */
+    public function register(ServiceProviderInterface $provider, array $values = array())
+    {
+        $this->providers[] = $provider;
+
+        $provider->register($this);
+
+        foreach ($values as $key => $value) {
+            $this[$key] = $value;
+        }
+
+        return $this;
+    }
+
+    /**
+     * Boots all service providers.
+     *
+     * This method is automatically called by handle(), but you can use it
+     * to boot all service providers when not handling a request.
+     */
+    public function boot()
+    {
+        if (!$this->booted) {
+            foreach ($this->providers as $provider) {
+                $provider->boot($this);
+            }
+
+            $this->booted = true;
+        }
+    }
+
+    /**
+     * Maps a pattern to a callable.
+     *
+     * You can optionally specify HTTP methods that should be matched.
+     *
+     * @param string $pattern Matched route pattern
+     * @param mixed  $to      Callback that returns the response when matched
+     *
+     * @return Controller
+     */
+    public function match($pattern, $to = null)
+    {
+        return $this['controllers']->match($pattern, $to);
+    }
+
+    /**
+     * Maps a GET request to a callable.
+     *
+     * @param string $pattern Matched route pattern
+     * @param mixed  $to      Callback that returns the response when matched
+     *
+     * @return Controller
+     */
+    public function get($pattern, $to = null)
+    {
+        return $this['controllers']->get($pattern, $to);
+    }
+
+    /**
+     * Maps a POST request to a callable.
+     *
+     * @param string $pattern Matched route pattern
+     * @param mixed  $to      Callback that returns the response when matched
+     *
+     * @return Controller
+     */
+    public function post($pattern, $to = null)
+    {
+        return $this['controllers']->post($pattern, $to);
+    }
+
+    /**
+     * Maps a PUT request to a callable.
+     *
+     * @param string $pattern Matched route pattern
+     * @param mixed  $to      Callback that returns the response when matched
+     *
+     * @return Controller
+     */
+    public function put($pattern, $to = null)
+    {
+        return $this['controllers']->put($pattern, $to);
+    }
+
+    /**
+     * Maps a DELETE request to a callable.
+     *
+     * @param string $pattern Matched route pattern
+     * @param mixed  $to      Callback that returns the response when matched
+     *
+     * @return Controller
+     */
+    public function delete($pattern, $to = null)
+    {
+        return $this['controllers']->delete($pattern, $to);
+    }
+
+    /**
+     * Maps a PATCH request to a callable.
+     *
+     * @param string $pattern Matched route pattern
+     * @param mixed  $to      Callback that returns the response when matched
+     *
+     * @return Controller
+     */
+    public function patch($pattern, $to = null)
+    {
+        return $this['controllers']->patch($pattern, $to);
+    }
+
+    /**
+     * Adds an event listener that listens on the specified events.
+     *
+     * @param string   $eventName The event to listen on
+     * @param callable $callback  The listener
+     * @param int      $priority  The higher this value, the earlier an event
+     *                            listener will be triggered in the chain (defaults to 0)
+     */
+    public function on($eventName, $callback, $priority = 0)
+    {
+        if ($this->booted) {
+            $this['dispatcher']->addListener($eventName, $this['callback_resolver']->resolveCallback($callback), $priority);
+
+            return;
+        }
+
+        $this['dispatcher'] = $this->share($this->extend('dispatcher', function ($dispatcher, $app) use ($callback, $priority, $eventName) {
+            $dispatcher->addListener($eventName, $app['callback_resolver']->resolveCallback($callback), $priority);
+
+            return $dispatcher;
+        }));
+    }
+
+    /**
+     * Registers a before filter.
+     *
+     * Before filters are run before any route has been matched.
+     *
+     * @param mixed $callback Before filter callback
+     * @param int   $priority The higher this value, the earlier an event
+     *                        listener will be triggered in the chain (defaults to 0)
+     */
+    public function before($callback, $priority = 0)
+    {
+        $app = $this;
+
+        $this->on(KernelEvents::REQUEST, function (GetResponseEvent $event) use ($callback, $app) {
+            if (HttpKernelInterface::MASTER_REQUEST !== $event->getRequestType()) {
+                return;
+            }
+
+            $ret = call_user_func($app['callback_resolver']->resolveCallback($callback), $event->getRequest(), $app);
+
+            if ($ret instanceof Response) {
+                $event->setResponse($ret);
+            }
+        }, $priority);
+    }
+
+    /**
+     * Registers an after filter.
+     *
+     * After filters are run after the controller has been executed.
+     *
+     * @param mixed $callback After filter callback
+     * @param int   $priority The higher this value, the earlier an event
+     *                        listener will be triggered in the chain (defaults to 0)
+     */
+    public function after($callback, $priority = 0)
+    {
+        $app = $this;
+
+        $this->on(KernelEvents::RESPONSE, function (FilterResponseEvent $event) use ($callback, $app) {
+            if (HttpKernelInterface::MASTER_REQUEST !== $event->getRequestType()) {
+                return;
+            }
+
+            $response = call_user_func($app['callback_resolver']->resolveCallback($callback), $event->getRequest(), $event->getResponse(), $app);
+            if ($response instanceof Response) {
+                $event->setResponse($response);
+            } elseif (null !== $response) {
+                throw new \RuntimeException('An after middleware returned an invalid response value. Must return null or an instance of Response.');
+            }
+        }, $priority);
+    }
+
+    /**
+     * Registers a finish filter.
+     *
+     * Finish filters are run after the response has been sent.
+     *
+     * @param mixed $callback Finish filter callback
+     * @param int   $priority The higher this value, the earlier an event
+     *                        listener will be triggered in the chain (defaults to 0)
+     */
+    public function finish($callback, $priority = 0)
+    {
+        $app = $this;
+
+        $this->on(KernelEvents::TERMINATE, function (PostResponseEvent $event) use ($callback, $app) {
+            call_user_func($app['callback_resolver']->resolveCallback($callback), $event->getRequest(), $event->getResponse(), $app);
+        }, $priority);
+    }
+
+    /**
+     * Aborts the current request by sending a proper HTTP error.
+     *
+     * @param int    $statusCode The HTTP status code
+     * @param string $message    The status message
+     * @param array  $headers    An array of HTTP headers
+     */
+    public function abort($statusCode, $message = '', array $headers = array())
+    {
+        throw new HttpException($statusCode, $message, null, $headers);
+    }
+
+    /**
+     * Registers an error handler.
+     *
+     * Error handlers are simple callables which take a single Exception
+     * as an argument. If a controller throws an exception, an error handler
+     * can return a specific response.
+     *
+     * When an exception occurs, all handlers will be called, until one returns
+     * something (a string or a Response object), at which point that will be
+     * returned to the client.
+     *
+     * For this reason you should add logging handlers before output handlers.
+     *
+     * @param mixed $callback Error handler callback, takes an Exception argument
+     * @param int   $priority The higher this value, the earlier an event
+     *                        listener will be triggered in the chain (defaults to -8)
+     */
+    public function error($callback, $priority = -8)
+    {
+        $this->on(KernelEvents::EXCEPTION, new ExceptionListenerWrapper($this, $callback), $priority);
+    }
+
+    /**
+     * Flushes the controller collection.
+     *
+     * @param string $prefix The route prefix
+     */
+    public function flush($prefix = '')
+    {
+        $this['routes']->addCollection($this['controllers']->flush($prefix));
+    }
+
+    /**
+     * Redirects the user to another URL.
+     *
+     * @param string $url    The URL to redirect to
+     * @param int    $status The status code (302 by default)
+     *
+     * @return RedirectResponse
+     */
+    public function redirect($url, $status = 302)
+    {
+        return new RedirectResponse($url, $status);
+    }
+
+    /**
+     * Creates a streaming response.
+     *
+     * @param mixed $callback A valid PHP callback
+     * @param int   $status   The response status code
+     * @param array $headers  An array of response headers
+     *
+     * @return StreamedResponse
+     */
+    public function stream($callback = null, $status = 200, array $headers = array())
+    {
+        return new StreamedResponse($callback, $status, $headers);
+    }
+
+    /**
+     * Escapes a text for HTML.
+     *
+     * @param string $text         The input text to be escaped
+     * @param int    $flags        The flags (@see htmlspecialchars)
+     * @param string $charset      The charset
+     * @param bool   $doubleEncode Whether to try to avoid double escaping or not
+     *
+     * @return string Escaped text
+     */
+    public function escape($text, $flags = ENT_COMPAT, $charset = null, $doubleEncode = true)
+    {
+        return htmlspecialchars($text, $flags, $charset ?: $this['charset'], $doubleEncode);
+    }
+
+    /**
+     * Convert some data into a JSON response.
+     *
+     * @param mixed $data    The response data
+     * @param int   $status  The response status code
+     * @param array $headers An array of response headers
+     *
+     * @return JsonResponse
+     */
+    public function json($data = array(), $status = 200, array $headers = array())
+    {
+        return new JsonResponse($data, $status, $headers);
+    }
+
+    /**
+     * Sends a file.
+     *
+     * @param \SplFileInfo|string $file               The file to stream
+     * @param int                 $status             The response status code
+     * @param array               $headers            An array of response headers
+     * @param null|string         $contentDisposition The type of Content-Disposition to set automatically with the filename
+     *
+     * @return BinaryFileResponse
+     *
+     * @throws \RuntimeException When the feature is not supported, before http-foundation v2.2
+     */
+    public function sendFile($file, $status = 200, array $headers = array(), $contentDisposition = null)
+    {
+        return new BinaryFileResponse($file, $status, $headers, true, $contentDisposition);
+    }
+
+    /**
+     * Mounts controllers under the given route prefix.
+     *
+     * @param string                                           $prefix      The route prefix
+     * @param ControllerCollection|ControllerProviderInterface $controllers A ControllerCollection or a ControllerProviderInterface instance
+     *
+     * @return Application
+     */
+    public function mount($prefix, $controllers)
+    {
+        if ($controllers instanceof ControllerProviderInterface) {
+            $connectedControllers = $controllers->connect($this);
+
+            if (!$connectedControllers instanceof ControllerCollection) {
+                throw new \LogicException(sprintf('The method "%s::connect" must return a "ControllerCollection" instance. Got: "%s"', get_class($controllers), is_object($connectedControllers) ? get_class($connectedControllers) : gettype($connectedControllers)));
+            }
+
+            $controllers = $connectedControllers;
+        } elseif (!$controllers instanceof ControllerCollection) {
+            throw new \LogicException('The "mount" method takes either a "ControllerCollection" or a "ControllerProviderInterface" instance.');
+        }
+
+        $this['controllers']->mount($prefix, $controllers);
+
+        return $this;
+    }
+
+    /**
+     * Handles the request and delivers the response.
+     *
+     * @param Request|null $request Request to process
+     */
+    public function run(Request $request = null)
+    {
+        if (null === $request) {
+            $request = Request::createFromGlobals();
+        }
+
+        $response = $this->handle($request);
+        $response->send();
+        $this->terminate($request, $response);
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * If you call this method directly instead of run(), you must call the
+     * terminate() method yourself if you want the finish filters to be run.
+     */
+    public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = true)
+    {
+        if (!$this->booted) {
+            $this->boot();
+        }
+
+        $current = HttpKernelInterface::SUB_REQUEST === $type ? $this['request'] : $this['request_error'];
+
+        $this['request'] = $request;
+
+        $this->flush();
+
+        $response = $this['kernel']->handle($request, $type, $catch);
+
+        $this['request'] = $current;
+
+        return $response;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function terminate(Request $request, Response $response)
+    {
+        $this['kernel']->terminate($request, $response);
+    }
+}

+ 35 - 0
lib/silex/vendor/silex/silex/src/Silex/Application/FormTrait.php

@@ -0,0 +1,35 @@
+<?php
+
+/*
+ * This file is part of the Silex framework.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Silex\Application;
+
+use Symfony\Component\Form\FormBuilder;
+
+/**
+ * Form trait.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+trait FormTrait
+{
+    /**
+     * Creates and returns a form builder instance
+     *
+     * @param mixed $data    The initial data for the form
+     * @param array $options Options for the form
+     *
+     * @return FormBuilder
+     */
+    public function form($data = null, array $options = array())
+    {
+        return $this['form.factory']->createBuilder('form', $data, $options);
+    }
+}

+ 36 - 0
lib/silex/vendor/silex/silex/src/Silex/Application/MonologTrait.php

@@ -0,0 +1,36 @@
+<?php
+
+/*
+ * This file is part of the Silex framework.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Silex\Application;
+
+use Monolog\Logger;
+
+/**
+ * Monolog trait.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+trait MonologTrait
+{
+    /**
+     * Adds a log record.
+     *
+     * @param string $message The log message
+     * @param array  $context The log context
+     * @param int    $level   The logging level
+     *
+     * @return bool Whether the record has been processed
+     */
+    public function log($message, array $context = array(), $level = Logger::INFO)
+    {
+        return $this['monolog']->addRecord($level, $message, $context);
+    }
+}

+ 58 - 0
lib/silex/vendor/silex/silex/src/Silex/Application/SecurityTrait.php

@@ -0,0 +1,58 @@
+<?php
+
+/*
+ * This file is part of the Silex framework.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Silex\Application;
+
+use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
+use Symfony\Component\Security\Core\User\UserInterface;
+
+/**
+ * Security trait.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+trait SecurityTrait
+{
+    /**
+     * Gets a user from the Security Context.
+     *
+     * @return mixed
+     *
+     * @see TokenInterface::getUser()
+     */
+    public function user()
+    {
+        if (null === $token = $this['security']->getToken()) {
+            return;
+        }
+
+        if (!is_object($user = $token->getUser())) {
+            return;
+        }
+
+        return $user;
+    }
+
+    /**
+     * Encodes the raw password.
+     *
+     * @param UserInterface $user     A UserInterface instance
+     * @param string        $password The password to encode
+     *
+     * @return string The encoded password
+     *
+     * @throws \RuntimeException when no password encoder could be found for the user
+     */
+    public function encodePassword(UserInterface $user, $password)
+    {
+        return $this['security.encoder_factory']->getEncoder($user)->encodePassword($password, $user->getSalt());
+    }
+}

+ 33 - 0
lib/silex/vendor/silex/silex/src/Silex/Application/SwiftmailerTrait.php

@@ -0,0 +1,33 @@
+<?php
+
+/*
+ * This file is part of the Silex framework.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Silex\Application;
+
+/**
+ * Swiftmailer trait.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+trait SwiftmailerTrait
+{
+    /**
+     * Sends an email.
+     *
+     * @param \Swift_Message $message          A \Swift_Message instance
+     * @param array          $failedRecipients An array of failures by-reference
+     *
+     * @return int The number of sent messages
+     */
+    public function mail(\Swift_Message $message, &$failedRecipients = null)
+    {
+        return $this['mailer']->send($message, $failedRecipients);
+    }
+}

+ 51 - 0
lib/silex/vendor/silex/silex/src/Silex/Application/TranslationTrait.php

@@ -0,0 +1,51 @@
+<?php
+
+/*
+ * This file is part of the Silex framework.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Silex\Application;
+
+/**
+ * Translation trait.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+trait TranslationTrait
+{
+    /**
+     * Translates the given message.
+     *
+     * @param string $id         The message id
+     * @param array  $parameters An array of parameters for the message
+     * @param string $domain     The domain for the message
+     * @param string $locale     The locale
+     *
+     * @return string The translated string
+     */
+    public function trans($id, array $parameters = array(), $domain = 'messages', $locale = null)
+    {
+        return $this['translator']->trans($id, $parameters, $domain, $locale);
+    }
+
+    /**
+     * Translates the given choice message by choosing a translation according to a number.
+     *
+     * @param string $id         The message id
+     * @param int    $number     The number to use to find the indice of the message
+     * @param array  $parameters An array of parameters for the message
+     * @param string $domain     The domain for the message
+     * @param string $locale     The locale
+     *
+     * @return string The translated string
+     */
+    public function transChoice($id, $number, array $parameters = array(), $domain = 'messages', $locale = null)
+    {
+        return $this['translator']->transChoice($id, $number, $parameters, $domain, $locale);
+    }
+}

+ 65 - 0
lib/silex/vendor/silex/silex/src/Silex/Application/TwigTrait.php

@@ -0,0 +1,65 @@
+<?php
+
+/*
+ * This file is part of the Silex framework.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Silex\Application;
+
+use Symfony\Component\HttpFoundation\Response;
+use Symfony\Component\HttpFoundation\StreamedResponse;
+
+/**
+ * Twig trait.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+trait TwigTrait
+{
+    /**
+     * Renders a view and returns a Response.
+     *
+     * To stream a view, pass an instance of StreamedResponse as a third argument.
+     *
+     * @param string   $view       The view name
+     * @param array    $parameters An array of parameters to pass to the view
+     * @param Response $response   A Response instance
+     *
+     * @return Response A Response instance
+     */
+    public function render($view, array $parameters = array(), Response $response = null)
+    {
+        $twig = $this['twig'];
+
+        if ($response instanceof StreamedResponse) {
+            $response->setCallback(function () use ($twig, $view, $parameters) {
+                $twig->display($view, $parameters);
+            });
+        } else {
+            if (null === $response) {
+                $response = new Response();
+            }
+            $response->setContent($twig->render($view, $parameters));
+        }
+
+        return $response;
+    }
+
+    /**
+     * Renders a view.
+     *
+     * @param string $view       The view name
+     * @param array  $parameters An array of parameters to pass to the view
+     *
+     * @return string The rendered view
+     */
+    public function renderView($view, array $parameters = array())
+    {
+        return $this['twig']->render($view, $parameters);
+    }
+}

+ 48 - 0
lib/silex/vendor/silex/silex/src/Silex/Application/UrlGeneratorTrait.php

@@ -0,0 +1,48 @@
+<?php
+
+/*
+ * This file is part of the Silex framework.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Silex\Application;
+
+use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
+
+/**
+ * UrlGenerator trait.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+trait UrlGeneratorTrait
+{
+    /**
+     * Generates a path from the given parameters.
+     *
+     * @param string $route      The name of the route
+     * @param mixed  $parameters An array of parameters
+     *
+     * @return string The generated path
+     */
+    public function path($route, $parameters = array())
+    {
+        return $this['url_generator']->generate($route, $parameters, UrlGeneratorInterface::ABSOLUTE_PATH);
+    }
+
+    /**
+     * Generates an absolute URL from the given parameters.
+     *
+     * @param string $route      The name of the route
+     * @param mixed  $parameters An array of parameters
+     *
+     * @return string The generated URL
+     */
+    public function url($route, $parameters = array())
+    {
+        return $this['url_generator']->generate($route, $parameters, UrlGeneratorInterface::ABSOLUTE_URL);
+    }
+}

+ 70 - 0
lib/silex/vendor/silex/silex/src/Silex/CallbackResolver.php

@@ -0,0 +1,70 @@
+<?php
+
+/*
+ * This file is part of the Silex framework.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Silex;
+
+class CallbackResolver
+{
+    const SERVICE_PATTERN = "/[A-Za-z0-9\._\-]+:[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/";
+
+    private $app;
+
+    public function __construct(\Pimple $app)
+    {
+        $this->app = $app;
+    }
+
+    /**
+     * Returns true if the string is a valid service method representation.
+     *
+     * @param string $name
+     *
+     * @return bool
+     */
+    public function isValid($name)
+    {
+        return is_string($name) && preg_match(static::SERVICE_PATTERN, $name);
+    }
+
+    /**
+     * Returns a callable given its string representation.
+     *
+     * @param string $name
+     *
+     * @return array A callable array
+     *
+     * @throws \InvalidArgumentException In case the method does not exist.
+     */
+    public function convertCallback($name)
+    {
+        list($service, $method) = explode(':', $name, 2);
+
+        if (!isset($this->app[$service])) {
+            throw new \InvalidArgumentException(sprintf('Service "%s" does not exist.', $service));
+        }
+
+        return array($this->app[$service], $method);
+    }
+
+    /**
+     * Returns a callable given its string representation if it is a valid service method.
+     *
+     * @param string $name
+     *
+     * @return array A callable array
+     *
+     * @throws \InvalidArgumentException In case the method does not exist.
+     */
+    public function resolveCallback($name)
+    {
+        return $this->isValid($name) ? $this->convertCallback($name) : $name;
+    }
+}

+ 87 - 0
lib/silex/vendor/silex/silex/src/Silex/ConstraintValidatorFactory.php

@@ -0,0 +1,87 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Silex;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\ConstraintValidatorFactoryInterface;
+use Symfony\Component\Validator\ConstraintValidator;
+
+/**
+ * Uses a service container to create constraint validators with dependencies.
+ *
+ * @author Kris Wallsmith <kris@symfony.com>
+ * @author Alex Kalyvitis <alex.kalyvitis@gmail.com>
+ */
+class ConstraintValidatorFactory implements ConstraintValidatorFactoryInterface
+{
+    /**
+     * @var \Pimple
+     */
+    protected $container;
+
+    /**
+     * @var array
+     */
+    protected $serviceNames;
+
+    /**
+     * @var array
+     */
+    protected $validators;
+
+    /**
+     * Constructor
+     *
+     * @param \Pimple $container    DI container
+     * @param array   $serviceNames Validator service names
+     */
+    public function __construct(\Pimple $container, array $serviceNames = array())
+    {
+        $this->container    = $container;
+        $this->serviceNames = $serviceNames;
+        $this->validators   = array();
+    }
+
+    /**
+     * Returns the validator for the supplied constraint.
+     *
+     * @param  Constraint          $constraint A constraint
+     * @return ConstraintValidator A validator for the supplied constraint
+     */
+    public function getInstance(Constraint $constraint)
+    {
+        $name = $constraint->validatedBy();
+
+        if (isset($this->validators[$name])) {
+            return $this->validators[$name];
+        }
+
+        $this->validators[$name] = $this->createValidator($name);
+
+        return $this->validators[$name];
+    }
+
+    /**
+     * Returns the validator instance
+     *
+     * @param  string              $name
+     * @return ConstraintValidator
+     */
+    private function createValidator($name)
+    {
+        if (isset($this->serviceNames[$name])) {
+            return $this->container[$this->serviceNames[$name]];
+        }
+
+        return new $name();
+    }
+}

+ 118 - 0
lib/silex/vendor/silex/silex/src/Silex/Controller.php

@@ -0,0 +1,118 @@
+<?php
+
+/*
+ * This file is part of the Silex framework.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Silex;
+
+use Silex\Exception\ControllerFrozenException;
+
+/**
+ * A wrapper for a controller, mapped to a route.
+ *
+ * __call() forwards method-calls to Route, but returns instance of Controller
+ * listing Route's methods below, so that IDEs know they are valid
+ *
+ * @method Controller assert(string $variable, string $regexp)
+ * @method Controller value(string $variable, mixed $default)
+ * @method Controller convert(string $variable, mixed $callback)
+ * @method Controller method(string $method)
+ * @method Controller requireHttp()
+ * @method Controller requireHttps()
+ * @method Controller before(mixed $callback)
+ * @method Controller after(mixed $callback)
+ * @author Igor Wiedler <igor@wiedler.ch>
+ */
+class Controller
+{
+    private $route;
+    private $routeName;
+    private $isFrozen = false;
+
+    /**
+     * Constructor.
+     *
+     * @param Route $route
+     */
+    public function __construct(Route $route)
+    {
+        $this->route = $route;
+    }
+
+    /**
+     * Gets the controller's route.
+     *
+     * @return Route
+     */
+    public function getRoute()
+    {
+        return $this->route;
+    }
+
+    /**
+     * Gets the controller's route name.
+     *
+     * @return string
+     */
+    public function getRouteName()
+    {
+        return $this->routeName;
+    }
+
+    /**
+     * Sets the controller's route.
+     *
+     * @param string $routeName
+     *
+     * @return Controller $this The current Controller instance
+     */
+    public function bind($routeName)
+    {
+        if ($this->isFrozen) {
+            throw new ControllerFrozenException(sprintf('Calling %s on frozen %s instance.', __METHOD__, __CLASS__));
+        }
+
+        $this->routeName = $routeName;
+
+        return $this;
+    }
+
+    public function __call($method, $arguments)
+    {
+        if (!method_exists($this->route, $method)) {
+            throw new \BadMethodCallException(sprintf('Method "%s::%s" does not exist.', get_class($this->route), $method));
+        }
+
+        call_user_func_array(array($this->route, $method), $arguments);
+
+        return $this;
+    }
+
+    /**
+     * Freezes the controller.
+     *
+     * Once the controller is frozen, you can no longer change the route name
+     */
+    public function freeze()
+    {
+        $this->isFrozen = true;
+    }
+
+    public function generateRouteName($prefix)
+    {
+        $requirements = $this->route->getRequirements();
+        $method = isset($requirements['_method']) ? $requirements['_method'] : '';
+
+        $routeName = $prefix.$method.$this->route->getPath();
+        $routeName = str_replace(array('/', ':', '|', '-'), '_', $routeName);
+        $routeName = preg_replace('/[^a-z0-9A-Z_.]+/', '', $routeName);
+
+        return $routeName;
+    }
+}

+ 202 - 0
lib/silex/vendor/silex/silex/src/Silex/ControllerCollection.php

@@ -0,0 +1,202 @@
+<?php
+
+/*
+ * This file is part of the Silex framework.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Silex;
+
+use Symfony\Component\Routing\RouteCollection;
+use Symfony\Component\HttpFoundation\Request;
+
+/**
+ * Builds Silex controllers.
+ *
+ * It acts as a staging area for routes. You are able to set the route name
+ * until flush() is called, at which point all controllers are frozen and
+ * converted to a RouteCollection.
+ *
+ * __call() forwards method-calls to Route, but returns instance of ControllerCollection
+ * listing Route's methods below, so that IDEs know they are valid
+ *
+ * @method ControllerCollection assert(string $variable, string $regexp)
+ * @method ControllerCollection value(string $variable, mixed $default)
+ * @method ControllerCollection convert(string $variable, mixed $callback)
+ * @method ControllerCollection method(string $method)
+ * @method ControllerCollection requireHttp()
+ * @method ControllerCollection requireHttps()
+ * @method ControllerCollection before(mixed $callback)
+ * @method ControllerCollection after(mixed $callback)
+ *
+ * @author Igor Wiedler <igor@wiedler.ch>
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class ControllerCollection
+{
+    protected $controllers = array();
+    protected $defaultRoute;
+    protected $defaultController;
+    protected $prefix;
+
+    public function __construct(Route $defaultRoute)
+    {
+        $this->defaultRoute = $defaultRoute;
+        $this->defaultController = function (Request $request) {
+            throw new \LogicException(sprintf('The "%s" route must have code to run when it matches.', $request->attributes->get('_route')));
+        };
+    }
+
+    /**
+     * Mounts controllers under the given route prefix.
+     *
+     * @param string               $prefix      The route prefix
+     * @param ControllerCollection $controllers A ControllerCollection instance
+     */
+    public function mount($prefix, ControllerCollection $controllers)
+    {
+        $controllers->prefix = $prefix;
+
+        $this->controllers[] = $controllers;
+    }
+
+    /**
+     * Maps a pattern to a callable.
+     *
+     * You can optionally specify HTTP methods that should be matched.
+     *
+     * @param string $pattern Matched route pattern
+     * @param mixed  $to      Callback that returns the response when matched
+     *
+     * @return Controller
+     */
+    public function match($pattern, $to = null)
+    {
+        $route = clone $this->defaultRoute;
+        $route->setPath($pattern);
+        $this->controllers[] = $controller = new Controller($route);
+        $route->setDefault('_controller', null === $to ? $this->defaultController : $to);
+
+        return $controller;
+    }
+
+    /**
+     * Maps a GET request to a callable.
+     *
+     * @param string $pattern Matched route pattern
+     * @param mixed  $to      Callback that returns the response when matched
+     *
+     * @return Controller
+     */
+    public function get($pattern, $to = null)
+    {
+        return $this->match($pattern, $to)->method('GET');
+    }
+
+    /**
+     * Maps a POST request to a callable.
+     *
+     * @param string $pattern Matched route pattern
+     * @param mixed  $to      Callback that returns the response when matched
+     *
+     * @return Controller
+     */
+    public function post($pattern, $to = null)
+    {
+        return $this->match($pattern, $to)->method('POST');
+    }
+
+    /**
+     * Maps a PUT request to a callable.
+     *
+     * @param string $pattern Matched route pattern
+     * @param mixed  $to      Callback that returns the response when matched
+     *
+     * @return Controller
+     */
+    public function put($pattern, $to = null)
+    {
+        return $this->match($pattern, $to)->method('PUT');
+    }
+
+    /**
+     * Maps a DELETE request to a callable.
+     *
+     * @param string $pattern Matched route pattern
+     * @param mixed  $to      Callback that returns the response when matched
+     *
+     * @return Controller
+     */
+    public function delete($pattern, $to = null)
+    {
+        return $this->match($pattern, $to)->method('DELETE');
+    }
+
+    /**
+     * Maps a PATCH request to a callable.
+     *
+     * @param string $pattern Matched route pattern
+     * @param mixed  $to      Callback that returns the response when matched
+     *
+     * @return Controller
+     */
+    public function patch($pattern, $to = null)
+    {
+        return $this->match($pattern, $to)->method('PATCH');
+    }
+
+    public function __call($method, $arguments)
+    {
+        if (!method_exists($this->defaultRoute, $method)) {
+            throw new \BadMethodCallException(sprintf('Method "%s::%s" does not exist.', get_class($this->defaultRoute), $method));
+        }
+
+        call_user_func_array(array($this->defaultRoute, $method), $arguments);
+
+        foreach ($this->controllers as $controller) {
+            if ($controller instanceof Controller) {
+                call_user_func_array(array($controller, $method), $arguments);
+            }
+        }
+
+        return $this;
+    }
+
+    /**
+     * Persists and freezes staged controllers.
+     *
+     * @param string $prefix
+     *
+     * @return RouteCollection A RouteCollection instance
+     */
+    public function flush($prefix = '')
+    {
+        $routes = new RouteCollection();
+
+        foreach ($this->controllers as $controller) {
+            if ($controller instanceof Controller) {
+                if (!$name = $controller->getRouteName()) {
+                    $name = $controller->generateRouteName($prefix);
+                    while ($routes->get($name)) {
+                        $name .= '_';
+                    }
+                    $controller->bind($name);
+                }
+                $routes->add($name, $controller->getRoute());
+                $controller->freeze();
+            } else {
+                $routes->addCollection($controller->flush($controller->prefix));
+            }
+        }
+
+        $routes->addPrefix($prefix);
+
+        $this->controllers = array();
+
+        return $routes;
+    }
+}

+ 29 - 0
lib/silex/vendor/silex/silex/src/Silex/ControllerProviderInterface.php

@@ -0,0 +1,29 @@
+<?php
+
+/*
+ * This file is part of the Silex framework.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Silex;
+
+/**
+ * Interface for controller providers.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+interface ControllerProviderInterface
+{
+    /**
+     * Returns routes to connect to the given application.
+     *
+     * @param Application $app An Application instance
+     *
+     * @return ControllerCollection A ControllerCollection instance
+     */
+    public function connect(Application $app);
+}

+ 52 - 0
lib/silex/vendor/silex/silex/src/Silex/ControllerResolver.php

@@ -0,0 +1,52 @@
+<?php
+
+/*
+ * This file is part of the Silex framework.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Silex;
+
+use Psr\Log\LoggerInterface;
+use Symfony\Component\HttpKernel\Controller\ControllerResolver as BaseControllerResolver;
+use Symfony\Component\HttpFoundation\Request;
+
+/**
+ * Adds Application as a valid argument for controllers.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class ControllerResolver extends BaseControllerResolver
+{
+    protected $app;
+
+    /**
+     * Constructor.
+     *
+     * @param Application     $app    An Application instance
+     * @param LoggerInterface $logger A LoggerInterface instance
+     */
+    public function __construct(Application $app, LoggerInterface $logger = null)
+    {
+        $this->app = $app;
+
+        parent::__construct($logger);
+    }
+
+    protected function doGetArguments(Request $request, $controller, array $parameters)
+    {
+        foreach ($parameters as $param) {
+            if ($param->getClass() && $param->getClass()->isInstance($this->app)) {
+                $request->attributes->set($param->getName(), $this->app);
+
+                break;
+            }
+        }
+
+        return parent::doGetArguments($request, $controller, $parameters);
+    }
+}

+ 66 - 0
lib/silex/vendor/silex/silex/src/Silex/EventListener/ConverterListener.php

@@ -0,0 +1,66 @@
+<?php
+
+/*
+ * This file is part of the Silex framework.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Silex\EventListener;
+
+use Silex\CallbackResolver;
+use Symfony\Component\HttpKernel\KernelEvents;
+use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
+use Symfony\Component\Routing\RouteCollection;
+
+/**
+ * Handles converters.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class ConverterListener implements EventSubscriberInterface
+{
+    protected $routes;
+    protected $callbackResolver;
+
+    /**
+     * Constructor.
+     *
+     * @param RouteCollection  $routes           A RouteCollection instance
+     * @param CallbackResolver $callbackResolver A CallbackResolver instance
+     */
+    public function __construct(RouteCollection $routes, CallbackResolver $callbackResolver)
+    {
+        $this->routes = $routes;
+        $this->callbackResolver = $callbackResolver;
+    }
+
+    /**
+     * Handles converters.
+     *
+     * @param FilterControllerEvent $event The event to handle
+     */
+    public function onKernelController(FilterControllerEvent $event)
+    {
+        $request = $event->getRequest();
+        $route = $this->routes->get($request->attributes->get('_route'));
+        if ($route && $converters = $route->getOption('_converters')) {
+            foreach ($converters as $name => $callback) {
+                $callback = $this->callbackResolver->resolveCallback($callback);
+
+                $request->attributes->set($name, call_user_func($callback, $request->attributes->get($name), $request));
+            }
+        }
+    }
+
+    public static function getSubscribedEvents()
+    {
+        return array(
+            KernelEvents::CONTROLLER => 'onKernelController',
+        );
+    }
+}

+ 42 - 0
lib/silex/vendor/silex/silex/src/Silex/EventListener/LocaleListener.php

@@ -0,0 +1,42 @@
+<?php
+
+/*
+ * This file is part of the Silex framework.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Silex\EventListener;
+
+use Symfony\Component\HttpKernel\Event\GetResponseEvent;
+use Symfony\Component\HttpKernel\EventListener\LocaleListener as BaseLocaleListener;
+use Symfony\Component\HttpFoundation\RequestStack;
+use Symfony\Component\Routing\RequestContextAwareInterface;
+use Silex\Application;
+
+/**
+ * Initializes the locale based on the current request.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class LocaleListener extends BaseLocaleListener
+{
+    protected $app;
+
+    public function __construct(Application $app, RequestContextAwareInterface $router = null, RequestStack $requestStack = null)
+    {
+        parent::__construct($app['locale'], $router, $requestStack);
+
+        $this->app = $app;
+    }
+
+    public function onKernelRequest(GetResponseEvent $event)
+    {
+        parent::onKernelRequest($event);
+
+        $this->app['locale'] = $event->getRequest()->getLocale();
+    }
+}

+ 128 - 0
lib/silex/vendor/silex/silex/src/Silex/EventListener/LogListener.php

@@ -0,0 +1,128 @@
+<?php
+
+/*
+ * This file is part of the Silex framework.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Silex\EventListener;
+
+use Psr\Log\LoggerInterface;
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
+use Symfony\Component\HttpKernel\HttpKernelInterface;
+use Symfony\Component\HttpKernel\Event\GetResponseEvent;
+use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
+use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
+use Symfony\Component\HttpKernel\KernelEvents;
+use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpFoundation\Response;
+use Symfony\Component\HttpFoundation\RedirectResponse;
+
+/**
+ * Log request, response and exceptions.
+ */
+class LogListener implements EventSubscriberInterface
+{
+    protected $logger;
+
+    public function __construct(LoggerInterface $logger)
+    {
+        $this->logger = $logger;
+    }
+
+    /**
+     * Logs master requests on event KernelEvents::REQUEST.
+     *
+     * @param GetResponseEvent $event
+     */
+    public function onKernelRequest(GetResponseEvent $event)
+    {
+        if (HttpKernelInterface::MASTER_REQUEST !== $event->getRequestType()) {
+            return;
+        }
+
+        $this->logRequest($event->getRequest());
+    }
+
+    /**
+     * Logs master response on event KernelEvents::RESPONSE.
+     *
+     * @param FilterResponseEvent $event
+     */
+    public function onKernelResponse(FilterResponseEvent $event)
+    {
+        if (HttpKernelInterface::MASTER_REQUEST !== $event->getRequestType()) {
+            return;
+        }
+
+        $this->logResponse($event->getResponse());
+    }
+
+    /**
+     * Logs uncaught exceptions on event KernelEvents::EXCEPTION.
+     *
+     * @param GetResponseForExceptionEvent $event
+     */
+    public function onKernelException(GetResponseForExceptionEvent $event)
+    {
+        $this->logException($event->getException());
+    }
+
+    /**
+     * Logs a request.
+     *
+     * @param Request $request
+     */
+    protected function logRequest(Request $request)
+    {
+        $this->logger->info('> '.$request->getMethod().' '.$request->getRequestUri());
+    }
+
+    /**
+     * Logs a response.
+     *
+     * @param Response $response
+     */
+    protected function logResponse(Response $response)
+    {
+        if ($response instanceof RedirectResponse) {
+            $this->logger->info('< '.$response->getStatusCode().' '.$response->getTargetUrl());
+        } else {
+            $this->logger->info('< '.$response->getStatusCode());
+        }
+    }
+
+    /**
+     * Logs an exception.
+     *
+     * @param \Exception $e
+     */
+    protected function logException(\Exception $e)
+    {
+        $message = sprintf('%s: %s (uncaught exception) at %s line %s', get_class($e), $e->getMessage(), $e->getFile(), $e->getLine());
+
+        if ($e instanceof HttpExceptionInterface && $e->getStatusCode() < 500) {
+            $this->logger->error($message, array('exception' => $e));
+        } else {
+            $this->logger->critical($message, array('exception' => $e));
+        }
+    }
+
+    public static function getSubscribedEvents()
+    {
+        return array(
+            KernelEvents::REQUEST => array('onKernelRequest', 0),
+            KernelEvents::RESPONSE => array('onKernelResponse', 0),
+            /*
+             * Priority -4 is used to come after those from SecurityServiceProvider (0)
+             * but before the error handlers added with Silex\Application::error (defaults to -8)
+             */
+            KernelEvents::EXCEPTION => array('onKernelException', -4),
+        );
+    }
+}

+ 96 - 0
lib/silex/vendor/silex/silex/src/Silex/EventListener/MiddlewareListener.php

@@ -0,0 +1,96 @@
+<?php
+
+/*
+ * This file is part of the Silex framework.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Silex\EventListener;
+
+use Symfony\Component\HttpKernel\KernelEvents;
+use Symfony\Component\HttpKernel\Event\GetResponseEvent;
+use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
+use Symfony\Component\HttpFoundation\Response;
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
+use Silex\Application;
+
+/**
+ * Manages the route middlewares.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class MiddlewareListener implements EventSubscriberInterface
+{
+    protected $app;
+
+    /**
+     * Constructor.
+     *
+     * @param Application $app An Application instance
+     */
+    public function __construct(Application $app)
+    {
+        $this->app = $app;
+    }
+
+    /**
+     * Runs before filters.
+     *
+     * @param GetResponseEvent $event The event to handle
+     */
+    public function onKernelRequest(GetResponseEvent $event)
+    {
+        $request = $event->getRequest();
+        $routeName = $request->attributes->get('_route');
+        if (!$route = $this->app['routes']->get($routeName)) {
+            return;
+        }
+
+        foreach ((array) $route->getOption('_before_middlewares') as $callback) {
+            $ret = call_user_func($this->app['callback_resolver']->resolveCallback($callback), $request, $this->app);
+            if ($ret instanceof Response) {
+                $event->setResponse($ret);
+
+                return;
+            } elseif (null !== $ret) {
+                throw new \RuntimeException(sprintf('A before middleware for route "%s" returned an invalid response value. Must return null or an instance of Response.', $routeName));
+            }
+        }
+    }
+
+    /**
+     * Runs after filters.
+     *
+     * @param FilterResponseEvent $event The event to handle
+     */
+    public function onKernelResponse(FilterResponseEvent $event)
+    {
+        $request = $event->getRequest();
+        $routeName = $request->attributes->get('_route');
+        if (!$route = $this->app['routes']->get($routeName)) {
+            return;
+        }
+
+        foreach ((array) $route->getOption('_after_middlewares') as $callback) {
+            $response = call_user_func($this->app['callback_resolver']->resolveCallback($callback), $request, $event->getResponse(), $this->app);
+            if ($response instanceof Response) {
+                $event->setResponse($response);
+            } elseif (null !== $response) {
+                throw new \RuntimeException(sprintf('An after middleware for route "%s" returned an invalid response value. Must return null or an instance of Response.', $routeName));
+            }
+        }
+    }
+
+    public static function getSubscribedEvents()
+    {
+        return array(
+            // this must be executed after the late events defined with before() (and their priority is -512)
+            KernelEvents::REQUEST  => array('onKernelRequest', -1024),
+            KernelEvents::RESPONSE => array('onKernelResponse', 128),
+        );
+    }
+}

+ 51 - 0
lib/silex/vendor/silex/silex/src/Silex/EventListener/StringToResponseListener.php

@@ -0,0 +1,51 @@
+<?php
+
+/*
+ * This file is part of the Silex framework.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Silex\EventListener;
+
+use Symfony\Component\HttpKernel\KernelEvents;
+use Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent;
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
+use Symfony\Component\HttpFoundation\Response;
+
+/**
+ * Converts string responses to proper Response instances.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class StringToResponseListener implements EventSubscriberInterface
+{
+    /**
+     * Handles string responses.
+     *
+     * @param GetResponseForControllerResultEvent $event The event to handle
+     */
+    public function onKernelView(GetResponseForControllerResultEvent $event)
+    {
+        $response = $event->getControllerResult();
+
+        if (!(
+            null === $response
+            || is_array($response)
+            || $response instanceof Response
+            || (is_object($response) && !method_exists($response, '__toString'))
+        )) {
+            $event->setResponse(new Response((string) $response));
+        }
+    }
+
+    public static function getSubscribedEvents()
+    {
+        return array(
+            KernelEvents::VIEW => array('onKernelView', -10),
+        );
+    }
+}

+ 21 - 0
lib/silex/vendor/silex/silex/src/Silex/Exception/ControllerFrozenException.php

@@ -0,0 +1,21 @@
+<?php
+
+/*
+ * This file is part of the Silex framework.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Silex\Exception;
+
+/**
+ * Exception, is thrown when a frozen controller is modified
+ *
+ * @author Igor Wiedler <igor@wiedler.ch>
+ */
+class ControllerFrozenException extends \RuntimeException
+{
+}

+ 58 - 0
lib/silex/vendor/silex/silex/src/Silex/ExceptionHandler.php

@@ -0,0 +1,58 @@
+<?php
+
+/*
+ * This file is part of the Silex framework.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Silex;
+
+use Symfony\Component\Debug\ExceptionHandler as DebugExceptionHandler;
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
+use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
+use Symfony\Component\HttpKernel\KernelEvents;
+
+/**
+ * Defaults exception handler.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class ExceptionHandler implements EventSubscriberInterface
+{
+    protected $debug;
+    protected $enabled;
+
+    public function __construct($debug)
+    {
+        $this->debug = $debug;
+        $this->enabled = true;
+    }
+
+    public function disable()
+    {
+        $this->enabled = false;
+    }
+
+    public function onSilexError(GetResponseForExceptionEvent $event)
+    {
+        if (!$this->enabled) {
+            return;
+        }
+
+        $handler = new DebugExceptionHandler($this->debug);
+
+        $event->setResponse($handler->createResponse($event->getException()));
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public static function getSubscribedEvents()
+    {
+        return array(KernelEvents::EXCEPTION => array('onSilexError', -255));
+    }
+}

+ 93 - 0
lib/silex/vendor/silex/silex/src/Silex/ExceptionListenerWrapper.php

@@ -0,0 +1,93 @@
+<?php
+
+/*
+ * This file is part of the Silex framework.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Silex;
+
+use Symfony\Component\HttpFoundation\Response;
+use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
+use Symfony\Component\HttpKernel\KernelEvents;
+use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
+use Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent;
+
+/**
+ * Wraps exception listeners.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class ExceptionListenerWrapper
+{
+    protected $app;
+    protected $callback;
+
+    /**
+     * Constructor.
+     *
+     * @param Application $app      An Application instance
+     * @param callable    $callback
+     */
+    public function __construct(Application $app, $callback)
+    {
+        $this->app = $app;
+        $this->callback = $callback;
+    }
+
+    public function __invoke(GetResponseForExceptionEvent $event)
+    {
+        $exception = $event->getException();
+        $this->callback = $this->app['callback_resolver']->resolveCallback($this->callback);
+
+        if (!$this->shouldRun($exception)) {
+            return;
+        }
+
+        $code = $exception instanceof HttpExceptionInterface ? $exception->getStatusCode() : 500;
+
+        $response = call_user_func($this->callback, $exception, $code);
+
+        $this->ensureResponse($response, $event);
+    }
+
+    protected function shouldRun(\Exception $exception)
+    {
+        if (is_array($this->callback)) {
+            $callbackReflection = new \ReflectionMethod($this->callback[0], $this->callback[1]);
+        } elseif (is_object($this->callback) && !$this->callback instanceof \Closure) {
+            $callbackReflection = new \ReflectionObject($this->callback);
+            $callbackReflection = $callbackReflection->getMethod('__invoke');
+        } else {
+            $callbackReflection = new \ReflectionFunction($this->callback);
+        }
+
+        if ($callbackReflection->getNumberOfParameters() > 0) {
+            $parameters = $callbackReflection->getParameters();
+            $expectedException = $parameters[0];
+            if ($expectedException->getClass() && !$expectedException->getClass()->isInstance($exception)) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    protected function ensureResponse($response, GetResponseForExceptionEvent $event)
+    {
+        if ($response instanceof Response) {
+            $event->setResponse($response);
+        } else {
+            $viewEvent = new GetResponseForControllerResultEvent($this->app['kernel'], $event->getRequest(), $event->getRequestType(), $response);
+            $this->app['dispatcher']->dispatch(KernelEvents::VIEW, $viewEvent);
+
+            if ($viewEvent->hasResponse()) {
+                $event->setResponse($viewEvent->getResponse());
+            }
+        }
+    }
+}

Einige Dateien werden nicht angezeigt, da zu viele Dateien in diesem Diff geändert wurden.