diff --git a/core/composer.json b/core/composer.json
index 452ad59ae023ed2272bff1f3aa00d8006a84350c..fba8153e7fde007805423c7dff32a0b2293d5dce 100644
--- a/core/composer.json
+++ b/core/composer.json
@@ -120,8 +120,7 @@
     "drupal/update": "self.version",
     "drupal/user": "self.version",
     "drupal/views": "self.version",
-    "drupal/views_ui": "self.version",
-    "symfony/translation": "~2.4"
+    "drupal/views_ui": "self.version"
   },
   "minimum-stability": "dev",
   "prefer-stable": true,
@@ -129,8 +128,7 @@
     "psr-4": {
       "Drupal\\Core\\": "lib/Drupal/Core",
       "Drupal\\Component\\": "lib/Drupal/Component",
-      "Drupal\\Driver\\": "../drivers/lib/Drupal/Driver",
-      "Symfony\\Component\\Translation\\": "lib/Symfony/Component/Translation"
+      "Drupal\\Driver\\": "../drivers/lib/Drupal/Driver"
     },
     "files": [
       "lib/Drupal.php"
diff --git a/core/composer.lock b/core/composer.lock
index 40f50fb12f76733e8ce67af88742d6b4c44ef3ea..c66e5d82d0343a42fc41ed5fac09742b39cb4b43 100644
--- a/core/composer.lock
+++ b/core/composer.lock
@@ -4,7 +4,7 @@
         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
         "This file is @generated automatically"
     ],
-    "hash": "5916317ae84f5caeb1bb254f4fe65775",
+    "hash": "e789e5736fbe96c9b9502e89b53dcebe",
     "packages": [
         {
             "name": "behat/mink",
@@ -2916,6 +2916,67 @@
             "homepage": "https://symfony.com",
             "time": "2015-08-31 16:44:53"
         },
+        {
+            "name": "symfony/translation",
+            "version": "v2.7.4",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/Translation.git",
+                "reference": "485877661835e188cd78345c6d4eef1290d17571"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/Translation/zipball/485877661835e188cd78345c6d4eef1290d17571",
+                "reference": "485877661835e188cd78345c6d4eef1290d17571",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.3.9"
+            },
+            "conflict": {
+                "symfony/config": "<2.7"
+            },
+            "require-dev": {
+                "psr/log": "~1.0",
+                "symfony/config": "~2.7",
+                "symfony/intl": "~2.4",
+                "symfony/phpunit-bridge": "~2.7",
+                "symfony/yaml": "~2.2"
+            },
+            "suggest": {
+                "psr/log": "To use logging capability in translator",
+                "symfony/config": "",
+                "symfony/yaml": ""
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "2.7-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Symfony\\Component\\Translation\\": ""
+                }
+            },
+            "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 Translation Component",
+            "homepage": "https://symfony.com",
+            "time": "2015-09-06 08:36:38"
+        },
         {
             "name": "symfony/validator",
             "version": "v2.7.4",
diff --git a/core/composer.txt b/core/composer.txt
new file mode 100644
index 0000000000000000000000000000000000000000..0e133d959f5bd076b7ebc2099e1a7a983d199fbd
--- /dev/null
+++ b/core/composer.txt
@@ -0,0 +1,32 @@
+The libraries listed here are the only ones we officially depend on. Anything
+else is either provided only for development purposes or an implicit dependency
+that may be removed in the future, if it is properly decoupled from the packages
+depending on it.
+
+doctrine/common
+doctrine/annotations
+easyrdf/easyrdf
+egulias/email-validator
+fabpot/goutte
+guzzlehttp/guzzle
+masterminds/html5
+stack/builder
+symfony/class-loader
+symfony/console
+symfony/dependency-injection
+symfony/event-dispatcher
+symfony/http-foundation
+symfony/http-kernel
+symfony/routing
+symfony/serializer
+symfony/validator
+symfony/process
+symfony/yaml
+symfony-cmf/routing
+symfony/psr-http-message-bridge
+twig/twig
+zendframework/zend-diactoros
+zendframework/zend-feed
+
+If you are writing code that depends on a library not listed here, you should
+add it explicitly as a dependency yourself in your own "composer.json" file.
diff --git a/core/lib/Symfony/Component/README.txt b/core/lib/Symfony/Component/README.txt
deleted file mode 100644
index be736567d2e9bebbec90a2864fdc8615ecde83d6..0000000000000000000000000000000000000000
--- a/core/lib/Symfony/Component/README.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-Symfony component interfaces included as part of the Drupal codebase are used to
-provide Drupal-specific implementations of Symfony subsystems that are not
-available as standalone components and thus cannot be cherry-picked.
-
-A composer.json "replace" entry is used in order to bypass the composer.json
-dependency onto the Symfony components originally including the interfaces
-provided here.
diff --git a/core/vendor/composer/autoload_psr4.php b/core/vendor/composer/autoload_psr4.php
index 7fac11d7e0b9b7cbf6506f8ca6a90c9a702f490f..bd3969e3ba734fd505e37413fbdf6759485f29e6 100644
--- a/core/vendor/composer/autoload_psr4.php
+++ b/core/vendor/composer/autoload_psr4.php
@@ -12,7 +12,7 @@
     'Zend\\Diactoros\\' => array($vendorDir . '/zendframework/zend-diactoros/src'),
     'Symfony\\Component\\Yaml\\' => array($vendorDir . '/symfony/yaml'),
     'Symfony\\Component\\Validator\\' => array($vendorDir . '/symfony/validator'),
-    'Symfony\\Component\\Translation\\' => array($baseDir . '/lib/Symfony/Component/Translation'),
+    'Symfony\\Component\\Translation\\' => array($vendorDir . '/symfony/translation'),
     'Symfony\\Component\\Serializer\\' => array($vendorDir . '/symfony/serializer'),
     'Symfony\\Component\\Routing\\' => array($vendorDir . '/symfony/routing'),
     'Symfony\\Component\\Process\\' => array($vendorDir . '/symfony/process'),
diff --git a/core/vendor/composer/installed.json b/core/vendor/composer/installed.json
index 14a7478379b76f8fa01512c6d9b36ee9d26251d9..b539d270348b9a87a82562a835cadabbe8e11f1d 100644
--- a/core/vendor/composer/installed.json
+++ b/core/vendor/composer/installed.json
@@ -3415,5 +3415,68 @@
         "keywords": [
             "templating"
         ]
+    },
+    {
+        "name": "symfony/translation",
+        "version": "v2.7.4",
+        "version_normalized": "2.7.4.0",
+        "source": {
+            "type": "git",
+            "url": "https://github.com/symfony/Translation.git",
+            "reference": "485877661835e188cd78345c6d4eef1290d17571"
+        },
+        "dist": {
+            "type": "zip",
+            "url": "https://api.github.com/repos/symfony/Translation/zipball/485877661835e188cd78345c6d4eef1290d17571",
+            "reference": "485877661835e188cd78345c6d4eef1290d17571",
+            "shasum": ""
+        },
+        "require": {
+            "php": ">=5.3.9"
+        },
+        "conflict": {
+            "symfony/config": "<2.7"
+        },
+        "require-dev": {
+            "psr/log": "~1.0",
+            "symfony/config": "~2.7",
+            "symfony/intl": "~2.4",
+            "symfony/phpunit-bridge": "~2.7",
+            "symfony/yaml": "~2.2"
+        },
+        "suggest": {
+            "psr/log": "To use logging capability in translator",
+            "symfony/config": "",
+            "symfony/yaml": ""
+        },
+        "time": "2015-09-06 08:36:38",
+        "type": "library",
+        "extra": {
+            "branch-alias": {
+                "dev-master": "2.7-dev"
+            }
+        },
+        "installation-source": "dist",
+        "autoload": {
+            "psr-4": {
+                "Symfony\\Component\\Translation\\": ""
+            }
+        },
+        "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 Translation Component",
+        "homepage": "https://symfony.com"
     }
 ]
diff --git a/core/vendor/symfony/translation/.gitignore b/core/vendor/symfony/translation/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..c49a5d8df5c6548379f00c77fe572a7217bce218
--- /dev/null
+++ b/core/vendor/symfony/translation/.gitignore
@@ -0,0 +1,3 @@
+vendor/
+composer.lock
+phpunit.xml
diff --git a/core/vendor/symfony/translation/CHANGELOG.md b/core/vendor/symfony/translation/CHANGELOG.md
new file mode 100644
index 0000000000000000000000000000000000000000..157752ca7718005db47ac773f18482e08f7c0ecf
--- /dev/null
+++ b/core/vendor/symfony/translation/CHANGELOG.md
@@ -0,0 +1,47 @@
+CHANGELOG
+=========
+
+2.7.0
+-----
+
+ * added DataCollectorTranslator for collecting the translated messages.
+
+2.6.0
+-----
+
+ * added possibility to cache catalogues
+ * added TranslatorBagInterface
+ * added LoggingTranslator
+ * added Translator::getMessages() for retrieving the message catalogue as an array
+
+2.5.0
+-----
+
+ * added relative file path template to the file dumpers
+ * added optional backup to the file dumpers
+ * changed IcuResFileDumper to extend FileDumper
+
+2.3.0
+-----
+
+ * added classes to make operations on catalogues (like making a diff or a merge on 2 catalogues)
+ * added Translator::getFallbackLocales()
+ * deprecated Translator::setFallbackLocale() in favor of the new Translator::setFallbackLocales() method
+
+2.2.0
+-----
+
+ * QtTranslationsLoader class renamed to QtFileLoader. QtTranslationsLoader is deprecated and will be removed in 2.3.
+ * [BC BREAK] uniformized the exception thrown by the load() method when an error occurs. The load() method now
+   throws Symfony\Component\Translation\Exception\NotFoundResourceException when a resource cannot be found
+   and Symfony\Component\Translation\Exception\InvalidResourceException when a resource is invalid.
+ * changed the exception class thrown by some load() methods from \RuntimeException to \InvalidArgumentException
+   (IcuDatFileLoader, IcuResFileLoader and QtFileLoader)
+
+2.1.0
+-----
+
+ * added support for more than one fallback locale
+ * added support for extracting translation messages from templates (Twig and PHP)
+ * added dumpers for translation catalogs
+ * added support for QT, gettext, and ResourceBundles
diff --git a/core/vendor/symfony/translation/Catalogue/AbstractOperation.php b/core/vendor/symfony/translation/Catalogue/AbstractOperation.php
new file mode 100644
index 0000000000000000000000000000000000000000..062056b7317c434e229f42cb163ff0e7944bdd66
--- /dev/null
+++ b/core/vendor/symfony/translation/Catalogue/AbstractOperation.php
@@ -0,0 +1,146 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Catalogue;
+
+use Symfony\Component\Translation\MessageCatalogue;
+use Symfony\Component\Translation\MessageCatalogueInterface;
+
+/**
+ * Base catalogues binary operation class.
+ *
+ * @author Jean-François Simon <contact@jfsimon.fr>
+ */
+abstract class AbstractOperation implements OperationInterface
+{
+    /**
+     * @var MessageCatalogueInterface
+     */
+    protected $source;
+
+    /**
+     * @var MessageCatalogueInterface
+     */
+    protected $target;
+
+    /**
+     * @var MessageCatalogue
+     */
+    protected $result;
+
+    /**
+     * @var null|array
+     */
+    private $domains;
+
+    /**
+     * @var array
+     */
+    protected $messages;
+
+    /**
+     * @param MessageCatalogueInterface $source
+     * @param MessageCatalogueInterface $target
+     *
+     * @throws \LogicException
+     */
+    public function __construct(MessageCatalogueInterface $source, MessageCatalogueInterface $target)
+    {
+        if ($source->getLocale() !== $target->getLocale()) {
+            throw new \LogicException('Operated catalogues must belong to the same locale.');
+        }
+
+        $this->source = $source;
+        $this->target = $target;
+        $this->result = new MessageCatalogue($source->getLocale());
+        $this->domains = null;
+        $this->messages = array();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getDomains()
+    {
+        if (null === $this->domains) {
+            $this->domains = array_values(array_unique(array_merge($this->source->getDomains(), $this->target->getDomains())));
+        }
+
+        return $this->domains;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getMessages($domain)
+    {
+        if (!in_array($domain, $this->getDomains())) {
+            throw new \InvalidArgumentException(sprintf('Invalid domain: %s.', $domain));
+        }
+
+        if (!isset($this->messages[$domain]['all'])) {
+            $this->processDomain($domain);
+        }
+
+        return $this->messages[$domain]['all'];
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getNewMessages($domain)
+    {
+        if (!in_array($domain, $this->getDomains())) {
+            throw new \InvalidArgumentException(sprintf('Invalid domain: %s.', $domain));
+        }
+
+        if (!isset($this->messages[$domain]['new'])) {
+            $this->processDomain($domain);
+        }
+
+        return $this->messages[$domain]['new'];
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getObsoleteMessages($domain)
+    {
+        if (!in_array($domain, $this->getDomains())) {
+            throw new \InvalidArgumentException(sprintf('Invalid domain: %s.', $domain));
+        }
+
+        if (!isset($this->messages[$domain]['obsolete'])) {
+            $this->processDomain($domain);
+        }
+
+        return $this->messages[$domain]['obsolete'];
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getResult()
+    {
+        foreach ($this->getDomains() as $domain) {
+            if (!isset($this->messages[$domain])) {
+                $this->processDomain($domain);
+            }
+        }
+
+        return $this->result;
+    }
+
+    /**
+     * @param string $domain
+     */
+    abstract protected function processDomain($domain);
+}
diff --git a/core/vendor/symfony/translation/Catalogue/DiffOperation.php b/core/vendor/symfony/translation/Catalogue/DiffOperation.php
new file mode 100644
index 0000000000000000000000000000000000000000..2d1994ee279146d54203ce6bca92fbe44b70b1c1
--- /dev/null
+++ b/core/vendor/symfony/translation/Catalogue/DiffOperation.php
@@ -0,0 +1,55 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Catalogue;
+
+/**
+ * Diff operation between two catalogues.
+ *
+ * @author Jean-François Simon <contact@jfsimon.fr>
+ */
+class DiffOperation extends AbstractOperation
+{
+    /**
+     * {@inheritdoc}
+     */
+    protected function processDomain($domain)
+    {
+        $this->messages[$domain] = array(
+            'all' => array(),
+            'new' => array(),
+            'obsolete' => array(),
+        );
+
+        foreach ($this->source->all($domain) as $id => $message) {
+            if ($this->target->has($id, $domain)) {
+                $this->messages[$domain]['all'][$id] = $message;
+                $this->result->add(array($id => $message), $domain);
+                if (null !== $keyMetadata = $this->source->getMetadata($id, $domain)) {
+                    $this->result->setMetadata($id, $keyMetadata, $domain);
+                }
+            } else {
+                $this->messages[$domain]['obsolete'][$id] = $message;
+            }
+        }
+
+        foreach ($this->target->all($domain) as $id => $message) {
+            if (!$this->source->has($id, $domain)) {
+                $this->messages[$domain]['all'][$id] = $message;
+                $this->messages[$domain]['new'][$id] = $message;
+                $this->result->add(array($id => $message), $domain);
+                if (null !== $keyMetadata = $this->target->getMetadata($id, $domain)) {
+                    $this->result->setMetadata($id, $keyMetadata, $domain);
+                }
+            }
+        }
+    }
+}
diff --git a/core/vendor/symfony/translation/Catalogue/MergeOperation.php b/core/vendor/symfony/translation/Catalogue/MergeOperation.php
new file mode 100644
index 0000000000000000000000000000000000000000..562ca0ea0854aa6d4a92836fd7596cd48960a87f
--- /dev/null
+++ b/core/vendor/symfony/translation/Catalogue/MergeOperation.php
@@ -0,0 +1,51 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Catalogue;
+
+/**
+ * Merge operation between two catalogues.
+ *
+ * @author Jean-François Simon <contact@jfsimon.fr>
+ */
+class MergeOperation extends AbstractOperation
+{
+    /**
+     * {@inheritdoc}
+     */
+    protected function processDomain($domain)
+    {
+        $this->messages[$domain] = array(
+            'all' => array(),
+            'new' => array(),
+            'obsolete' => array(),
+        );
+
+        foreach ($this->source->all($domain) as $id => $message) {
+            $this->messages[$domain]['all'][$id] = $message;
+            $this->result->add(array($id => $message), $domain);
+            if (null !== $keyMetadata = $this->source->getMetadata($id, $domain)) {
+                $this->result->setMetadata($id, $keyMetadata, $domain);
+            }
+        }
+
+        foreach ($this->target->all($domain) as $id => $message) {
+            if (!$this->source->has($id, $domain)) {
+                $this->messages[$domain]['all'][$id] = $message;
+                $this->messages[$domain]['new'][$id] = $message;
+                $this->result->add(array($id => $message), $domain);
+                if (null !== $keyMetadata = $this->target->getMetadata($id, $domain)) {
+                    $this->result->setMetadata($id, $keyMetadata, $domain);
+                }
+            }
+        }
+    }
+}
diff --git a/core/vendor/symfony/translation/Catalogue/OperationInterface.php b/core/vendor/symfony/translation/Catalogue/OperationInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..d72378a3b3c175a53713ace530eb49cd26107078
--- /dev/null
+++ b/core/vendor/symfony/translation/Catalogue/OperationInterface.php
@@ -0,0 +1,63 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Catalogue;
+
+use Symfony\Component\Translation\MessageCatalogueInterface;
+
+/**
+ * Represents an operation on catalogue(s).
+ *
+ * @author Jean-François Simon <jeanfrancois.simon@sensiolabs.com>
+ */
+interface OperationInterface
+{
+    /**
+     * Returns domains affected by operation.
+     *
+     * @return array
+     */
+    public function getDomains();
+
+    /**
+     * Returns all valid messages after operation.
+     *
+     * @param string $domain
+     *
+     * @return array
+     */
+    public function getMessages($domain);
+
+    /**
+     * Returns new messages after operation.
+     *
+     * @param string $domain
+     *
+     * @return array
+     */
+    public function getNewMessages($domain);
+
+    /**
+     * Returns obsolete messages after operation.
+     *
+     * @param string $domain
+     *
+     * @return array
+     */
+    public function getObsoleteMessages($domain);
+
+    /**
+     * Returns resulting catalogue.
+     *
+     * @return MessageCatalogueInterface
+     */
+    public function getResult();
+}
diff --git a/core/vendor/symfony/translation/DataCollector/TranslationDataCollector.php b/core/vendor/symfony/translation/DataCollector/TranslationDataCollector.php
new file mode 100644
index 0000000000000000000000000000000000000000..c3c140f4a94f9382208fbe022ddc7698e2943c3f
--- /dev/null
+++ b/core/vendor/symfony/translation/DataCollector/TranslationDataCollector.php
@@ -0,0 +1,145 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\DataCollector;
+
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpFoundation\Response;
+use Symfony\Component\HttpKernel\DataCollector\DataCollector;
+use Symfony\Component\HttpKernel\DataCollector\LateDataCollectorInterface;
+use Symfony\Component\Translation\DataCollectorTranslator;
+
+/**
+ * @author Abdellatif Ait boudad <a.aitboudad@gmail.com>
+ */
+class TranslationDataCollector extends DataCollector implements LateDataCollectorInterface
+{
+    /**
+     * @var DataCollectorTranslator
+     */
+    private $translator;
+
+    /**
+     * @param DataCollectorTranslator $translator
+     */
+    public function __construct(DataCollectorTranslator $translator)
+    {
+        $this->translator = $translator;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function lateCollect()
+    {
+        $messages = $this->sanitizeCollectedMessages($this->translator->getCollectedMessages());
+
+        $this->data = $this->computeCount($messages);
+        $this->data['messages'] = $messages;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function collect(Request $request, Response $response, \Exception $exception = null)
+    {
+    }
+
+    /**
+     * @return array
+     */
+    public function getMessages()
+    {
+        return isset($this->data['messages']) ? $this->data['messages'] : array();
+    }
+
+    /**
+     * @return int
+     */
+    public function getCountMissings()
+    {
+        return isset($this->data[DataCollectorTranslator::MESSAGE_MISSING]) ? $this->data[DataCollectorTranslator::MESSAGE_MISSING] : 0;
+    }
+
+    /**
+     * @return int
+     */
+    public function getCountFallbacks()
+    {
+        return isset($this->data[DataCollectorTranslator::MESSAGE_EQUALS_FALLBACK]) ? $this->data[DataCollectorTranslator::MESSAGE_EQUALS_FALLBACK] : 0;
+    }
+
+    /**
+     * @return int
+     */
+    public function getCountDefines()
+    {
+        return isset($this->data[DataCollectorTranslator::MESSAGE_DEFINED]) ? $this->data[DataCollectorTranslator::MESSAGE_DEFINED] : 0;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getName()
+    {
+        return 'translation';
+    }
+
+    private function sanitizeCollectedMessages($messages)
+    {
+        $result = array();
+        foreach ($messages as $key => $message) {
+            $messageId = $message['locale'].$message['domain'].$message['id'];
+
+            if (!isset($result[$messageId])) {
+                $message['count'] = 1;
+                $messages[$key]['translation'] = $this->sanitizeString($message['translation']);
+                $result[$messageId] = $message;
+            } else {
+                ++$result[$messageId]['count'];
+            }
+
+            unset($messages[$key]);
+        }
+
+        return $result;
+    }
+
+    private function computeCount($messages)
+    {
+        $count = array(
+            DataCollectorTranslator::MESSAGE_DEFINED => 0,
+            DataCollectorTranslator::MESSAGE_MISSING => 0,
+            DataCollectorTranslator::MESSAGE_EQUALS_FALLBACK => 0,
+        );
+
+        foreach ($messages as $message) {
+            ++$count[$message['state']];
+        }
+
+        return $count;
+    }
+
+    private function sanitizeString($string, $length = 80)
+    {
+        $string = trim(preg_replace('/\s+/', ' ', $string));
+
+        if (function_exists('mb_strlen') && false !== $encoding = mb_detect_encoding($string)) {
+            if (mb_strlen($string, $encoding) > $length) {
+                return mb_substr($string, 0, $length - 3, $encoding).'...';
+            }
+        } elseif (strlen($string) > $length) {
+            return substr($string, 0, $length - 3).'...';
+        }
+
+        return $string;
+    }
+}
diff --git a/core/vendor/symfony/translation/DataCollectorTranslator.php b/core/vendor/symfony/translation/DataCollectorTranslator.php
new file mode 100644
index 0000000000000000000000000000000000000000..813a85760ae141e0662b59d12fab17e91bf29c72
--- /dev/null
+++ b/core/vendor/symfony/translation/DataCollectorTranslator.php
@@ -0,0 +1,152 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation;
+
+/**
+ * @author Abdellatif Ait boudad <a.aitboudad@gmail.com>
+ */
+class DataCollectorTranslator implements TranslatorInterface, TranslatorBagInterface
+{
+    const MESSAGE_DEFINED = 0;
+    const MESSAGE_MISSING = 1;
+    const MESSAGE_EQUALS_FALLBACK = 2;
+
+    /**
+     * @var TranslatorInterface|TranslatorBagInterface
+     */
+    private $translator;
+
+    /**
+     * @var array
+     */
+    private $messages = array();
+
+    /**
+     * @param TranslatorInterface $translator The translator must implement TranslatorBagInterface
+     */
+    public function __construct(TranslatorInterface $translator)
+    {
+        if (!$translator instanceof TranslatorBagInterface) {
+            throw new \InvalidArgumentException(sprintf('The Translator "%s" must implement TranslatorInterface and TranslatorBagInterface.', get_class($translator)));
+        }
+
+        $this->translator = $translator;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function trans($id, array $parameters = array(), $domain = null, $locale = null)
+    {
+        $trans = $this->translator->trans($id, $parameters, $domain, $locale);
+        $this->collectMessage($locale, $domain, $id, $trans);
+
+        return $trans;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function transChoice($id, $number, array $parameters = array(), $domain = null, $locale = null)
+    {
+        $trans = $this->translator->transChoice($id, $number, $parameters, $domain, $locale);
+        $this->collectMessage($locale, $domain, $id, $trans);
+
+        return $trans;
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @api
+     */
+    public function setLocale($locale)
+    {
+        $this->translator->setLocale($locale);
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @api
+     */
+    public function getLocale()
+    {
+        return $this->translator->getLocale();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getCatalogue($locale = null)
+    {
+        return $this->translator->getCatalogue($locale);
+    }
+
+    /**
+     * Passes through all unknown calls onto the translator object.
+     */
+    public function __call($method, $args)
+    {
+        return call_user_func_array(array($this->translator, $method), $args);
+    }
+
+    /**
+     * @return array
+     */
+    public function getCollectedMessages()
+    {
+        return $this->messages;
+    }
+
+    /**
+     * @param string|null $locale
+     * @param string|null $domain
+     * @param string      $id
+     * @param string      $trans
+     */
+    private function collectMessage($locale, $domain, $id, $translation)
+    {
+        if (null === $domain) {
+            $domain = 'messages';
+        }
+
+        $id = (string) $id;
+        $catalogue = $this->translator->getCatalogue($locale);
+        $locale = $catalogue->getLocale();
+        if ($catalogue->defines($id, $domain)) {
+            $state = self::MESSAGE_DEFINED;
+        } elseif ($catalogue->has($id, $domain)) {
+            $state = self::MESSAGE_EQUALS_FALLBACK;
+
+            $fallbackCatalogue = $catalogue->getFallBackCatalogue();
+            while ($fallbackCatalogue) {
+                if ($fallbackCatalogue->defines($id, $domain)) {
+                    $locale = $fallbackCatalogue->getLocale();
+                    break;
+                }
+
+                $fallbackCatalogue = $fallbackCatalogue->getFallBackCatalogue();
+            }
+        } else {
+            $state = self::MESSAGE_MISSING;
+        }
+
+        $this->messages[] = array(
+            'locale' => $locale,
+            'domain' => $domain,
+            'id' => $id,
+            'translation' => $translation,
+            'state' => $state,
+        );
+    }
+}
diff --git a/core/vendor/symfony/translation/Dumper/CsvFileDumper.php b/core/vendor/symfony/translation/Dumper/CsvFileDumper.php
new file mode 100644
index 0000000000000000000000000000000000000000..08005b097d54d65ac0ba22f23a06a5f914e0b77d
--- /dev/null
+++ b/core/vendor/symfony/translation/Dumper/CsvFileDumper.php
@@ -0,0 +1,63 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Dumper;
+
+use Symfony\Component\Translation\MessageCatalogue;
+
+/**
+ * CsvFileDumper generates a csv formatted string representation of a message catalogue.
+ *
+ * @author Stealth35
+ */
+class CsvFileDumper extends FileDumper
+{
+    private $delimiter = ';';
+    private $enclosure = '"';
+
+    /**
+     * {@inheritdoc}
+     */
+    public function format(MessageCatalogue $messages, $domain = 'messages')
+    {
+        $handle = fopen('php://memory', 'rb+');
+
+        foreach ($messages->all($domain) as $source => $target) {
+            fputcsv($handle, array($source, $target), $this->delimiter, $this->enclosure);
+        }
+
+        rewind($handle);
+        $output = stream_get_contents($handle);
+        fclose($handle);
+
+        return $output;
+    }
+
+    /**
+     * Sets the delimiter and escape character for CSV.
+     *
+     * @param string $delimiter delimiter character
+     * @param string $enclosure enclosure character
+     */
+    public function setCsvControl($delimiter = ';', $enclosure = '"')
+    {
+        $this->delimiter = $delimiter;
+        $this->enclosure = $enclosure;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function getExtension()
+    {
+        return 'csv';
+    }
+}
diff --git a/core/vendor/symfony/translation/Dumper/DumperInterface.php b/core/vendor/symfony/translation/Dumper/DumperInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..cebc65ed89d90f6b1a2c7e5f627d5b6afce60353
--- /dev/null
+++ b/core/vendor/symfony/translation/Dumper/DumperInterface.php
@@ -0,0 +1,31 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Dumper;
+
+use Symfony\Component\Translation\MessageCatalogue;
+
+/**
+ * DumperInterface is the interface implemented by all translation dumpers.
+ * There is no common option.
+ *
+ * @author Michel Salib <michelsalib@hotmail.com>
+ */
+interface DumperInterface
+{
+    /**
+     * Dumps the message catalogue.
+     *
+     * @param MessageCatalogue $messages The message catalogue
+     * @param array            $options  Options that are used by the dumper
+     */
+    public function dump(MessageCatalogue $messages, $options = array());
+}
diff --git a/core/vendor/symfony/translation/Dumper/FileDumper.php b/core/vendor/symfony/translation/Dumper/FileDumper.php
new file mode 100644
index 0000000000000000000000000000000000000000..f2f17d64fde16b29f9a9dc5eb4d27b5f0f919ca2
--- /dev/null
+++ b/core/vendor/symfony/translation/Dumper/FileDumper.php
@@ -0,0 +1,122 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Dumper;
+
+use Symfony\Component\Translation\MessageCatalogue;
+
+/**
+ * FileDumper is an implementation of DumperInterface that dump a message catalogue to file(s).
+ * Performs backup of already existing files.
+ *
+ * Options:
+ * - path (mandatory): the directory where the files should be saved
+ *
+ * @author Michel Salib <michelsalib@hotmail.com>
+ */
+abstract class FileDumper implements DumperInterface
+{
+    /**
+     * A template for the relative paths to files.
+     *
+     * @var string
+     */
+    protected $relativePathTemplate = '%domain%.%locale%.%extension%';
+
+    /**
+     * Make file backup before the dump.
+     *
+     * @var bool
+     */
+    private $backup = true;
+
+    /**
+     * Sets the template for the relative paths to files.
+     *
+     * @param string $relativePathTemplate A template for the relative paths to files
+     */
+    public function setRelativePathTemplate($relativePathTemplate)
+    {
+        $this->relativePathTemplate = $relativePathTemplate;
+    }
+
+    /**
+     * Sets backup flag.
+     *
+     * @param bool
+     */
+    public function setBackup($backup)
+    {
+        $this->backup = $backup;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function dump(MessageCatalogue $messages, $options = array())
+    {
+        if (!array_key_exists('path', $options)) {
+            throw new \InvalidArgumentException('The file dumper needs a path option.');
+        }
+
+        // save a file for each domain
+        foreach ($messages->getDomains() as $domain) {
+            // backup
+            $fullpath = $options['path'].'/'.$this->getRelativePath($domain, $messages->getLocale());
+            if (file_exists($fullpath)) {
+                if ($this->backup) {
+                    copy($fullpath, $fullpath.'~');
+                }
+            } else {
+                $directory = dirname($fullpath);
+                if (!file_exists($directory) && !@mkdir($directory, 0777, true)) {
+                    throw new \RuntimeException(sprintf('Unable to create directory "%s".', $directory));
+                }
+            }
+            // save file
+            file_put_contents($fullpath, $this->format($messages, $domain));
+        }
+    }
+
+    /**
+     * Transforms a domain of a message catalogue to its string representation.
+     *
+     * @param MessageCatalogue $messages
+     * @param string           $domain
+     *
+     * @return string representation
+     */
+    abstract protected function format(MessageCatalogue $messages, $domain);
+
+    /**
+     * Gets the file extension of the dumper.
+     *
+     * @return string file extension
+     */
+    abstract protected function getExtension();
+
+    /**
+     * Gets the relative file path using the template.
+     *
+     * @param string $domain The domain
+     * @param string $locale The locale
+     *
+     * @return string The relative file path
+     */
+    private function getRelativePath($domain, $locale)
+    {
+        return strtr($this->relativePathTemplate, array(
+            '%domain%' => $domain,
+            '%locale%' => $locale,
+            '%extension%' => $this->getExtension(),
+        ));
+    }
+}
diff --git a/core/vendor/symfony/translation/Dumper/IcuResFileDumper.php b/core/vendor/symfony/translation/Dumper/IcuResFileDumper.php
new file mode 100644
index 0000000000000000000000000000000000000000..0a2ed9f737335b3672993d774b43275331d90a94
--- /dev/null
+++ b/core/vendor/symfony/translation/Dumper/IcuResFileDumper.php
@@ -0,0 +1,112 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Dumper;
+
+use Symfony\Component\Translation\MessageCatalogue;
+
+/**
+ * IcuResDumper generates an ICU ResourceBundle formatted string representation of a message catalogue.
+ *
+ * @author Stealth35
+ */
+class IcuResFileDumper extends FileDumper
+{
+    /**
+     * {@inheritdoc}
+     */
+    protected $relativePathTemplate = '%domain%/%locale%.%extension%';
+
+    /**
+     * {@inheritdoc}
+     */
+    public function format(MessageCatalogue $messages, $domain = 'messages')
+    {
+        $data = $indexes = $resources = '';
+
+        foreach ($messages->all($domain) as $source => $target) {
+            $indexes .= pack('v', strlen($data) + 28);
+            $data    .= $source."\0";
+        }
+
+        $data .= $this->writePadding($data);
+
+        $keyTop = $this->getPosition($data);
+
+        foreach ($messages->all($domain) as $source => $target) {
+            $resources .= pack('V', $this->getPosition($data));
+
+            $data .= pack('V', strlen($target))
+                .mb_convert_encoding($target."\0", 'UTF-16LE', 'UTF-8')
+                .$this->writePadding($data)
+                  ;
+        }
+
+        $resOffset = $this->getPosition($data);
+
+        $data .= pack('v', count($messages))
+            .$indexes
+            .$this->writePadding($data)
+            .$resources
+              ;
+
+        $bundleTop = $this->getPosition($data);
+
+        $root = pack('V7',
+            $resOffset + (2 << 28), // Resource Offset + Resource Type
+            6,                      // Index length
+            $keyTop,                // Index keys top
+            $bundleTop,             // Index resources top
+            $bundleTop,             // Index bundle top
+            count($messages),       // Index max table length
+            0                       // Index attributes
+        );
+
+        $header = pack('vC2v4C12@32',
+            32,                     // Header size
+            0xDA, 0x27,             // Magic number 1 and 2
+            20, 0, 0, 2,            // Rest of the header, ..., Size of a char
+            0x52, 0x65, 0x73, 0x42, // Data format identifier
+            1, 2, 0, 0,             // Data version
+            1, 4, 0, 0              // Unicode version
+        );
+
+        $output = $header
+               .$root
+               .$data;
+
+        return $output;
+    }
+
+    private function writePadding($data)
+    {
+        $padding = strlen($data) % 4;
+
+        if ($padding) {
+            return str_repeat("\xAA", 4 - $padding);
+        }
+    }
+
+    private function getPosition($data)
+    {
+        $position = (strlen($data) + 28) / 4;
+
+        return $position;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function getExtension()
+    {
+        return 'res';
+    }
+}
diff --git a/core/vendor/symfony/translation/Dumper/IniFileDumper.php b/core/vendor/symfony/translation/Dumper/IniFileDumper.php
new file mode 100644
index 0000000000000000000000000000000000000000..45df389bd6987844c2218150273b2f802b3cfa11
--- /dev/null
+++ b/core/vendor/symfony/translation/Dumper/IniFileDumper.php
@@ -0,0 +1,45 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Dumper;
+
+use Symfony\Component\Translation\MessageCatalogue;
+
+/**
+ * IniFileDumper generates an ini formatted string representation of a message catalogue.
+ *
+ * @author Stealth35
+ */
+class IniFileDumper extends FileDumper
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function format(MessageCatalogue $messages, $domain = 'messages')
+    {
+        $output = '';
+
+        foreach ($messages->all($domain) as $source => $target) {
+            $escapeTarget = str_replace('"', '\"', $target);
+            $output .= $source.'="'.$escapeTarget."\"\n";
+        }
+
+        return $output;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function getExtension()
+    {
+        return 'ini';
+    }
+}
diff --git a/core/vendor/symfony/translation/Dumper/JsonFileDumper.php b/core/vendor/symfony/translation/Dumper/JsonFileDumper.php
new file mode 100644
index 0000000000000000000000000000000000000000..7ad35184cd55e98041266b4d01c3c653ffe7e83d
--- /dev/null
+++ b/core/vendor/symfony/translation/Dumper/JsonFileDumper.php
@@ -0,0 +1,38 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Dumper;
+
+use Symfony\Component\Translation\MessageCatalogue;
+
+/**
+ * JsonFileDumper generates an json formatted string representation of a message catalogue.
+ *
+ * @author singles
+ */
+class JsonFileDumper extends FileDumper
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function format(MessageCatalogue $messages, $domain = 'messages')
+    {
+        return json_encode($messages->all($domain), defined('JSON_PRETTY_PRINT') ? JSON_PRETTY_PRINT : 0);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function getExtension()
+    {
+        return 'json';
+    }
+}
diff --git a/core/vendor/symfony/translation/Dumper/MoFileDumper.php b/core/vendor/symfony/translation/Dumper/MoFileDumper.php
new file mode 100644
index 0000000000000000000000000000000000000000..f8dc6ac395fc492a6f3caabdc82ed47b02abe67b
--- /dev/null
+++ b/core/vendor/symfony/translation/Dumper/MoFileDumper.php
@@ -0,0 +1,82 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Dumper;
+
+use Symfony\Component\Translation\MessageCatalogue;
+use Symfony\Component\Translation\Loader\MoFileLoader;
+
+/**
+ * MoFileDumper generates a gettext formatted string representation of a message catalogue.
+ *
+ * @author Stealth35
+ */
+class MoFileDumper extends FileDumper
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function format(MessageCatalogue $messages, $domain = 'messages')
+    {
+        $output = $sources = $targets = $sourceOffsets = $targetOffsets = '';
+        $offsets = array();
+        $size = 0;
+
+        foreach ($messages->all($domain) as $source => $target) {
+            $offsets[] = array_map('strlen', array($sources, $source, $targets, $target));
+            $sources .= "\0".$source;
+            $targets .= "\0".$target;
+            ++$size;
+        }
+
+        $header = array(
+            'magicNumber' => MoFileLoader::MO_LITTLE_ENDIAN_MAGIC,
+            'formatRevision' => 0,
+            'count' => $size,
+            'offsetId' => MoFileLoader::MO_HEADER_SIZE,
+            'offsetTranslated' => MoFileLoader::MO_HEADER_SIZE + (8 * $size),
+            'sizeHashes' => 0,
+            'offsetHashes' => MoFileLoader::MO_HEADER_SIZE + (16 * $size),
+        );
+
+        $sourcesSize = strlen($sources);
+        $sourcesStart = $header['offsetHashes'] + 1;
+
+        foreach ($offsets as $offset) {
+            $sourceOffsets .= $this->writeLong($offset[1])
+                          .$this->writeLong($offset[0] + $sourcesStart);
+            $targetOffsets .= $this->writeLong($offset[3])
+                          .$this->writeLong($offset[2] + $sourcesStart + $sourcesSize);
+        }
+
+        $output = implode(array_map(array($this, 'writeLong'), $header))
+               .$sourceOffsets
+               .$targetOffsets
+               .$sources
+               .$targets
+                ;
+
+        return $output;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function getExtension()
+    {
+        return 'mo';
+    }
+
+    private function writeLong($str)
+    {
+        return pack('V*', $str);
+    }
+}
diff --git a/core/vendor/symfony/translation/Dumper/PhpFileDumper.php b/core/vendor/symfony/translation/Dumper/PhpFileDumper.php
new file mode 100644
index 0000000000000000000000000000000000000000..b354c1245c993915b1c413f11fa8861438b44ac6
--- /dev/null
+++ b/core/vendor/symfony/translation/Dumper/PhpFileDumper.php
@@ -0,0 +1,40 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Dumper;
+
+use Symfony\Component\Translation\MessageCatalogue;
+
+/**
+ * PhpFileDumper generates PHP files from a message catalogue.
+ *
+ * @author Michel Salib <michelsalib@hotmail.com>
+ */
+class PhpFileDumper extends FileDumper
+{
+    /**
+     * {@inheritdoc}
+     */
+    protected function format(MessageCatalogue $messages, $domain)
+    {
+        $output = "<?php\n\nreturn ".var_export($messages->all($domain), true).";\n";
+
+        return $output;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function getExtension()
+    {
+        return 'php';
+    }
+}
diff --git a/core/vendor/symfony/translation/Dumper/PoFileDumper.php b/core/vendor/symfony/translation/Dumper/PoFileDumper.php
new file mode 100644
index 0000000000000000000000000000000000000000..983064b5d7ca9e68c5c361d4e0edf05aec5775cc
--- /dev/null
+++ b/core/vendor/symfony/translation/Dumper/PoFileDumper.php
@@ -0,0 +1,61 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Dumper;
+
+use Symfony\Component\Translation\MessageCatalogue;
+
+/**
+ * PoFileDumper generates a gettext formatted string representation of a message catalogue.
+ *
+ * @author Stealth35
+ */
+class PoFileDumper extends FileDumper
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function format(MessageCatalogue $messages, $domain = 'messages')
+    {
+        $output = 'msgid ""'."\n";
+        $output .= 'msgstr ""'."\n";
+        $output .= '"Content-Type: text/plain; charset=UTF-8\n"'."\n";
+        $output .= '"Content-Transfer-Encoding: 8bit\n"'."\n";
+        $output .= '"Language: '.$messages->getLocale().'\n"'."\n";
+        $output .= "\n";
+
+        $newLine = false;
+        foreach ($messages->all($domain) as $source => $target) {
+            if ($newLine) {
+                $output .= "\n";
+            } else {
+                $newLine = true;
+            }
+            $output .= sprintf('msgid "%s"'."\n", $this->escape($source));
+            $output .= sprintf('msgstr "%s"', $this->escape($target));
+        }
+
+        return $output;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function getExtension()
+    {
+        return 'po';
+    }
+
+    private function escape($str)
+    {
+        return addcslashes($str, "\0..\37\42\134");
+    }
+}
diff --git a/core/vendor/symfony/translation/Dumper/QtFileDumper.php b/core/vendor/symfony/translation/Dumper/QtFileDumper.php
new file mode 100644
index 0000000000000000000000000000000000000000..42aa0934814932fb417471a5d74b4456b71bdf39
--- /dev/null
+++ b/core/vendor/symfony/translation/Dumper/QtFileDumper.php
@@ -0,0 +1,50 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Dumper;
+
+use Symfony\Component\Translation\MessageCatalogue;
+
+/**
+ * QtFileDumper generates ts files from a message catalogue.
+ *
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ */
+class QtFileDumper extends FileDumper
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function format(MessageCatalogue $messages, $domain)
+    {
+        $dom = new \DOMDocument('1.0', 'utf-8');
+        $dom->formatOutput = true;
+        $ts = $dom->appendChild($dom->createElement('TS'));
+        $context = $ts->appendChild($dom->createElement('context'));
+        $context->appendChild($dom->createElement('name', $domain));
+
+        foreach ($messages->all($domain) as $source => $target) {
+            $message = $context->appendChild($dom->createElement('message'));
+            $message->appendChild($dom->createElement('source', $source));
+            $message->appendChild($dom->createElement('translation', $target));
+        }
+
+        return $dom->saveXML();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function getExtension()
+    {
+        return 'ts';
+    }
+}
diff --git a/core/vendor/symfony/translation/Dumper/XliffFileDumper.php b/core/vendor/symfony/translation/Dumper/XliffFileDumper.php
new file mode 100644
index 0000000000000000000000000000000000000000..58d19733dbb36a65dfc337812b53783915bb248e
--- /dev/null
+++ b/core/vendor/symfony/translation/Dumper/XliffFileDumper.php
@@ -0,0 +1,109 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Dumper;
+
+use Symfony\Component\Translation\MessageCatalogue;
+
+/**
+ * XliffFileDumper generates xliff files from a message catalogue.
+ *
+ * @author Michel Salib <michelsalib@hotmail.com>
+ */
+class XliffFileDumper extends FileDumper
+{
+    /**
+     * @var string
+     */
+    private $defaultLocale;
+
+    /**
+     * {@inheritdoc}
+     */
+    public function dump(MessageCatalogue $messages, $options = array())
+    {
+        if (array_key_exists('default_locale', $options)) {
+            $this->defaultLocale = $options['default_locale'];
+        } else {
+            $this->defaultLocale = \Locale::getDefault();
+        }
+
+        parent::dump($messages, $options);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function format(MessageCatalogue $messages, $domain)
+    {
+        $dom = new \DOMDocument('1.0', 'utf-8');
+        $dom->formatOutput = true;
+
+        $xliff = $dom->appendChild($dom->createElement('xliff'));
+        $xliff->setAttribute('version', '1.2');
+        $xliff->setAttribute('xmlns', 'urn:oasis:names:tc:xliff:document:1.2');
+
+        $xliffFile = $xliff->appendChild($dom->createElement('file'));
+        $xliffFile->setAttribute('source-language', str_replace('_', '-', $this->defaultLocale));
+        $xliffFile->setAttribute('target-language', str_replace('_', '-', $messages->getLocale()));
+        $xliffFile->setAttribute('datatype', 'plaintext');
+        $xliffFile->setAttribute('original', 'file.ext');
+
+        $xliffBody = $xliffFile->appendChild($dom->createElement('body'));
+        foreach ($messages->all($domain) as $source => $target) {
+            $translation = $dom->createElement('trans-unit');
+
+            $translation->setAttribute('id', md5($source));
+            $translation->setAttribute('resname', $source);
+
+            $s = $translation->appendChild($dom->createElement('source'));
+            $s->appendChild($dom->createTextNode($source));
+
+            // Does the target contain characters requiring a CDATA section?
+            $text = 1 === preg_match('/[&<>]/', $target) ? $dom->createCDATASection($target) : $dom->createTextNode($target);
+
+            $t = $translation->appendChild($dom->createElement('target'));
+            $t->appendChild($text);
+
+            $metadata = $messages->getMetadata($source, $domain);
+            if (null !== $metadata && array_key_exists('notes', $metadata) && is_array($metadata['notes'])) {
+                foreach ($metadata['notes'] as $note) {
+                    if (!isset($note['content'])) {
+                        continue;
+                    }
+
+                    $n = $translation->appendChild($dom->createElement('note'));
+                    $n->appendChild($dom->createTextNode($note['content']));
+
+                    if (isset($note['priority'])) {
+                        $n->setAttribute('priority', $note['priority']);
+                    }
+
+                    if (isset($note['from'])) {
+                        $n->setAttribute('from', $note['from']);
+                    }
+                }
+            }
+
+            $xliffBody->appendChild($translation);
+        }
+
+        return $dom->saveXML();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function getExtension()
+    {
+        return 'xlf';
+    }
+}
diff --git a/core/vendor/symfony/translation/Dumper/YamlFileDumper.php b/core/vendor/symfony/translation/Dumper/YamlFileDumper.php
new file mode 100644
index 0000000000000000000000000000000000000000..870fb9838042da23f0c2ecbb959a3b8f0fb7a650
--- /dev/null
+++ b/core/vendor/symfony/translation/Dumper/YamlFileDumper.php
@@ -0,0 +1,43 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Dumper;
+
+use Symfony\Component\Translation\MessageCatalogue;
+use Symfony\Component\Yaml\Yaml;
+
+/**
+ * YamlFileDumper generates yaml files from a message catalogue.
+ *
+ * @author Michel Salib <michelsalib@hotmail.com>
+ */
+class YamlFileDumper extends FileDumper
+{
+    /**
+     * {@inheritdoc}
+     */
+    protected function format(MessageCatalogue $messages, $domain)
+    {
+        if (!class_exists('Symfony\Component\Yaml\Yaml')) {
+            throw new \LogicException('Dumping translations in the YAML format requires the Symfony Yaml component.');
+        }
+
+        return Yaml::dump($messages->all($domain));
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function getExtension()
+    {
+        return 'yml';
+    }
+}
diff --git a/core/vendor/symfony/translation/Exception/ExceptionInterface.php b/core/vendor/symfony/translation/Exception/ExceptionInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..7757e669a0cc95072481f1529535f72e1f66ed6a
--- /dev/null
+++ b/core/vendor/symfony/translation/Exception/ExceptionInterface.php
@@ -0,0 +1,23 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Exception;
+
+/**
+ * Exception interface for all exceptions thrown by the component.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ *
+ * @api
+ */
+interface ExceptionInterface
+{
+}
diff --git a/core/vendor/symfony/translation/Exception/InvalidResourceException.php b/core/vendor/symfony/translation/Exception/InvalidResourceException.php
new file mode 100644
index 0000000000000000000000000000000000000000..6413f1ae79ee574e7ce62501078e9ee12aa73c35
--- /dev/null
+++ b/core/vendor/symfony/translation/Exception/InvalidResourceException.php
@@ -0,0 +1,23 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Exception;
+
+/**
+ * Thrown when a resource cannot be loaded.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ *
+ * @api
+ */
+class InvalidResourceException extends \InvalidArgumentException implements ExceptionInterface
+{
+}
diff --git a/core/vendor/symfony/translation/Exception/NotFoundResourceException.php b/core/vendor/symfony/translation/Exception/NotFoundResourceException.php
new file mode 100644
index 0000000000000000000000000000000000000000..7826e5ce51bef6b125e80aa10f8225179303bf61
--- /dev/null
+++ b/core/vendor/symfony/translation/Exception/NotFoundResourceException.php
@@ -0,0 +1,23 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Exception;
+
+/**
+ * Thrown when a resource does not exist.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ *
+ * @api
+ */
+class NotFoundResourceException extends \InvalidArgumentException implements ExceptionInterface
+{
+}
diff --git a/core/vendor/symfony/translation/Extractor/AbstractFileExtractor.php b/core/vendor/symfony/translation/Extractor/AbstractFileExtractor.php
new file mode 100644
index 0000000000000000000000000000000000000000..196bc3341060aa718dc86a31d32aabacd236faf7
--- /dev/null
+++ b/core/vendor/symfony/translation/Extractor/AbstractFileExtractor.php
@@ -0,0 +1,83 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Extractor;
+
+/**
+ * Base class used by classes that extract translation messages from files.
+ *
+ * @author Marcos D. Sánchez <marcosdsanchez@gmail.com>
+ */
+abstract class AbstractFileExtractor
+{
+    /**
+     * @param string|array $resource files, a file or a directory
+     *
+     * @return array
+     */
+    protected function extractFiles($resource)
+    {
+        if (is_array($resource) || $resource instanceof \Traversable) {
+            $files = array();
+            foreach ($resource as $file) {
+                if ($this->canBeExtracted($file)) {
+                    $files[] = $this->toSplFileInfo($file);
+                }
+            }
+        } elseif (is_file($resource)) {
+            $files = $this->canBeExtracted($resource) ? array($this->toSplFileInfo($resource)) : array();
+        } else {
+            $files = $this->extractFromDirectory($resource);
+        }
+
+        return $files;
+    }
+
+    /**
+     * @param string $file
+     *
+     * @return \SplFileInfo
+     */
+    private function toSplFileInfo($file)
+    {
+        return ($file instanceof \SplFileInfo) ? $file : new \SplFileInfo($file);
+    }
+
+    /**
+     * @param string $file
+     *
+     * @throws \InvalidArgumentException
+     *
+     * @return bool
+     */
+    protected function isFile($file)
+    {
+        if (!is_file($file)) {
+            throw new \InvalidArgumentException(sprintf('The "%s" file does not exist.', $file));
+        }
+
+        return true;
+    }
+
+    /**
+     * @param string $file
+     *
+     * @return bool
+     */
+    abstract protected function canBeExtracted($file);
+
+    /**
+     * @param string|array $resource files, a file or a directory
+     *
+     * @return array files to be extracted
+     */
+    abstract protected function extractFromDirectory($resource);
+}
diff --git a/core/vendor/symfony/translation/Extractor/ChainExtractor.php b/core/vendor/symfony/translation/Extractor/ChainExtractor.php
new file mode 100644
index 0000000000000000000000000000000000000000..50e3c84579f2bcbcd1174cf9de019904e7c1d6fc
--- /dev/null
+++ b/core/vendor/symfony/translation/Extractor/ChainExtractor.php
@@ -0,0 +1,60 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Extractor;
+
+use Symfony\Component\Translation\MessageCatalogue;
+
+/**
+ * ChainExtractor extracts translation messages from template files.
+ *
+ * @author Michel Salib <michelsalib@hotmail.com>
+ */
+class ChainExtractor implements ExtractorInterface
+{
+    /**
+     * The extractors.
+     *
+     * @var ExtractorInterface[]
+     */
+    private $extractors = array();
+
+    /**
+     * Adds a loader to the translation extractor.
+     *
+     * @param string             $format    The format of the loader
+     * @param ExtractorInterface $extractor The loader
+     */
+    public function addExtractor($format, ExtractorInterface $extractor)
+    {
+        $this->extractors[$format] = $extractor;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function setPrefix($prefix)
+    {
+        foreach ($this->extractors as $extractor) {
+            $extractor->setPrefix($prefix);
+        }
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function extract($directory, MessageCatalogue $catalogue)
+    {
+        foreach ($this->extractors as $extractor) {
+            $extractor->extract($directory, $catalogue);
+        }
+    }
+}
diff --git a/core/vendor/symfony/translation/Extractor/ExtractorInterface.php b/core/vendor/symfony/translation/Extractor/ExtractorInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..438f80b32f053a026ca3cecb640dd9e5c34c0626
--- /dev/null
+++ b/core/vendor/symfony/translation/Extractor/ExtractorInterface.php
@@ -0,0 +1,38 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Extractor;
+
+use Symfony\Component\Translation\MessageCatalogue;
+
+/**
+ * Extracts translation messages from a directory or files to the catalogue.
+ * New found messages are injected to the catalogue using the prefix.
+ *
+ * @author Michel Salib <michelsalib@hotmail.com>
+ */
+interface ExtractorInterface
+{
+    /**
+     * Extracts translation messages from files, a file or a directory to the catalogue.
+     *
+     * @param string|array     $resource  files, a file or a directory
+     * @param MessageCatalogue $catalogue The catalogue
+     */
+    public function extract($resource, MessageCatalogue $catalogue);
+
+    /**
+     * Sets the prefix that should be used for new found messages.
+     *
+     * @param string $prefix The prefix
+     */
+    public function setPrefix($prefix);
+}
diff --git a/core/vendor/symfony/translation/IdentityTranslator.php b/core/vendor/symfony/translation/IdentityTranslator.php
new file mode 100644
index 0000000000000000000000000000000000000000..9c9212e80305028c0cde67208d719c4780f2939a
--- /dev/null
+++ b/core/vendor/symfony/translation/IdentityTranslator.php
@@ -0,0 +1,77 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation;
+
+/**
+ * IdentityTranslator does not translate anything.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ *
+ * @api
+ */
+class IdentityTranslator implements TranslatorInterface
+{
+    private $selector;
+    private $locale;
+
+    /**
+     * Constructor.
+     *
+     * @param MessageSelector|null $selector The message selector for pluralization
+     *
+     * @api
+     */
+    public function __construct(MessageSelector $selector = null)
+    {
+        $this->selector = $selector ?: new MessageSelector();
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @api
+     */
+    public function setLocale($locale)
+    {
+        $this->locale = $locale;
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @api
+     */
+    public function getLocale()
+    {
+        return $this->locale ?: \Locale::getDefault();
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @api
+     */
+    public function trans($id, array $parameters = array(), $domain = null, $locale = null)
+    {
+        return strtr((string) $id, $parameters);
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @api
+     */
+    public function transChoice($id, $number, array $parameters = array(), $domain = null, $locale = null)
+    {
+        return strtr($this->selector->choose((string) $id, (int) $number, $locale ?: $this->getLocale()), $parameters);
+    }
+}
diff --git a/core/vendor/symfony/translation/Interval.php b/core/vendor/symfony/translation/Interval.php
new file mode 100644
index 0000000000000000000000000000000000000000..2a51156ef73560e9bea2a419f392f930fcf632ef
--- /dev/null
+++ b/core/vendor/symfony/translation/Interval.php
@@ -0,0 +1,107 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation;
+
+/**
+ * Tests if a given number belongs to a given math interval.
+ *
+ * An interval can represent a finite set of numbers:
+ *
+ *  {1,2,3,4}
+ *
+ * An interval can represent numbers between two numbers:
+ *
+ *  [1, +Inf]
+ *  ]-1,2[
+ *
+ * The left delimiter can be [ (inclusive) or ] (exclusive).
+ * The right delimiter can be [ (exclusive) or ] (inclusive).
+ * Beside numbers, you can use -Inf and +Inf for the infinite.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ *
+ * @see    http://en.wikipedia.org/wiki/Interval_%28mathematics%29#The_ISO_notation
+ */
+class Interval
+{
+    /**
+     * Tests if the given number is in the math interval.
+     *
+     * @param int    $number   A number
+     * @param string $interval An interval
+     *
+     * @return bool
+     *
+     * @throws \InvalidArgumentException
+     */
+    public static function test($number, $interval)
+    {
+        $interval = trim($interval);
+
+        if (!preg_match('/^'.self::getIntervalRegexp().'$/x', $interval, $matches)) {
+            throw new \InvalidArgumentException(sprintf('"%s" is not a valid interval.', $interval));
+        }
+
+        if ($matches[1]) {
+            foreach (explode(',', $matches[2]) as $n) {
+                if ($number == $n) {
+                    return true;
+                }
+            }
+        } else {
+            $leftNumber = self::convertNumber($matches['left']);
+            $rightNumber = self::convertNumber($matches['right']);
+
+            return
+                ('[' === $matches['left_delimiter'] ? $number >= $leftNumber : $number > $leftNumber)
+                && (']' === $matches['right_delimiter'] ? $number <= $rightNumber : $number < $rightNumber)
+            ;
+        }
+
+        return false;
+    }
+
+    /**
+     * Returns a Regexp that matches valid intervals.
+     *
+     * @return string A Regexp (without the delimiters)
+     */
+    public static function getIntervalRegexp()
+    {
+        return <<<EOF
+        ({\s*
+            (\-?\d+(\.\d+)?[\s*,\s*\-?\d+(\.\d+)?]*)
+        \s*})
+
+            |
+
+        (?P<left_delimiter>[\[\]])
+            \s*
+            (?P<left>-Inf|\-?\d+(\.\d+)?)
+            \s*,\s*
+            (?P<right>\+?Inf|\-?\d+(\.\d+)?)
+            \s*
+        (?P<right_delimiter>[\[\]])
+EOF;
+    }
+
+    private static function convertNumber($number)
+    {
+        if ('-Inf' === $number) {
+            return log(0);
+        } elseif ('+Inf' === $number || 'Inf' === $number) {
+            return -log(0);
+        }
+
+        return (float) $number;
+    }
+}
diff --git a/core/lib/Symfony/Component/LICENSE b/core/vendor/symfony/translation/LICENSE
similarity index 100%
rename from core/lib/Symfony/Component/LICENSE
rename to core/vendor/symfony/translation/LICENSE
diff --git a/core/vendor/symfony/translation/Loader/ArrayLoader.php b/core/vendor/symfony/translation/Loader/ArrayLoader.php
new file mode 100644
index 0000000000000000000000000000000000000000..68ba81d4658d141853d0471711c1a15bdcad5d4c
--- /dev/null
+++ b/core/vendor/symfony/translation/Loader/ArrayLoader.php
@@ -0,0 +1,70 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Loader;
+
+use Symfony\Component\Translation\MessageCatalogue;
+
+/**
+ * ArrayLoader loads translations from a PHP array.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ *
+ * @api
+ */
+class ArrayLoader implements LoaderInterface
+{
+    /**
+     * {@inheritdoc}
+     *
+     * @api
+     */
+    public function load($resource, $locale, $domain = 'messages')
+    {
+        $this->flatten($resource);
+        $catalogue = new MessageCatalogue($locale);
+        $catalogue->add($resource, $domain);
+
+        return $catalogue;
+    }
+
+    /**
+     * Flattens an nested array of translations.
+     *
+     * The scheme used is:
+     *   'key' => array('key2' => array('key3' => 'value'))
+     * Becomes:
+     *   'key.key2.key3' => 'value'
+     *
+     * This function takes an array by reference and will modify it
+     *
+     * @param array  &$messages The array that will be flattened
+     * @param array  $subnode   Current subnode being parsed, used internally for recursive calls
+     * @param string $path      Current path being parsed, used internally for recursive calls
+     */
+    private function flatten(array &$messages, array $subnode = null, $path = null)
+    {
+        if (null === $subnode) {
+            $subnode = &$messages;
+        }
+        foreach ($subnode as $key => $value) {
+            if (is_array($value)) {
+                $nodePath = $path ? $path.'.'.$key : $key;
+                $this->flatten($messages, $value, $nodePath);
+                if (null === $path) {
+                    unset($messages[$key]);
+                }
+            } elseif (null !== $path) {
+                $messages[$path.'.'.$key] = $value;
+            }
+        }
+    }
+}
diff --git a/core/vendor/symfony/translation/Loader/CsvFileLoader.php b/core/vendor/symfony/translation/Loader/CsvFileLoader.php
new file mode 100644
index 0000000000000000000000000000000000000000..fc927601d900eb45b271a46daa1929998ba855e2
--- /dev/null
+++ b/core/vendor/symfony/translation/Loader/CsvFileLoader.php
@@ -0,0 +1,95 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Loader;
+
+use Symfony\Component\Translation\Exception\InvalidResourceException;
+use Symfony\Component\Translation\Exception\NotFoundResourceException;
+use Symfony\Component\Config\Resource\FileResource;
+
+/**
+ * CsvFileLoader loads translations from CSV files.
+ *
+ * @author Saša Stamenković <umpirsky@gmail.com>
+ *
+ * @api
+ */
+class CsvFileLoader extends ArrayLoader
+{
+    private $delimiter = ';';
+    private $enclosure = '"';
+    private $escape = '\\';
+
+    /**
+     * {@inheritdoc}
+     *
+     * @api
+     */
+    public function load($resource, $locale, $domain = 'messages')
+    {
+        if (!stream_is_local($resource)) {
+            throw new InvalidResourceException(sprintf('This is not a local file "%s".', $resource));
+        }
+
+        if (!file_exists($resource)) {
+            throw new NotFoundResourceException(sprintf('File "%s" not found.', $resource));
+        }
+
+        $messages = array();
+
+        try {
+            $file = new \SplFileObject($resource, 'rb');
+        } catch (\RuntimeException $e) {
+            throw new NotFoundResourceException(sprintf('Error opening file "%s".', $resource), 0, $e);
+        }
+
+        $file->setFlags(\SplFileObject::READ_CSV | \SplFileObject::SKIP_EMPTY);
+        $file->setCsvControl($this->delimiter, $this->enclosure, $this->escape);
+
+        foreach ($file as $data) {
+            if (substr($data[0], 0, 1) === '#') {
+                continue;
+            }
+
+            if (!isset($data[1])) {
+                continue;
+            }
+
+            if (count($data) == 2) {
+                $messages[$data[0]] = $data[1];
+            } else {
+                continue;
+            }
+        }
+
+        $catalogue = parent::load($messages, $locale, $domain);
+
+        if (class_exists('Symfony\Component\Config\Resource\FileResource')) {
+            $catalogue->addResource(new FileResource($resource));
+        }
+
+        return $catalogue;
+    }
+
+    /**
+     * Sets the delimiter, enclosure, and escape character for CSV.
+     *
+     * @param string $delimiter delimiter character
+     * @param string $enclosure enclosure character
+     * @param string $escape    escape character
+     */
+    public function setCsvControl($delimiter = ';', $enclosure = '"', $escape = '\\')
+    {
+        $this->delimiter = $delimiter;
+        $this->enclosure = $enclosure;
+        $this->escape = $escape;
+    }
+}
diff --git a/core/vendor/symfony/translation/Loader/IcuDatFileLoader.php b/core/vendor/symfony/translation/Loader/IcuDatFileLoader.php
new file mode 100644
index 0000000000000000000000000000000000000000..71ba90a39d9cc118f6ee9622029632b193c35eff
--- /dev/null
+++ b/core/vendor/symfony/translation/Loader/IcuDatFileLoader.php
@@ -0,0 +1,62 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Loader;
+
+use Symfony\Component\Translation\MessageCatalogue;
+use Symfony\Component\Translation\Exception\InvalidResourceException;
+use Symfony\Component\Translation\Exception\NotFoundResourceException;
+use Symfony\Component\Config\Resource\FileResource;
+
+/**
+ * IcuResFileLoader loads translations from a resource bundle.
+ *
+ * @author stealth35
+ */
+class IcuDatFileLoader extends IcuResFileLoader
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function load($resource, $locale, $domain = 'messages')
+    {
+        if (!stream_is_local($resource.'.dat')) {
+            throw new InvalidResourceException(sprintf('This is not a local file "%s".', $resource));
+        }
+
+        if (!file_exists($resource.'.dat')) {
+            throw new NotFoundResourceException(sprintf('File "%s" not found.', $resource));
+        }
+
+        try {
+            $rb = new \ResourceBundle($locale, $resource);
+        } catch (\Exception $e) {
+            // HHVM compatibility: constructor throws on invalid resource
+            $rb = null;
+        }
+
+        if (!$rb) {
+            throw new InvalidResourceException(sprintf('Cannot load resource "%s"', $resource));
+        } elseif (intl_is_failure($rb->getErrorCode())) {
+            throw new InvalidResourceException($rb->getErrorMessage(), $rb->getErrorCode());
+        }
+
+        $messages = $this->flatten($rb);
+        $catalogue = new MessageCatalogue($locale);
+        $catalogue->add($messages, $domain);
+
+        if (class_exists('Symfony\Component\Config\Resource\FileResource')) {
+            $catalogue->addResource(new FileResource($resource.'.dat'));
+        }
+
+        return $catalogue;
+    }
+}
diff --git a/core/vendor/symfony/translation/Loader/IcuResFileLoader.php b/core/vendor/symfony/translation/Loader/IcuResFileLoader.php
new file mode 100644
index 0000000000000000000000000000000000000000..2f8037fb164d8a70ad2210f4e21130f92d1039fe
--- /dev/null
+++ b/core/vendor/symfony/translation/Loader/IcuResFileLoader.php
@@ -0,0 +1,92 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Loader;
+
+use Symfony\Component\Translation\MessageCatalogue;
+use Symfony\Component\Translation\Exception\InvalidResourceException;
+use Symfony\Component\Translation\Exception\NotFoundResourceException;
+use Symfony\Component\Config\Resource\DirectoryResource;
+
+/**
+ * IcuResFileLoader loads translations from a resource bundle.
+ *
+ * @author stealth35
+ */
+class IcuResFileLoader implements LoaderInterface
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function load($resource, $locale, $domain = 'messages')
+    {
+        if (!stream_is_local($resource)) {
+            throw new InvalidResourceException(sprintf('This is not a local file "%s".', $resource));
+        }
+
+        if (!is_dir($resource)) {
+            throw new NotFoundResourceException(sprintf('File "%s" not found.', $resource));
+        }
+
+        try {
+            $rb = new \ResourceBundle($locale, $resource);
+        } catch (\Exception $e) {
+            // HHVM compatibility: constructor throws on invalid resource
+            $rb = null;
+        }
+
+        if (!$rb) {
+            throw new InvalidResourceException(sprintf('Cannot load resource "%s"', $resource));
+        } elseif (intl_is_failure($rb->getErrorCode())) {
+            throw new InvalidResourceException($rb->getErrorMessage(), $rb->getErrorCode());
+        }
+
+        $messages = $this->flatten($rb);
+        $catalogue = new MessageCatalogue($locale);
+        $catalogue->add($messages, $domain);
+
+        if (class_exists('Symfony\Component\Config\Resource\DirectoryResource')) {
+            $catalogue->addResource(new DirectoryResource($resource));
+        }
+
+        return $catalogue;
+    }
+
+    /**
+     * Flattens an ResourceBundle.
+     *
+     * The scheme used is:
+     *   key { key2 { key3 { "value" } } }
+     * Becomes:
+     *   'key.key2.key3' => 'value'
+     *
+     * This function takes an array by reference and will modify it
+     *
+     * @param \ResourceBundle $rb       the ResourceBundle that will be flattened
+     * @param array           $messages used internally for recursive calls
+     * @param string          $path     current path being parsed, used internally for recursive calls
+     *
+     * @return array the flattened ResourceBundle
+     */
+    protected function flatten(\ResourceBundle $rb, array &$messages = array(), $path = null)
+    {
+        foreach ($rb as $key => $value) {
+            $nodePath = $path ? $path.'.'.$key : $key;
+            if ($value instanceof \ResourceBundle) {
+                $this->flatten($value, $messages, $nodePath);
+            } else {
+                $messages[$nodePath] = $value;
+            }
+        }
+
+        return $messages;
+    }
+}
diff --git a/core/vendor/symfony/translation/Loader/IniFileLoader.php b/core/vendor/symfony/translation/Loader/IniFileLoader.php
new file mode 100644
index 0000000000000000000000000000000000000000..1b3a7b19118ff4cf4d302231b1931d56a7feed9e
--- /dev/null
+++ b/core/vendor/symfony/translation/Loader/IniFileLoader.php
@@ -0,0 +1,48 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Loader;
+
+use Symfony\Component\Translation\Exception\InvalidResourceException;
+use Symfony\Component\Translation\Exception\NotFoundResourceException;
+use Symfony\Component\Config\Resource\FileResource;
+
+/**
+ * IniFileLoader loads translations from an ini file.
+ *
+ * @author stealth35
+ */
+class IniFileLoader extends ArrayLoader
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function load($resource, $locale, $domain = 'messages')
+    {
+        if (!stream_is_local($resource)) {
+            throw new InvalidResourceException(sprintf('This is not a local file "%s".', $resource));
+        }
+
+        if (!file_exists($resource)) {
+            throw new NotFoundResourceException(sprintf('File "%s" not found.', $resource));
+        }
+
+        $messages = parse_ini_file($resource, true);
+
+        $catalogue = parent::load($messages, $locale, $domain);
+
+        if (class_exists('Symfony\Component\Config\Resource\FileResource')) {
+            $catalogue->addResource(new FileResource($resource));
+        }
+
+        return $catalogue;
+    }
+}
diff --git a/core/vendor/symfony/translation/Loader/JsonFileLoader.php b/core/vendor/symfony/translation/Loader/JsonFileLoader.php
new file mode 100644
index 0000000000000000000000000000000000000000..81717f3d9418f74f7f4bb979c69d36389b365757
--- /dev/null
+++ b/core/vendor/symfony/translation/Loader/JsonFileLoader.php
@@ -0,0 +1,81 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Loader;
+
+use Symfony\Component\Translation\Exception\InvalidResourceException;
+use Symfony\Component\Translation\Exception\NotFoundResourceException;
+use Symfony\Component\Config\Resource\FileResource;
+
+/**
+ * JsonFileLoader loads translations from an json file.
+ *
+ * @author singles
+ */
+class JsonFileLoader extends ArrayLoader
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function load($resource, $locale, $domain = 'messages')
+    {
+        if (!stream_is_local($resource)) {
+            throw new InvalidResourceException(sprintf('This is not a local file "%s".', $resource));
+        }
+
+        if (!file_exists($resource)) {
+            throw new NotFoundResourceException(sprintf('File "%s" not found.', $resource));
+        }
+
+        $messages = array();
+        if ($data = file_get_contents($resource)) {
+            $messages = json_decode($data, true);
+
+            if (0 < $errorCode = json_last_error()) {
+                throw new InvalidResourceException(sprintf('Error parsing JSON - %s', $this->getJSONErrorMessage($errorCode)));
+            }
+        }
+
+        if (null === $messages) {
+            $messages = array();
+        }
+
+        $catalogue = parent::load($messages, $locale, $domain);
+        $catalogue->addResource(new FileResource($resource));
+
+        return $catalogue;
+    }
+
+    /**
+     * Translates JSON_ERROR_* constant into meaningful message.
+     *
+     * @param int $errorCode Error code returned by json_last_error() call
+     *
+     * @return string Message string
+     */
+    private function getJSONErrorMessage($errorCode)
+    {
+        switch ($errorCode) {
+            case JSON_ERROR_DEPTH:
+                return 'Maximum stack depth exceeded';
+            case JSON_ERROR_STATE_MISMATCH:
+                return 'Underflow or the modes mismatch';
+            case JSON_ERROR_CTRL_CHAR:
+                return 'Unexpected control character found';
+            case JSON_ERROR_SYNTAX:
+                return 'Syntax error, malformed JSON';
+            case JSON_ERROR_UTF8:
+                return 'Malformed UTF-8 characters, possibly incorrectly encoded';
+            default:
+                return 'Unknown error';
+        }
+    }
+}
diff --git a/core/vendor/symfony/translation/Loader/LoaderInterface.php b/core/vendor/symfony/translation/Loader/LoaderInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..0b28e14a0de82232cc9fde3fd676f2e25ee9d6c8
--- /dev/null
+++ b/core/vendor/symfony/translation/Loader/LoaderInterface.php
@@ -0,0 +1,42 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Loader;
+
+use Symfony\Component\Translation\MessageCatalogue;
+use Symfony\Component\Translation\Exception\InvalidResourceException;
+use Symfony\Component\Translation\Exception\NotFoundResourceException;
+
+/**
+ * LoaderInterface is the interface implemented by all translation loaders.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ *
+ * @api
+ */
+interface LoaderInterface
+{
+    /**
+     * Loads a locale.
+     *
+     * @param mixed  $resource A resource
+     * @param string $locale   A locale
+     * @param string $domain   The domain
+     *
+     * @return MessageCatalogue A MessageCatalogue instance
+     *
+     * @api
+     *
+     * @throws NotFoundResourceException when the resource cannot be found
+     * @throws InvalidResourceException  when the resource cannot be loaded
+     */
+    public function load($resource, $locale, $domain = 'messages');
+}
diff --git a/core/vendor/symfony/translation/Loader/MoFileLoader.php b/core/vendor/symfony/translation/Loader/MoFileLoader.php
new file mode 100644
index 0000000000000000000000000000000000000000..746fd5290434761d00030174ae066a3a9b3003cc
--- /dev/null
+++ b/core/vendor/symfony/translation/Loader/MoFileLoader.php
@@ -0,0 +1,191 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Loader;
+
+use Symfony\Component\Translation\Exception\InvalidResourceException;
+use Symfony\Component\Translation\Exception\NotFoundResourceException;
+use Symfony\Component\Config\Resource\FileResource;
+
+/**
+ * @copyright Copyright (c) 2010, Union of RAD http://union-of-rad.org (http://lithify.me/)
+ */
+class MoFileLoader extends ArrayLoader
+{
+    /**
+     * Magic used for validating the format of a MO file as well as
+     * detecting if the machine used to create that file was little endian.
+     *
+     * @var float
+     */
+    const MO_LITTLE_ENDIAN_MAGIC = 0x950412de;
+
+    /**
+     * Magic used for validating the format of a MO file as well as
+     * detecting if the machine used to create that file was big endian.
+     *
+     * @var float
+     */
+    const MO_BIG_ENDIAN_MAGIC = 0xde120495;
+
+    /**
+     * The size of the header of a MO file in bytes.
+     *
+     * @var int Number of bytes.
+     */
+    const MO_HEADER_SIZE = 28;
+
+    public function load($resource, $locale, $domain = 'messages')
+    {
+        if (!stream_is_local($resource)) {
+            throw new InvalidResourceException(sprintf('This is not a local file "%s".', $resource));
+        }
+
+        if (!file_exists($resource)) {
+            throw new NotFoundResourceException(sprintf('File "%s" not found.', $resource));
+        }
+
+        $messages = $this->parse($resource);
+
+        // empty file
+        if (null === $messages) {
+            $messages = array();
+        }
+
+        // not an array
+        if (!is_array($messages)) {
+            throw new InvalidResourceException(sprintf('The file "%s" must contain a valid mo file.', $resource));
+        }
+
+        $catalogue = parent::load($messages, $locale, $domain);
+
+        if (class_exists('Symfony\Component\Config\Resource\FileResource')) {
+            $catalogue->addResource(new FileResource($resource));
+        }
+
+        return $catalogue;
+    }
+
+    /**
+     * Parses machine object (MO) format, independent of the machine's endian it
+     * was created on. Both 32bit and 64bit systems are supported.
+     *
+     * @param resource $resource
+     *
+     * @return array
+     *
+     * @throws InvalidResourceException If stream content has an invalid format.
+     */
+    private function parse($resource)
+    {
+        $stream = fopen($resource, 'r');
+
+        $stat = fstat($stream);
+
+        if ($stat['size'] < self::MO_HEADER_SIZE) {
+            throw new InvalidResourceException('MO stream content has an invalid format.');
+        }
+        $magic = unpack('V1', fread($stream, 4));
+        $magic = hexdec(substr(dechex(current($magic)), -8));
+
+        if ($magic == self::MO_LITTLE_ENDIAN_MAGIC) {
+            $isBigEndian = false;
+        } elseif ($magic == self::MO_BIG_ENDIAN_MAGIC) {
+            $isBigEndian = true;
+        } else {
+            throw new InvalidResourceException('MO stream content has an invalid format.');
+        }
+
+        // formatRevision
+        $this->readLong($stream, $isBigEndian);
+        $count = $this->readLong($stream, $isBigEndian);
+        $offsetId = $this->readLong($stream, $isBigEndian);
+        $offsetTranslated = $this->readLong($stream, $isBigEndian);
+        // sizeHashes
+        $this->readLong($stream, $isBigEndian);
+        // offsetHashes
+        $this->readLong($stream, $isBigEndian);
+
+        $messages = array();
+
+        for ($i = 0; $i < $count; ++$i) {
+            $singularId = $pluralId = null;
+            $translated = null;
+
+            fseek($stream, $offsetId + $i * 8);
+
+            $length = $this->readLong($stream, $isBigEndian);
+            $offset = $this->readLong($stream, $isBigEndian);
+
+            if ($length < 1) {
+                continue;
+            }
+
+            fseek($stream, $offset);
+            $singularId = fread($stream, $length);
+
+            if (strpos($singularId, "\000") !== false) {
+                list($singularId, $pluralId) = explode("\000", $singularId);
+            }
+
+            fseek($stream, $offsetTranslated + $i * 8);
+            $length = $this->readLong($stream, $isBigEndian);
+            $offset = $this->readLong($stream, $isBigEndian);
+
+            if ($length < 1) {
+                continue;
+            }
+
+            fseek($stream, $offset);
+            $translated = fread($stream, $length);
+
+            if (strpos($translated, "\000") !== false) {
+                $translated = explode("\000", $translated);
+            }
+
+            $ids = array('singular' => $singularId, 'plural' => $pluralId);
+            $item = compact('ids', 'translated');
+
+            if (is_array($item['translated'])) {
+                $messages[$item['ids']['singular']] = stripcslashes($item['translated'][0]);
+                if (isset($item['ids']['plural'])) {
+                    $plurals = array();
+                    foreach ($item['translated'] as $plural => $translated) {
+                        $plurals[] = sprintf('{%d} %s', $plural, $translated);
+                    }
+                    $messages[$item['ids']['plural']] = stripcslashes(implode('|', $plurals));
+                }
+            } elseif (!empty($item['ids']['singular'])) {
+                $messages[$item['ids']['singular']] = stripcslashes($item['translated']);
+            }
+        }
+
+        fclose($stream);
+
+        return array_filter($messages);
+    }
+
+    /**
+     * Reads an unsigned long from stream respecting endianess.
+     *
+     * @param resource $stream
+     * @param bool     $isBigEndian
+     *
+     * @return int
+     */
+    private function readLong($stream, $isBigEndian)
+    {
+        $result = unpack($isBigEndian ? 'N1' : 'V1', fread($stream, 4));
+        $result = current($result);
+
+        return (int) substr($result, -8);
+    }
+}
diff --git a/core/vendor/symfony/translation/Loader/PhpFileLoader.php b/core/vendor/symfony/translation/Loader/PhpFileLoader.php
new file mode 100644
index 0000000000000000000000000000000000000000..9ce2e7d2fa0debcf9e1558becd2729b0699fb43c
--- /dev/null
+++ b/core/vendor/symfony/translation/Loader/PhpFileLoader.php
@@ -0,0 +1,52 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Loader;
+
+use Symfony\Component\Translation\Exception\InvalidResourceException;
+use Symfony\Component\Translation\Exception\NotFoundResourceException;
+use Symfony\Component\Config\Resource\FileResource;
+
+/**
+ * PhpFileLoader loads translations from PHP files returning an array of translations.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ *
+ * @api
+ */
+class PhpFileLoader extends ArrayLoader
+{
+    /**
+     * {@inheritdoc}
+     *
+     * @api
+     */
+    public function load($resource, $locale, $domain = 'messages')
+    {
+        if (!stream_is_local($resource)) {
+            throw new InvalidResourceException(sprintf('This is not a local file "%s".', $resource));
+        }
+
+        if (!file_exists($resource)) {
+            throw new NotFoundResourceException(sprintf('File "%s" not found.', $resource));
+        }
+
+        $messages = require $resource;
+
+        $catalogue = parent::load($messages, $locale, $domain);
+
+        if (class_exists('Symfony\Component\Config\Resource\FileResource')) {
+            $catalogue->addResource(new FileResource($resource));
+        }
+
+        return $catalogue;
+    }
+}
diff --git a/core/vendor/symfony/translation/Loader/PoFileLoader.php b/core/vendor/symfony/translation/Loader/PoFileLoader.php
new file mode 100644
index 0000000000000000000000000000000000000000..b5d12e98216437bdb28fde1230f6ba464130d435
--- /dev/null
+++ b/core/vendor/symfony/translation/Loader/PoFileLoader.php
@@ -0,0 +1,180 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Loader;
+
+use Symfony\Component\Translation\Exception\InvalidResourceException;
+use Symfony\Component\Translation\Exception\NotFoundResourceException;
+use Symfony\Component\Config\Resource\FileResource;
+
+/**
+ * @copyright Copyright (c) 2010, Union of RAD http://union-of-rad.org (http://lithify.me/)
+ * @copyright Copyright (c) 2012, Clemens Tolboom
+ */
+class PoFileLoader extends ArrayLoader
+{
+    public function load($resource, $locale, $domain = 'messages')
+    {
+        if (!stream_is_local($resource)) {
+            throw new InvalidResourceException(sprintf('This is not a local file "%s".', $resource));
+        }
+
+        if (!file_exists($resource)) {
+            throw new NotFoundResourceException(sprintf('File "%s" not found.', $resource));
+        }
+
+        $messages = $this->parse($resource);
+
+        // empty file
+        if (null === $messages) {
+            $messages = array();
+        }
+
+        // not an array
+        if (!is_array($messages)) {
+            throw new InvalidResourceException(sprintf('The file "%s" must contain a valid po file.', $resource));
+        }
+
+        $catalogue = parent::load($messages, $locale, $domain);
+
+        if (class_exists('Symfony\Component\Config\Resource\FileResource')) {
+            $catalogue->addResource(new FileResource($resource));
+        }
+
+        return $catalogue;
+    }
+
+    /**
+     * Parses portable object (PO) format.
+     *
+     * From http://www.gnu.org/software/gettext/manual/gettext.html#PO-Files
+     * we should be able to parse files having:
+     *
+     * white-space
+     * #  translator-comments
+     * #. extracted-comments
+     * #: reference...
+     * #, flag...
+     * #| msgid previous-untranslated-string
+     * msgid untranslated-string
+     * msgstr translated-string
+     *
+     * extra or different lines are:
+     *
+     * #| msgctxt previous-context
+     * #| msgid previous-untranslated-string
+     * msgctxt context
+     *
+     * #| msgid previous-untranslated-string-singular
+     * #| msgid_plural previous-untranslated-string-plural
+     * msgid untranslated-string-singular
+     * msgid_plural untranslated-string-plural
+     * msgstr[0] translated-string-case-0
+     * ...
+     * msgstr[N] translated-string-case-n
+     *
+     * The definition states:
+     * - white-space and comments are optional.
+     * - msgid "" that an empty singleline defines a header.
+     *
+     * This parser sacrifices some features of the reference implementation the
+     * differences to that implementation are as follows.
+     * - No support for comments spanning multiple lines.
+     * - Translator and extracted comments are treated as being the same type.
+     * - Message IDs are allowed to have other encodings as just US-ASCII.
+     *
+     * Items with an empty id are ignored.
+     *
+     * @param resource $resource
+     *
+     * @return array
+     */
+    private function parse($resource)
+    {
+        $stream = fopen($resource, 'r');
+
+        $defaults = array(
+            'ids' => array(),
+            'translated' => null,
+        );
+
+        $messages = array();
+        $item = $defaults;
+
+        while ($line = fgets($stream)) {
+            $line = trim($line);
+
+            if ($line === '') {
+                // Whitespace indicated current item is done
+                $this->addMessage($messages, $item);
+                $item = $defaults;
+            } elseif (substr($line, 0, 7) === 'msgid "') {
+                // We start a new msg so save previous
+                // TODO: this fails when comments or contexts are added
+                $this->addMessage($messages, $item);
+                $item = $defaults;
+                $item['ids']['singular'] = substr($line, 7, -1);
+            } elseif (substr($line, 0, 8) === 'msgstr "') {
+                $item['translated'] = substr($line, 8, -1);
+            } elseif ($line[0] === '"') {
+                $continues = isset($item['translated']) ? 'translated' : 'ids';
+
+                if (is_array($item[$continues])) {
+                    end($item[$continues]);
+                    $item[$continues][key($item[$continues])] .= substr($line, 1, -1);
+                } else {
+                    $item[$continues] .= substr($line, 1, -1);
+                }
+            } elseif (substr($line, 0, 14) === 'msgid_plural "') {
+                $item['ids']['plural'] = substr($line, 14, -1);
+            } elseif (substr($line, 0, 7) === 'msgstr[') {
+                $size = strpos($line, ']');
+                $item['translated'][(int) substr($line, 7, 1)] = substr($line, $size + 3, -1);
+            }
+        }
+        // save last item
+        $this->addMessage($messages, $item);
+        fclose($stream);
+
+        return $messages;
+    }
+
+    /**
+     * Save a translation item to the messages.
+     *
+     * A .po file could contain by error missing plural indexes. We need to
+     * fix these before saving them.
+     *
+     * @param array $messages
+     * @param array $item
+     */
+    private function addMessage(array &$messages, array $item)
+    {
+        if (is_array($item['translated'])) {
+            $messages[stripcslashes($item['ids']['singular'])] = stripcslashes($item['translated'][0]);
+            if (isset($item['ids']['plural'])) {
+                $plurals = $item['translated'];
+                // PO are by definition indexed so sort by index.
+                ksort($plurals);
+                // Make sure every index is filled.
+                end($plurals);
+                $count = key($plurals);
+                // Fill missing spots with '-'.
+                $empties = array_fill(0, $count + 1, '-');
+                $plurals += $empties;
+                ksort($plurals);
+                $messages[stripcslashes($item['ids']['plural'])] = stripcslashes(implode('|', $plurals));
+            }
+        } elseif (!empty($item['ids']['singular'])) {
+            $messages[stripcslashes($item['ids']['singular'])] = stripcslashes($item['translated']);
+        }
+    }
+}
diff --git a/core/vendor/symfony/translation/Loader/QtFileLoader.php b/core/vendor/symfony/translation/Loader/QtFileLoader.php
new file mode 100644
index 0000000000000000000000000000000000000000..6dd0696c6f5ffb26f385cc8940e62bf7f0b1ee13
--- /dev/null
+++ b/core/vendor/symfony/translation/Loader/QtFileLoader.php
@@ -0,0 +1,81 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Loader;
+
+use Symfony\Component\Config\Util\XmlUtils;
+use Symfony\Component\Translation\MessageCatalogue;
+use Symfony\Component\Translation\Exception\InvalidResourceException;
+use Symfony\Component\Translation\Exception\NotFoundResourceException;
+use Symfony\Component\Config\Resource\FileResource;
+
+/**
+ * QtFileLoader loads translations from QT Translations XML files.
+ *
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ *
+ * @api
+ */
+class QtFileLoader implements LoaderInterface
+{
+    /**
+     * {@inheritdoc}
+     *
+     * @api
+     */
+    public function load($resource, $locale, $domain = 'messages')
+    {
+        if (!stream_is_local($resource)) {
+            throw new InvalidResourceException(sprintf('This is not a local file "%s".', $resource));
+        }
+
+        if (!file_exists($resource)) {
+            throw new NotFoundResourceException(sprintf('File "%s" not found.', $resource));
+        }
+
+        try {
+            $dom = XmlUtils::loadFile($resource);
+        } catch (\InvalidArgumentException $e) {
+            throw new InvalidResourceException(sprintf('Unable to load "%s".', $resource), $e->getCode(), $e);
+        }
+
+        $internalErrors = libxml_use_internal_errors(true);
+        libxml_clear_errors();
+
+        $xpath = new \DOMXPath($dom);
+        $nodes = $xpath->evaluate('//TS/context/name[text()="'.$domain.'"]');
+
+        $catalogue = new MessageCatalogue($locale);
+        if ($nodes->length == 1) {
+            $translations = $nodes->item(0)->nextSibling->parentNode->parentNode->getElementsByTagName('message');
+            foreach ($translations as $translation) {
+                $translationValue = (string) $translation->getElementsByTagName('translation')->item(0)->nodeValue;
+
+                if (!empty($translationValue)) {
+                    $catalogue->set(
+                        (string) $translation->getElementsByTagName('source')->item(0)->nodeValue,
+                        $translationValue,
+                        $domain
+                    );
+                }
+                $translation = $translation->nextSibling;
+            }
+
+            if (class_exists('Symfony\Component\Config\Resource\FileResource')) {
+                $catalogue->addResource(new FileResource($resource));
+            }
+        }
+
+        libxml_use_internal_errors($internalErrors);
+
+        return $catalogue;
+    }
+}
diff --git a/core/vendor/symfony/translation/Loader/XliffFileLoader.php b/core/vendor/symfony/translation/Loader/XliffFileLoader.php
new file mode 100644
index 0000000000000000000000000000000000000000..109f35b7268a21ed9ab9ea9866eebe15c56a1075
--- /dev/null
+++ b/core/vendor/symfony/translation/Loader/XliffFileLoader.php
@@ -0,0 +1,188 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Loader;
+
+use Symfony\Component\Config\Util\XmlUtils;
+use Symfony\Component\Translation\MessageCatalogue;
+use Symfony\Component\Translation\Exception\InvalidResourceException;
+use Symfony\Component\Translation\Exception\NotFoundResourceException;
+use Symfony\Component\Config\Resource\FileResource;
+
+/**
+ * XliffFileLoader loads translations from XLIFF files.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ *
+ * @api
+ */
+class XliffFileLoader implements LoaderInterface
+{
+    /**
+     * {@inheritdoc}
+     *
+     * @api
+     */
+    public function load($resource, $locale, $domain = 'messages')
+    {
+        if (!stream_is_local($resource)) {
+            throw new InvalidResourceException(sprintf('This is not a local file "%s".', $resource));
+        }
+
+        if (!file_exists($resource)) {
+            throw new NotFoundResourceException(sprintf('File "%s" not found.', $resource));
+        }
+
+        list($xml, $encoding) = $this->parseFile($resource);
+        $xml->registerXPathNamespace('xliff', 'urn:oasis:names:tc:xliff:document:1.2');
+
+        $catalogue = new MessageCatalogue($locale);
+        foreach ($xml->xpath('//xliff:trans-unit') as $translation) {
+            $attributes = $translation->attributes();
+
+            if (!(isset($attributes['resname']) || isset($translation->source))) {
+                continue;
+            }
+
+            $source = isset($attributes['resname']) && $attributes['resname'] ? $attributes['resname'] : $translation->source;
+            // If the xlf file has another encoding specified, try to convert it because
+            // simple_xml will always return utf-8 encoded values
+            $target = $this->utf8ToCharset((string) (isset($translation->target) ? $translation->target : $source), $encoding);
+
+            $catalogue->set((string) $source, $target, $domain);
+
+            if (isset($translation->note)) {
+                $notes = array();
+                foreach ($translation->note as $xmlNote) {
+                    $noteAttributes = $xmlNote->attributes();
+                    $note = array('content' => $this->utf8ToCharset((string) $xmlNote, $encoding));
+                    if (isset($noteAttributes['priority'])) {
+                        $note['priority'] = (int) $noteAttributes['priority'];
+                    }
+
+                    if (isset($noteAttributes['from'])) {
+                        $note['from'] = (string) $noteAttributes['from'];
+                    }
+
+                    $notes[] = $note;
+                }
+
+                $catalogue->setMetadata((string) $source, array('notes' => $notes), $domain);
+            }
+        }
+
+        if (class_exists('Symfony\Component\Config\Resource\FileResource')) {
+            $catalogue->addResource(new FileResource($resource));
+        }
+
+        return $catalogue;
+    }
+
+    /**
+     * Convert a UTF8 string to the specified encoding.
+     *
+     * @param string $content  String to decode
+     * @param string $encoding Target encoding
+     *
+     * @return string
+     */
+    private function utf8ToCharset($content, $encoding = null)
+    {
+        if ('UTF-8' !== $encoding && !empty($encoding)) {
+            if (function_exists('mb_convert_encoding')) {
+                return mb_convert_encoding($content, $encoding, 'UTF-8');
+            }
+
+            if (function_exists('iconv')) {
+                return iconv('UTF-8', $encoding, $content);
+            }
+
+            throw new \RuntimeException('No suitable convert encoding function (use UTF-8 as your encoding or install the iconv or mbstring extension).');
+        }
+
+        return $content;
+    }
+
+    /**
+     * Validates and parses the given file into a SimpleXMLElement.
+     *
+     * @param string $file
+     *
+     * @throws \RuntimeException
+     *
+     * @return \SimpleXMLElement
+     *
+     * @throws InvalidResourceException
+     */
+    private function parseFile($file)
+    {
+        try {
+            $dom = XmlUtils::loadFile($file);
+        } catch (\InvalidArgumentException $e) {
+            throw new InvalidResourceException(sprintf('Unable to load "%s": %s', $file, $e->getMessage()), $e->getCode(), $e);
+        }
+
+        $internalErrors = libxml_use_internal_errors(true);
+
+        $location = str_replace('\\', '/', __DIR__).'/schema/dic/xliff-core/xml.xsd';
+        $parts = explode('/', $location);
+        if (0 === stripos($location, 'phar://')) {
+            $tmpfile = tempnam(sys_get_temp_dir(), 'sf2');
+            if ($tmpfile) {
+                copy($location, $tmpfile);
+                $parts = explode('/', str_replace('\\', '/', $tmpfile));
+            }
+        }
+        $drive = '\\' === DIRECTORY_SEPARATOR ? array_shift($parts).'/' : '';
+        $location = 'file:///'.$drive.implode('/', array_map('rawurlencode', $parts));
+
+        $source = file_get_contents(__DIR__.'/schema/dic/xliff-core/xliff-core-1.2-strict.xsd');
+        $source = str_replace('http://www.w3.org/2001/xml.xsd', $location, $source);
+
+        if (!@$dom->schemaValidateSource($source)) {
+            throw new InvalidResourceException(sprintf('Invalid resource provided: "%s"; Errors: %s', $file, implode("\n", $this->getXmlErrors($internalErrors))));
+        }
+
+        $dom->normalizeDocument();
+
+        libxml_clear_errors();
+        libxml_use_internal_errors($internalErrors);
+
+        return array(simplexml_import_dom($dom), strtoupper($dom->encoding));
+    }
+
+    /**
+     * Returns the XML errors of the internal XML parser.
+     *
+     * @param bool $internalErrors
+     *
+     * @return array An array of errors
+     */
+    private function getXmlErrors($internalErrors)
+    {
+        $errors = array();
+        foreach (libxml_get_errors() as $error) {
+            $errors[] = sprintf('[%s %s] %s (in %s - line %d, column %d)',
+                LIBXML_ERR_WARNING == $error->level ? 'WARNING' : 'ERROR',
+                $error->code,
+                trim($error->message),
+                $error->file ?: 'n/a',
+                $error->line,
+                $error->column
+            );
+        }
+
+        libxml_clear_errors();
+        libxml_use_internal_errors($internalErrors);
+
+        return $errors;
+    }
+}
diff --git a/core/vendor/symfony/translation/Loader/YamlFileLoader.php b/core/vendor/symfony/translation/Loader/YamlFileLoader.php
new file mode 100644
index 0000000000000000000000000000000000000000..fb0946cc577f5a6a4135fc5625dfde3d170de9c5
--- /dev/null
+++ b/core/vendor/symfony/translation/Loader/YamlFileLoader.php
@@ -0,0 +1,78 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Loader;
+
+use Symfony\Component\Translation\Exception\InvalidResourceException;
+use Symfony\Component\Translation\Exception\NotFoundResourceException;
+use Symfony\Component\Config\Resource\FileResource;
+use Symfony\Component\Yaml\Parser as YamlParser;
+use Symfony\Component\Yaml\Exception\ParseException;
+
+/**
+ * YamlFileLoader loads translations from Yaml files.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ *
+ * @api
+ */
+class YamlFileLoader extends ArrayLoader
+{
+    private $yamlParser;
+
+    /**
+     * {@inheritdoc}
+     *
+     * @api
+     */
+    public function load($resource, $locale, $domain = 'messages')
+    {
+        if (!stream_is_local($resource)) {
+            throw new InvalidResourceException(sprintf('This is not a local file "%s".', $resource));
+        }
+
+        if (!file_exists($resource)) {
+            throw new NotFoundResourceException(sprintf('File "%s" not found.', $resource));
+        }
+
+        if (!class_exists('Symfony\Component\Yaml\Parser')) {
+            throw new \LogicException('Loading translations from the YAML format requires the Symfony Yaml component.');
+        }
+
+        if (null === $this->yamlParser) {
+            $this->yamlParser = new YamlParser();
+        }
+
+        try {
+            $messages = $this->yamlParser->parse(file_get_contents($resource));
+        } catch (ParseException $e) {
+            throw new InvalidResourceException(sprintf('Error parsing YAML, invalid file "%s"', $resource), 0, $e);
+        }
+
+        // empty file
+        if (null === $messages) {
+            $messages = array();
+        }
+
+        // not an array
+        if (!is_array($messages)) {
+            throw new InvalidResourceException(sprintf('The file "%s" must contain a YAML array.', $resource));
+        }
+
+        $catalogue = parent::load($messages, $locale, $domain);
+
+        if (class_exists('Symfony\Component\Config\Resource\FileResource')) {
+            $catalogue->addResource(new FileResource($resource));
+        }
+
+        return $catalogue;
+    }
+}
diff --git a/core/vendor/symfony/translation/Loader/schema/dic/xliff-core/xliff-core-1.2-strict.xsd b/core/vendor/symfony/translation/Loader/schema/dic/xliff-core/xliff-core-1.2-strict.xsd
new file mode 100644
index 0000000000000000000000000000000000000000..3ce2a8e8ab73fbf27bd55bde01579962bc3060f5
--- /dev/null
+++ b/core/vendor/symfony/translation/Loader/schema/dic/xliff-core/xliff-core-1.2-strict.xsd
@@ -0,0 +1,2223 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+
+May-19-2004:
+- Changed the <choice> for ElemType_header, moving minOccurs="0" maxOccurs="unbounded" from its elements 
+to <choice> itself.
+- Added <choice> for ElemType_trans-unit to allow "any order" for <context-group>, <count-group>, <prop-group>, <note>, and
+<alt-trans>.
+
+Oct-2005
+- updated version info to 1.2
+- equiv-trans attribute to <trans-unit> element 
+- merged-trans attribute for <group> element
+- Add the <seg-source> element as optional in the <trans-unit> and <alt-trans> content models, at the same level as <source> 
+- Create a new value "seg" for the mtype attribute of the <mrk> element
+- Add mid as an optional attribute for the <alt-trans> element
+
+Nov-14-2005
+- Changed name attribute for <context-group> from required to optional
+- Added extension point at <xliff>
+
+Jan-9-2006
+- Added alttranstype type attribute to <alt-trans>, and values
+
+Jan-10-2006
+- Corrected error with overwritten purposeValueList
+- Corrected name="AttrType_Version",  attribute should have been "name"
+
+-->
+<xsd:schema xmlns:xlf="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="urn:oasis:names:tc:xliff:document:1.2" xml:lang="en">
+  <!-- Import for xml:lang and xml:space -->
+  <xsd:import namespace="http://www.w3.org/XML/1998/namespace" schemaLocation="http://www.w3.org/2001/xml.xsd"/>
+  <!-- Attributes Lists -->
+  <xsd:simpleType name="XTend">
+    <xsd:restriction base="xsd:string">
+      <xsd:pattern value="x-[^\s]+"/>
+    </xsd:restriction>
+  </xsd:simpleType>
+  <xsd:simpleType name="context-typeValueList">
+    <xsd:annotation>
+      <xsd:documentation>Values for the attribute 'context-type'.</xsd:documentation>
+    </xsd:annotation>
+    <xsd:restriction base="xsd:string">
+      <xsd:enumeration value="database">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a database content.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="element">
+        <xsd:annotation>
+          <xsd:documentation>Indicates the content of an element within an XML document.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="elementtitle">
+        <xsd:annotation>
+          <xsd:documentation>Indicates the name of an element within an XML document.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="linenumber">
+        <xsd:annotation>
+          <xsd:documentation>Indicates the line number from the sourcefile (see context-type="sourcefile") where the &lt;source&gt; is found.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="numparams">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a the number of parameters contained within the &lt;source&gt;.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="paramnotes">
+        <xsd:annotation>
+          <xsd:documentation>Indicates notes pertaining to the parameters in the &lt;source&gt;.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="record">
+        <xsd:annotation>
+          <xsd:documentation>Indicates the content of a record within a database.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="recordtitle">
+        <xsd:annotation>
+          <xsd:documentation>Indicates the name of a record within a database.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="sourcefile">
+        <xsd:annotation>
+          <xsd:documentation>Indicates the original source file in the case that multiple files are merged to form the original file from which the XLIFF file is created. This differs from the original &lt;file&gt; attribute in that this sourcefile is one of many that make up that file.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+    </xsd:restriction>
+  </xsd:simpleType>
+  <xsd:simpleType name="count-typeValueList">
+    <xsd:annotation>
+      <xsd:documentation>Values for the attribute 'count-type'.</xsd:documentation>
+    </xsd:annotation>
+    <xsd:restriction base="xsd:NMTOKEN">
+      <xsd:enumeration value="num-usages">
+        <xsd:annotation>
+          <xsd:documentation>Indicates the count units are items that are used X times in a certain context; example: this is a reusable text unit which is used 42 times in other texts.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="repetition">
+        <xsd:annotation>
+          <xsd:documentation>Indicates the count units are translation units existing already in the same document.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="total">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a total count.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+    </xsd:restriction>
+  </xsd:simpleType>
+  <xsd:simpleType name="InlineDelimitersValueList">
+    <xsd:annotation>
+      <xsd:documentation>Values for the attribute 'ctype' when used other elements than &lt;ph&gt; or &lt;x&gt;.</xsd:documentation>
+    </xsd:annotation>
+    <xsd:restriction base="xsd:NMTOKEN">
+      <xsd:enumeration value="bold">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a run of bolded text.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="italic">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a run of text in italics.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="underlined">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a run of underlined text.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="link">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a run of hyper-text.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+    </xsd:restriction>
+  </xsd:simpleType>
+  <xsd:simpleType name="InlinePlaceholdersValueList">
+    <xsd:annotation>
+      <xsd:documentation>Values for the attribute 'ctype' when used with &lt;ph&gt; or &lt;x&gt;.</xsd:documentation>
+    </xsd:annotation>
+    <xsd:restriction base="xsd:NMTOKEN">
+      <xsd:enumeration value="image">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a inline image.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="pb">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a page break.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="lb">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a line break.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+    </xsd:restriction>
+  </xsd:simpleType>
+  <xsd:simpleType name="mime-typeValueList">
+    <xsd:restriction base="xsd:string">
+      <xsd:pattern value="(text|multipart|message|application|image|audio|video|model)(/.+)*"/>
+    </xsd:restriction>
+  </xsd:simpleType>
+  <xsd:simpleType name="datatypeValueList">
+    <xsd:annotation>
+      <xsd:documentation>Values for the attribute 'datatype'.</xsd:documentation>
+    </xsd:annotation>
+    <xsd:restriction base="xsd:NMTOKEN">
+      <xsd:enumeration value="asp">
+        <xsd:annotation>
+          <xsd:documentation>Indicates Active Server Page data.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="c">
+        <xsd:annotation>
+          <xsd:documentation>Indicates C source file data.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="cdf">
+        <xsd:annotation>
+          <xsd:documentation>Indicates Channel Definition Format (CDF) data.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="cfm">
+        <xsd:annotation>
+          <xsd:documentation>Indicates ColdFusion data.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="cpp">
+        <xsd:annotation>
+          <xsd:documentation>Indicates C++ source file data.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="csharp">
+        <xsd:annotation>
+          <xsd:documentation>Indicates C-Sharp data.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="cstring">
+        <xsd:annotation>
+          <xsd:documentation>Indicates strings from C, ASM, and driver files data.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="csv">
+        <xsd:annotation>
+          <xsd:documentation>Indicates comma-separated values data.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="database">
+        <xsd:annotation>
+          <xsd:documentation>Indicates database data.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="documentfooter">
+        <xsd:annotation>
+          <xsd:documentation>Indicates portions of document that follows data and contains metadata.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="documentheader">
+        <xsd:annotation>
+          <xsd:documentation>Indicates portions of document that precedes data and contains metadata.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="filedialog">
+        <xsd:annotation>
+          <xsd:documentation>Indicates data from standard UI file operations dialogs (e.g., Open, Save, Save As, Export, Import).</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="form">
+        <xsd:annotation>
+          <xsd:documentation>Indicates standard user input screen data.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="html">
+        <xsd:annotation>
+          <xsd:documentation>Indicates HyperText Markup Language (HTML) data - document instance.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="htmlbody">
+        <xsd:annotation>
+          <xsd:documentation>Indicates content within an HTML document’s &lt;body&gt; element.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="ini">
+        <xsd:annotation>
+          <xsd:documentation>Indicates Windows INI file data.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="interleaf">
+        <xsd:annotation>
+          <xsd:documentation>Indicates Interleaf data.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="javaclass">
+        <xsd:annotation>
+          <xsd:documentation>Indicates Java source file data (extension '.java').</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="javapropertyresourcebundle">
+        <xsd:annotation>
+          <xsd:documentation>Indicates Java property resource bundle data.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="javalistresourcebundle">
+        <xsd:annotation>
+          <xsd:documentation>Indicates Java list resource bundle data.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="javascript">
+        <xsd:annotation>
+          <xsd:documentation>Indicates JavaScript source file data.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="jscript">
+        <xsd:annotation>
+          <xsd:documentation>Indicates JScript source file data.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="layout">
+        <xsd:annotation>
+          <xsd:documentation>Indicates information relating to formatting.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="lisp">
+        <xsd:annotation>
+          <xsd:documentation>Indicates LISP source file data.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="margin">
+        <xsd:annotation>
+          <xsd:documentation>Indicates information relating to margin formats.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="menufile">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a file containing menu.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="messagefile">
+        <xsd:annotation>
+          <xsd:documentation>Indicates numerically identified string table.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="mif">
+        <xsd:annotation>
+          <xsd:documentation>Indicates Maker Interchange Format (MIF) data.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="mimetype">
+        <xsd:annotation>
+          <xsd:documentation>Indicates that the datatype attribute value is a MIME Type value and is defined in the mime-type attribute.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="mo">
+        <xsd:annotation>
+          <xsd:documentation>Indicates GNU Machine Object data.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="msglib">
+        <xsd:annotation>
+          <xsd:documentation>Indicates Message Librarian strings created by Novell's Message Librarian Tool.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="pagefooter">
+        <xsd:annotation>
+          <xsd:documentation>Indicates information to be displayed at the bottom of each page of a document.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="pageheader">
+        <xsd:annotation>
+          <xsd:documentation>Indicates information to be displayed at the top of each page of a document.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="parameters">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a list of property values (e.g., settings within INI files or preferences dialog).</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="pascal">
+        <xsd:annotation>
+          <xsd:documentation>Indicates Pascal source file data.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="php">
+        <xsd:annotation>
+          <xsd:documentation>Indicates Hypertext Preprocessor data.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="plaintext">
+        <xsd:annotation>
+          <xsd:documentation>Indicates plain text file (no formatting other than, possibly, wrapping).</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="po">
+        <xsd:annotation>
+          <xsd:documentation>Indicates GNU Portable Object file.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="report">
+        <xsd:annotation>
+          <xsd:documentation>Indicates dynamically generated user defined document. e.g. Oracle Report, Crystal Report, etc.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="resources">
+        <xsd:annotation>
+          <xsd:documentation>Indicates Windows .NET binary resources.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="resx">
+        <xsd:annotation>
+          <xsd:documentation>Indicates Windows .NET Resources.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="rtf">
+        <xsd:annotation>
+          <xsd:documentation>Indicates Rich Text Format (RTF) data.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="sgml">
+        <xsd:annotation>
+          <xsd:documentation>Indicates Standard Generalized Markup Language (SGML) data - document instance.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="sgmldtd">
+        <xsd:annotation>
+          <xsd:documentation>Indicates Standard Generalized Markup Language (SGML) data - Document Type Definition (DTD).</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="svg">
+        <xsd:annotation>
+          <xsd:documentation>Indicates Scalable Vector Graphic (SVG) data.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="vbscript">
+        <xsd:annotation>
+          <xsd:documentation>Indicates VisualBasic Script source file.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="warning">
+        <xsd:annotation>
+          <xsd:documentation>Indicates warning message.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="winres">
+        <xsd:annotation>
+          <xsd:documentation>Indicates Windows (Win32) resources (i.e. resources extracted from an RC script, a message file, or a compiled file).</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="xhtml">
+        <xsd:annotation>
+          <xsd:documentation>Indicates Extensible HyperText Markup Language (XHTML) data - document instance.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="xml">
+        <xsd:annotation>
+          <xsd:documentation>Indicates Extensible Markup Language (XML) data - document instance.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="xmldtd">
+        <xsd:annotation>
+          <xsd:documentation>Indicates Extensible Markup Language (XML) data - Document Type Definition (DTD).</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="xsl">
+        <xsd:annotation>
+          <xsd:documentation>Indicates Extensible Stylesheet Language (XSL) data.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="xul">
+        <xsd:annotation>
+          <xsd:documentation>Indicates XUL elements.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+    </xsd:restriction>
+  </xsd:simpleType>
+  <xsd:simpleType name="mtypeValueList">
+    <xsd:annotation>
+      <xsd:documentation>Values for the attribute 'mtype'.</xsd:documentation>
+    </xsd:annotation>
+    <xsd:restriction base="xsd:NMTOKEN">
+      <xsd:enumeration value="abbrev">
+        <xsd:annotation>
+          <xsd:documentation>Indicates the marked text is an abbreviation.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="abbreviated-form">
+        <xsd:annotation>
+          <xsd:documentation>ISO-12620 2.1.8: A term resulting from the omission of any part of the full term while designating the same concept.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="abbreviation">
+        <xsd:annotation>
+          <xsd:documentation>ISO-12620 2.1.8.1: An abbreviated form of a simple term resulting from the omission of some of its letters (e.g. 'adj.' for 'adjective').</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="acronym">
+        <xsd:annotation>
+          <xsd:documentation>ISO-12620 2.1.8.4: An abbreviated form of a term made up of letters from the full form of a multiword term strung together into a sequence pronounced only syllabically (e.g. 'radar' for 'radio detecting and ranging').</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="appellation">
+        <xsd:annotation>
+          <xsd:documentation>ISO-12620: A proper-name term, such as the name of an agency or other proper entity.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="collocation">
+        <xsd:annotation>
+          <xsd:documentation>ISO-12620 2.1.18.1: A recurrent word combination characterized by cohesion in that the components of the collocation must co-occur within an utterance or series of utterances, even though they do not necessarily have to maintain immediate proximity to one another.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="common-name">
+        <xsd:annotation>
+          <xsd:documentation>ISO-12620 2.1.5: A synonym for an international scientific term that is used in general discourse in a given language.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="datetime">
+        <xsd:annotation>
+          <xsd:documentation>Indicates the marked text is a date and/or time.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="equation">
+        <xsd:annotation>
+          <xsd:documentation>ISO-12620 2.1.15: An expression used to represent a concept based on a statement that two mathematical expressions are, for instance, equal as identified by the equal sign (=), or assigned to one another by a similar sign.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="expanded-form">
+        <xsd:annotation>
+          <xsd:documentation>ISO-12620 2.1.7: The complete representation of a term for which there is an abbreviated form.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="formula">
+        <xsd:annotation>
+          <xsd:documentation>ISO-12620 2.1.14: Figures, symbols or the like used to express a concept briefly, such as a mathematical or chemical formula.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="head-term">
+        <xsd:annotation>
+          <xsd:documentation>ISO-12620 2.1.1: The concept designation that has been chosen to head a terminological record.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="initialism">
+        <xsd:annotation>
+          <xsd:documentation>ISO-12620 2.1.8.3: An abbreviated form of a term consisting of some of the initial letters of the words making up a multiword term or the term elements making up a compound term when these letters are pronounced individually (e.g. 'BSE' for 'bovine spongiform encephalopathy').</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="international-scientific-term">
+        <xsd:annotation>
+          <xsd:documentation>ISO-12620 2.1.4: A term that is part of an international scientific nomenclature as adopted by an appropriate scientific body.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="internationalism">
+        <xsd:annotation>
+          <xsd:documentation>ISO-12620 2.1.6: A term that has the same or nearly identical orthographic or phonemic form in many languages.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="logical-expression">
+        <xsd:annotation>
+          <xsd:documentation>ISO-12620 2.1.16: An expression used to represent a concept based on mathematical or logical relations, such as statements of inequality, set relationships, Boolean operations, and the like.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="materials-management-unit">
+        <xsd:annotation>
+          <xsd:documentation>ISO-12620 2.1.17: A unit to track object.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="name">
+        <xsd:annotation>
+          <xsd:documentation>Indicates the marked text is a name.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="near-synonym">
+        <xsd:annotation>
+          <xsd:documentation>ISO-12620 2.1.3: A term that represents the same or a very similar concept as another term in the same language, but for which interchangeability is limited to some contexts and inapplicable in others.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="part-number">
+        <xsd:annotation>
+          <xsd:documentation>ISO-12620 2.1.17.2: A unique alphanumeric designation assigned to an object in a manufacturing system.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="phrase">
+        <xsd:annotation>
+          <xsd:documentation>Indicates the marked text is a phrase.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="phraseological-unit">
+        <xsd:annotation>
+          <xsd:documentation>ISO-12620 2.1.18: Any group of two or more words that form a unit, the meaning of which frequently cannot be deduced based on the combined sense of the words making up the phrase.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="protected">
+        <xsd:annotation>
+          <xsd:documentation>Indicates the marked text should not be translated.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="romanized-form">
+        <xsd:annotation>
+          <xsd:documentation>ISO-12620 2.1.12: A form of a term resulting from an operation whereby non-Latin writing systems are converted to the Latin alphabet.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="seg">
+        <xsd:annotation>
+          <xsd:documentation>Indicates that the marked text represents a segment.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="set-phrase">
+        <xsd:annotation>
+          <xsd:documentation>ISO-12620 2.1.18.2: A fixed, lexicalized phrase.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="short-form">
+        <xsd:annotation>
+          <xsd:documentation>ISO-12620 2.1.8.2: A variant of a multiword term that includes fewer words than the full form of the term (e.g. 'Group of Twenty-four' for 'Intergovernmental Group of Twenty-four on International Monetary Affairs').</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="sku">
+        <xsd:annotation>
+          <xsd:documentation>ISO-12620 2.1.17.1: Stock keeping unit, an inventory item identified by a unique alphanumeric designation assigned to an object in an inventory control system.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="standard-text">
+        <xsd:annotation>
+          <xsd:documentation>ISO-12620 2.1.19: A fixed chunk of recurring text.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="symbol">
+        <xsd:annotation>
+          <xsd:documentation>ISO-12620 2.1.13: A designation of a concept by letters, numerals, pictograms or any combination thereof.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="synonym">
+        <xsd:annotation>
+          <xsd:documentation>ISO-12620 2.1.2: Any term that represents the same or a very similar concept as the main entry term in a term entry.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="synonymous-phrase">
+        <xsd:annotation>
+          <xsd:documentation>ISO-12620 2.1.18.3: Phraseological unit in a language that expresses the same semantic content as another phrase in that same language.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="term">
+        <xsd:annotation>
+          <xsd:documentation>Indicates the marked text is a term.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="transcribed-form">
+        <xsd:annotation>
+          <xsd:documentation>ISO-12620 2.1.11: A form of a term resulting from an operation whereby the characters of one writing system are represented by characters from another writing system, taking into account the pronunciation of the characters converted.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="transliterated-form">
+        <xsd:annotation>
+          <xsd:documentation>ISO-12620 2.1.10: A form of a term resulting from an operation whereby the characters of an alphabetic writing system are represented by characters from another alphabetic writing system.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="truncated-term">
+        <xsd:annotation>
+          <xsd:documentation>ISO-12620 2.1.8.5: An abbreviated form of a term resulting from the omission of one or more term elements or syllables (e.g. 'flu' for 'influenza').</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="variant">
+        <xsd:annotation>
+          <xsd:documentation>ISO-12620 2.1.9: One of the alternate forms of a term.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+    </xsd:restriction>
+  </xsd:simpleType>
+  <xsd:simpleType name="restypeValueList">
+    <xsd:annotation>
+      <xsd:documentation>Values for the attribute 'restype'.</xsd:documentation>
+    </xsd:annotation>
+    <xsd:restriction base="xsd:NMTOKEN">
+      <xsd:enumeration value="auto3state">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a Windows RC AUTO3STATE control.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="autocheckbox">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a Windows RC AUTOCHECKBOX control.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="autoradiobutton">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a Windows RC AUTORADIOBUTTON control.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="bedit">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a Windows RC BEDIT control.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="bitmap">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a bitmap, for example a BITMAP resource in Windows.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="button">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a button object, for example a BUTTON control Windows.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="caption">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a caption, such as the caption of a dialog box.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="cell">
+        <xsd:annotation>
+          <xsd:documentation>Indicates the cell in a table, for example the content of the &lt;td&gt; element in HTML.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="checkbox">
+        <xsd:annotation>
+          <xsd:documentation>Indicates check box object, for example a CHECKBOX control in Windows.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="checkboxmenuitem">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a menu item with an associated checkbox.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="checkedlistbox">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a list box, but with a check-box for each item.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="colorchooser">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a color selection dialog.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="combobox">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a combination of edit box and listbox object, for example a COMBOBOX control in Windows.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="comboboxexitem">
+        <xsd:annotation>
+          <xsd:documentation>Indicates an initialization entry of an extended combobox DLGINIT resource block. (code 0x1234).</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="comboboxitem">
+        <xsd:annotation>
+          <xsd:documentation>Indicates an initialization entry of a combobox DLGINIT resource block (code 0x0403).</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="component">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a UI base class element that cannot be represented by any other element.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="contextmenu">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a context menu.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="ctext">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a Windows RC CTEXT control.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="cursor">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a cursor, for example a CURSOR resource in Windows.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="datetimepicker">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a date/time picker.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="defpushbutton">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a Windows RC DEFPUSHBUTTON control.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="dialog">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a dialog box.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="dlginit">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a Windows RC DLGINIT resource block.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="edit">
+        <xsd:annotation>
+          <xsd:documentation>Indicates an edit box object, for example an EDIT control in Windows.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="file">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a filename.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="filechooser">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a file dialog.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="fn">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a footnote.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="font">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a font name.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="footer">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a footer.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="frame">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a frame object.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="grid">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a XUL grid element.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="groupbox">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a groupbox object, for example a GROUPBOX control in Windows.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="header">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a header item.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="heading">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a heading, such has the content of &lt;h1&gt;, &lt;h2&gt;, etc. in HTML.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="hedit">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a Windows RC HEDIT control.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="hscrollbar">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a horizontal scrollbar.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="icon">
+        <xsd:annotation>
+          <xsd:documentation>Indicates an icon, for example an ICON resource in Windows.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="iedit">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a Windows RC IEDIT control.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="keywords">
+        <xsd:annotation>
+          <xsd:documentation>Indicates keyword list, such as the content of the Keywords meta-data in HTML, or a K footnote in WinHelp RTF.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="label">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a label object.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="linklabel">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a label that is also a HTML link (not necessarily a URL).</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="list">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a list (a group of list-items, for example an &lt;ol&gt; or &lt;ul&gt; element in HTML).</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="listbox">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a listbox object, for example an LISTBOX control in Windows.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="listitem">
+        <xsd:annotation>
+          <xsd:documentation>Indicates an list item (an entry in a list).</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="ltext">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a Windows RC LTEXT control.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="menu">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a menu (a group of menu-items).</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="menubar">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a toolbar containing one or more tope level menus.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="menuitem">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a menu item (an entry in a menu).</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="menuseparator">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a XUL menuseparator element.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="message">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a message, for example an entry in a MESSAGETABLE resource in Windows.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="monthcalendar">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a calendar control.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="numericupdown">
+        <xsd:annotation>
+          <xsd:documentation>Indicates an edit box beside a spin control.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="panel">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a catch all for rectangular areas.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="popupmenu">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a standalone menu not necessarily associated with a menubar.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="pushbox">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a pushbox object, for example a PUSHBOX control in Windows.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="pushbutton">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a Windows RC PUSHBUTTON control.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="radio">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a radio button object.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="radiobuttonmenuitem">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a menuitem with associated radio button.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="rcdata">
+        <xsd:annotation>
+          <xsd:documentation>Indicates raw data resources for an application.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="row">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a row in a table.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="rtext">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a Windows RC RTEXT control.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="scrollpane">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a user navigable container used to show a portion of a document.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="separator">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a generic divider object (e.g. menu group separator).</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="shortcut">
+        <xsd:annotation>
+          <xsd:documentation>Windows accelerators, shortcuts in resource or property files.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="spinner">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a UI control to indicate process activity but not progress.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="splitter">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a splitter bar.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="state3">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a Windows RC STATE3 control.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="statusbar">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a window for providing feedback to the users, like 'read-only', etc.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="string">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a string, for example an entry in a STRINGTABLE resource in Windows.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="tabcontrol">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a layers of controls with a tab to select layers.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="table">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a display and edits regular two-dimensional tables of cells.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="textbox">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a XUL textbox element.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="togglebutton">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a UI button that can be toggled to on or off state.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="toolbar">
+        <xsd:annotation>
+          <xsd:documentation>Indicates an array of controls, usually buttons.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="tooltip">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a pop up tool tip text.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="trackbar">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a bar with a pointer indicating a position within a certain range.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="tree">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a control that displays a set of hierarchical data.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="uri">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a URI (URN or URL).</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="userbutton">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a Windows RC USERBUTTON control.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="usercontrol">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a user-defined control like CONTROL control in Windows.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="var">
+        <xsd:annotation>
+          <xsd:documentation>Indicates the text of a variable.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="versioninfo">
+        <xsd:annotation>
+          <xsd:documentation>Indicates version information about a resource like VERSIONINFO in Windows.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="vscrollbar">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a vertical scrollbar.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="window">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a graphical window.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+    </xsd:restriction>
+  </xsd:simpleType>
+  <xsd:simpleType name="size-unitValueList">
+    <xsd:annotation>
+      <xsd:documentation>Values for the attribute 'size-unit'.</xsd:documentation>
+    </xsd:annotation>
+    <xsd:restriction base="xsd:NMTOKEN">
+      <xsd:enumeration value="byte">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a size in 8-bit bytes.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="char">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a size in Unicode characters.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="col">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a size in columns. Used for HTML text area.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="cm">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a size in centimeters.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="dlgunit">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a size in dialog units, as defined in Windows resources.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="em">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a size in 'font-size' units (as defined in CSS).</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="ex">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a size in 'x-height' units (as defined in CSS).</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="glyph">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a size in glyphs. A glyph is considered to be one or more combined Unicode characters that represent a single displayable text character. Sometimes referred to as a 'grapheme cluster'</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="in">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a size in inches.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="mm">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a size in millimeters.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="percent">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a size in percentage.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="pixel">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a size in pixels.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="point">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a size in point.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="row">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a size in rows. Used for HTML text area.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+    </xsd:restriction>
+  </xsd:simpleType>
+  <xsd:simpleType name="stateValueList">
+    <xsd:annotation>
+      <xsd:documentation>Values for the attribute 'state'.</xsd:documentation>
+    </xsd:annotation>
+    <xsd:restriction base="xsd:NMTOKEN">
+      <xsd:enumeration value="final">
+        <xsd:annotation>
+          <xsd:documentation>Indicates the terminating state.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="needs-adaptation">
+        <xsd:annotation>
+          <xsd:documentation>Indicates only non-textual information needs adaptation.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="needs-l10n">
+        <xsd:annotation>
+          <xsd:documentation>Indicates both text and non-textual information needs adaptation.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="needs-review-adaptation">
+        <xsd:annotation>
+          <xsd:documentation>Indicates only non-textual information needs review.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="needs-review-l10n">
+        <xsd:annotation>
+          <xsd:documentation>Indicates both text and non-textual information needs review.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="needs-review-translation">
+        <xsd:annotation>
+          <xsd:documentation>Indicates that only the text of the item needs to be reviewed.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="needs-translation">
+        <xsd:annotation>
+          <xsd:documentation>Indicates that the item needs to be translated.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="new">
+        <xsd:annotation>
+          <xsd:documentation>Indicates that the item is new. For example, translation units that were not in a previous version of the document.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="signed-off">
+        <xsd:annotation>
+          <xsd:documentation>Indicates that changes are reviewed and approved.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="translated">
+        <xsd:annotation>
+          <xsd:documentation>Indicates that the item has been translated.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+    </xsd:restriction>
+  </xsd:simpleType>
+  <xsd:simpleType name="state-qualifierValueList">
+    <xsd:annotation>
+      <xsd:documentation>Values for the attribute 'state-qualifier'.</xsd:documentation>
+    </xsd:annotation>
+    <xsd:restriction base="xsd:NMTOKEN">
+      <xsd:enumeration value="exact-match">
+        <xsd:annotation>
+          <xsd:documentation>Indicates an exact match. An exact match occurs when a source text of a segment is exactly the same as the source text of a segment that was translated previously.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="fuzzy-match">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a fuzzy match. A fuzzy match occurs when a source text of a segment is very similar to the source text of a segment that was translated previously (e.g. when the difference is casing, a few changed words, white-space discripancy, etc.).</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="id-match">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a match based on matching IDs (in addition to matching text).</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="leveraged-glossary">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a translation derived from a glossary.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="leveraged-inherited">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a translation derived from existing translation.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="leveraged-mt">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a translation derived from machine translation.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="leveraged-repository">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a translation derived from a translation repository.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="leveraged-tm">
+        <xsd:annotation>
+          <xsd:documentation>Indicates a translation derived from a translation memory.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="mt-suggestion">
+        <xsd:annotation>
+          <xsd:documentation>Indicates the translation is suggested by machine translation.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="rejected-grammar">
+        <xsd:annotation>
+          <xsd:documentation>Indicates that the item has been rejected because of incorrect grammar.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="rejected-inaccurate">
+        <xsd:annotation>
+          <xsd:documentation>Indicates that the item has been rejected because it is incorrect.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="rejected-length">
+        <xsd:annotation>
+          <xsd:documentation>Indicates that the item has been rejected because it is too long or too short.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="rejected-spelling">
+        <xsd:annotation>
+          <xsd:documentation>Indicates that the item has been rejected because of incorrect spelling.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="tm-suggestion">
+        <xsd:annotation>
+          <xsd:documentation>Indicates the translation is suggested by translation memory.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+    </xsd:restriction>
+  </xsd:simpleType>
+  <xsd:simpleType name="unitValueList">
+    <xsd:annotation>
+      <xsd:documentation>Values for the attribute 'unit'.</xsd:documentation>
+    </xsd:annotation>
+    <xsd:restriction base="xsd:NMTOKEN">
+      <xsd:enumeration value="word">
+        <xsd:annotation>
+          <xsd:documentation>Refers to words.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="page">
+        <xsd:annotation>
+          <xsd:documentation>Refers to pages.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="trans-unit">
+        <xsd:annotation>
+          <xsd:documentation>Refers to &lt;trans-unit&gt; elements.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="bin-unit">
+        <xsd:annotation>
+          <xsd:documentation>Refers to &lt;bin-unit&gt; elements.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="glyph">
+        <xsd:annotation>
+          <xsd:documentation>Refers to glyphs.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="item">
+        <xsd:annotation>
+          <xsd:documentation>Refers to &lt;trans-unit&gt; and/or &lt;bin-unit&gt; elements.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="instance">
+        <xsd:annotation>
+          <xsd:documentation>Refers to the occurrences of instances defined by the count-type value.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="character">
+        <xsd:annotation>
+          <xsd:documentation>Refers to characters.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="line">
+        <xsd:annotation>
+          <xsd:documentation>Refers to lines.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="sentence">
+        <xsd:annotation>
+          <xsd:documentation>Refers to sentences.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="paragraph">
+        <xsd:annotation>
+          <xsd:documentation>Refers to paragraphs.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="segment">
+        <xsd:annotation>
+          <xsd:documentation>Refers to segments.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="placeable">
+        <xsd:annotation>
+          <xsd:documentation>Refers to placeables (inline elements).</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+    </xsd:restriction>
+  </xsd:simpleType>
+  <xsd:simpleType name="priorityValueList">
+    <xsd:annotation>
+      <xsd:documentation>Values for the attribute 'priority'.</xsd:documentation>
+    </xsd:annotation>
+    <xsd:restriction base="xsd:positiveInteger">
+      <xsd:enumeration value="1">
+        <xsd:annotation>
+          <xsd:documentation>Highest priority.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="2">
+        <xsd:annotation>
+          <xsd:documentation>High priority.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="3">
+        <xsd:annotation>
+          <xsd:documentation>High priority, but not as important as 2.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="4">
+        <xsd:annotation>
+          <xsd:documentation>High priority, but not as important as 3.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="5">
+        <xsd:annotation>
+          <xsd:documentation>Medium priority, but more important than 6.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="6">
+        <xsd:annotation>
+          <xsd:documentation>Medium priority, but less important than 5.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="7">
+        <xsd:annotation>
+          <xsd:documentation>Low priority, but more important than 8.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="8">
+        <xsd:annotation>
+          <xsd:documentation>Low priority, but more important than 9.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="9">
+        <xsd:annotation>
+          <xsd:documentation>Low priority.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="10">
+        <xsd:annotation>
+          <xsd:documentation>Lowest priority.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+    </xsd:restriction>
+  </xsd:simpleType>
+  <xsd:simpleType name="reformatValueYesNo">
+    <xsd:restriction base="xsd:string">
+      <xsd:enumeration value="yes">
+        <xsd:annotation>
+          <xsd:documentation>This value indicates that all properties can be reformatted. This value must be used alone.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="no">
+        <xsd:annotation>
+          <xsd:documentation>This value indicates that no properties should be reformatted. This value must be used alone.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+    </xsd:restriction>
+  </xsd:simpleType>
+  <xsd:simpleType name="reformatValueList">
+    <xsd:list>
+      <xsd:simpleType>
+        <xsd:union memberTypes="xlf:XTend">
+          <xsd:simpleType>
+            <xsd:restriction base="xsd:string">
+              <xsd:enumeration value="coord">
+                <xsd:annotation>
+                  <xsd:documentation>This value indicates that all information in the coord attribute can be modified.</xsd:documentation>
+                </xsd:annotation>
+              </xsd:enumeration>
+              <xsd:enumeration value="coord-x">
+                <xsd:annotation>
+                  <xsd:documentation>This value indicates that the x information in the coord attribute can be modified.</xsd:documentation>
+                </xsd:annotation>
+              </xsd:enumeration>
+              <xsd:enumeration value="coord-y">
+                <xsd:annotation>
+                  <xsd:documentation>This value indicates that the y information in the coord attribute can be modified.</xsd:documentation>
+                </xsd:annotation>
+              </xsd:enumeration>
+              <xsd:enumeration value="coord-cx">
+                <xsd:annotation>
+                  <xsd:documentation>This value indicates that the cx information in the coord attribute can be modified.</xsd:documentation>
+                </xsd:annotation>
+              </xsd:enumeration>
+              <xsd:enumeration value="coord-cy">
+                <xsd:annotation>
+                  <xsd:documentation>This value indicates that the cy information in the coord attribute can be modified.</xsd:documentation>
+                </xsd:annotation>
+              </xsd:enumeration>
+              <xsd:enumeration value="font">
+                <xsd:annotation>
+                  <xsd:documentation>This value indicates that all the information in the font attribute can be modified.</xsd:documentation>
+                </xsd:annotation>
+              </xsd:enumeration>
+              <xsd:enumeration value="font-name">
+                <xsd:annotation>
+                  <xsd:documentation>This value indicates that the name information in the font attribute can be modified.</xsd:documentation>
+                </xsd:annotation>
+              </xsd:enumeration>
+              <xsd:enumeration value="font-size">
+                <xsd:annotation>
+                  <xsd:documentation>This value indicates that the size information in the font attribute can be modified.</xsd:documentation>
+                </xsd:annotation>
+              </xsd:enumeration>
+              <xsd:enumeration value="font-weight">
+                <xsd:annotation>
+                  <xsd:documentation>This value indicates that the weight information in the font attribute can be modified.</xsd:documentation>
+                </xsd:annotation>
+              </xsd:enumeration>
+              <xsd:enumeration value="css-style">
+                <xsd:annotation>
+                  <xsd:documentation>This value indicates that the information in the css-style attribute can be modified.</xsd:documentation>
+                </xsd:annotation>
+              </xsd:enumeration>
+              <xsd:enumeration value="style">
+                <xsd:annotation>
+                  <xsd:documentation>This value indicates that the information in the style attribute can be modified.</xsd:documentation>
+                </xsd:annotation>
+              </xsd:enumeration>
+              <xsd:enumeration value="ex-style">
+                <xsd:annotation>
+                  <xsd:documentation>This value indicates that the information in the exstyle attribute can be modified.</xsd:documentation>
+                </xsd:annotation>
+              </xsd:enumeration>
+            </xsd:restriction>
+          </xsd:simpleType>
+        </xsd:union>
+      </xsd:simpleType>
+    </xsd:list>
+  </xsd:simpleType>
+  <xsd:simpleType name="purposeValueList">
+    <xsd:restriction base="xsd:string">
+      <xsd:enumeration value="information">
+        <xsd:annotation>
+          <xsd:documentation>Indicates that the context is informational in nature, specifying for example, how a term should be translated. Thus, should be displayed to anyone editing the XLIFF document.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="location">
+        <xsd:annotation>
+          <xsd:documentation>Indicates that the context-group is used to specify where the term was found in the translatable source. Thus, it is not displayed.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="match">
+        <xsd:annotation>
+          <xsd:documentation>Indicates that the context information should be used during translation memory lookups. Thus, it is not displayed.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+    </xsd:restriction>
+  </xsd:simpleType>
+  <xsd:simpleType name="alttranstypeValueList">
+    <xsd:restriction base="xsd:string">
+      <xsd:enumeration value="proposal">
+        <xsd:annotation>
+          <xsd:documentation>Represents a translation proposal from a translation memory or other resource.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="previous-version">
+        <xsd:annotation>
+          <xsd:documentation>Represents a previous version of the target element.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="rejected">
+        <xsd:annotation>
+          <xsd:documentation>Represents a rejected version of the target element.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="reference">
+        <xsd:annotation>
+          <xsd:documentation>Represents a translation to be used for reference purposes only, for example from a related product or a different language.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+      <xsd:enumeration value="accepted">
+        <xsd:annotation>
+          <xsd:documentation>Represents a proposed translation that was used for the translation of the trans-unit, possibly modified.</xsd:documentation>
+        </xsd:annotation>
+      </xsd:enumeration>
+    </xsd:restriction>
+  </xsd:simpleType>
+  <!-- Other Types -->
+  <xsd:complexType name="ElemType_ExternalReference">
+    <xsd:choice>
+      <xsd:element ref="xlf:internal-file"/>
+      <xsd:element ref="xlf:external-file"/>
+    </xsd:choice>
+  </xsd:complexType>
+  <xsd:simpleType name="AttrType_purpose">
+    <xsd:list>
+      <xsd:simpleType>
+        <xsd:union memberTypes="xlf:purposeValueList xlf:XTend"/>
+      </xsd:simpleType>
+    </xsd:list>
+  </xsd:simpleType>
+  <xsd:simpleType name="AttrType_datatype">
+    <xsd:union memberTypes="xlf:datatypeValueList xlf:XTend"/>
+  </xsd:simpleType>
+  <xsd:simpleType name="AttrType_restype">
+    <xsd:union memberTypes="xlf:restypeValueList xlf:XTend"/>
+  </xsd:simpleType>
+  <xsd:simpleType name="AttrType_alttranstype">
+    <xsd:union memberTypes="xlf:alttranstypeValueList xlf:XTend"/>
+  </xsd:simpleType>
+  <xsd:simpleType name="AttrType_context-type">
+    <xsd:union memberTypes="xlf:context-typeValueList xlf:XTend"/>
+  </xsd:simpleType>
+  <xsd:simpleType name="AttrType_state">
+    <xsd:union memberTypes="xlf:stateValueList xlf:XTend"/>
+  </xsd:simpleType>
+  <xsd:simpleType name="AttrType_state-qualifier">
+    <xsd:union memberTypes="xlf:state-qualifierValueList xlf:XTend"/>
+  </xsd:simpleType>
+  <xsd:simpleType name="AttrType_count-type">
+    <xsd:union memberTypes="xlf:restypeValueList xlf:count-typeValueList xlf:datatypeValueList xlf:stateValueList xlf:state-qualifierValueList xlf:XTend"/>
+  </xsd:simpleType>
+  <xsd:simpleType name="AttrType_InlineDelimiters">
+    <xsd:union memberTypes="xlf:InlineDelimitersValueList xlf:XTend"/>
+  </xsd:simpleType>
+  <xsd:simpleType name="AttrType_InlinePlaceholders">
+    <xsd:union memberTypes="xlf:InlinePlaceholdersValueList xlf:XTend"/>
+  </xsd:simpleType>
+  <xsd:simpleType name="AttrType_size-unit">
+    <xsd:union memberTypes="xlf:size-unitValueList xlf:XTend"/>
+  </xsd:simpleType>
+  <xsd:simpleType name="AttrType_mtype">
+    <xsd:union memberTypes="xlf:mtypeValueList xlf:XTend"/>
+  </xsd:simpleType>
+  <xsd:simpleType name="AttrType_unit">
+    <xsd:union memberTypes="xlf:unitValueList xlf:XTend"/>
+  </xsd:simpleType>
+  <xsd:simpleType name="AttrType_priority">
+    <xsd:union memberTypes="xlf:priorityValueList"/>
+  </xsd:simpleType>
+  <xsd:simpleType name="AttrType_reformat">
+    <xsd:union memberTypes="xlf:reformatValueYesNo xlf:reformatValueList"/>
+  </xsd:simpleType>
+  <xsd:simpleType name="AttrType_YesNo">
+    <xsd:restriction base="xsd:NMTOKEN">
+      <xsd:enumeration value="yes"/>
+      <xsd:enumeration value="no"/>
+    </xsd:restriction>
+  </xsd:simpleType>
+  <xsd:simpleType name="AttrType_Position">
+    <xsd:restriction base="xsd:NMTOKEN">
+      <xsd:enumeration value="open"/>
+      <xsd:enumeration value="close"/>
+    </xsd:restriction>
+  </xsd:simpleType>
+  <xsd:simpleType name="AttrType_assoc">
+    <xsd:restriction base="xsd:NMTOKEN">
+      <xsd:enumeration value="preceding"/>
+      <xsd:enumeration value="following"/>
+      <xsd:enumeration value="both"/>
+    </xsd:restriction>
+  </xsd:simpleType>
+  <xsd:simpleType name="AttrType_annotates">
+    <xsd:restriction base="xsd:NMTOKEN">
+      <xsd:enumeration value="source"/>
+      <xsd:enumeration value="target"/>
+      <xsd:enumeration value="general"/>
+    </xsd:restriction>
+  </xsd:simpleType>
+  <xsd:simpleType name="AttrType_Coordinates">
+    <xsd:annotation>
+      <xsd:documentation>Values for the attribute 'coord'.</xsd:documentation>
+    </xsd:annotation>
+    <xsd:restriction base="xsd:string">
+      <xsd:pattern value="(-?\d+|#);(-?\d+|#);(-?\d+|#);(-?\d+|#)"/>
+    </xsd:restriction>
+  </xsd:simpleType>
+  <xsd:simpleType name="AttrType_Version">
+    <xsd:annotation>
+      <xsd:documentation>Version values: 1.0 and 1.1 are allowed for backward compatibility.</xsd:documentation>
+    </xsd:annotation>
+    <xsd:restriction base="xsd:string">
+      <xsd:enumeration value="1.2"/>
+      <xsd:enumeration value="1.1"/>
+      <xsd:enumeration value="1.0"/>
+    </xsd:restriction>
+  </xsd:simpleType>
+  <!-- Groups -->
+  <xsd:group name="ElemGroup_TextContent">
+    <xsd:choice>
+      <xsd:element ref="xlf:g"/>
+      <xsd:element ref="xlf:bpt"/>
+      <xsd:element ref="xlf:ept"/>
+      <xsd:element ref="xlf:ph"/>
+      <xsd:element ref="xlf:it"/>
+      <xsd:element ref="xlf:mrk"/>
+      <xsd:element ref="xlf:x"/>
+      <xsd:element ref="xlf:bx"/>
+      <xsd:element ref="xlf:ex"/>
+    </xsd:choice>
+  </xsd:group>
+  <xsd:attributeGroup name="AttrGroup_TextContent">
+    <xsd:attribute name="id" type="xsd:string" use="required"/>
+    <xsd:attribute name="xid" type="xsd:string" use="optional"/>
+    <xsd:attribute name="equiv-text" type="xsd:string" use="optional"/>
+    <xsd:anyAttribute namespace="##other" processContents="strict"/>
+  </xsd:attributeGroup>
+  <!-- XLIFF Structure -->
+  <xsd:element name="xliff">
+    <xsd:complexType>
+      <xsd:sequence maxOccurs="unbounded">
+        <xsd:any maxOccurs="unbounded" minOccurs="0" namespace="##other" processContents="strict"/>
+        <xsd:element ref="xlf:file"/>
+      </xsd:sequence>
+      <xsd:attribute name="version" type="xlf:AttrType_Version" use="required"/>
+      <xsd:attribute ref="xml:lang" use="optional"/>
+      <xsd:anyAttribute namespace="##other" processContents="strict"/>
+    </xsd:complexType>
+  </xsd:element>
+  <xsd:element name="file">
+    <xsd:complexType>
+      <xsd:sequence>
+        <xsd:element minOccurs="0" ref="xlf:header"/>
+        <xsd:element ref="xlf:body"/>
+      </xsd:sequence>
+      <xsd:attribute name="original" type="xsd:string" use="required"/>
+      <xsd:attribute name="source-language" type="xsd:language" use="required"/>
+      <xsd:attribute name="datatype" type="xlf:AttrType_datatype" use="required"/>
+      <xsd:attribute name="tool-id" type="xsd:string" use="optional"/>
+      <xsd:attribute name="date" type="xsd:dateTime" use="optional"/>
+      <xsd:attribute ref="xml:space" use="optional"/>
+      <xsd:attribute name="category" type="xsd:string" use="optional"/>
+      <xsd:attribute name="target-language" type="xsd:language" use="optional"/>
+      <xsd:attribute name="product-name" type="xsd:string" use="optional"/>
+      <xsd:attribute name="product-version" type="xsd:string" use="optional"/>
+      <xsd:attribute name="build-num" type="xsd:string" use="optional"/>
+      <xsd:anyAttribute namespace="##other" processContents="strict"/>
+    </xsd:complexType>
+    <xsd:unique name="U_group_id">
+      <xsd:selector xpath=".//xlf:group"/>
+      <xsd:field xpath="@id"/>
+    </xsd:unique>
+    <xsd:key name="K_unit_id">
+      <xsd:selector xpath=".//xlf:trans-unit|.//xlf:bin-unit"/>
+      <xsd:field xpath="@id"/>
+    </xsd:key>
+    <xsd:keyref name="KR_unit_id" refer="xlf:K_unit_id">
+      <xsd:selector xpath=".//bpt|.//ept|.//it|.//ph|.//g|.//x|.//bx|.//ex|.//sub"/>
+      <xsd:field xpath="@xid"/>
+    </xsd:keyref>
+    <xsd:key name="K_tool-id">
+      <xsd:selector xpath="xlf:header/xlf:tool"/>
+      <xsd:field xpath="@tool-id"/>
+    </xsd:key>
+    <xsd:keyref name="KR_file_tool-id" refer="xlf:K_tool-id">
+      <xsd:selector xpath="."/>
+      <xsd:field xpath="@tool-id"/>
+    </xsd:keyref>
+    <xsd:keyref name="KR_phase_tool-id" refer="xlf:K_tool-id">
+      <xsd:selector xpath="xlf:header/xlf:phase-group/xlf:phase"/>
+      <xsd:field xpath="@tool-id"/>
+    </xsd:keyref>
+    <xsd:keyref name="KR_alt-trans_tool-id" refer="xlf:K_tool-id">
+      <xsd:selector xpath=".//xlf:trans-unit/xlf:alt-trans"/>
+      <xsd:field xpath="@tool-id"/>
+    </xsd:keyref>
+    <xsd:key name="K_count-group_name">
+      <xsd:selector xpath=".//xlf:count-group"/>
+      <xsd:field xpath="@name"/>
+    </xsd:key>
+    <xsd:unique name="U_context-group_name">
+      <xsd:selector xpath=".//xlf:context-group"/>
+      <xsd:field xpath="@name"/>
+    </xsd:unique>
+    <xsd:key name="K_phase-name">
+      <xsd:selector xpath="xlf:header/xlf:phase-group/xlf:phase"/>
+      <xsd:field xpath="@phase-name"/>
+    </xsd:key>
+    <xsd:keyref name="KR_phase-name" refer="xlf:K_phase-name">
+      <xsd:selector xpath=".//xlf:count|.//xlf:trans-unit|.//xlf:target|.//bin-unit|.//bin-target"/>
+      <xsd:field xpath="@phase-name"/>
+    </xsd:keyref>
+    <xsd:unique name="U_uid">
+      <xsd:selector xpath=".//xlf:external-file"/>
+      <xsd:field xpath="@uid"/>
+    </xsd:unique>
+  </xsd:element>
+  <xsd:element name="header">
+    <xsd:complexType>
+      <xsd:sequence>
+        <xsd:element minOccurs="0" name="skl" type="xlf:ElemType_ExternalReference"/>
+        <xsd:element minOccurs="0" ref="xlf:phase-group"/>
+        <xsd:choice maxOccurs="unbounded" minOccurs="0">
+          <xsd:element name="glossary" type="xlf:ElemType_ExternalReference"/>
+          <xsd:element name="reference" type="xlf:ElemType_ExternalReference"/>
+          <xsd:element ref="xlf:count-group"/>
+          <xsd:element ref="xlf:note"/>
+          <xsd:element ref="xlf:tool"/>
+        </xsd:choice>
+        <xsd:any maxOccurs="unbounded" minOccurs="0" namespace="##other" processContents="strict"/>
+      </xsd:sequence>
+    </xsd:complexType>
+  </xsd:element>
+  <xsd:element name="internal-file">
+    <xsd:complexType>
+      <xsd:simpleContent>
+        <xsd:extension base="xsd:string">
+          <xsd:attribute name="form" type="xsd:string"/>
+          <xsd:attribute name="crc" type="xsd:NMTOKEN"/>
+        </xsd:extension>
+      </xsd:simpleContent>
+    </xsd:complexType>
+  </xsd:element>
+  <xsd:element name="external-file">
+    <xsd:complexType>
+      <xsd:attribute name="href" type="xsd:string" use="required"/>
+      <xsd:attribute name="crc" type="xsd:NMTOKEN"/>
+      <xsd:attribute name="uid" type="xsd:NMTOKEN"/>
+    </xsd:complexType>
+  </xsd:element>
+  <xsd:element name="note">
+    <xsd:complexType>
+      <xsd:simpleContent>
+        <xsd:extension base="xsd:string">
+          <xsd:attribute ref="xml:lang" use="optional"/>
+          <xsd:attribute default="1" name="priority" type="xlf:AttrType_priority" use="optional"/>
+          <xsd:attribute name="from" type="xsd:string" use="optional"/>
+          <xsd:attribute default="general" name="annotates" type="xlf:AttrType_annotates" use="optional"/>
+        </xsd:extension>
+      </xsd:simpleContent>
+    </xsd:complexType>
+  </xsd:element>
+  <xsd:element name="phase-group">
+    <xsd:complexType>
+      <xsd:sequence maxOccurs="unbounded">
+        <xsd:element ref="xlf:phase"/>
+      </xsd:sequence>
+    </xsd:complexType>
+  </xsd:element>
+  <xsd:element name="phase">
+    <xsd:complexType>
+      <xsd:sequence maxOccurs="unbounded" minOccurs="0">
+        <xsd:element ref="xlf:note"/>
+      </xsd:sequence>
+      <xsd:attribute name="phase-name" type="xsd:string" use="required"/>
+      <xsd:attribute name="process-name" type="xsd:string" use="required"/>
+      <xsd:attribute name="company-name" type="xsd:string" use="optional"/>
+      <xsd:attribute name="tool-id" type="xsd:string" use="optional"/>
+      <xsd:attribute name="date" type="xsd:dateTime" use="optional"/>
+      <xsd:attribute name="job-id" type="xsd:string" use="optional"/>
+      <xsd:attribute name="contact-name" type="xsd:string" use="optional"/>
+      <xsd:attribute name="contact-email" type="xsd:string" use="optional"/>
+      <xsd:attribute name="contact-phone" type="xsd:string" use="optional"/>
+    </xsd:complexType>
+  </xsd:element>
+  <xsd:element name="count-group">
+    <xsd:complexType>
+      <xsd:sequence maxOccurs="unbounded" minOccurs="0">
+        <xsd:element ref="xlf:count"/>
+      </xsd:sequence>
+      <xsd:attribute name="name" type="xsd:string" use="required"/>
+    </xsd:complexType>
+  </xsd:element>
+  <xsd:element name="count">
+    <xsd:complexType>
+      <xsd:simpleContent>
+        <xsd:extension base="xsd:string">
+          <xsd:attribute name="count-type" type="xlf:AttrType_count-type" use="optional"/>
+          <xsd:attribute name="phase-name" type="xsd:string" use="optional"/>
+          <xsd:attribute default="word" name="unit" type="xlf:AttrType_unit" use="optional"/>
+        </xsd:extension>
+      </xsd:simpleContent>
+    </xsd:complexType>
+  </xsd:element>
+  <xsd:element name="context-group">
+    <xsd:complexType>
+      <xsd:sequence maxOccurs="unbounded">
+        <xsd:element ref="xlf:context"/>
+      </xsd:sequence>
+      <xsd:attribute name="name" type="xsd:string" use="optional"/>
+      <xsd:attribute name="crc" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute name="purpose" type="xlf:AttrType_purpose" use="optional"/>
+    </xsd:complexType>
+  </xsd:element>
+  <xsd:element name="context">
+    <xsd:complexType>
+      <xsd:simpleContent>
+        <xsd:extension base="xsd:string">
+          <xsd:attribute name="context-type" type="xlf:AttrType_context-type" use="required"/>
+          <xsd:attribute default="no" name="match-mandatory" type="xlf:AttrType_YesNo" use="optional"/>
+          <xsd:attribute name="crc" type="xsd:NMTOKEN" use="optional"/>
+        </xsd:extension>
+      </xsd:simpleContent>
+    </xsd:complexType>
+  </xsd:element>
+  <xsd:element name="tool">
+    <xsd:complexType mixed="true">
+      <xsd:sequence>
+        <xsd:any namespace="##any" processContents="strict" minOccurs="0" maxOccurs="unbounded"/>
+      </xsd:sequence>
+      <xsd:attribute name="tool-id" type="xsd:string" use="required"/>
+      <xsd:attribute name="tool-name" type="xsd:string" use="required"/>
+      <xsd:attribute name="tool-version" type="xsd:string" use="optional"/>
+      <xsd:attribute name="tool-company" type="xsd:string" use="optional"/>
+      <xsd:anyAttribute namespace="##other" processContents="strict"/>
+    </xsd:complexType>
+  </xsd:element>
+  <xsd:element name="body">
+    <xsd:complexType>
+      <xsd:choice maxOccurs="unbounded" minOccurs="0">
+        <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:group"/>
+        <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:trans-unit"/>
+        <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:bin-unit"/>
+      </xsd:choice>
+    </xsd:complexType>
+  </xsd:element>
+  <xsd:element name="group">
+    <xsd:complexType>
+      <xsd:sequence>
+        <xsd:sequence>
+          <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:context-group"/>
+          <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:count-group"/>
+          <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:note"/>
+          <xsd:any maxOccurs="unbounded" minOccurs="0" namespace="##other" processContents="strict"/>
+        </xsd:sequence>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:group"/>
+          <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:trans-unit"/>
+          <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:bin-unit"/>
+        </xsd:choice>
+      </xsd:sequence>
+      <xsd:attribute name="id" type="xsd:string" use="optional"/>
+      <xsd:attribute name="datatype" type="xlf:AttrType_datatype" use="optional"/>
+      <xsd:attribute default="default" ref="xml:space" use="optional"/>
+      <xsd:attribute name="restype" type="xlf:AttrType_restype" use="optional"/>
+      <xsd:attribute name="resname" type="xsd:string" use="optional"/>
+      <xsd:attribute name="extradata" type="xsd:string" use="optional"/>
+      <xsd:attribute name="extype" type="xsd:string" use="optional"/>
+      <xsd:attribute name="help-id" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute name="menu" type="xsd:string" use="optional"/>
+      <xsd:attribute name="menu-option" type="xsd:string" use="optional"/>
+      <xsd:attribute name="menu-name" type="xsd:string" use="optional"/>
+      <xsd:attribute name="coord" type="xlf:AttrType_Coordinates" use="optional"/>
+      <xsd:attribute name="font" type="xsd:string" use="optional"/>
+      <xsd:attribute name="css-style" type="xsd:string" use="optional"/>
+      <xsd:attribute name="style" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute name="exstyle" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute default="yes" name="translate" type="xlf:AttrType_YesNo" use="optional"/>
+      <xsd:attribute default="yes" name="reformat" type="xlf:AttrType_reformat" use="optional"/>
+      <xsd:attribute default="pixel" name="size-unit" type="xlf:AttrType_size-unit" use="optional"/>
+      <xsd:attribute name="maxwidth" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute name="minwidth" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute name="maxheight" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute name="minheight" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute name="maxbytes" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute name="minbytes" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute name="charclass" type="xsd:string" use="optional"/>
+      <xsd:attribute default="no" name="merged-trans" type="xlf:AttrType_YesNo" use="optional"/>
+      <xsd:anyAttribute namespace="##other" processContents="strict"/>
+    </xsd:complexType>
+  </xsd:element>
+  <xsd:element name="trans-unit">
+    <xsd:complexType>
+      <xsd:sequence>
+        <xsd:element ref="xlf:source"/>
+        <xsd:element minOccurs="0" ref="xlf:seg-source"/>
+        <xsd:element minOccurs="0" ref="xlf:target"/>
+        <xsd:choice maxOccurs="unbounded" minOccurs="0">
+          <xsd:element ref="xlf:context-group"/>
+          <xsd:element ref="xlf:count-group"/>
+          <xsd:element ref="xlf:note"/>
+          <xsd:element ref="xlf:alt-trans"/>
+        </xsd:choice>
+        <xsd:any maxOccurs="unbounded" minOccurs="0" namespace="##other" processContents="strict"/>
+      </xsd:sequence>
+      <xsd:attribute name="id" type="xsd:string" use="required"/>
+      <xsd:attribute name="approved" type="xlf:AttrType_YesNo" use="optional"/>
+      <xsd:attribute default="yes" name="translate" type="xlf:AttrType_YesNo" use="optional"/>
+      <xsd:attribute default="yes" name="reformat" type="xlf:AttrType_reformat" use="optional"/>
+      <xsd:attribute default="default" ref="xml:space" use="optional"/>
+      <xsd:attribute name="datatype" type="xlf:AttrType_datatype" use="optional"/>
+      <xsd:attribute name="phase-name" type="xsd:string" use="optional"/>
+      <xsd:attribute name="restype" type="xlf:AttrType_restype" use="optional"/>
+      <xsd:attribute name="resname" type="xsd:string" use="optional"/>
+      <xsd:attribute name="extradata" type="xsd:string" use="optional"/>
+      <xsd:attribute name="extype" type="xsd:string" use="optional"/>
+      <xsd:attribute name="help-id" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute name="menu" type="xsd:string" use="optional"/>
+      <xsd:attribute name="menu-option" type="xsd:string" use="optional"/>
+      <xsd:attribute name="menu-name" type="xsd:string" use="optional"/>
+      <xsd:attribute name="coord" type="xlf:AttrType_Coordinates" use="optional"/>
+      <xsd:attribute name="font" type="xsd:string" use="optional"/>
+      <xsd:attribute name="css-style" type="xsd:string" use="optional"/>
+      <xsd:attribute name="style" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute name="exstyle" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute default="pixel" name="size-unit" type="xlf:AttrType_size-unit" use="optional"/>
+      <xsd:attribute name="maxwidth" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute name="minwidth" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute name="maxheight" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute name="minheight" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute name="maxbytes" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute name="minbytes" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute name="charclass" type="xsd:string" use="optional"/>
+      <xsd:attribute default="yes" name="merged-trans" type="xlf:AttrType_YesNo" use="optional"/>
+      <xsd:anyAttribute namespace="##other" processContents="strict"/>
+    </xsd:complexType>
+    <xsd:unique name="U_tu_segsrc_mid">
+      <xsd:selector xpath="./xlf:seg-source/xlf:mrk"/>
+      <xsd:field xpath="@mid"/>
+    </xsd:unique>
+    <xsd:keyref name="KR_tu_segsrc_mid" refer="xlf:U_tu_segsrc_mid">
+      <xsd:selector xpath="./xlf:target/xlf:mrk|./xlf:alt-trans"/>
+      <xsd:field xpath="@mid"/>
+    </xsd:keyref>
+  </xsd:element>
+  <xsd:element name="source">
+    <xsd:complexType mixed="true">
+      <xsd:group maxOccurs="unbounded" minOccurs="0" ref="xlf:ElemGroup_TextContent"/>
+      <xsd:attribute ref="xml:lang" use="optional"/>
+      <xsd:anyAttribute namespace="##other" processContents="strict"/>
+    </xsd:complexType>
+    <xsd:unique name="U_source_bpt_rid">
+      <xsd:selector xpath=".//xlf:bpt"/>
+      <xsd:field xpath="@rid"/>
+    </xsd:unique>
+    <xsd:keyref name="KR_source_ept_rid" refer="xlf:U_source_bpt_rid">
+      <xsd:selector xpath=".//xlf:ept"/>
+      <xsd:field xpath="@rid"/>
+    </xsd:keyref>
+    <xsd:unique name="U_source_bx_rid">
+      <xsd:selector xpath=".//xlf:bx"/>
+      <xsd:field xpath="@rid"/>
+    </xsd:unique>
+    <xsd:keyref name="KR_source_ex_rid" refer="xlf:U_source_bx_rid">
+      <xsd:selector xpath=".//xlf:ex"/>
+      <xsd:field xpath="@rid"/>
+    </xsd:keyref>
+  </xsd:element>
+  <xsd:element name="seg-source">
+    <xsd:complexType mixed="true">
+      <xsd:group maxOccurs="unbounded" minOccurs="0" ref="xlf:ElemGroup_TextContent"/>
+      <xsd:attribute ref="xml:lang" use="optional"/>
+      <xsd:anyAttribute namespace="##other" processContents="strict"/>
+    </xsd:complexType>
+    <xsd:unique name="U_segsrc_bpt_rid">
+      <xsd:selector xpath=".//xlf:bpt"/>
+      <xsd:field xpath="@rid"/>
+    </xsd:unique>
+    <xsd:keyref name="KR_segsrc_ept_rid" refer="xlf:U_segsrc_bpt_rid">
+      <xsd:selector xpath=".//xlf:ept"/>
+      <xsd:field xpath="@rid"/>
+    </xsd:keyref>
+    <xsd:unique name="U_segsrc_bx_rid">
+      <xsd:selector xpath=".//xlf:bx"/>
+      <xsd:field xpath="@rid"/>
+    </xsd:unique>
+    <xsd:keyref name="KR_segsrc_ex_rid" refer="xlf:U_segsrc_bx_rid">
+      <xsd:selector xpath=".//xlf:ex"/>
+      <xsd:field xpath="@rid"/>
+    </xsd:keyref>
+  </xsd:element>
+  <xsd:element name="target">
+    <xsd:complexType mixed="true">
+      <xsd:group maxOccurs="unbounded" minOccurs="0" ref="xlf:ElemGroup_TextContent"/>
+      <xsd:attribute name="state" type="xlf:AttrType_state" use="optional"/>
+      <xsd:attribute name="state-qualifier" type="xlf:AttrType_state-qualifier" use="optional"/>
+      <xsd:attribute name="phase-name" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute ref="xml:lang" use="optional"/>
+      <xsd:attribute name="resname" type="xsd:string" use="optional"/>
+      <xsd:attribute name="coord" type="xlf:AttrType_Coordinates" use="optional"/>
+      <xsd:attribute name="font" type="xsd:string" use="optional"/>
+      <xsd:attribute name="css-style" type="xsd:string" use="optional"/>
+      <xsd:attribute name="style" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute name="exstyle" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute default="yes" name="equiv-trans" type="xlf:AttrType_YesNo" use="optional"/>
+      <xsd:anyAttribute namespace="##other" processContents="strict"/>
+    </xsd:complexType>
+    <xsd:unique name="U_target_bpt_rid">
+      <xsd:selector xpath=".//xlf:bpt"/>
+      <xsd:field xpath="@rid"/>
+    </xsd:unique>
+    <xsd:keyref name="KR_target_ept_rid" refer="xlf:U_target_bpt_rid">
+      <xsd:selector xpath=".//xlf:ept"/>
+      <xsd:field xpath="@rid"/>
+    </xsd:keyref>
+    <xsd:unique name="U_target_bx_rid">
+      <xsd:selector xpath=".//xlf:bx"/>
+      <xsd:field xpath="@rid"/>
+    </xsd:unique>
+    <xsd:keyref name="KR_target_ex_rid" refer="xlf:U_target_bx_rid">
+      <xsd:selector xpath=".//xlf:ex"/>
+      <xsd:field xpath="@rid"/>
+    </xsd:keyref>
+  </xsd:element>
+  <xsd:element name="alt-trans">
+    <xsd:complexType>
+      <xsd:sequence>
+        <xsd:element minOccurs="0" ref="xlf:source"/>
+        <xsd:element minOccurs="0" ref="xlf:seg-source"/>
+        <xsd:element maxOccurs="1" ref="xlf:target"/>
+        <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:context-group"/>
+        <xsd:element maxOccurs="unbounded" minOccurs="0" ref="xlf:note"/>
+        <xsd:any maxOccurs="unbounded" minOccurs="0" namespace="##other" processContents="strict"/>
+      </xsd:sequence>
+      <xsd:attribute name="match-quality" type="xsd:string" use="optional"/>
+      <xsd:attribute name="tool-id" type="xsd:string" use="optional"/>
+      <xsd:attribute name="crc" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute ref="xml:lang" use="optional"/>
+      <xsd:attribute name="origin" type="xsd:string" use="optional"/>
+      <xsd:attribute name="datatype" type="xlf:AttrType_datatype" use="optional"/>
+      <xsd:attribute default="default" ref="xml:space" use="optional"/>
+      <xsd:attribute name="restype" type="xlf:AttrType_restype" use="optional"/>
+      <xsd:attribute name="resname" type="xsd:string" use="optional"/>
+      <xsd:attribute name="extradata" type="xsd:string" use="optional"/>
+      <xsd:attribute name="extype" type="xsd:string" use="optional"/>
+      <xsd:attribute name="help-id" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute name="menu" type="xsd:string" use="optional"/>
+      <xsd:attribute name="menu-option" type="xsd:string" use="optional"/>
+      <xsd:attribute name="menu-name" type="xsd:string" use="optional"/>
+      <xsd:attribute name="mid" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute name="coord" type="xlf:AttrType_Coordinates" use="optional"/>
+      <xsd:attribute name="font" type="xsd:string" use="optional"/>
+      <xsd:attribute name="css-style" type="xsd:string" use="optional"/>
+      <xsd:attribute name="style" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute name="exstyle" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute name="phase-name" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute default="proposal" name="alttranstype" type="xlf:AttrType_alttranstype" use="optional"/>
+      <xsd:anyAttribute namespace="##other" processContents="strict"/>
+    </xsd:complexType>
+    <xsd:unique name="U_at_segsrc_mid">
+      <xsd:selector xpath="./xlf:seg-source/xlf:mrk"/>
+      <xsd:field xpath="@mid"/>
+    </xsd:unique>
+    <xsd:keyref name="KR_at_segsrc_mid" refer="xlf:U_at_segsrc_mid">
+      <xsd:selector xpath="./xlf:target/xlf:mrk"/>
+      <xsd:field xpath="@mid"/>
+    </xsd:keyref>
+  </xsd:element>
+  <xsd:element name="bin-unit">
+    <xsd:complexType>
+      <xsd:sequence>
+        <xsd:element ref="xlf:bin-source"/>
+        <xsd:element minOccurs="0" ref="xlf:bin-target"/>
+        <xsd:choice maxOccurs="unbounded" minOccurs="0">
+          <xsd:element ref="xlf:context-group"/>
+          <xsd:element ref="xlf:count-group"/>
+          <xsd:element ref="xlf:note"/>
+          <xsd:element ref="xlf:trans-unit"/>
+        </xsd:choice>
+        <xsd:any maxOccurs="unbounded" minOccurs="0" namespace="##other" processContents="strict"/>
+      </xsd:sequence>
+      <xsd:attribute name="id" type="xsd:string" use="required"/>
+      <xsd:attribute name="mime-type" type="xlf:mime-typeValueList" use="required"/>
+      <xsd:attribute name="approved" type="xlf:AttrType_YesNo" use="optional"/>
+      <xsd:attribute default="yes" name="translate" type="xlf:AttrType_YesNo" use="optional"/>
+      <xsd:attribute default="yes" name="reformat" type="xlf:AttrType_reformat" use="optional"/>
+      <xsd:attribute name="restype" type="xlf:AttrType_restype" use="optional"/>
+      <xsd:attribute name="resname" type="xsd:string" use="optional"/>
+      <xsd:attribute name="phase-name" type="xsd:string" use="optional"/>
+      <xsd:anyAttribute namespace="##other" processContents="strict"/>
+    </xsd:complexType>
+  </xsd:element>
+  <xsd:element name="bin-source">
+    <xsd:complexType>
+      <xsd:choice>
+        <xsd:element ref="xlf:internal-file"/>
+        <xsd:element ref="xlf:external-file"/>
+      </xsd:choice>
+      <xsd:anyAttribute namespace="##other" processContents="strict"/>
+    </xsd:complexType>
+  </xsd:element>
+  <xsd:element name="bin-target">
+    <xsd:complexType>
+      <xsd:choice>
+        <xsd:element ref="xlf:internal-file"/>
+        <xsd:element ref="xlf:external-file"/>
+      </xsd:choice>
+      <xsd:attribute name="mime-type" type="xlf:mime-typeValueList" use="optional"/>
+      <xsd:attribute name="state" type="xlf:AttrType_state" use="optional"/>
+      <xsd:attribute name="state-qualifier" type="xlf:AttrType_state-qualifier" use="optional"/>
+      <xsd:attribute name="phase-name" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute name="restype" type="xlf:AttrType_restype" use="optional"/>
+      <xsd:attribute name="resname" type="xsd:string" use="optional"/>
+      <xsd:anyAttribute namespace="##other" processContents="strict"/>
+    </xsd:complexType>
+  </xsd:element>
+  <!-- Element for inline codes -->
+  <xsd:element name="g">
+    <xsd:complexType mixed="true">
+      <xsd:group maxOccurs="unbounded" minOccurs="0" ref="xlf:ElemGroup_TextContent"/>
+      <xsd:attribute name="ctype" type="xlf:AttrType_InlineDelimiters" use="optional"/>
+      <xsd:attribute default="yes" name="clone" type="xlf:AttrType_YesNo" use="optional"/>
+      <xsd:attributeGroup ref="xlf:AttrGroup_TextContent"/>
+    </xsd:complexType>
+  </xsd:element>
+  <xsd:element name="x">
+    <xsd:complexType>
+      <xsd:attribute name="ctype" type="xlf:AttrType_InlinePlaceholders" use="optional"/>
+      <xsd:attribute default="yes" name="clone" type="xlf:AttrType_YesNo" use="optional"/>
+      <xsd:attributeGroup ref="xlf:AttrGroup_TextContent"/>
+    </xsd:complexType>
+  </xsd:element>
+  <xsd:element name="bx">
+    <xsd:complexType>
+      <xsd:attribute name="rid" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute name="ctype" type="xlf:AttrType_InlineDelimiters" use="optional"/>
+      <xsd:attribute default="yes" name="clone" type="xlf:AttrType_YesNo" use="optional"/>
+      <xsd:attributeGroup ref="xlf:AttrGroup_TextContent"/>
+    </xsd:complexType>
+  </xsd:element>
+  <xsd:element name="ex">
+    <xsd:complexType>
+      <xsd:attribute name="rid" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attributeGroup ref="xlf:AttrGroup_TextContent"/>
+    </xsd:complexType>
+  </xsd:element>
+  <xsd:element name="ph">
+    <xsd:complexType mixed="true">
+      <xsd:sequence maxOccurs="unbounded" minOccurs="0">
+        <xsd:element ref="xlf:sub"/>
+      </xsd:sequence>
+      <xsd:attribute name="ctype" type="xlf:AttrType_InlinePlaceholders" use="optional"/>
+      <xsd:attribute name="crc" type="xsd:string" use="optional"/>
+      <xsd:attribute name="assoc" type="xlf:AttrType_assoc" use="optional"/>
+      <xsd:attributeGroup ref="xlf:AttrGroup_TextContent"/>
+    </xsd:complexType>
+  </xsd:element>
+  <xsd:element name="bpt">
+    <xsd:complexType mixed="true">
+      <xsd:sequence maxOccurs="unbounded" minOccurs="0">
+        <xsd:element ref="xlf:sub"/>
+      </xsd:sequence>
+      <xsd:attribute name="rid" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute name="ctype" type="xlf:AttrType_InlineDelimiters" use="optional"/>
+      <xsd:attribute name="crc" type="xsd:string" use="optional"/>
+      <xsd:attributeGroup ref="xlf:AttrGroup_TextContent"/>
+    </xsd:complexType>
+  </xsd:element>
+  <xsd:element name="ept">
+    <xsd:complexType mixed="true">
+      <xsd:sequence maxOccurs="unbounded" minOccurs="0">
+        <xsd:element ref="xlf:sub"/>
+      </xsd:sequence>
+      <xsd:attribute name="rid" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute name="crc" type="xsd:string" use="optional"/>
+      <xsd:attributeGroup ref="xlf:AttrGroup_TextContent"/>
+    </xsd:complexType>
+  </xsd:element>
+  <xsd:element name="it">
+    <xsd:complexType mixed="true">
+      <xsd:sequence maxOccurs="unbounded" minOccurs="0">
+        <xsd:element ref="xlf:sub"/>
+      </xsd:sequence>
+      <xsd:attribute name="pos" type="xlf:AttrType_Position" use="required"/>
+      <xsd:attribute name="rid" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute name="ctype" type="xlf:AttrType_InlineDelimiters" use="optional"/>
+      <xsd:attribute name="crc" type="xsd:string" use="optional"/>
+      <xsd:attributeGroup ref="xlf:AttrGroup_TextContent"/>
+    </xsd:complexType>
+  </xsd:element>
+  <xsd:element name="sub">
+    <xsd:complexType mixed="true">
+      <xsd:group maxOccurs="unbounded" minOccurs="0" ref="xlf:ElemGroup_TextContent"/>
+      <xsd:attribute name="datatype" type="xlf:AttrType_datatype" use="optional"/>
+      <xsd:attribute name="ctype" type="xlf:AttrType_InlineDelimiters" use="optional"/>
+      <xsd:attribute name="xid" type="xsd:string" use="optional"/>
+    </xsd:complexType>
+  </xsd:element>
+  <xsd:element name="mrk">
+    <xsd:complexType mixed="true">
+      <xsd:group maxOccurs="unbounded" minOccurs="0" ref="xlf:ElemGroup_TextContent"/>
+      <xsd:attribute name="mtype" type="xlf:AttrType_mtype" use="required"/>
+      <xsd:attribute name="mid" type="xsd:NMTOKEN" use="optional"/>
+      <xsd:attribute name="comment" type="xsd:string" use="optional"/>
+      <xsd:anyAttribute namespace="##other" processContents="strict"/>
+    </xsd:complexType>
+  </xsd:element>
+</xsd:schema>
diff --git a/core/vendor/symfony/translation/Loader/schema/dic/xliff-core/xml.xsd b/core/vendor/symfony/translation/Loader/schema/dic/xliff-core/xml.xsd
new file mode 100644
index 0000000000000000000000000000000000000000..a46162a7a7a647cd1b0c90f30783c6d0b9c27aa7
--- /dev/null
+++ b/core/vendor/symfony/translation/Loader/schema/dic/xliff-core/xml.xsd
@@ -0,0 +1,309 @@
+<?xml version='1.0'?>
+<?xml-stylesheet href="../2008/09/xsd.xsl" type="text/xsl"?>
+<xs:schema targetNamespace="http://www.w3.org/XML/1998/namespace" 
+  xmlns:xs="http://www.w3.org/2001/XMLSchema" 
+  xmlns ="http://www.w3.org/1999/xhtml"
+  xml:lang="en">
+
+ <xs:annotation>
+  <xs:documentation>
+   <div>
+    <h1>About the XML namespace</h1>
+
+    <div class="bodytext">
+     <p>
+
+      This schema document describes the XML namespace, in a form
+      suitable for import by other schema documents.
+     </p>
+     <p>
+      See <a href="http://www.w3.org/XML/1998/namespace.html">
+      http://www.w3.org/XML/1998/namespace.html</a> and
+      <a href="http://www.w3.org/TR/REC-xml">
+      http://www.w3.org/TR/REC-xml</a> for information 
+      about this namespace.
+     </p>
+
+     <p>
+      Note that local names in this namespace are intended to be
+      defined only by the World Wide Web Consortium or its subgroups.
+      The names currently defined in this namespace are listed below.
+      They should not be used with conflicting semantics by any Working
+      Group, specification, or document instance.
+     </p>
+     <p>   
+      See further below in this document for more information about <a
+      href="#usage">how to refer to this schema document from your own
+      XSD schema documents</a> and about <a href="#nsversioning">the
+      namespace-versioning policy governing this schema document</a>.
+     </p>
+    </div>
+   </div>
+
+  </xs:documentation>
+ </xs:annotation>
+
+ <xs:attribute name="lang">
+  <xs:annotation>
+   <xs:documentation>
+    <div>
+     
+      <h3>lang (as an attribute name)</h3>
+      <p>
+
+       denotes an attribute whose value
+       is a language code for the natural language of the content of
+       any element; its value is inherited.  This name is reserved
+       by virtue of its definition in the XML specification.</p>
+     
+    </div>
+    <div>
+     <h4>Notes</h4>
+     <p>
+      Attempting to install the relevant ISO 2- and 3-letter
+      codes as the enumerated possible values is probably never
+      going to be a realistic possibility.  
+     </p>
+     <p>
+
+      See BCP 47 at <a href="http://www.rfc-editor.org/rfc/bcp/bcp47.txt">
+       http://www.rfc-editor.org/rfc/bcp/bcp47.txt</a>
+      and the IANA language subtag registry at
+      <a href="http://www.iana.org/assignments/language-subtag-registry">
+       http://www.iana.org/assignments/language-subtag-registry</a>
+      for further information.
+     </p>
+     <p>
+
+      The union allows for the 'un-declaration' of xml:lang with
+      the empty string.
+     </p>
+    </div>
+   </xs:documentation>
+  </xs:annotation>
+  <xs:simpleType>
+   <xs:union memberTypes="xs:language">
+    <xs:simpleType>    
+     <xs:restriction base="xs:string">
+      <xs:enumeration value=""/>
+
+     </xs:restriction>
+    </xs:simpleType>
+   </xs:union>
+  </xs:simpleType>
+ </xs:attribute>
+
+ <xs:attribute name="space">
+  <xs:annotation>
+   <xs:documentation>
+
+    <div>
+     
+      <h3>space (as an attribute name)</h3>
+      <p>
+       denotes an attribute whose
+       value is a keyword indicating what whitespace processing
+       discipline is intended for the content of the element; its
+       value is inherited.  This name is reserved by virtue of its
+       definition in the XML specification.</p>
+     
+    </div>
+   </xs:documentation>
+  </xs:annotation>
+  <xs:simpleType>
+
+   <xs:restriction base="xs:NCName">
+    <xs:enumeration value="default"/>
+    <xs:enumeration value="preserve"/>
+   </xs:restriction>
+  </xs:simpleType>
+ </xs:attribute>
+ 
+ <xs:attribute name="base" type="xs:anyURI"> <xs:annotation>
+   <xs:documentation>
+
+    <div>
+     
+      <h3>base (as an attribute name)</h3>
+      <p>
+       denotes an attribute whose value
+       provides a URI to be used as the base for interpreting any
+       relative URIs in the scope of the element on which it
+       appears; its value is inherited.  This name is reserved
+       by virtue of its definition in the XML Base specification.</p>
+     
+     <p>
+      See <a
+      href="http://www.w3.org/TR/xmlbase/">http://www.w3.org/TR/xmlbase/</a>
+      for information about this attribute.
+     </p>
+
+    </div>
+   </xs:documentation>
+  </xs:annotation>
+ </xs:attribute>
+ 
+ <xs:attribute name="id" type="xs:ID">
+  <xs:annotation>
+   <xs:documentation>
+    <div>
+     
+      <h3>id (as an attribute name)</h3> 
+      <p>
+
+       denotes an attribute whose value
+       should be interpreted as if declared to be of type ID.
+       This name is reserved by virtue of its definition in the
+       xml:id specification.</p>
+     
+     <p>
+      See <a
+      href="http://www.w3.org/TR/xml-id/">http://www.w3.org/TR/xml-id/</a>
+      for information about this attribute.
+     </p>
+    </div>
+   </xs:documentation>
+  </xs:annotation>
+
+ </xs:attribute>
+
+ <xs:attributeGroup name="specialAttrs">
+  <xs:attribute ref="xml:base"/>
+  <xs:attribute ref="xml:lang"/>
+  <xs:attribute ref="xml:space"/>
+  <xs:attribute ref="xml:id"/>
+ </xs:attributeGroup>
+
+ <xs:annotation>
+
+  <xs:documentation>
+   <div>
+   
+    <h3>Father (in any context at all)</h3> 
+
+    <div class="bodytext">
+     <p>
+      denotes Jon Bosak, the chair of 
+      the original XML Working Group.  This name is reserved by 
+      the following decision of the W3C XML Plenary and 
+      XML Coordination groups:
+     </p>
+     <blockquote>
+       <p>
+
+	In appreciation for his vision, leadership and
+	dedication the W3C XML Plenary on this 10th day of
+	February, 2000, reserves for Jon Bosak in perpetuity
+	the XML name "xml:Father".
+       </p>
+     </blockquote>
+    </div>
+   </div>
+  </xs:documentation>
+ </xs:annotation>
+
+ <xs:annotation>
+  <xs:documentation>
+
+   <div xml:id="usage" id="usage">
+    <h2><a name="usage">About this schema document</a></h2>
+
+    <div class="bodytext">
+     <p>
+      This schema defines attributes and an attribute group suitable
+      for use by schemas wishing to allow <code>xml:base</code>,
+      <code>xml:lang</code>, <code>xml:space</code> or
+      <code>xml:id</code> attributes on elements they define.
+     </p>
+
+     <p>
+      To enable this, such a schema must import this schema for
+      the XML namespace, e.g. as follows:
+     </p>
+     <pre>
+          &lt;schema.. .>
+          .. .
+           &lt;import namespace="http://www.w3.org/XML/1998/namespace"
+                      schemaLocation="http://www.w3.org/2001/xml.xsd"/>
+     </pre>
+     <p>
+      or
+     </p>
+     <pre>
+
+           &lt;import namespace="http://www.w3.org/XML/1998/namespace"
+                      schemaLocation="http://www.w3.org/2009/01/xml.xsd"/>
+     </pre>
+     <p>
+      Subsequently, qualified reference to any of the attributes or the
+      group defined below will have the desired effect, e.g.
+     </p>
+     <pre>
+          &lt;type.. .>
+          .. .
+           &lt;attributeGroup ref="xml:specialAttrs"/>
+     </pre>
+     <p>
+      will define a type which will schema-validate an instance element
+      with any of those attributes.
+     </p>
+
+    </div>
+   </div>
+  </xs:documentation>
+ </xs:annotation>
+
+ <xs:annotation>
+  <xs:documentation>
+   <div id="nsversioning" xml:id="nsversioning">
+    <h2><a name="nsversioning">Versioning policy for this schema document</a></h2>
+
+    <div class="bodytext">
+     <p>
+      In keeping with the XML Schema WG's standard versioning
+      policy, this schema document will persist at
+      <a href="http://www.w3.org/2009/01/xml.xsd">
+       http://www.w3.org/2009/01/xml.xsd</a>.
+     </p>
+     <p>
+      At the date of issue it can also be found at
+      <a href="http://www.w3.org/2001/xml.xsd">
+       http://www.w3.org/2001/xml.xsd</a>.
+     </p>
+
+     <p>
+      The schema document at that URI may however change in the future,
+      in order to remain compatible with the latest version of XML
+      Schema itself, or with the XML namespace itself.  In other words,
+      if the XML Schema or XML namespaces change, the version of this
+      document at <a href="http://www.w3.org/2001/xml.xsd">
+       http://www.w3.org/2001/xml.xsd 
+      </a> 
+      will change accordingly; the version at 
+      <a href="http://www.w3.org/2009/01/xml.xsd">
+       http://www.w3.org/2009/01/xml.xsd 
+      </a> 
+      will not change.
+     </p>
+     <p>
+
+      Previous dated (and unchanging) versions of this schema 
+      document are at:
+     </p>
+     <ul>
+      <li><a href="http://www.w3.org/2009/01/xml.xsd">
+	http://www.w3.org/2009/01/xml.xsd</a></li>
+      <li><a href="http://www.w3.org/2007/08/xml.xsd">
+	http://www.w3.org/2007/08/xml.xsd</a></li>
+      <li><a href="http://www.w3.org/2004/10/xml.xsd">
+
+	http://www.w3.org/2004/10/xml.xsd</a></li>
+      <li><a href="http://www.w3.org/2001/03/xml.xsd">
+	http://www.w3.org/2001/03/xml.xsd</a></li>
+     </ul>
+    </div>
+   </div>
+  </xs:documentation>
+ </xs:annotation>
+
+</xs:schema>
diff --git a/core/vendor/symfony/translation/LoggingTranslator.php b/core/vendor/symfony/translation/LoggingTranslator.php
new file mode 100644
index 0000000000000000000000000000000000000000..4ff3531228071f0ae924532de35e6d7f0ecbedb2
--- /dev/null
+++ b/core/vendor/symfony/translation/LoggingTranslator.php
@@ -0,0 +1,128 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation;
+
+use Psr\Log\LoggerInterface;
+
+/**
+ * @author Abdellatif Ait boudad <a.aitboudad@gmail.com>
+ */
+class LoggingTranslator implements TranslatorInterface, TranslatorBagInterface
+{
+    /**
+     * @var TranslatorInterface|TranslatorBagInterface
+     */
+    private $translator;
+
+    /**
+     * @var LoggerInterface
+     */
+    private $logger;
+
+    /**
+     * @param TranslatorInterface $translator The translator must implement TranslatorBagInterface
+     * @param LoggerInterface     $logger
+     */
+    public function __construct(TranslatorInterface $translator, LoggerInterface $logger)
+    {
+        if (!$translator instanceof TranslatorBagInterface) {
+            throw new \InvalidArgumentException(sprintf('The Translator "%s" must implement TranslatorInterface and TranslatorBagInterface.', get_class($translator)));
+        }
+
+        $this->translator = $translator;
+        $this->logger = $logger;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function trans($id, array $parameters = array(), $domain = null, $locale = null)
+    {
+        $trans = $this->translator->trans($id, $parameters, $domain, $locale);
+        $this->log($id, $domain, $locale);
+
+        return $trans;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function transChoice($id, $number, array $parameters = array(), $domain = null, $locale = null)
+    {
+        $trans = $this->translator->transChoice($id, $number, $parameters, $domain, $locale);
+        $this->log($id, $domain, $locale);
+
+        return $trans;
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @api
+     */
+    public function setLocale($locale)
+    {
+        $this->translator->setLocale($locale);
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @api
+     */
+    public function getLocale()
+    {
+        return $this->translator->getLocale();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getCatalogue($locale = null)
+    {
+        return $this->translator->getCatalogue($locale);
+    }
+
+    /**
+     * Passes through all unknown calls onto the translator object.
+     */
+    public function __call($method, $args)
+    {
+        return call_user_func_array(array($this->translator, $method), $args);
+    }
+
+    /**
+     * Logs for missing translations.
+     *
+     * @param string      $id
+     * @param string|null $domain
+     * @param string|null $locale
+     */
+    private function log($id, $domain, $locale)
+    {
+        if (null === $domain) {
+            $domain = 'messages';
+        }
+
+        $id = (string) $id;
+        $catalogue = $this->translator->getCatalogue($locale);
+        if ($catalogue->defines($id, $domain)) {
+            return;
+        }
+
+        if ($catalogue->has($id, $domain)) {
+            $this->logger->debug('Translation use fallback catalogue.', array('id' => $id, 'domain' => $domain, 'locale' => $catalogue->getLocale()));
+        } else {
+            $this->logger->warning('Translation not found.', array('id' => $id, 'domain' => $domain, 'locale' => $catalogue->getLocale()));
+        }
+    }
+}
diff --git a/core/vendor/symfony/translation/MessageCatalogue.php b/core/vendor/symfony/translation/MessageCatalogue.php
new file mode 100644
index 0000000000000000000000000000000000000000..35beb3d94739ad0b1d7d55db2542d97e18aaba39
--- /dev/null
+++ b/core/vendor/symfony/translation/MessageCatalogue.php
@@ -0,0 +1,300 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation;
+
+use Symfony\Component\Config\Resource\ResourceInterface;
+
+/**
+ * MessageCatalogue.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ *
+ * @api
+ */
+class MessageCatalogue implements MessageCatalogueInterface, MetadataAwareInterface
+{
+    private $messages = array();
+    private $metadata = array();
+    private $resources = array();
+    private $locale;
+    private $fallbackCatalogue;
+    private $parent;
+
+    /**
+     * Constructor.
+     *
+     * @param string $locale   The locale
+     * @param array  $messages An array of messages classified by domain
+     *
+     * @api
+     */
+    public function __construct($locale, array $messages = array())
+    {
+        $this->locale = $locale;
+        $this->messages = $messages;
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @api
+     */
+    public function getLocale()
+    {
+        return $this->locale;
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @api
+     */
+    public function getDomains()
+    {
+        return array_keys($this->messages);
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @api
+     */
+    public function all($domain = null)
+    {
+        if (null === $domain) {
+            return $this->messages;
+        }
+
+        return isset($this->messages[$domain]) ? $this->messages[$domain] : array();
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @api
+     */
+    public function set($id, $translation, $domain = 'messages')
+    {
+        $this->add(array($id => $translation), $domain);
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @api
+     */
+    public function has($id, $domain = 'messages')
+    {
+        if (isset($this->messages[$domain][$id])) {
+            return true;
+        }
+
+        if (null !== $this->fallbackCatalogue) {
+            return $this->fallbackCatalogue->has($id, $domain);
+        }
+
+        return false;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function defines($id, $domain = 'messages')
+    {
+        return isset($this->messages[$domain][$id]);
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @api
+     */
+    public function get($id, $domain = 'messages')
+    {
+        if (isset($this->messages[$domain][$id])) {
+            return $this->messages[$domain][$id];
+        }
+
+        if (null !== $this->fallbackCatalogue) {
+            return $this->fallbackCatalogue->get($id, $domain);
+        }
+
+        return $id;
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @api
+     */
+    public function replace($messages, $domain = 'messages')
+    {
+        $this->messages[$domain] = array();
+
+        $this->add($messages, $domain);
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @api
+     */
+    public function add($messages, $domain = 'messages')
+    {
+        if (!isset($this->messages[$domain])) {
+            $this->messages[$domain] = $messages;
+        } else {
+            $this->messages[$domain] = array_replace($this->messages[$domain], $messages);
+        }
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @api
+     */
+    public function addCatalogue(MessageCatalogueInterface $catalogue)
+    {
+        if ($catalogue->getLocale() !== $this->locale) {
+            throw new \LogicException(sprintf('Cannot add a catalogue for locale "%s" as the current locale for this catalogue is "%s"', $catalogue->getLocale(), $this->locale));
+        }
+
+        foreach ($catalogue->all() as $domain => $messages) {
+            $this->add($messages, $domain);
+        }
+
+        foreach ($catalogue->getResources() as $resource) {
+            $this->addResource($resource);
+        }
+
+        if ($catalogue instanceof MetadataAwareInterface) {
+            $metadata = $catalogue->getMetadata('', '');
+            $this->addMetadata($metadata);
+        }
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @api
+     */
+    public function addFallbackCatalogue(MessageCatalogueInterface $catalogue)
+    {
+        // detect circular references
+        $c = $catalogue;
+        while ($c = $c->getFallbackCatalogue()) {
+            if ($c->getLocale() === $this->getLocale()) {
+                throw new \LogicException(sprintf('Circular reference detected when adding a fallback catalogue for locale "%s".', $catalogue->getLocale()));
+            }
+        }
+
+        $c = $this;
+        do {
+            if ($c->getLocale() === $catalogue->getLocale()) {
+                throw new \LogicException(sprintf('Circular reference detected when adding a fallback catalogue for locale "%s".', $catalogue->getLocale()));
+            }
+        } while ($c = $c->parent);
+
+        $catalogue->parent = $this;
+        $this->fallbackCatalogue = $catalogue;
+
+        foreach ($catalogue->getResources() as $resource) {
+            $this->addResource($resource);
+        }
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @api
+     */
+    public function getFallbackCatalogue()
+    {
+        return $this->fallbackCatalogue;
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @api
+     */
+    public function getResources()
+    {
+        return array_values($this->resources);
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @api
+     */
+    public function addResource(ResourceInterface $resource)
+    {
+        $this->resources[$resource->__toString()] = $resource;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getMetadata($key = '', $domain = 'messages')
+    {
+        if ('' == $domain) {
+            return $this->metadata;
+        }
+
+        if (isset($this->metadata[$domain])) {
+            if ('' == $key) {
+                return $this->metadata[$domain];
+            }
+
+            if (isset($this->metadata[$domain][$key])) {
+                return $this->metadata[$domain][$key];
+            }
+        }
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function setMetadata($key, $value, $domain = 'messages')
+    {
+        $this->metadata[$domain][$key] = $value;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function deleteMetadata($key = '', $domain = 'messages')
+    {
+        if ('' == $domain) {
+            $this->metadata = array();
+        } elseif ('' == $key) {
+            unset($this->metadata[$domain]);
+        } else {
+            unset($this->metadata[$domain][$key]);
+        }
+    }
+
+    /**
+     * Adds current values with the new values.
+     *
+     * @param array $values Values to add
+     */
+    private function addMetadata(array $values)
+    {
+        foreach ($values as $domain => $keys) {
+            foreach ($keys as $key => $value) {
+                $this->setMetadata($key, $value, $domain);
+            }
+        }
+    }
+}
diff --git a/core/vendor/symfony/translation/MessageCatalogueInterface.php b/core/vendor/symfony/translation/MessageCatalogueInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..647e3374e1eca2c584ea67f9adf5dac4479a6186
--- /dev/null
+++ b/core/vendor/symfony/translation/MessageCatalogueInterface.php
@@ -0,0 +1,172 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation;
+
+use Symfony\Component\Config\Resource\ResourceInterface;
+
+/**
+ * MessageCatalogueInterface.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ *
+ * @api
+ */
+interface MessageCatalogueInterface
+{
+    /**
+     * Gets the catalogue locale.
+     *
+     * @return string The locale
+     *
+     * @api
+     */
+    public function getLocale();
+
+    /**
+     * Gets the domains.
+     *
+     * @return array An array of domains
+     *
+     * @api
+     */
+    public function getDomains();
+
+    /**
+     * Gets the messages within a given domain.
+     *
+     * If $domain is null, it returns all messages.
+     *
+     * @param string $domain The domain name
+     *
+     * @return array An array of messages
+     *
+     * @api
+     */
+    public function all($domain = null);
+
+    /**
+     * Sets a message translation.
+     *
+     * @param string $id          The message id
+     * @param string $translation The messages translation
+     * @param string $domain      The domain name
+     *
+     * @api
+     */
+    public function set($id, $translation, $domain = 'messages');
+
+    /**
+     * Checks if a message has a translation.
+     *
+     * @param string $id     The message id
+     * @param string $domain The domain name
+     *
+     * @return bool true if the message has a translation, false otherwise
+     *
+     * @api
+     */
+    public function has($id, $domain = 'messages');
+
+    /**
+     * Checks if a message has a translation (it does not take into account the fallback mechanism).
+     *
+     * @param string $id     The message id
+     * @param string $domain The domain name
+     *
+     * @return bool true if the message has a translation, false otherwise
+     *
+     * @api
+     */
+    public function defines($id, $domain = 'messages');
+
+    /**
+     * Gets a message translation.
+     *
+     * @param string $id     The message id
+     * @param string $domain The domain name
+     *
+     * @return string The message translation
+     *
+     * @api
+     */
+    public function get($id, $domain = 'messages');
+
+    /**
+     * Sets translations for a given domain.
+     *
+     * @param array  $messages An array of translations
+     * @param string $domain   The domain name
+     *
+     * @api
+     */
+    public function replace($messages, $domain = 'messages');
+
+    /**
+     * Adds translations for a given domain.
+     *
+     * @param array  $messages An array of translations
+     * @param string $domain   The domain name
+     *
+     * @api
+     */
+    public function add($messages, $domain = 'messages');
+
+    /**
+     * Merges translations from the given Catalogue into the current one.
+     *
+     * The two catalogues must have the same locale.
+     *
+     * @param MessageCatalogueInterface $catalogue A MessageCatalogueInterface instance
+     *
+     * @api
+     */
+    public function addCatalogue(MessageCatalogueInterface $catalogue);
+
+    /**
+     * Merges translations from the given Catalogue into the current one
+     * only when the translation does not exist.
+     *
+     * This is used to provide default translations when they do not exist for the current locale.
+     *
+     * @param MessageCatalogueInterface $catalogue A MessageCatalogueInterface instance
+     *
+     * @api
+     */
+    public function addFallbackCatalogue(MessageCatalogueInterface $catalogue);
+
+    /**
+     * Gets the fallback catalogue.
+     *
+     * @return MessageCatalogueInterface|null A MessageCatalogueInterface instance or null when no fallback has been set
+     *
+     * @api
+     */
+    public function getFallbackCatalogue();
+
+    /**
+     * Returns an array of resources loaded to build this collection.
+     *
+     * @return ResourceInterface[] An array of resources
+     *
+     * @api
+     */
+    public function getResources();
+
+    /**
+     * Adds a resource for this collection.
+     *
+     * @param ResourceInterface $resource A resource instance
+     *
+     * @api
+     */
+    public function addResource(ResourceInterface $resource);
+}
diff --git a/core/vendor/symfony/translation/MessageSelector.php b/core/vendor/symfony/translation/MessageSelector.php
new file mode 100644
index 0000000000000000000000000000000000000000..f7fde31ad90905cab4d59faaf9bab68d8bd93ce2
--- /dev/null
+++ b/core/vendor/symfony/translation/MessageSelector.php
@@ -0,0 +1,90 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation;
+
+/**
+ * MessageSelector.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @api
+ */
+class MessageSelector
+{
+    /**
+     * Given a message with different plural translations separated by a
+     * pipe (|), this method returns the correct portion of the message based
+     * on the given number, locale and the pluralization rules in the message
+     * itself.
+     *
+     * The message supports two different types of pluralization rules:
+     *
+     * interval: {0} There are no apples|{1} There is one apple|]1,Inf] There are %count% apples
+     * indexed:  There is one apple|There are %count% apples
+     *
+     * The indexed solution can also contain labels (e.g. one: There is one apple).
+     * This is purely for making the translations more clear - it does not
+     * affect the functionality.
+     *
+     * The two methods can also be mixed:
+     *     {0} There are no apples|one: There is one apple|more: There are %count% apples
+     *
+     * @param string $message The message being translated
+     * @param int    $number  The number of items represented for the message
+     * @param string $locale  The locale to use for choosing
+     *
+     * @return string
+     *
+     * @throws \InvalidArgumentException
+     *
+     * @api
+     */
+    public function choose($message, $number, $locale)
+    {
+        $parts = explode('|', $message);
+        $explicitRules = array();
+        $standardRules = array();
+        foreach ($parts as $part) {
+            $part = trim($part);
+
+            if (preg_match('/^(?P<interval>'.Interval::getIntervalRegexp().')\s*(?P<message>.*?)$/xs', $part, $matches)) {
+                $explicitRules[$matches['interval']] = $matches['message'];
+            } elseif (preg_match('/^\w+\:\s*(.*?)$/', $part, $matches)) {
+                $standardRules[] = $matches[1];
+            } else {
+                $standardRules[] = $part;
+            }
+        }
+
+        // try to match an explicit rule, then fallback to the standard ones
+        foreach ($explicitRules as $interval => $m) {
+            if (Interval::test($number, $interval)) {
+                return $m;
+            }
+        }
+
+        $position = PluralizationRules::get($number, $locale);
+
+        if (!isset($standardRules[$position])) {
+            // when there's exactly one rule given, and that rule is a standard
+            // rule, use this rule
+            if (1 === count($parts) && isset($standardRules[0])) {
+                return $standardRules[0];
+            }
+
+            throw new \InvalidArgumentException(sprintf('Unable to choose a translation for "%s" with locale "%s" for value "%d". Double check that this translation has the correct plural options (e.g. "There is one apple|There are %%count%% apples").', $message, $locale, $number));
+        }
+
+        return $standardRules[$position];
+    }
+}
diff --git a/core/vendor/symfony/translation/MetadataAwareInterface.php b/core/vendor/symfony/translation/MetadataAwareInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..e93c6fbc713114d79dfa40f653b6878c5f3a3bc0
--- /dev/null
+++ b/core/vendor/symfony/translation/MetadataAwareInterface.php
@@ -0,0 +1,54 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation;
+
+/**
+ * MetadataAwareInterface.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+interface MetadataAwareInterface
+{
+    /**
+     * Gets metadata for the given domain and key.
+     *
+     * Passing an empty domain will return an array with all metadata indexed by
+     * domain and then by key. Passing an empty key will return an array with all
+     * metadata for the given domain.
+     *
+     * @param string $key    The key
+     * @param string $domain The domain name
+     *
+     * @return mixed The value that was set or an array with the domains/keys or null
+     */
+    public function getMetadata($key = '', $domain = 'messages');
+
+    /**
+     * Adds metadata to a message domain.
+     *
+     * @param string $key    The key
+     * @param mixed  $value  The value
+     * @param string $domain The domain name
+     */
+    public function setMetadata($key, $value, $domain = 'messages');
+
+    /**
+     * Deletes metadata for the given key and domain.
+     *
+     * Passing an empty domain will delete all metadata. Passing an empty key will
+     * delete all metadata for the given domain.
+     *
+     * @param string $key    The key
+     * @param string $domain The domain name
+     */
+    public function deleteMetadata($key = '', $domain = 'messages');
+}
diff --git a/core/vendor/symfony/translation/PluralizationRules.php b/core/vendor/symfony/translation/PluralizationRules.php
new file mode 100644
index 0000000000000000000000000000000000000000..3ef8f00b6e934f2c1ba487cd9de253c57230ae8f
--- /dev/null
+++ b/core/vendor/symfony/translation/PluralizationRules.php
@@ -0,0 +1,214 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation;
+
+/**
+ * Returns the plural rules for a given locale.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class PluralizationRules
+{
+    private static $rules = array();
+
+    /**
+     * Returns the plural position to use for the given locale and number.
+     *
+     * @param int    $number The number
+     * @param string $locale The locale
+     *
+     * @return int The plural position
+     */
+    public static function get($number, $locale)
+    {
+        if ('pt_BR' === $locale) {
+            // temporary set a locale for brazilian
+            $locale = 'xbr';
+        }
+
+        if (strlen($locale) > 3) {
+            $locale = substr($locale, 0, -strlen(strrchr($locale, '_')));
+        }
+
+        if (isset(self::$rules[$locale])) {
+            $return = call_user_func(self::$rules[$locale], $number);
+
+            if (!is_int($return) || $return < 0) {
+                return 0;
+            }
+
+            return $return;
+        }
+
+        /*
+         * The plural rules are derived from code of the Zend Framework (2010-09-25),
+         * which is subject to the new BSD license (http://framework.zend.com/license/new-bsd).
+         * Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
+         */
+        switch ($locale) {
+            case 'az':
+            case 'bo':
+            case 'dz':
+            case 'id':
+            case 'ja':
+            case 'jv':
+            case 'ka':
+            case 'km':
+            case 'kn':
+            case 'ko':
+            case 'ms':
+            case 'th':
+            case 'tr':
+            case 'vi':
+            case 'zh':
+                return 0;
+                break;
+
+            case 'af':
+            case 'bn':
+            case 'bg':
+            case 'ca':
+            case 'da':
+            case 'de':
+            case 'el':
+            case 'en':
+            case 'eo':
+            case 'es':
+            case 'et':
+            case 'eu':
+            case 'fa':
+            case 'fi':
+            case 'fo':
+            case 'fur':
+            case 'fy':
+            case 'gl':
+            case 'gu':
+            case 'ha':
+            case 'he':
+            case 'hu':
+            case 'is':
+            case 'it':
+            case 'ku':
+            case 'lb':
+            case 'ml':
+            case 'mn':
+            case 'mr':
+            case 'nah':
+            case 'nb':
+            case 'ne':
+            case 'nl':
+            case 'nn':
+            case 'no':
+            case 'om':
+            case 'or':
+            case 'pa':
+            case 'pap':
+            case 'ps':
+            case 'pt':
+            case 'so':
+            case 'sq':
+            case 'sv':
+            case 'sw':
+            case 'ta':
+            case 'te':
+            case 'tk':
+            case 'ur':
+            case 'zu':
+                return ($number == 1) ? 0 : 1;
+
+            case 'am':
+            case 'bh':
+            case 'fil':
+            case 'fr':
+            case 'gun':
+            case 'hi':
+            case 'ln':
+            case 'mg':
+            case 'nso':
+            case 'xbr':
+            case 'ti':
+            case 'wa':
+                return (($number == 0) || ($number == 1)) ? 0 : 1;
+
+            case 'be':
+            case 'bs':
+            case 'hr':
+            case 'ru':
+            case 'sr':
+            case 'uk':
+                return (($number % 10 == 1) && ($number % 100 != 11)) ? 0 : ((($number % 10 >= 2) && ($number % 10 <= 4) && (($number % 100 < 10) || ($number % 100 >= 20))) ? 1 : 2);
+
+            case 'cs':
+            case 'sk':
+                return ($number == 1) ? 0 : ((($number >= 2) && ($number <= 4)) ? 1 : 2);
+
+            case 'ga':
+                return ($number == 1) ? 0 : (($number == 2) ? 1 : 2);
+
+            case 'lt':
+                return (($number % 10 == 1) && ($number % 100 != 11)) ? 0 : ((($number % 10 >= 2) && (($number % 100 < 10) || ($number % 100 >= 20))) ? 1 : 2);
+
+            case 'sl':
+                return ($number % 100 == 1) ? 0 : (($number % 100 == 2) ? 1 : ((($number % 100 == 3) || ($number % 100 == 4)) ? 2 : 3));
+
+            case 'mk':
+                return ($number % 10 == 1) ? 0 : 1;
+
+            case 'mt':
+                return ($number == 1) ? 0 : ((($number == 0) || (($number % 100 > 1) && ($number % 100 < 11))) ? 1 : ((($number % 100 > 10) && ($number % 100 < 20)) ? 2 : 3));
+
+            case 'lv':
+                return ($number == 0) ? 0 : ((($number % 10 == 1) && ($number % 100 != 11)) ? 1 : 2);
+
+            case 'pl':
+                return ($number == 1) ? 0 : ((($number % 10 >= 2) && ($number % 10 <= 4) && (($number % 100 < 12) || ($number % 100 > 14))) ? 1 : 2);
+
+            case 'cy':
+                return ($number == 1) ? 0 : (($number == 2) ? 1 : ((($number == 8) || ($number == 11)) ? 2 : 3));
+
+            case 'ro':
+                return ($number == 1) ? 0 : ((($number == 0) || (($number % 100 > 0) && ($number % 100 < 20))) ? 1 : 2);
+
+            case 'ar':
+                return ($number == 0) ? 0 : (($number == 1) ? 1 : (($number == 2) ? 2 : ((($number % 100 >= 3) && ($number % 100 <= 10)) ? 3 : ((($number % 100 >= 11) && ($number % 100 <= 99)) ? 4 : 5))));
+
+            default:
+                return 0;
+        }
+    }
+
+    /**
+     * Overrides the default plural rule for a given locale.
+     *
+     * @param string $rule   A PHP callable
+     * @param string $locale The locale
+     *
+     * @throws \LogicException
+     */
+    public static function set($rule, $locale)
+    {
+        if ('pt_BR' === $locale) {
+            // temporary set a locale for brazilian
+            $locale = 'xbr';
+        }
+
+        if (strlen($locale) > 3) {
+            $locale = substr($locale, 0, -strlen(strrchr($locale, '_')));
+        }
+
+        if (!is_callable($rule)) {
+            throw new \LogicException('The given rule can not be called');
+        }
+
+        self::$rules[$locale] = $rule;
+    }
+}
diff --git a/core/vendor/symfony/translation/README.md b/core/vendor/symfony/translation/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..2b46b517719d192a40326fd26532d76bde2b53d4
--- /dev/null
+++ b/core/vendor/symfony/translation/README.md
@@ -0,0 +1,37 @@
+Translation Component
+=====================
+
+Translation provides tools for loading translation files and generating
+translated strings from these including support for pluralization.
+
+```php
+use Symfony\Component\Translation\Translator;
+use Symfony\Component\Translation\MessageSelector;
+use Symfony\Component\Translation\Loader\ArrayLoader;
+
+$translator = new Translator('fr_FR', new MessageSelector());
+$translator->setFallbackLocales(array('fr'));
+$translator->addLoader('array', new ArrayLoader());
+$translator->addResource('array', array(
+    'Hello World!' => 'Bonjour',
+), 'fr');
+
+echo $translator->trans('Hello World!')."\n";
+```
+
+Resources
+---------
+
+Silex integration:
+
+https://github.com/silexphp/Silex/blob/master/src/Silex/Provider/TranslationServiceProvider.php
+
+Documentation:
+
+https://symfony.com/doc/2.7/book/translation.html
+
+You can run the unit tests with the following command:
+
+    $ cd path/to/Symfony/Component/Translation/
+    $ composer install
+    $ phpunit
diff --git a/core/vendor/symfony/translation/Tests/Catalogue/AbstractOperationTest.php b/core/vendor/symfony/translation/Tests/Catalogue/AbstractOperationTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..30c21afa64c155f039f736e2f56686e20efe68c7
--- /dev/null
+++ b/core/vendor/symfony/translation/Tests/Catalogue/AbstractOperationTest.php
@@ -0,0 +1,73 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Tests\Catalogue;
+
+use Symfony\Component\Translation\MessageCatalogue;
+use Symfony\Component\Translation\MessageCatalogueInterface;
+
+abstract class AbstractOperationTest extends \PHPUnit_Framework_TestCase
+{
+    public function testGetEmptyDomains()
+    {
+        $this->assertEquals(
+            array(),
+            $this->createOperation(
+                new MessageCatalogue('en'),
+                new MessageCatalogue('en')
+            )->getDomains()
+        );
+    }
+
+    public function testGetMergedDomains()
+    {
+        $this->assertEquals(
+            array('a', 'b', 'c'),
+            $this->createOperation(
+                new MessageCatalogue('en', array('a' => array(), 'b' => array())),
+                new MessageCatalogue('en', array('b' => array(), 'c' => array()))
+            )->getDomains()
+        );
+    }
+
+    public function testGetMessagesFromUnknownDomain()
+    {
+        $this->setExpectedException('InvalidArgumentException');
+        $this->createOperation(
+            new MessageCatalogue('en'),
+            new MessageCatalogue('en')
+        )->getMessages('domain');
+    }
+
+    public function testGetEmptyMessages()
+    {
+        $this->assertEquals(
+            array(),
+            $this->createOperation(
+                new MessageCatalogue('en', array('a' => array())),
+                new MessageCatalogue('en')
+            )->getMessages('a')
+        );
+    }
+
+    public function testGetEmptyResult()
+    {
+        $this->assertEquals(
+            new MessageCatalogue('en'),
+            $this->createOperation(
+                new MessageCatalogue('en'),
+                new MessageCatalogue('en')
+            )->getResult()
+        );
+    }
+
+    abstract protected function createOperation(MessageCatalogueInterface $source, MessageCatalogueInterface $target);
+}
diff --git a/core/vendor/symfony/translation/Tests/Catalogue/DiffOperationTest.php b/core/vendor/symfony/translation/Tests/Catalogue/DiffOperationTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..26bd5823df1296eb92a06d701ce6c29286aa578d
--- /dev/null
+++ b/core/vendor/symfony/translation/Tests/Catalogue/DiffOperationTest.php
@@ -0,0 +1,82 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Tests\Catalogue;
+
+use Symfony\Component\Translation\Catalogue\DiffOperation;
+use Symfony\Component\Translation\MessageCatalogue;
+use Symfony\Component\Translation\MessageCatalogueInterface;
+
+class DiffOperationTest extends AbstractOperationTest
+{
+    public function testGetMessagesFromSingleDomain()
+    {
+        $operation = $this->createOperation(
+            new MessageCatalogue('en', array('messages' => array('a' => 'old_a', 'b' => 'old_b'))),
+            new MessageCatalogue('en', array('messages' => array('a' => 'new_a', 'c' => 'new_c')))
+        );
+
+        $this->assertEquals(
+            array('a' => 'old_a', 'c' => 'new_c'),
+            $operation->getMessages('messages')
+        );
+
+        $this->assertEquals(
+            array('c' => 'new_c'),
+            $operation->getNewMessages('messages')
+        );
+
+        $this->assertEquals(
+            array('b' => 'old_b'),
+            $operation->getObsoleteMessages('messages')
+        );
+    }
+
+    public function testGetResultFromSingleDomain()
+    {
+        $this->assertEquals(
+            new MessageCatalogue('en', array(
+                'messages' => array('a' => 'old_a', 'c' => 'new_c'),
+            )),
+            $this->createOperation(
+                new MessageCatalogue('en', array('messages' => array('a' => 'old_a', 'b' => 'old_b'))),
+                new MessageCatalogue('en', array('messages' => array('a' => 'new_a', 'c' => 'new_c')))
+            )->getResult()
+        );
+    }
+
+    public function testGetResultWithMetadata()
+    {
+        $leftCatalogue = new MessageCatalogue('en', array('messages' => array('a' => 'old_a', 'b' => 'old_b')));
+        $leftCatalogue->setMetadata('a', 'foo', 'messages');
+        $leftCatalogue->setMetadata('b', 'bar', 'messages');
+        $rightCatalogue = new MessageCatalogue('en', array('messages' => array('b' => 'new_b', 'c' => 'new_c')));
+        $rightCatalogue->setMetadata('b', 'baz', 'messages');
+        $rightCatalogue->setMetadata('c', 'qux', 'messages');
+
+        $diffCatalogue = new MessageCatalogue('en', array('messages' => array('b' => 'old_b', 'c' => 'new_c')));
+        $diffCatalogue->setMetadata('b', 'bar', 'messages');
+        $diffCatalogue->setMetadata('c', 'qux', 'messages');
+
+        $this->assertEquals(
+            $diffCatalogue,
+            $this->createOperation(
+                $leftCatalogue,
+                $rightCatalogue
+            )->getResult()
+        );
+    }
+
+    protected function createOperation(MessageCatalogueInterface $source, MessageCatalogueInterface $target)
+    {
+        return new DiffOperation($source, $target);
+    }
+}
diff --git a/core/vendor/symfony/translation/Tests/Catalogue/MergeOperationTest.php b/core/vendor/symfony/translation/Tests/Catalogue/MergeOperationTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..8b51c15daec9210788f1e6d7ba5754664401bd63
--- /dev/null
+++ b/core/vendor/symfony/translation/Tests/Catalogue/MergeOperationTest.php
@@ -0,0 +1,83 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Tests\Catalogue;
+
+use Symfony\Component\Translation\Catalogue\MergeOperation;
+use Symfony\Component\Translation\MessageCatalogue;
+use Symfony\Component\Translation\MessageCatalogueInterface;
+
+class MergeOperationTest extends AbstractOperationTest
+{
+    public function testGetMessagesFromSingleDomain()
+    {
+        $operation = $this->createOperation(
+            new MessageCatalogue('en', array('messages' => array('a' => 'old_a', 'b' => 'old_b'))),
+            new MessageCatalogue('en', array('messages' => array('a' => 'new_a', 'c' => 'new_c')))
+        );
+
+        $this->assertEquals(
+            array('a' => 'old_a', 'b' => 'old_b', 'c' => 'new_c'),
+            $operation->getMessages('messages')
+        );
+
+        $this->assertEquals(
+            array('c' => 'new_c'),
+            $operation->getNewMessages('messages')
+        );
+
+        $this->assertEquals(
+            array(),
+            $operation->getObsoleteMessages('messages')
+        );
+    }
+
+    public function testGetResultFromSingleDomain()
+    {
+        $this->assertEquals(
+            new MessageCatalogue('en', array(
+                'messages' => array('a' => 'old_a', 'b' => 'old_b', 'c' => 'new_c'),
+            )),
+            $this->createOperation(
+                new MessageCatalogue('en', array('messages' => array('a' => 'old_a', 'b' => 'old_b'))),
+                new MessageCatalogue('en', array('messages' => array('a' => 'new_a', 'c' => 'new_c')))
+            )->getResult()
+        );
+    }
+
+    public function testGetResultWithMetadata()
+    {
+        $leftCatalogue = new MessageCatalogue('en', array('messages' => array('a' => 'old_a', 'b' => 'old_b')));
+        $leftCatalogue->setMetadata('a', 'foo', 'messages');
+        $leftCatalogue->setMetadata('b', 'bar', 'messages');
+        $rightCatalogue = new MessageCatalogue('en', array('messages' => array('b' => 'new_b', 'c' => 'new_c')));
+        $rightCatalogue->setMetadata('b', 'baz', 'messages');
+        $rightCatalogue->setMetadata('c', 'qux', 'messages');
+
+        $mergedCatalogue = new MessageCatalogue('en', array('messages' => array('a' => 'old_a', 'b' => 'old_b', 'c' => 'new_c')));
+        $mergedCatalogue->setMetadata('a', 'foo', 'messages');
+        $mergedCatalogue->setMetadata('b', 'bar', 'messages');
+        $mergedCatalogue->setMetadata('c', 'qux', 'messages');
+
+        $this->assertEquals(
+            $mergedCatalogue,
+            $this->createOperation(
+                $leftCatalogue,
+                $rightCatalogue
+            )->getResult()
+        );
+    }
+
+    protected function createOperation(MessageCatalogueInterface $source, MessageCatalogueInterface $target)
+    {
+        return new MergeOperation($source, $target);
+    }
+}
diff --git a/core/vendor/symfony/translation/Tests/DataCollector/TranslationDataCollectorTest.php b/core/vendor/symfony/translation/Tests/DataCollector/TranslationDataCollectorTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..085d31267b3a456b44e625d471bf057203d37483
--- /dev/null
+++ b/core/vendor/symfony/translation/Tests/DataCollector/TranslationDataCollectorTest.php
@@ -0,0 +1,121 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Tests\DataCollector;
+
+use Symfony\Component\Translation\DataCollectorTranslator;
+use Symfony\Component\Translation\DataCollector\TranslationDataCollector;
+
+class TranslationDataCollectorTest extends \PHPUnit_Framework_TestCase
+{
+    protected function setUp()
+    {
+        if (!class_exists('Symfony\Component\HttpKernel\DataCollector\DataCollector')) {
+            $this->markTestSkipped('The "DataCollector" is not available');
+        }
+    }
+
+    public function testCollectEmptyMessages()
+    {
+        $translator = $this->getTranslator();
+        $translator->expects($this->any())->method('getCollectedMessages')->will($this->returnValue(array()));
+
+        $dataCollector = new TranslationDataCollector($translator);
+        $dataCollector->lateCollect();
+
+        $this->assertEquals(0, $dataCollector->getCountMissings());
+        $this->assertEquals(0, $dataCollector->getCountFallbacks());
+        $this->assertEquals(0, $dataCollector->getCountDefines());
+        $this->assertEquals(array(), $dataCollector->getMessages());
+    }
+
+    public function testCollect()
+    {
+        $collectedMessages = array(
+            array(
+                  'id' => 'foo',
+                  'translation' => 'foo (en)',
+                  'locale' => 'en',
+                  'domain' => 'messages',
+                  'state' => DataCollectorTranslator::MESSAGE_DEFINED,
+            ),
+            array(
+                  'id' => 'bar',
+                  'translation' => 'bar (fr)',
+                  'locale' => 'fr',
+                  'domain' => 'messages',
+                  'state' => DataCollectorTranslator::MESSAGE_EQUALS_FALLBACK,
+            ),
+            array(
+                  'id' => 'choice',
+                  'translation' => 'choice',
+                  'locale' => 'en',
+                  'domain' => 'messages',
+                  'state' => DataCollectorTranslator::MESSAGE_MISSING,
+            ),
+            array(
+                  'id' => 'choice',
+                  'translation' => 'choice',
+                  'locale' => 'en',
+                  'domain' => 'messages',
+                  'state' => DataCollectorTranslator::MESSAGE_MISSING,
+            ),
+        );
+        $expectedMessages = array(
+            array(
+                  'id' => 'foo',
+                  'translation' => 'foo (en)',
+                  'locale' => 'en',
+                  'domain' => 'messages',
+                  'state' => DataCollectorTranslator::MESSAGE_DEFINED,
+                  'count' => 1,
+            ),
+            array(
+                  'id' => 'bar',
+                  'translation' => 'bar (fr)',
+                  'locale' => 'fr',
+                  'domain' => 'messages',
+                  'state' => DataCollectorTranslator::MESSAGE_EQUALS_FALLBACK,
+                  'count' => 1,
+            ),
+            array(
+                  'id' => 'choice',
+                  'translation' => 'choice',
+                  'locale' => 'en',
+                  'domain' => 'messages',
+                  'state' => DataCollectorTranslator::MESSAGE_MISSING,
+                  'count' => 2,
+            ),
+        );
+
+        $translator = $this->getTranslator();
+        $translator->expects($this->any())->method('getCollectedMessages')->will($this->returnValue($collectedMessages));
+
+        $dataCollector = new TranslationDataCollector($translator);
+        $dataCollector->lateCollect();
+
+        $this->assertEquals(1, $dataCollector->getCountMissings());
+        $this->assertEquals(1, $dataCollector->getCountFallbacks());
+        $this->assertEquals(1, $dataCollector->getCountDefines());
+        $this->assertEquals($expectedMessages, array_values($dataCollector->getMessages()));
+    }
+
+    private function getTranslator()
+    {
+        $translator = $this
+            ->getMockBuilder('Symfony\Component\Translation\DataCollectorTranslator')
+            ->disableOriginalConstructor()
+            ->getMock()
+        ;
+
+        return $translator;
+    }
+}
diff --git a/core/vendor/symfony/translation/Tests/DataCollectorTranslatorTest.php b/core/vendor/symfony/translation/Tests/DataCollectorTranslatorTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..8e98ad31f43c8679ade7d1db7b09d78f11394c8c
--- /dev/null
+++ b/core/vendor/symfony/translation/Tests/DataCollectorTranslatorTest.php
@@ -0,0 +1,81 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Tests;
+
+use Symfony\Component\Translation\Translator;
+use Symfony\Component\Translation\DataCollectorTranslator;
+use Symfony\Component\Translation\Loader\ArrayLoader;
+
+class DataCollectorTranslatorTest extends \PHPUnit_Framework_TestCase
+{
+    protected function setUp()
+    {
+        if (!class_exists('Symfony\Component\HttpKernel\DataCollector\DataCollector')) {
+            $this->markTestSkipped('The "DataCollector" is not available');
+        }
+    }
+    public function testCollectMessages()
+    {
+        $collector = $this->createCollector();
+        $collector->setFallbackLocales(array('fr', 'ru'));
+
+        $collector->trans('foo');
+        $collector->trans('bar');
+        $collector->transChoice('choice', 0);
+        $collector->trans('bar_ru');
+
+        $expectedMessages = array();
+        $expectedMessages[] = array(
+              'id' => 'foo',
+              'translation' => 'foo (en)',
+              'locale' => 'en',
+              'domain' => 'messages',
+              'state' => DataCollectorTranslator::MESSAGE_DEFINED,
+        );
+        $expectedMessages[] = array(
+              'id' => 'bar',
+              'translation' => 'bar (fr)',
+              'locale' => 'fr',
+              'domain' => 'messages',
+              'state' => DataCollectorTranslator::MESSAGE_EQUALS_FALLBACK,
+        );
+        $expectedMessages[] = array(
+              'id' => 'choice',
+              'translation' => 'choice',
+              'locale' => 'en',
+              'domain' => 'messages',
+              'state' => DataCollectorTranslator::MESSAGE_MISSING,
+        );
+        $expectedMessages[] = array(
+              'id' => 'bar_ru',
+              'translation' => 'bar (ru)',
+              'locale' => 'ru',
+              'domain' => 'messages',
+              'state' => DataCollectorTranslator::MESSAGE_EQUALS_FALLBACK,
+        );
+
+        $this->assertEquals($expectedMessages, $collector->getCollectedMessages());
+    }
+
+    private function createCollector()
+    {
+        $translator = new Translator('en');
+        $translator->addLoader('array', new ArrayLoader());
+        $translator->addResource('array', array('foo' => 'foo (en)'), 'en');
+        $translator->addResource('array', array('bar' => 'bar (fr)'), 'fr');
+        $translator->addResource('array', array('bar_ru' => 'bar (ru)'), 'ru');
+
+        $collector = new DataCollectorTranslator($translator);
+
+        return $collector;
+    }
+}
diff --git a/core/vendor/symfony/translation/Tests/Dumper/CsvFileDumperTest.php b/core/vendor/symfony/translation/Tests/Dumper/CsvFileDumperTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..29177ff5f59034cb3de5a55cfc1bd39f1d44d1e5
--- /dev/null
+++ b/core/vendor/symfony/translation/Tests/Dumper/CsvFileDumperTest.php
@@ -0,0 +1,33 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Tests\Dumper;
+
+use Symfony\Component\Translation\MessageCatalogue;
+use Symfony\Component\Translation\Dumper\CsvFileDumper;
+
+class CsvFileDumperTest extends \PHPUnit_Framework_TestCase
+{
+    public function testDump()
+    {
+        $catalogue = new MessageCatalogue('en');
+        $catalogue->add(array('foo' => 'bar', 'bar' => 'foo
+foo', 'foo;foo' => 'bar'));
+
+        $tempDir = sys_get_temp_dir();
+        $dumper = new CsvFileDumper();
+        $dumper->dump($catalogue, array('path' => $tempDir));
+
+        $this->assertEquals(file_get_contents(__DIR__.'/../fixtures/valid.csv'), file_get_contents($tempDir.'/messages.en.csv'));
+
+        unlink($tempDir.'/messages.en.csv');
+    }
+}
diff --git a/core/vendor/symfony/translation/Tests/Dumper/FileDumperTest.php b/core/vendor/symfony/translation/Tests/Dumper/FileDumperTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..96820890922a055ccbc52c986c882f79a3d3dcbe
--- /dev/null
+++ b/core/vendor/symfony/translation/Tests/Dumper/FileDumperTest.php
@@ -0,0 +1,70 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Tests\Dumper;
+
+use Symfony\Component\Translation\MessageCatalogue;
+use Symfony\Component\Translation\Dumper\FileDumper;
+
+class FileDumperTest extends \PHPUnit_Framework_TestCase
+{
+    public function testDumpBackupsFileIfExisting()
+    {
+        $tempDir = sys_get_temp_dir();
+        $file = $tempDir.'/messages.en.concrete';
+        $backupFile = $file.'~';
+
+        @touch($file);
+
+        $catalogue = new MessageCatalogue('en');
+        $catalogue->add(array('foo' => 'bar'));
+
+        $dumper = new ConcreteFileDumper();
+        $dumper->dump($catalogue, array('path' => $tempDir));
+
+        $this->assertTrue(file_exists($backupFile));
+
+        @unlink($file);
+        @unlink($backupFile);
+    }
+
+    public function testDumpCreatesNestedDirectoriesAndFile()
+    {
+        $tempDir = sys_get_temp_dir();
+        $translationsDir = $tempDir.'/test/translations';
+        $file = $translationsDir.'/messages.en.concrete';
+
+        $catalogue = new MessageCatalogue('en');
+        $catalogue->add(array('foo' => 'bar'));
+
+        $dumper = new ConcreteFileDumper();
+        $dumper->setRelativePathTemplate('test/translations/%domain%.%locale%.%extension%');
+        $dumper->dump($catalogue, array('path' => $tempDir));
+
+        $this->assertTrue(file_exists($file));
+
+        @unlink($file);
+        @rmdir($translationsDir);
+    }
+}
+
+class ConcreteFileDumper extends FileDumper
+{
+    protected function format(MessageCatalogue $messages, $domain)
+    {
+        return '';
+    }
+
+    protected function getExtension()
+    {
+        return 'concrete';
+    }
+}
diff --git a/core/vendor/symfony/translation/Tests/Dumper/IcuResFileDumperTest.php b/core/vendor/symfony/translation/Tests/Dumper/IcuResFileDumperTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..7be7dfbf5de067caee30561fd547e521ba1758c7
--- /dev/null
+++ b/core/vendor/symfony/translation/Tests/Dumper/IcuResFileDumperTest.php
@@ -0,0 +1,38 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Tests\Dumper;
+
+use Symfony\Component\Translation\MessageCatalogue;
+use Symfony\Component\Translation\Dumper\IcuResFileDumper;
+
+class IcuResFileDumperTest extends \PHPUnit_Framework_TestCase
+{
+    public function testDump()
+    {
+        if (!function_exists('mb_convert_encoding')) {
+            $this->markTestSkipped('This test requires mbstring to work.');
+        }
+
+        $catalogue = new MessageCatalogue('en');
+        $catalogue->add(array('foo' => 'bar'));
+
+        $tempDir = sys_get_temp_dir().'/IcuResFileDumperTest';
+        $dumper = new IcuResFileDumper();
+        $dumper->dump($catalogue, array('path' => $tempDir));
+
+        $this->assertEquals(file_get_contents(__DIR__.'/../fixtures/resourcebundle/res/en.res'), file_get_contents($tempDir.'/messages/en.res'));
+
+        @unlink($tempDir.'/messages/en.res');
+        @rmdir($tempDir.'/messages');
+        @rmdir($tempDir);
+    }
+}
diff --git a/core/vendor/symfony/translation/Tests/Dumper/IniFileDumperTest.php b/core/vendor/symfony/translation/Tests/Dumper/IniFileDumperTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..2a2cefde1ef50205c7f1258374bae5ef9d6e1714
--- /dev/null
+++ b/core/vendor/symfony/translation/Tests/Dumper/IniFileDumperTest.php
@@ -0,0 +1,32 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Tests\Dumper;
+
+use Symfony\Component\Translation\MessageCatalogue;
+use Symfony\Component\Translation\Dumper\IniFileDumper;
+
+class IniFileDumperTest extends \PHPUnit_Framework_TestCase
+{
+    public function testDump()
+    {
+        $catalogue = new MessageCatalogue('en');
+        $catalogue->add(array('foo' => 'bar'));
+
+        $tempDir = sys_get_temp_dir();
+        $dumper = new IniFileDumper();
+        $dumper->dump($catalogue, array('path' => $tempDir));
+
+        $this->assertEquals(file_get_contents(__DIR__.'/../fixtures/resources.ini'), file_get_contents($tempDir.'/messages.en.ini'));
+
+        unlink($tempDir.'/messages.en.ini');
+    }
+}
diff --git a/core/vendor/symfony/translation/Tests/Dumper/JsonFileDumperTest.php b/core/vendor/symfony/translation/Tests/Dumper/JsonFileDumperTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..697cd939f607ad5ae23ac2b24a7b52d50a7b5519
--- /dev/null
+++ b/core/vendor/symfony/translation/Tests/Dumper/JsonFileDumperTest.php
@@ -0,0 +1,36 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Tests\Dumper;
+
+use Symfony\Component\Translation\MessageCatalogue;
+use Symfony\Component\Translation\Dumper\JsonFileDumper;
+
+class JsonFileDumperTest extends \PHPUnit_Framework_TestCase
+{
+    public function testDump()
+    {
+        if (PHP_VERSION_ID < 50400) {
+            $this->markTestIncomplete('PHP below 5.4 doesn\'t support JSON pretty printing');
+        }
+
+        $catalogue = new MessageCatalogue('en');
+        $catalogue->add(array('foo' => 'bar'));
+
+        $tempDir = sys_get_temp_dir();
+        $dumper = new JsonFileDumper();
+        $dumper->dump($catalogue, array('path' => $tempDir));
+
+        $this->assertEquals(file_get_contents(__DIR__.'/../fixtures/resources.json'), file_get_contents($tempDir.'/messages.en.json'));
+
+        unlink($tempDir.'/messages.en.json');
+    }
+}
diff --git a/core/vendor/symfony/translation/Tests/Dumper/MoFileDumperTest.php b/core/vendor/symfony/translation/Tests/Dumper/MoFileDumperTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..439a25cd222fcff4060ace1225394f8dba075101
--- /dev/null
+++ b/core/vendor/symfony/translation/Tests/Dumper/MoFileDumperTest.php
@@ -0,0 +1,31 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Tests\Dumper;
+
+use Symfony\Component\Translation\MessageCatalogue;
+use Symfony\Component\Translation\Dumper\MoFileDumper;
+
+class MoFileDumperTest extends \PHPUnit_Framework_TestCase
+{
+    public function testDump()
+    {
+        $catalogue = new MessageCatalogue('en');
+        $catalogue->add(array('foo' => 'bar'));
+
+        $tempDir = sys_get_temp_dir();
+        $dumper = new MoFileDumper();
+        $dumper->dump($catalogue, array('path' => $tempDir));
+        $this->assertEquals(file_get_contents(__DIR__.'/../fixtures/resources.mo'), file_get_contents($tempDir.'/messages.en.mo'));
+
+        unlink($tempDir.'/messages.en.mo');
+    }
+}
diff --git a/core/vendor/symfony/translation/Tests/Dumper/PhpFileDumperTest.php b/core/vendor/symfony/translation/Tests/Dumper/PhpFileDumperTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..18be5a0dc48a6fddfad58abfde2c02fd57ec75f3
--- /dev/null
+++ b/core/vendor/symfony/translation/Tests/Dumper/PhpFileDumperTest.php
@@ -0,0 +1,32 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Tests\Dumper;
+
+use Symfony\Component\Translation\MessageCatalogue;
+use Symfony\Component\Translation\Dumper\PhpFileDumper;
+
+class PhpFileDumperTest extends \PHPUnit_Framework_TestCase
+{
+    public function testDump()
+    {
+        $catalogue = new MessageCatalogue('en');
+        $catalogue->add(array('foo' => 'bar'));
+
+        $tempDir = sys_get_temp_dir();
+        $dumper = new PhpFileDumper();
+        $dumper->dump($catalogue, array('path' => $tempDir));
+
+        $this->assertEquals(file_get_contents(__DIR__.'/../fixtures/resources.php'), file_get_contents($tempDir.'/messages.en.php'));
+
+        unlink($tempDir.'/messages.en.php');
+    }
+}
diff --git a/core/vendor/symfony/translation/Tests/Dumper/PoFileDumperTest.php b/core/vendor/symfony/translation/Tests/Dumper/PoFileDumperTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..0296d6b2eaaa1cafd8488a7f2666d79cd3f4ff47
--- /dev/null
+++ b/core/vendor/symfony/translation/Tests/Dumper/PoFileDumperTest.php
@@ -0,0 +1,31 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Tests\Dumper;
+
+use Symfony\Component\Translation\MessageCatalogue;
+use Symfony\Component\Translation\Dumper\PoFileDumper;
+
+class PoFileDumperTest extends \PHPUnit_Framework_TestCase
+{
+    public function testDump()
+    {
+        $catalogue = new MessageCatalogue('en');
+        $catalogue->add(array('foo' => 'bar'));
+
+        $tempDir = sys_get_temp_dir();
+        $dumper = new PoFileDumper();
+        $dumper->dump($catalogue, array('path' => $tempDir));
+        $this->assertEquals(file_get_contents(__DIR__.'/../fixtures/resources.po'), file_get_contents($tempDir.'/messages.en.po'));
+
+        unlink($tempDir.'/messages.en.po');
+    }
+}
diff --git a/core/vendor/symfony/translation/Tests/Dumper/QtFileDumperTest.php b/core/vendor/symfony/translation/Tests/Dumper/QtFileDumperTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..d7d8fb7e469878102be1805ffe65ad204c04cacf
--- /dev/null
+++ b/core/vendor/symfony/translation/Tests/Dumper/QtFileDumperTest.php
@@ -0,0 +1,32 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Tests\Dumper;
+
+use Symfony\Component\Translation\MessageCatalogue;
+use Symfony\Component\Translation\Dumper\QtFileDumper;
+
+class QtFileDumperTest extends \PHPUnit_Framework_TestCase
+{
+    public function testDump()
+    {
+        $catalogue = new MessageCatalogue('en');
+        $catalogue->add(array('foo' => 'bar'), 'resources');
+
+        $tempDir = sys_get_temp_dir();
+        $dumper = new QtFileDumper();
+        $dumper->dump($catalogue, array('path' => $tempDir));
+
+        $this->assertEquals(file_get_contents(__DIR__.'/../fixtures/resources.ts'), file_get_contents($tempDir.'/resources.en.ts'));
+
+        unlink($tempDir.'/resources.en.ts');
+    }
+}
diff --git a/core/vendor/symfony/translation/Tests/Dumper/XliffFileDumperTest.php b/core/vendor/symfony/translation/Tests/Dumper/XliffFileDumperTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..dff2cc4c94a5bc6c3e58e3c939a7aa6b92185c84
--- /dev/null
+++ b/core/vendor/symfony/translation/Tests/Dumper/XliffFileDumperTest.php
@@ -0,0 +1,41 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Tests\Dumper;
+
+use Symfony\Component\Translation\MessageCatalogue;
+use Symfony\Component\Translation\Dumper\XliffFileDumper;
+
+class XliffFileDumperTest extends \PHPUnit_Framework_TestCase
+{
+    public function testDump()
+    {
+        $catalogue = new MessageCatalogue('en_US');
+        $catalogue->add(array(
+            'foo' => 'bar',
+            'key' => '',
+            'key.with.cdata' => '<source> & <target>',
+        ));
+        $catalogue->setMetadata('foo', array('notes' => array(array('priority' => 1, 'from' => 'bar', 'content' => 'baz'))));
+        $catalogue->setMetadata('key', array('notes' => array(array('content' => 'baz'), array('content' => 'qux'))));
+
+        $tempDir = sys_get_temp_dir();
+        $dumper = new XliffFileDumper();
+        $dumper->dump($catalogue, array('path' => $tempDir, 'default_locale' => 'fr_FR'));
+
+        $this->assertEquals(
+            file_get_contents(__DIR__.'/../fixtures/resources-clean.xlf'),
+            file_get_contents($tempDir.'/messages.en_US.xlf')
+        );
+
+        unlink($tempDir.'/messages.en_US.xlf');
+    }
+}
diff --git a/core/vendor/symfony/translation/Tests/Dumper/YamlFileDumperTest.php b/core/vendor/symfony/translation/Tests/Dumper/YamlFileDumperTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..3c68ade753114ab6aeaa6bf97bfccdef44f530af
--- /dev/null
+++ b/core/vendor/symfony/translation/Tests/Dumper/YamlFileDumperTest.php
@@ -0,0 +1,32 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Tests\Dumper;
+
+use Symfony\Component\Translation\MessageCatalogue;
+use Symfony\Component\Translation\Dumper\YamlFileDumper;
+
+class YamlFileDumperTest extends \PHPUnit_Framework_TestCase
+{
+    public function testDump()
+    {
+        $catalogue = new MessageCatalogue('en');
+        $catalogue->add(array('foo' => 'bar'));
+
+        $tempDir = sys_get_temp_dir();
+        $dumper = new YamlFileDumper();
+        $dumper->dump($catalogue, array('path' => $tempDir));
+
+        $this->assertEquals(file_get_contents(__DIR__.'/../fixtures/resources.yml'), file_get_contents($tempDir.'/messages.en.yml'));
+
+        unlink($tempDir.'/messages.en.yml');
+    }
+}
diff --git a/core/vendor/symfony/translation/Tests/IdentityTranslatorTest.php b/core/vendor/symfony/translation/Tests/IdentityTranslatorTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..352dd318dc73c6d3a3a33ed6410dd67a0203437d
--- /dev/null
+++ b/core/vendor/symfony/translation/Tests/IdentityTranslatorTest.php
@@ -0,0 +1,95 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Tests;
+
+use Symfony\Component\Intl\Util\IntlTestHelper;
+use Symfony\Component\Translation\IdentityTranslator;
+
+class IdentityTranslatorTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @dataProvider getTransTests
+     */
+    public function testTrans($expected, $id, $parameters)
+    {
+        $translator = new IdentityTranslator();
+
+        $this->assertEquals($expected, $translator->trans($id, $parameters));
+    }
+
+    /**
+     * @dataProvider getTransChoiceTests
+     */
+    public function testTransChoiceWithExplicitLocale($expected, $id, $number, $parameters)
+    {
+        $translator = new IdentityTranslator();
+        $translator->setLocale('en');
+
+        $this->assertEquals($expected, $translator->transChoice($id, $number, $parameters));
+    }
+
+    /**
+     * @dataProvider getTransChoiceTests
+     */
+    public function testTransChoiceWithDefaultLocale($expected, $id, $number, $parameters)
+    {
+        \Locale::setDefault('en');
+
+        $translator = new IdentityTranslator();
+
+        $this->assertEquals($expected, $translator->transChoice($id, $number, $parameters));
+    }
+
+    public function testGetSetLocale()
+    {
+        $translator = new IdentityTranslator();
+        $translator->setLocale('en');
+
+        $this->assertEquals('en', $translator->getLocale());
+    }
+
+    public function testGetLocaleReturnsDefaultLocaleIfNotSet()
+    {
+        // in order to test with "pt_BR"
+        IntlTestHelper::requireFullIntl($this);
+
+        $translator = new IdentityTranslator();
+
+        \Locale::setDefault('en');
+        $this->assertEquals('en', $translator->getLocale());
+
+        \Locale::setDefault('pt_BR');
+        $this->assertEquals('pt_BR', $translator->getLocale());
+    }
+
+    public function getTransTests()
+    {
+        return array(
+            array('Symfony is great!', 'Symfony is great!', array()),
+            array('Symfony is awesome!', 'Symfony is %what%!', array('%what%' => 'awesome')),
+        );
+    }
+
+    public function getTransChoiceTests()
+    {
+        return array(
+            array('There are no apples', '{0} There are no apples|{1} There is one apple|]1,Inf] There are %count% apples', 0, array('%count%' => 0)),
+            array('There is one apple', '{0} There are no apples|{1} There is one apple|]1,Inf] There are %count% apples', 1, array('%count%' => 1)),
+            array('There are 10 apples', '{0} There are no apples|{1} There is one apple|]1,Inf] There are %count% apples', 10, array('%count%' => 10)),
+            array('There are 0 apples', 'There is 1 apple|There are %count% apples', 0, array('%count%' => 0)),
+            array('There is 1 apple', 'There is 1 apple|There are %count% apples', 1, array('%count%' => 1)),
+            array('There are 10 apples', 'There is 1 apple|There are %count% apples', 10, array('%count%' => 10)),
+            // custom validation messages may be coded with a fixed value
+            array('There are 2 apples', 'There are 2 apples', 2, array('%count%' => 2)),
+        );
+    }
+}
diff --git a/core/vendor/symfony/translation/Tests/IntervalTest.php b/core/vendor/symfony/translation/Tests/IntervalTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..075c98b768f8e29687af45da345b23b6a3a4fb4e
--- /dev/null
+++ b/core/vendor/symfony/translation/Tests/IntervalTest.php
@@ -0,0 +1,48 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Tests;
+
+use Symfony\Component\Translation\Interval;
+
+class IntervalTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @dataProvider getTests
+     */
+    public function testTest($expected, $number, $interval)
+    {
+        $this->assertEquals($expected, Interval::test($number, $interval));
+    }
+
+    /**
+     * @expectedException \InvalidArgumentException
+     */
+    public function testTestException()
+    {
+        Interval::test(1, 'foobar');
+    }
+
+    public function getTests()
+    {
+        return array(
+            array(true, 3, '{1,2, 3 ,4}'),
+            array(false, 10, '{1,2, 3 ,4}'),
+            array(false, 3, '[1,2]'),
+            array(true, 1, '[1,2]'),
+            array(true, 2, '[1,2]'),
+            array(false, 1, ']1,2['),
+            array(false, 2, ']1,2['),
+            array(true, log(0), '[-Inf,2['),
+            array(true, -log(0), '[-2,+Inf]'),
+        );
+    }
+}
diff --git a/core/vendor/symfony/translation/Tests/Loader/CsvFileLoaderTest.php b/core/vendor/symfony/translation/Tests/Loader/CsvFileLoaderTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..463d3b50816f6b9f08ff452b3c09b2c4f77a87b1
--- /dev/null
+++ b/core/vendor/symfony/translation/Tests/Loader/CsvFileLoaderTest.php
@@ -0,0 +1,60 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Tests\Loader;
+
+use Symfony\Component\Translation\Loader\CsvFileLoader;
+use Symfony\Component\Config\Resource\FileResource;
+
+class CsvFileLoaderTest extends \PHPUnit_Framework_TestCase
+{
+    public function testLoad()
+    {
+        $loader = new CsvFileLoader();
+        $resource = __DIR__.'/../fixtures/resources.csv';
+        $catalogue = $loader->load($resource, 'en', 'domain1');
+
+        $this->assertEquals(array('foo' => 'bar'), $catalogue->all('domain1'));
+        $this->assertEquals('en', $catalogue->getLocale());
+        $this->assertEquals(array(new FileResource($resource)), $catalogue->getResources());
+    }
+
+    public function testLoadDoesNothingIfEmpty()
+    {
+        $loader = new CsvFileLoader();
+        $resource = __DIR__.'/../fixtures/empty.csv';
+        $catalogue = $loader->load($resource, 'en', 'domain1');
+
+        $this->assertEquals(array(), $catalogue->all('domain1'));
+        $this->assertEquals('en', $catalogue->getLocale());
+        $this->assertEquals(array(new FileResource($resource)), $catalogue->getResources());
+    }
+
+    /**
+     * @expectedException \Symfony\Component\Translation\Exception\NotFoundResourceException
+     */
+    public function testLoadNonExistingResource()
+    {
+        $loader = new CsvFileLoader();
+        $resource = __DIR__.'/../fixtures/not-exists.csv';
+        $loader->load($resource, 'en', 'domain1');
+    }
+
+    /**
+     * @expectedException \Symfony\Component\Translation\Exception\InvalidResourceException
+     */
+    public function testLoadNonLocalResource()
+    {
+        $loader = new CsvFileLoader();
+        $resource = 'http://example.com/resources.csv';
+        $loader->load($resource, 'en', 'domain1');
+    }
+}
diff --git a/core/vendor/symfony/translation/Tests/Loader/IcuDatFileLoaderTest.php b/core/vendor/symfony/translation/Tests/Loader/IcuDatFileLoaderTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..ea9643d682b3eeddb5c498565528679671b6ad2a
--- /dev/null
+++ b/core/vendor/symfony/translation/Tests/Loader/IcuDatFileLoaderTest.php
@@ -0,0 +1,68 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Tests\Loader;
+
+use Symfony\Component\Translation\Loader\IcuDatFileLoader;
+use Symfony\Component\Config\Resource\FileResource;
+
+class IcuDatFileLoaderTest extends LocalizedTestCase
+{
+    protected function setUp()
+    {
+        if (!extension_loaded('intl')) {
+            $this->markTestSkipped('This test requires intl extension to work.');
+        }
+    }
+
+    /**
+     * @expectedException \Symfony\Component\Translation\Exception\InvalidResourceException
+     */
+    public function testLoadInvalidResource()
+    {
+        $loader = new IcuDatFileLoader();
+        $loader->load(__DIR__.'/../fixtures/resourcebundle/corrupted/resources', 'es', 'domain2');
+    }
+
+    public function testDatEnglishLoad()
+    {
+        // bundled resource is build using pkgdata command which at least in ICU 4.2 comes in extremely! buggy form
+        // you must specify an temporary build directory which is not the same as current directory and
+        // MUST reside on the same partition. pkgdata -p resources -T /srv -d.packagelist.txt
+        $loader = new IcuDatFileLoader();
+        $resource = __DIR__.'/../fixtures/resourcebundle/dat/resources';
+        $catalogue = $loader->load($resource, 'en', 'domain1');
+
+        $this->assertEquals(array('symfony' => 'Symfony 2 is great'), $catalogue->all('domain1'));
+        $this->assertEquals('en', $catalogue->getLocale());
+        $this->assertEquals(array(new FileResource($resource.'.dat')), $catalogue->getResources());
+    }
+
+    public function testDatFrenchLoad()
+    {
+        $loader = new IcuDatFileLoader();
+        $resource = __DIR__.'/../fixtures/resourcebundle/dat/resources';
+        $catalogue = $loader->load($resource, 'fr', 'domain1');
+
+        $this->assertEquals(array('symfony' => 'Symfony 2 est génial'), $catalogue->all('domain1'));
+        $this->assertEquals('fr', $catalogue->getLocale());
+        $this->assertEquals(array(new FileResource($resource.'.dat')), $catalogue->getResources());
+    }
+
+    /**
+     * @expectedException \Symfony\Component\Translation\Exception\NotFoundResourceException
+     */
+    public function testLoadNonExistingResource()
+    {
+        $loader = new IcuDatFileLoader();
+        $loader->load(__DIR__.'/../fixtures/non-existing.txt', 'en', 'domain1');
+    }
+}
diff --git a/core/vendor/symfony/translation/Tests/Loader/IcuResFileLoaderTest.php b/core/vendor/symfony/translation/Tests/Loader/IcuResFileLoaderTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..1a935c0404d322c306be43f68449f947cabbdbe5
--- /dev/null
+++ b/core/vendor/symfony/translation/Tests/Loader/IcuResFileLoaderTest.php
@@ -0,0 +1,55 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Tests\Loader;
+
+use Symfony\Component\Translation\Loader\IcuResFileLoader;
+use Symfony\Component\Config\Resource\DirectoryResource;
+
+class IcuResFileLoaderTest extends LocalizedTestCase
+{
+    protected function setUp()
+    {
+        if (!extension_loaded('intl')) {
+            $this->markTestSkipped('This test requires intl extension to work.');
+        }
+    }
+
+    public function testLoad()
+    {
+        // resource is build using genrb command
+        $loader = new IcuResFileLoader();
+        $resource = __DIR__.'/../fixtures/resourcebundle/res';
+        $catalogue = $loader->load($resource, 'en', 'domain1');
+
+        $this->assertEquals(array('foo' => 'bar'), $catalogue->all('domain1'));
+        $this->assertEquals('en', $catalogue->getLocale());
+        $this->assertEquals(array(new DirectoryResource($resource)), $catalogue->getResources());
+    }
+
+    /**
+     * @expectedException \Symfony\Component\Translation\Exception\NotFoundResourceException
+     */
+    public function testLoadNonExistingResource()
+    {
+        $loader = new IcuResFileLoader();
+        $loader->load(__DIR__.'/../fixtures/non-existing.txt', 'en', 'domain1');
+    }
+
+    /**
+     * @expectedException \Symfony\Component\Translation\Exception\InvalidResourceException
+     */
+    public function testLoadInvalidResource()
+    {
+        $loader = new IcuResFileLoader();
+        $loader->load(__DIR__.'/../fixtures/resourcebundle/corrupted', 'en', 'domain1');
+    }
+}
diff --git a/core/vendor/symfony/translation/Tests/Loader/IniFileLoaderTest.php b/core/vendor/symfony/translation/Tests/Loader/IniFileLoaderTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..1a5de0ed58d69c7bd0fea63050e6f060e373042c
--- /dev/null
+++ b/core/vendor/symfony/translation/Tests/Loader/IniFileLoaderTest.php
@@ -0,0 +1,50 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Tests\Loader;
+
+use Symfony\Component\Translation\Loader\IniFileLoader;
+use Symfony\Component\Config\Resource\FileResource;
+
+class IniFileLoaderTest extends \PHPUnit_Framework_TestCase
+{
+    public function testLoad()
+    {
+        $loader = new IniFileLoader();
+        $resource = __DIR__.'/../fixtures/resources.ini';
+        $catalogue = $loader->load($resource, 'en', 'domain1');
+
+        $this->assertEquals(array('foo' => 'bar'), $catalogue->all('domain1'));
+        $this->assertEquals('en', $catalogue->getLocale());
+        $this->assertEquals(array(new FileResource($resource)), $catalogue->getResources());
+    }
+
+    public function testLoadDoesNothingIfEmpty()
+    {
+        $loader = new IniFileLoader();
+        $resource = __DIR__.'/../fixtures/empty.ini';
+        $catalogue = $loader->load($resource, 'en', 'domain1');
+
+        $this->assertEquals(array(), $catalogue->all('domain1'));
+        $this->assertEquals('en', $catalogue->getLocale());
+        $this->assertEquals(array(new FileResource($resource)), $catalogue->getResources());
+    }
+
+    /**
+     * @expectedException \Symfony\Component\Translation\Exception\NotFoundResourceException
+     */
+    public function testLoadNonExistingResource()
+    {
+        $loader = new IniFileLoader();
+        $resource = __DIR__.'/../fixtures/non-existing.ini';
+        $loader->load($resource, 'en', 'domain1');
+    }
+}
diff --git a/core/vendor/symfony/translation/Tests/Loader/JsonFileLoaderTest.php b/core/vendor/symfony/translation/Tests/Loader/JsonFileLoaderTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..6d4f353bf7dde2e8dfba585d04245569d9f06287
--- /dev/null
+++ b/core/vendor/symfony/translation/Tests/Loader/JsonFileLoaderTest.php
@@ -0,0 +1,68 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Tests\Loader;
+
+use Symfony\Component\Translation\Loader\JsonFileLoader;
+use Symfony\Component\Config\Resource\FileResource;
+
+class JsonFileLoaderTest extends \PHPUnit_Framework_TestCase
+{
+    protected function setUp()
+    {
+        if (!class_exists('Symfony\Component\Config\Loader\Loader')) {
+            $this->markTestSkipped('The "Config" component is not available');
+        }
+    }
+
+    public function testLoad()
+    {
+        $loader = new JsonFileLoader();
+        $resource = __DIR__.'/../fixtures/resources.json';
+        $catalogue = $loader->load($resource, 'en', 'domain1');
+
+        $this->assertEquals(array('foo' => 'bar'), $catalogue->all('domain1'));
+        $this->assertEquals('en', $catalogue->getLocale());
+        $this->assertEquals(array(new FileResource($resource)), $catalogue->getResources());
+    }
+
+    public function testLoadDoesNothingIfEmpty()
+    {
+        $loader = new JsonFileLoader();
+        $resource = __DIR__.'/../fixtures/empty.json';
+        $catalogue = $loader->load($resource, 'en', 'domain1');
+
+        $this->assertEquals(array(), $catalogue->all('domain1'));
+        $this->assertEquals('en', $catalogue->getLocale());
+        $this->assertEquals(array(new FileResource($resource)), $catalogue->getResources());
+    }
+
+    /**
+     * @expectedException \Symfony\Component\Translation\Exception\NotFoundResourceException
+     */
+    public function testLoadNonExistingResource()
+    {
+        $loader = new JsonFileLoader();
+        $resource = __DIR__.'/../fixtures/non-existing.json';
+        $loader->load($resource, 'en', 'domain1');
+    }
+
+    /**
+     * @expectedException           \Symfony\Component\Translation\Exception\InvalidResourceException
+     * @expectedExceptionMessage    Error parsing JSON - Syntax error, malformed JSON
+     */
+    public function testParseException()
+    {
+        $loader = new JsonFileLoader();
+        $resource = __DIR__.'/../fixtures/malformed.json';
+        $loader->load($resource, 'en', 'domain1');
+    }
+}
diff --git a/core/vendor/symfony/translation/Tests/Loader/LocalizedTestCase.php b/core/vendor/symfony/translation/Tests/Loader/LocalizedTestCase.php
new file mode 100644
index 0000000000000000000000000000000000000000..9d7c5d70e826319c6d3fc4f3a64ff5ec1e9fd8f1
--- /dev/null
+++ b/core/vendor/symfony/translation/Tests/Loader/LocalizedTestCase.php
@@ -0,0 +1,22 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Tests\Loader;
+
+abstract class LocalizedTestCase extends \PHPUnit_Framework_TestCase
+{
+    protected function setUp()
+    {
+        if (!extension_loaded('intl')) {
+            $this->markTestSkipped('The "intl" extension is not available');
+        }
+    }
+}
diff --git a/core/vendor/symfony/translation/Tests/Loader/MoFileLoaderTest.php b/core/vendor/symfony/translation/Tests/Loader/MoFileLoaderTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..34078d0a9e48c251e5d6e1b92262a8975a163a70
--- /dev/null
+++ b/core/vendor/symfony/translation/Tests/Loader/MoFileLoaderTest.php
@@ -0,0 +1,71 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Tests\Loader;
+
+use Symfony\Component\Translation\Loader\MoFileLoader;
+use Symfony\Component\Config\Resource\FileResource;
+
+class MoFileLoaderTest extends \PHPUnit_Framework_TestCase
+{
+    public function testLoad()
+    {
+        $loader = new MoFileLoader();
+        $resource = __DIR__.'/../fixtures/resources.mo';
+        $catalogue = $loader->load($resource, 'en', 'domain1');
+
+        $this->assertEquals(array('foo' => 'bar'), $catalogue->all('domain1'));
+        $this->assertEquals('en', $catalogue->getLocale());
+        $this->assertEquals(array(new FileResource($resource)), $catalogue->getResources());
+    }
+
+    public function testLoadPlurals()
+    {
+        $loader = new MoFileLoader();
+        $resource = __DIR__.'/../fixtures/plurals.mo';
+        $catalogue = $loader->load($resource, 'en', 'domain1');
+
+        $this->assertEquals(array('foo' => 'bar', 'foos' => '{0} bar|{1} bars'), $catalogue->all('domain1'));
+        $this->assertEquals('en', $catalogue->getLocale());
+        $this->assertEquals(array(new FileResource($resource)), $catalogue->getResources());
+    }
+
+    /**
+     * @expectedException \Symfony\Component\Translation\Exception\NotFoundResourceException
+     */
+    public function testLoadNonExistingResource()
+    {
+        $loader = new MoFileLoader();
+        $resource = __DIR__.'/../fixtures/non-existing.mo';
+        $loader->load($resource, 'en', 'domain1');
+    }
+
+    /**
+     * @expectedException \Symfony\Component\Translation\Exception\InvalidResourceException
+     */
+    public function testLoadInvalidResource()
+    {
+        $loader = new MoFileLoader();
+        $resource = __DIR__.'/../fixtures/empty.mo';
+        $loader->load($resource, 'en', 'domain1');
+    }
+
+    public function testLoadEmptyTranslation()
+    {
+        $loader = new MoFileLoader();
+        $resource = __DIR__.'/../fixtures/empty-translation.mo';
+        $catalogue = $loader->load($resource, 'en', 'message');
+
+        $this->assertEquals(array(), $catalogue->all('message'));
+        $this->assertEquals('en', $catalogue->getLocale());
+        $this->assertEquals(array(new FileResource($resource)), $catalogue->getResources());
+    }
+}
diff --git a/core/vendor/symfony/translation/Tests/Loader/PhpFileLoaderTest.php b/core/vendor/symfony/translation/Tests/Loader/PhpFileLoaderTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..0816b0f8549d19d839e201fce69963d346b9f00a
--- /dev/null
+++ b/core/vendor/symfony/translation/Tests/Loader/PhpFileLoaderTest.php
@@ -0,0 +1,49 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Tests\Loader;
+
+use Symfony\Component\Translation\Loader\PhpFileLoader;
+use Symfony\Component\Config\Resource\FileResource;
+
+class PhpFileLoaderTest extends \PHPUnit_Framework_TestCase
+{
+    public function testLoad()
+    {
+        $loader = new PhpFileLoader();
+        $resource = __DIR__.'/../fixtures/resources.php';
+        $catalogue = $loader->load($resource, 'en', 'domain1');
+
+        $this->assertEquals(array('foo' => 'bar'), $catalogue->all('domain1'));
+        $this->assertEquals('en', $catalogue->getLocale());
+        $this->assertEquals(array(new FileResource($resource)), $catalogue->getResources());
+    }
+
+    /**
+     * @expectedException \Symfony\Component\Translation\Exception\NotFoundResourceException
+     */
+    public function testLoadNonExistingResource()
+    {
+        $loader = new PhpFileLoader();
+        $resource = __DIR__.'/../fixtures/non-existing.php';
+        $loader->load($resource, 'en', 'domain1');
+    }
+
+    /**
+     * @expectedException \Symfony\Component\Translation\Exception\InvalidResourceException
+     */
+    public function testLoadThrowsAnExceptionIfFileNotLocal()
+    {
+        $loader = new PhpFileLoader();
+        $resource = 'http://example.com/resources.php';
+        $loader->load($resource, 'en', 'domain1');
+    }
+}
diff --git a/core/vendor/symfony/translation/Tests/Loader/PoFileLoaderTest.php b/core/vendor/symfony/translation/Tests/Loader/PoFileLoaderTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..87090eb7369227c82a338a05903065177dc97d98
--- /dev/null
+++ b/core/vendor/symfony/translation/Tests/Loader/PoFileLoaderTest.php
@@ -0,0 +1,96 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Tests\Loader;
+
+use Symfony\Component\Translation\Loader\PoFileLoader;
+use Symfony\Component\Config\Resource\FileResource;
+
+class PoFileLoaderTest extends \PHPUnit_Framework_TestCase
+{
+    public function testLoad()
+    {
+        $loader = new PoFileLoader();
+        $resource = __DIR__.'/../fixtures/resources.po';
+        $catalogue = $loader->load($resource, 'en', 'domain1');
+
+        $this->assertEquals(array('foo' => 'bar'), $catalogue->all('domain1'));
+        $this->assertEquals('en', $catalogue->getLocale());
+        $this->assertEquals(array(new FileResource($resource)), $catalogue->getResources());
+    }
+
+    public function testLoadPlurals()
+    {
+        $loader = new PoFileLoader();
+        $resource = __DIR__.'/../fixtures/plurals.po';
+        $catalogue = $loader->load($resource, 'en', 'domain1');
+
+        $this->assertEquals(array('foo' => 'bar', 'foos' => 'bar|bars'), $catalogue->all('domain1'));
+        $this->assertEquals('en', $catalogue->getLocale());
+        $this->assertEquals(array(new FileResource($resource)), $catalogue->getResources());
+    }
+
+    public function testLoadDoesNothingIfEmpty()
+    {
+        $loader = new PoFileLoader();
+        $resource = __DIR__.'/../fixtures/empty.po';
+        $catalogue = $loader->load($resource, 'en', 'domain1');
+
+        $this->assertEquals(array(), $catalogue->all('domain1'));
+        $this->assertEquals('en', $catalogue->getLocale());
+        $this->assertEquals(array(new FileResource($resource)), $catalogue->getResources());
+    }
+
+    /**
+     * @expectedException \Symfony\Component\Translation\Exception\NotFoundResourceException
+     */
+    public function testLoadNonExistingResource()
+    {
+        $loader = new PoFileLoader();
+        $resource = __DIR__.'/../fixtures/non-existing.po';
+        $loader->load($resource, 'en', 'domain1');
+    }
+
+    public function testLoadEmptyTranslation()
+    {
+        $loader = new PoFileLoader();
+        $resource = __DIR__.'/../fixtures/empty-translation.po';
+        $catalogue = $loader->load($resource, 'en', 'domain1');
+
+        $this->assertEquals(array('foo' => ''), $catalogue->all('domain1'));
+        $this->assertEquals('en', $catalogue->getLocale());
+        $this->assertEquals(array(new FileResource($resource)), $catalogue->getResources());
+    }
+
+    public function testEscapedId()
+    {
+        $loader = new PoFileLoader();
+        $resource = __DIR__.'/../fixtures/escaped-id.po';
+        $catalogue = $loader->load($resource, 'en', 'domain1');
+
+        $messages = $catalogue->all('domain1');
+        $this->assertArrayHasKey('escaped "foo"', $messages);
+        $this->assertEquals('escaped "bar"', $messages['escaped "foo"']);
+    }
+
+    public function testEscapedIdPlurals()
+    {
+        $loader = new PoFileLoader();
+        $resource = __DIR__.'/../fixtures/escaped-id-plurals.po';
+        $catalogue = $loader->load($resource, 'en', 'domain1');
+
+        $messages = $catalogue->all('domain1');
+        $this->assertArrayHasKey('escaped "foo"', $messages);
+        $this->assertArrayHasKey('escaped "foos"', $messages);
+        $this->assertEquals('escaped "bar"', $messages['escaped "foo"']);
+        $this->assertEquals('escaped "bar"|escaped "bars"', $messages['escaped "foos"']);
+    }
+}
diff --git a/core/vendor/symfony/translation/Tests/Loader/QtFileLoaderTest.php b/core/vendor/symfony/translation/Tests/Loader/QtFileLoaderTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..3aca86a53ed64ac297c490a7d01da459966cbbbe
--- /dev/null
+++ b/core/vendor/symfony/translation/Tests/Loader/QtFileLoaderTest.php
@@ -0,0 +1,67 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Tests\Loader;
+
+use Symfony\Component\Translation\Loader\QtFileLoader;
+use Symfony\Component\Config\Resource\FileResource;
+
+class QtFileLoaderTest extends \PHPUnit_Framework_TestCase
+{
+    public function testLoad()
+    {
+        $loader = new QtFileLoader();
+        $resource = __DIR__.'/../fixtures/resources.ts';
+        $catalogue = $loader->load($resource, 'en', 'resources');
+
+        $this->assertEquals(array('foo' => 'bar'), $catalogue->all('resources'));
+        $this->assertEquals('en', $catalogue->getLocale());
+        $this->assertEquals(array(new FileResource($resource)), $catalogue->getResources());
+    }
+
+    /**
+     * @expectedException \Symfony\Component\Translation\Exception\NotFoundResourceException
+     */
+    public function testLoadNonExistingResource()
+    {
+        $loader = new QtFileLoader();
+        $resource = __DIR__.'/../fixtures/non-existing.ts';
+        $loader->load($resource, 'en', 'domain1');
+    }
+
+    /**
+     * @expectedException \Symfony\Component\Translation\Exception\InvalidResourceException
+     */
+    public function testLoadNonLocalResource()
+    {
+        $loader = new QtFileLoader();
+        $resource = 'http://domain1.com/resources.ts';
+        $loader->load($resource, 'en', 'domain1');
+    }
+
+    /**
+     * @expectedException \Symfony\Component\Translation\Exception\InvalidResourceException
+     */
+    public function testLoadInvalidResource()
+    {
+        $loader = new QtFileLoader();
+        $resource = __DIR__.'/../fixtures/invalid-xml-resources.xlf';
+        $loader->load($resource, 'en', 'domain1');
+    }
+
+    public function testLoadEmptyResource()
+    {
+        $loader = new QtFileLoader();
+        $resource = __DIR__.'/../fixtures/empty.xlf';
+        $this->setExpectedException('Symfony\Component\Translation\Exception\InvalidResourceException', sprintf('Unable to load "%s".', $resource));
+        $loader->load($resource, 'en', 'domain1');
+    }
+}
diff --git a/core/vendor/symfony/translation/Tests/Loader/XliffFileLoaderTest.php b/core/vendor/symfony/translation/Tests/Loader/XliffFileLoaderTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..f1de081134a282d54a8bda5ebeae21938c318b3a
--- /dev/null
+++ b/core/vendor/symfony/translation/Tests/Loader/XliffFileLoaderTest.php
@@ -0,0 +1,143 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Tests\Loader;
+
+use Symfony\Component\Translation\Loader\XliffFileLoader;
+use Symfony\Component\Config\Resource\FileResource;
+
+class XliffFileLoaderTest extends \PHPUnit_Framework_TestCase
+{
+    public function testLoad()
+    {
+        $loader = new XliffFileLoader();
+        $resource = __DIR__.'/../fixtures/resources.xlf';
+        $catalogue = $loader->load($resource, 'en', 'domain1');
+
+        $this->assertEquals('en', $catalogue->getLocale());
+        $this->assertEquals(array(new FileResource($resource)), $catalogue->getResources());
+        $this->assertSame(array(), libxml_get_errors());
+        $this->assertContainsOnly('string', $catalogue->all('domain1'));
+    }
+
+    public function testLoadWithInternalErrorsEnabled()
+    {
+        libxml_use_internal_errors(true);
+
+        $this->assertSame(array(), libxml_get_errors());
+
+        $loader = new XliffFileLoader();
+        $resource = __DIR__.'/../fixtures/resources.xlf';
+        $catalogue = $loader->load($resource, 'en', 'domain1');
+
+        $this->assertEquals('en', $catalogue->getLocale());
+        $this->assertEquals(array(new FileResource($resource)), $catalogue->getResources());
+        $this->assertSame(array(), libxml_get_errors());
+    }
+
+    public function testLoadWithResname()
+    {
+        $loader = new XliffFileLoader();
+        $catalogue = $loader->load(__DIR__.'/../fixtures/resname.xlf', 'en', 'domain1');
+
+        $this->assertEquals(array('foo' => 'bar', 'bar' => 'baz', 'baz' => 'foo'), $catalogue->all('domain1'));
+    }
+
+    public function testIncompleteResource()
+    {
+        $loader = new XliffFileLoader();
+        $catalogue = $loader->load(__DIR__.'/../fixtures/resources.xlf', 'en', 'domain1');
+
+        $this->assertEquals(array('foo' => 'bar', 'extra' => 'extra', 'key' => '', 'test' => 'with'), $catalogue->all('domain1'));
+    }
+
+    public function testEncoding()
+    {
+        if (!function_exists('iconv') && !function_exists('mb_convert_encoding')) {
+            $this->markTestSkipped('The iconv and mbstring extensions are not available.');
+        }
+
+        $loader = new XliffFileLoader();
+        $catalogue = $loader->load(__DIR__.'/../fixtures/encoding.xlf', 'en', 'domain1');
+
+        $this->assertEquals(utf8_decode('föö'), $catalogue->get('bar', 'domain1'));
+        $this->assertEquals(utf8_decode('bär'), $catalogue->get('foo', 'domain1'));
+        $this->assertEquals(array('notes' => array(array('content' => utf8_decode('bäz')))), $catalogue->getMetadata('foo', 'domain1'));
+    }
+
+    /**
+     * @expectedException \Symfony\Component\Translation\Exception\InvalidResourceException
+     */
+    public function testLoadInvalidResource()
+    {
+        $loader = new XliffFileLoader();
+        $loader->load(__DIR__.'/../fixtures/resources.php', 'en', 'domain1');
+    }
+
+    /**
+     * @expectedException \Symfony\Component\Translation\Exception\InvalidResourceException
+     */
+    public function testLoadResourceDoesNotValidate()
+    {
+        $loader = new XliffFileLoader();
+        $loader->load(__DIR__.'/../fixtures/non-valid.xlf', 'en', 'domain1');
+    }
+
+    /**
+     * @expectedException \Symfony\Component\Translation\Exception\NotFoundResourceException
+     */
+    public function testLoadNonExistingResource()
+    {
+        $loader = new XliffFileLoader();
+        $resource = __DIR__.'/../fixtures/non-existing.xlf';
+        $loader->load($resource, 'en', 'domain1');
+    }
+
+    /**
+     * @expectedException \Symfony\Component\Translation\Exception\InvalidResourceException
+     */
+    public function testLoadThrowsAnExceptionIfFileNotLocal()
+    {
+        $loader = new XliffFileLoader();
+        $resource = 'http://example.com/resources.xlf';
+        $loader->load($resource, 'en', 'domain1');
+    }
+
+    /**
+     * @expectedException        \Symfony\Component\Translation\Exception\InvalidResourceException
+     * @expectedExceptionMessage Document types are not allowed.
+     */
+    public function testDocTypeIsNotAllowed()
+    {
+        $loader = new XliffFileLoader();
+        $loader->load(__DIR__.'/../fixtures/withdoctype.xlf', 'en', 'domain1');
+    }
+
+    public function testParseEmptyFile()
+    {
+        $loader = new XliffFileLoader();
+        $resource = __DIR__.'/../fixtures/empty.xlf';
+        $this->setExpectedException('Symfony\Component\Translation\Exception\InvalidResourceException', sprintf('Unable to load "%s":', $resource));
+        $loader->load($resource, 'en', 'domain1');
+    }
+
+    public function testLoadNotes()
+    {
+        $loader = new XliffFileLoader();
+        $catalogue = $loader->load(__DIR__.'/../fixtures/withnote.xlf', 'en', 'domain1');
+
+        $this->assertEquals(array('notes' => array(array('priority' => 1, 'content' => 'foo'))), $catalogue->getMetadata('foo', 'domain1'));
+        // message without target
+        $this->assertEquals(array('notes' => array(array('content' => 'bar', 'from' => 'foo'))), $catalogue->getMetadata('extra', 'domain1'));
+        // message with empty target
+        $this->assertEquals(array('notes' => array(array('content' => 'baz'), array('priority' => 2, 'from' => 'bar', 'content' => 'qux'))), $catalogue->getMetadata('key', 'domain1'));
+    }
+}
diff --git a/core/vendor/symfony/translation/Tests/Loader/YamlFileLoaderTest.php b/core/vendor/symfony/translation/Tests/Loader/YamlFileLoaderTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..00f7163468d557e7dbeee413b30b019e21392d6c
--- /dev/null
+++ b/core/vendor/symfony/translation/Tests/Loader/YamlFileLoaderTest.php
@@ -0,0 +1,70 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Tests\Loader;
+
+use Symfony\Component\Translation\Loader\YamlFileLoader;
+use Symfony\Component\Config\Resource\FileResource;
+
+class YamlFileLoaderTest extends \PHPUnit_Framework_TestCase
+{
+    public function testLoad()
+    {
+        $loader = new YamlFileLoader();
+        $resource = __DIR__.'/../fixtures/resources.yml';
+        $catalogue = $loader->load($resource, 'en', 'domain1');
+
+        $this->assertEquals(array('foo' => 'bar'), $catalogue->all('domain1'));
+        $this->assertEquals('en', $catalogue->getLocale());
+        $this->assertEquals(array(new FileResource($resource)), $catalogue->getResources());
+    }
+
+    public function testLoadDoesNothingIfEmpty()
+    {
+        $loader = new YamlFileLoader();
+        $resource = __DIR__.'/../fixtures/empty.yml';
+        $catalogue = $loader->load($resource, 'en', 'domain1');
+
+        $this->assertEquals(array(), $catalogue->all('domain1'));
+        $this->assertEquals('en', $catalogue->getLocale());
+        $this->assertEquals(array(new FileResource($resource)), $catalogue->getResources());
+    }
+
+    /**
+     * @expectedException \Symfony\Component\Translation\Exception\NotFoundResourceException
+     */
+    public function testLoadNonExistingResource()
+    {
+        $loader = new YamlFileLoader();
+        $resource = __DIR__.'/../fixtures/non-existing.yml';
+        $loader->load($resource, 'en', 'domain1');
+    }
+
+    /**
+     * @expectedException \Symfony\Component\Translation\Exception\InvalidResourceException
+     */
+    public function testLoadThrowsAnExceptionIfFileNotLocal()
+    {
+        $loader = new YamlFileLoader();
+        $resource = 'http://example.com/resources.yml';
+        $loader->load($resource, 'en', 'domain1');
+    }
+
+    /**
+     * @expectedException \Symfony\Component\Translation\Exception\InvalidResourceException
+     */
+    public function testLoadThrowsAnExceptionIfNotAnArray()
+    {
+        $loader = new YamlFileLoader();
+        $resource = __DIR__.'/../fixtures/non-valid.yml';
+        $loader->load($resource, 'en', 'domain1');
+    }
+}
diff --git a/core/vendor/symfony/translation/Tests/LoggingTranslatorTest.php b/core/vendor/symfony/translation/Tests/LoggingTranslatorTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..ab98d72e7425c78a3803129e5872e532eeb36b2d
--- /dev/null
+++ b/core/vendor/symfony/translation/Tests/LoggingTranslatorTest.php
@@ -0,0 +1,56 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Tests;
+
+use Symfony\Component\Translation\Translator;
+use Symfony\Component\Translation\LoggingTranslator;
+use Symfony\Component\Translation\Loader\ArrayLoader;
+
+class LoggingTranslatorTest extends \PHPUnit_Framework_TestCase
+{
+    protected function setUp()
+    {
+        if (!interface_exists('Psr\Log\LoggerInterface')) {
+            $this->markTestSkipped('The "LoggerInterface" is not available');
+        }
+    }
+
+    public function testTransWithNoTranslationIsLogged()
+    {
+        $logger = $this->getMock('Psr\Log\LoggerInterface');
+        $logger->expects($this->exactly(2))
+            ->method('warning')
+            ->with('Translation not found.')
+        ;
+
+        $translator = new Translator('ar');
+        $loggableTranslator = new LoggingTranslator($translator, $logger);
+        $loggableTranslator->transChoice('some_message2', 10, array('%count%' => 10));
+        $loggableTranslator->trans('bar');
+    }
+
+    public function testTransChoiceFallbackIsLogged()
+    {
+        $logger = $this->getMock('Psr\Log\LoggerInterface');
+        $logger->expects($this->once())
+            ->method('debug')
+            ->with('Translation use fallback catalogue.')
+        ;
+
+        $translator = new Translator('ar');
+        $translator->setFallbackLocales(array('en'));
+        $translator->addLoader('array', new ArrayLoader());
+        $translator->addResource('array', array('some_message2' => 'one thing|%count% things'), 'en');
+        $loggableTranslator = new LoggingTranslator($translator, $logger);
+        $loggableTranslator->transChoice('some_message2', 10, array('%count%' => 10));
+    }
+}
diff --git a/core/vendor/symfony/translation/Tests/MessageCatalogueTest.php b/core/vendor/symfony/translation/Tests/MessageCatalogueTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..6f55b8cc5e8fb6fbbd1a13c1880eb4e69a8c3219
--- /dev/null
+++ b/core/vendor/symfony/translation/Tests/MessageCatalogueTest.php
@@ -0,0 +1,214 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Tests;
+
+use Symfony\Component\Translation\MessageCatalogue;
+
+class MessageCatalogueTest extends \PHPUnit_Framework_TestCase
+{
+    public function testGetLocale()
+    {
+        $catalogue = new MessageCatalogue('en');
+
+        $this->assertEquals('en', $catalogue->getLocale());
+    }
+
+    public function testGetDomains()
+    {
+        $catalogue = new MessageCatalogue('en', array('domain1' => array(), 'domain2' => array()));
+
+        $this->assertEquals(array('domain1', 'domain2'), $catalogue->getDomains());
+    }
+
+    public function testAll()
+    {
+        $catalogue = new MessageCatalogue('en', $messages = array('domain1' => array('foo' => 'foo'), 'domain2' => array('bar' => 'bar')));
+
+        $this->assertEquals(array('foo' => 'foo'), $catalogue->all('domain1'));
+        $this->assertEquals(array(), $catalogue->all('domain88'));
+        $this->assertEquals($messages, $catalogue->all());
+    }
+
+    public function testHas()
+    {
+        $catalogue = new MessageCatalogue('en', array('domain1' => array('foo' => 'foo'), 'domain2' => array('bar' => 'bar')));
+
+        $this->assertTrue($catalogue->has('foo', 'domain1'));
+        $this->assertFalse($catalogue->has('bar', 'domain1'));
+        $this->assertFalse($catalogue->has('foo', 'domain88'));
+    }
+
+    public function testGetSet()
+    {
+        $catalogue = new MessageCatalogue('en', array('domain1' => array('foo' => 'foo'), 'domain2' => array('bar' => 'bar')));
+        $catalogue->set('foo1', 'foo1', 'domain1');
+
+        $this->assertEquals('foo', $catalogue->get('foo', 'domain1'));
+        $this->assertEquals('foo1', $catalogue->get('foo1', 'domain1'));
+    }
+
+    public function testAdd()
+    {
+        $catalogue = new MessageCatalogue('en', array('domain1' => array('foo' => 'foo'), 'domain2' => array('bar' => 'bar')));
+        $catalogue->add(array('foo1' => 'foo1'), 'domain1');
+
+        $this->assertEquals('foo', $catalogue->get('foo', 'domain1'));
+        $this->assertEquals('foo1', $catalogue->get('foo1', 'domain1'));
+
+        $catalogue->add(array('foo' => 'bar'), 'domain1');
+        $this->assertEquals('bar', $catalogue->get('foo', 'domain1'));
+        $this->assertEquals('foo1', $catalogue->get('foo1', 'domain1'));
+
+        $catalogue->add(array('foo' => 'bar'), 'domain88');
+        $this->assertEquals('bar', $catalogue->get('foo', 'domain88'));
+    }
+
+    public function testReplace()
+    {
+        $catalogue = new MessageCatalogue('en', array('domain1' => array('foo' => 'foo'), 'domain2' => array('bar' => 'bar')));
+        $catalogue->replace($messages = array('foo1' => 'foo1'), 'domain1');
+
+        $this->assertEquals($messages, $catalogue->all('domain1'));
+    }
+
+    public function testAddCatalogue()
+    {
+        $r = $this->getMock('Symfony\Component\Config\Resource\ResourceInterface');
+        $r->expects($this->any())->method('__toString')->will($this->returnValue('r'));
+
+        $r1 = $this->getMock('Symfony\Component\Config\Resource\ResourceInterface');
+        $r1->expects($this->any())->method('__toString')->will($this->returnValue('r1'));
+
+        $catalogue = new MessageCatalogue('en', array('domain1' => array('foo' => 'foo'), 'domain2' => array('bar' => 'bar')));
+        $catalogue->addResource($r);
+
+        $catalogue1 = new MessageCatalogue('en', array('domain1' => array('foo1' => 'foo1')));
+        $catalogue1->addResource($r1);
+
+        $catalogue->addCatalogue($catalogue1);
+
+        $this->assertEquals('foo', $catalogue->get('foo', 'domain1'));
+        $this->assertEquals('foo1', $catalogue->get('foo1', 'domain1'));
+
+        $this->assertEquals(array($r, $r1), $catalogue->getResources());
+    }
+
+    public function testAddFallbackCatalogue()
+    {
+        $r = $this->getMock('Symfony\Component\Config\Resource\ResourceInterface');
+        $r->expects($this->any())->method('__toString')->will($this->returnValue('r'));
+
+        $r1 = $this->getMock('Symfony\Component\Config\Resource\ResourceInterface');
+        $r1->expects($this->any())->method('__toString')->will($this->returnValue('r1'));
+
+        $catalogue = new MessageCatalogue('en_US', array('domain1' => array('foo' => 'foo'), 'domain2' => array('bar' => 'bar')));
+        $catalogue->addResource($r);
+
+        $catalogue1 = new MessageCatalogue('en', array('domain1' => array('foo' => 'bar', 'foo1' => 'foo1')));
+        $catalogue1->addResource($r1);
+
+        $catalogue->addFallbackCatalogue($catalogue1);
+
+        $this->assertEquals('foo', $catalogue->get('foo', 'domain1'));
+        $this->assertEquals('foo1', $catalogue->get('foo1', 'domain1'));
+
+        $this->assertEquals(array($r, $r1), $catalogue->getResources());
+    }
+
+    /**
+     * @expectedException \LogicException
+     */
+    public function testAddFallbackCatalogueWithParentCircularReference()
+    {
+        $main = new MessageCatalogue('en_US');
+        $fallback = new MessageCatalogue('fr_FR');
+
+        $fallback->addFallbackCatalogue($main);
+        $main->addFallbackCatalogue($fallback);
+    }
+
+    /**
+     * @expectedException \LogicException
+     */
+    public function testAddFallbackCatalogueWithFallbackCircularReference()
+    {
+        $fr = new MessageCatalogue('fr');
+        $en = new MessageCatalogue('en');
+        $es = new MessageCatalogue('es');
+
+        $fr->addFallbackCatalogue($en);
+        $es->addFallbackCatalogue($en);
+        $en->addFallbackCatalogue($fr);
+    }
+
+    /**
+     * @expectedException \LogicException
+     */
+    public function testAddCatalogueWhenLocaleIsNotTheSameAsTheCurrentOne()
+    {
+        $catalogue = new MessageCatalogue('en');
+        $catalogue->addCatalogue(new MessageCatalogue('fr', array()));
+    }
+
+    public function testGetAddResource()
+    {
+        $catalogue = new MessageCatalogue('en');
+        $r = $this->getMock('Symfony\Component\Config\Resource\ResourceInterface');
+        $r->expects($this->any())->method('__toString')->will($this->returnValue('r'));
+        $catalogue->addResource($r);
+        $catalogue->addResource($r);
+        $r1 = $this->getMock('Symfony\Component\Config\Resource\ResourceInterface');
+        $r1->expects($this->any())->method('__toString')->will($this->returnValue('r1'));
+        $catalogue->addResource($r1);
+
+        $this->assertEquals(array($r, $r1), $catalogue->getResources());
+    }
+
+    public function testMetadataDelete()
+    {
+        $catalogue = new MessageCatalogue('en');
+        $this->assertEquals(array(), $catalogue->getMetadata('', ''), 'Metadata is empty');
+        $catalogue->deleteMetadata('key', 'messages');
+        $catalogue->deleteMetadata('', 'messages');
+        $catalogue->deleteMetadata();
+    }
+
+    public function testMetadataSetGetDelete()
+    {
+        $catalogue = new MessageCatalogue('en');
+        $catalogue->setMetadata('key', 'value');
+        $this->assertEquals('value', $catalogue->getMetadata('key', 'messages'), "Metadata 'key' = 'value'");
+
+        $catalogue->setMetadata('key2', array());
+        $this->assertEquals(array(), $catalogue->getMetadata('key2', 'messages'), 'Metadata key2 is array');
+
+        $catalogue->deleteMetadata('key2', 'messages');
+        $this->assertNull($catalogue->getMetadata('key2', 'messages'), 'Metadata key2 should is deleted.');
+
+        $catalogue->deleteMetadata('key2', 'domain');
+        $this->assertNull($catalogue->getMetadata('key2', 'domain'), 'Metadata key2 should is deleted.');
+    }
+
+    public function testMetadataMerge()
+    {
+        $cat1 = new MessageCatalogue('en');
+        $cat1->setMetadata('a', 'b');
+        $this->assertEquals(array('messages' => array('a' => 'b')), $cat1->getMetadata('', ''), 'Cat1 contains messages metadata.');
+
+        $cat2 = new MessageCatalogue('en');
+        $cat2->setMetadata('b', 'c', 'domain');
+        $this->assertEquals(array('domain' => array('b' => 'c')), $cat2->getMetadata('', ''), 'Cat2 contains domain metadata.');
+
+        $cat1->addCatalogue($cat2);
+        $this->assertEquals(array('messages' => array('a' => 'b'), 'domain' => array('b' => 'c')), $cat1->getMetadata('', ''), 'Cat1 contains merged metadata.');
+    }
+}
diff --git a/core/vendor/symfony/translation/Tests/MessageSelectorTest.php b/core/vendor/symfony/translation/Tests/MessageSelectorTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..f89bed16d59b42cc205a0ad0a0fa5ab5999d0cde
--- /dev/null
+++ b/core/vendor/symfony/translation/Tests/MessageSelectorTest.php
@@ -0,0 +1,130 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Tests;
+
+use Symfony\Component\Translation\MessageSelector;
+
+class MessageSelectorTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @dataProvider getChooseTests
+     */
+    public function testChoose($expected, $id, $number)
+    {
+        $selector = new MessageSelector();
+
+        $this->assertEquals($expected, $selector->choose($id, $number, 'en'));
+    }
+
+    public function testReturnMessageIfExactlyOneStandardRuleIsGiven()
+    {
+        $selector = new MessageSelector();
+
+        $this->assertEquals('There are two apples', $selector->choose('There are two apples', 2, 'en'));
+    }
+
+    /**
+     * @dataProvider getNonMatchingMessages
+     * @expectedException \InvalidArgumentException
+     */
+    public function testThrowExceptionIfMatchingMessageCannotBeFound($id, $number)
+    {
+        $selector = new MessageSelector();
+
+        $selector->choose($id, $number, 'en');
+    }
+
+    public function getNonMatchingMessages()
+    {
+        return array(
+            array('{0} There are no apples|{1} There is one apple', 2),
+            array('{1} There is one apple|]1,Inf] There are %count% apples', 0),
+            array('{1} There is one apple|]2,Inf] There are %count% apples', 2),
+            array('{0} There are no apples|There is one apple', 2),
+        );
+    }
+
+    public function getChooseTests()
+    {
+        return array(
+            array('There are no apples', '{0} There are no apples|{1} There is one apple|]1,Inf] There are %count% apples', 0),
+            array('There are no apples', '{0}     There are no apples|{1} There is one apple|]1,Inf] There are %count% apples', 0),
+            array('There are no apples', '{0}There are no apples|{1} There is one apple|]1,Inf] There are %count% apples', 0),
+
+            array('There is one apple', '{0} There are no apples|{1} There is one apple|]1,Inf] There are %count% apples', 1),
+
+            array('There are %count% apples', '{0} There are no apples|{1} There is one apple|]1,Inf] There are %count% apples', 10),
+            array('There are %count% apples', '{0} There are no apples|{1} There is one apple|]1,Inf]There are %count% apples', 10),
+            array('There are %count% apples', '{0} There are no apples|{1} There is one apple|]1,Inf]     There are %count% apples', 10),
+
+            array('There are %count% apples', 'There is one apple|There are %count% apples', 0),
+            array('There is one apple', 'There is one apple|There are %count% apples', 1),
+            array('There are %count% apples', 'There is one apple|There are %count% apples', 10),
+
+            array('There are %count% apples', 'one: There is one apple|more: There are %count% apples', 0),
+            array('There is one apple', 'one: There is one apple|more: There are %count% apples', 1),
+            array('There are %count% apples', 'one: There is one apple|more: There are %count% apples', 10),
+
+            array('There are no apples', '{0} There are no apples|one: There is one apple|more: There are %count% apples', 0),
+            array('There is one apple', '{0} There are no apples|one: There is one apple|more: There are %count% apples', 1),
+            array('There are %count% apples', '{0} There are no apples|one: There is one apple|more: There are %count% apples', 10),
+
+            array('', '{0}|{1} There is one apple|]1,Inf] There are %count% apples', 0),
+            array('', '{0} There are no apples|{1}|]1,Inf] There are %count% apples', 1),
+
+            // Indexed only tests which are Gettext PoFile* compatible strings.
+            array('There are %count% apples', 'There is one apple|There are %count% apples', 0),
+            array('There is one apple', 'There is one apple|There are %count% apples', 1),
+            array('There are %count% apples', 'There is one apple|There are %count% apples', 2),
+
+            // Tests for float numbers
+            array('There is almost one apple', '{0} There are no apples|]0,1[ There is almost one apple|{1} There is one apple|[1,Inf] There is more than one apple', 0.7),
+            array('There is one apple', '{0} There are no apples|]0,1[There are %count% apples|{1} There is one apple|[1,Inf] There is more than one apple', 1),
+            array('There is more than one apple', '{0} There are no apples|]0,1[There are %count% apples|{1} There is one apple|[1,Inf] There is more than one apple', 1.7),
+            array('There are no apples', '{0} There are no apples|]0,1[There are %count% apples|{1} There is one apple|[1,Inf] There is more than one apple', 0),
+            array('There are no apples', '{0} There are no apples|]0,1[There are %count% apples|{1} There is one apple|[1,Inf] There is more than one apple', 0.0),
+            array('There are no apples', '{0.0} There are no apples|]0,1[There are %count% apples|{1} There is one apple|[1,Inf] There is more than one apple', 0),
+
+            // Test texts with new-lines
+            // with double-quotes and \n in id & double-quotes and actual newlines in text
+            array("This is a text with a\n            new-line in it. Selector = 0.", '{0}This is a text with a
+            new-line in it. Selector = 0.|{1}This is a text with a
+            new-line in it. Selector = 1.|[1,Inf]This is a text with a
+            new-line in it. Selector > 1.', 0),
+            // with double-quotes and \n in id and single-quotes and actual newlines in text
+            array("This is a text with a\n            new-line in it. Selector = 1.", '{0}This is a text with a
+            new-line in it. Selector = 0.|{1}This is a text with a
+            new-line in it. Selector = 1.|[1,Inf]This is a text with a
+            new-line in it. Selector > 1.', 1),
+            array("This is a text with a\n            new-line in it. Selector > 1.", '{0}This is a text with a
+            new-line in it. Selector = 0.|{1}This is a text with a
+            new-line in it. Selector = 1.|[1,Inf]This is a text with a
+            new-line in it. Selector > 1.', 5),
+            // with double-quotes and id split accros lines
+            array('This is a text with a
+            new-line in it. Selector = 1.', '{0}This is a text with a
+            new-line in it. Selector = 0.|{1}This is a text with a
+            new-line in it. Selector = 1.|[1,Inf]This is a text with a
+            new-line in it. Selector > 1.', 1),
+            // with single-quotes and id split accros lines
+            array('This is a text with a
+            new-line in it. Selector > 1.', '{0}This is a text with a
+            new-line in it. Selector = 0.|{1}This is a text with a
+            new-line in it. Selector = 1.|[1,Inf]This is a text with a
+            new-line in it. Selector > 1.', 5),
+            // with single-quotes and \n in text
+            array('This is a text with a\nnew-line in it. Selector = 0.', '{0}This is a text with a\nnew-line in it. Selector = 0.|{1}This is a text with a\nnew-line in it. Selector = 1.|[1,Inf]This is a text with a\nnew-line in it. Selector > 1.', 0),
+            // with double-quotes and id split accros lines
+            array("This is a text with a\nnew-line in it. Selector = 1.", "{0}This is a text with a\nnew-line in it. Selector = 0.|{1}This is a text with a\nnew-line in it. Selector = 1.|[1,Inf]This is a text with a\nnew-line in it. Selector > 1.", 1),
+        );
+    }
+}
diff --git a/core/vendor/symfony/translation/Tests/PluralizationRulesTest.php b/core/vendor/symfony/translation/Tests/PluralizationRulesTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..066e07f5ab3f2411c3f0136bc6f1344fad8dc90f
--- /dev/null
+++ b/core/vendor/symfony/translation/Tests/PluralizationRulesTest.php
@@ -0,0 +1,123 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Tests;
+
+use Symfony\Component\Translation\PluralizationRules;
+
+/**
+ * Test should cover all languages mentioned on http://translate.sourceforge.net/wiki/l10n/pluralforms
+ * and Plural forms mentioned on http://www.gnu.org/software/gettext/manual/gettext.html#Plural-forms.
+ *
+ * See also https://developer.mozilla.org/en/Localization_and_Plurals which mentions 15 rules having a maximum of 6 forms.
+ * The mozilla code is also interesting to check for.
+ *
+ * As mentioned by chx http://drupal.org/node/1273968 we can cover all by testing number from 0 to 199
+ *
+ * The goal to cover all languages is to far fetched so this test case is smaller.
+ *
+ * @author Clemens Tolboom clemens@build2be.nl
+ */
+class PluralizationRulesTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * We test failed langcode here.
+     *
+     * TODO: The languages mentioned in the data provide need to get fixed somehow within PluralizationRules.
+     *
+     * @dataProvider failingLangcodes
+     */
+    public function testFailedLangcodes($nplural, $langCodes)
+    {
+        $matrix = $this->generateTestData($nplural, $langCodes);
+        $this->validateMatrix($nplural, $matrix, false);
+    }
+
+    /**
+     * @dataProvider successLangcodes
+     */
+    public function testLangcodes($nplural, $langCodes)
+    {
+        $matrix = $this->generateTestData($nplural, $langCodes);
+        $this->validateMatrix($nplural, $matrix);
+    }
+
+    /**
+     * This array should contain all currently known langcodes.
+     *
+     * As it is impossible to have this ever complete we should try as hard as possible to have it almost complete.
+     *
+     * @return array
+     */
+    public function successLangcodes()
+    {
+        return array(
+            array('1', array('ay','bo', 'cgg','dz','id', 'ja', 'jbo', 'ka','kk','km','ko','ky')),
+            array('2', array('nl', 'fr', 'en', 'de', 'de_GE')),
+            array('3', array('be','bs','cs','hr')),
+            array('4', array('cy','mt', 'sl')),
+            array('5', array()),
+            array('6', array('ar')),
+        );
+    }
+
+    /**
+     * This array should be at least empty within the near future.
+     *
+     * This both depends on a complete list trying to add above as understanding
+     * the plural rules of the current failing languages.
+     *
+     * @return array with nplural together with langcodes
+     */
+    public function failingLangcodes()
+    {
+        return array(
+            array('1', array('fa')),
+            array('2', array('jbo')),
+            array('3', array('cbs')),
+            array('4', array('gd','kw')),
+            array('5', array('ga')),
+            array('6', array()),
+        );
+    }
+
+    /**
+     * We validate only on the plural coverage. Thus the real rules is not tested.
+     *
+     * @param string $nplural       plural expected
+     * @param array  $matrix        containing langcodes and their plural index values.
+     * @param bool   $expectSuccess
+     */
+    protected function validateMatrix($nplural, $matrix, $expectSuccess = true)
+    {
+        foreach ($matrix as $langCode => $data) {
+            $indexes = array_flip($data);
+            if ($expectSuccess) {
+                $this->assertEquals($nplural, count($indexes), "Langcode '$langCode' has '$nplural' plural forms.");
+            } else {
+                $this->assertNotEquals((int) $nplural, count($indexes), "Langcode '$langCode' has '$nplural' plural forms.");
+            }
+        }
+    }
+
+    protected function generateTestData($plural, $langCodes)
+    {
+        $matrix = array();
+        foreach ($langCodes as $langCode) {
+            for ($count = 0; $count < 200; ++$count) {
+                $plural = PluralizationRules::get($count, $langCode);
+                $matrix[$langCode][$count] = $plural;
+            }
+        }
+
+        return $matrix;
+    }
+}
diff --git a/core/vendor/symfony/translation/Tests/TranslatorCacheTest.php b/core/vendor/symfony/translation/Tests/TranslatorCacheTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..abe364c7368c7d3a33e1a8deadc58fbdb67f9e14
--- /dev/null
+++ b/core/vendor/symfony/translation/Tests/TranslatorCacheTest.php
@@ -0,0 +1,299 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Tests;
+
+use Symfony\Component\Config\Resource\ResourceInterface;
+use Symfony\Component\Translation\Loader\ArrayLoader;
+use Symfony\Component\Translation\Loader\LoaderInterface;
+use Symfony\Component\Translation\Translator;
+use Symfony\Component\Translation\MessageCatalogue;
+
+class TranslatorCacheTest extends \PHPUnit_Framework_TestCase
+{
+    protected $tmpDir;
+
+    protected function setUp()
+    {
+        $this->tmpDir = sys_get_temp_dir().'/sf2_translation';
+        $this->deleteTmpDir();
+    }
+
+    protected function tearDown()
+    {
+        $this->deleteTmpDir();
+    }
+
+    protected function deleteTmpDir()
+    {
+        if (!file_exists($dir = $this->tmpDir)) {
+            return;
+        }
+
+        $iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($this->tmpDir), \RecursiveIteratorIterator::CHILD_FIRST);
+        foreach ($iterator as $path) {
+            if (preg_match('#[/\\\\]\.\.?$#', $path->__toString())) {
+                continue;
+            }
+            if ($path->isDir()) {
+                rmdir($path->__toString());
+            } else {
+                unlink($path->__toString());
+            }
+        }
+        rmdir($this->tmpDir);
+    }
+
+    /**
+     * @dataProvider runForDebugAndProduction
+     */
+    public function testThatACacheIsUsed($debug)
+    {
+        $locale = 'any_locale';
+        $format = 'some_format';
+        $msgid = 'test';
+
+        // Prime the cache
+        $translator = new Translator($locale, null, $this->tmpDir, $debug);
+        $translator->addLoader($format, new ArrayLoader());
+        $translator->addResource($format, array($msgid => 'OK'), $locale);
+        $translator->trans($msgid);
+
+        // Try again and see we get a valid result whilst no loader can be used
+        $translator = new Translator($locale, null, $this->tmpDir, $debug);
+        $translator->addLoader($format, $this->createFailingLoader());
+        $translator->addResource($format, array($msgid => 'OK'), $locale);
+        $this->assertEquals('OK', $translator->trans($msgid), '-> caching does not work in '.($debug ? 'debug' : 'production'));
+    }
+
+    public function testCatalogueIsReloadedWhenResourcesAreNoLongerFresh()
+    {
+        /*
+         * The testThatACacheIsUsed() test showed that we don't need the loader as long as the cache
+         * is fresh.
+         *
+         * Now we add a Resource that is never fresh and make sure that the
+         * cache is discarded (the loader is called twice).
+         *
+         * We need to run this for debug=true only because in production the cache
+         * will never be revalidated.
+         */
+
+        $locale = 'any_locale';
+        $format = 'some_format';
+        $msgid = 'test';
+
+        $catalogue = new MessageCatalogue($locale, array());
+        $catalogue->addResource(new StaleResource()); // better use a helper class than a mock, because it gets serialized in the cache and re-loaded
+
+        /** @var LoaderInterface|\PHPUnit_Framework_MockObject_MockObject $loader */
+        $loader = $this->getMock('Symfony\Component\Translation\Loader\LoaderInterface');
+        $loader
+            ->expects($this->exactly(2))
+            ->method('load')
+            ->will($this->returnValue($catalogue))
+        ;
+
+        // 1st pass
+        $translator = new Translator($locale, null, $this->tmpDir, true);
+        $translator->addLoader($format, $loader);
+        $translator->addResource($format, null, $locale);
+        $translator->trans($msgid);
+
+        // 2nd pass
+        $translator = new Translator($locale, null, $this->tmpDir, true);
+        $translator->addLoader($format, $loader);
+        $translator->addResource($format, null, $locale);
+        $translator->trans($msgid);
+    }
+
+    /**
+     * @dataProvider runForDebugAndProduction
+     */
+    public function testDifferentTranslatorsForSameLocaleDoNotOverwriteEachOthersCache($debug)
+    {
+        /*
+         * Similar to the previous test. After we used the second translator, make
+         * sure there's still a useable cache for the first one.
+         */
+
+        $locale = 'any_locale';
+        $format = 'some_format';
+        $msgid = 'test';
+
+        // Create a Translator and prime its cache
+        $translator = new Translator($locale, null, $this->tmpDir, $debug);
+        $translator->addLoader($format, new ArrayLoader());
+        $translator->addResource($format, array($msgid => 'OK'), $locale);
+        $translator->trans($msgid);
+
+        // Create another Translator with a different catalogue for the same locale
+        $translator = new Translator($locale, null, $this->tmpDir, $debug);
+        $translator->addLoader($format, new ArrayLoader());
+        $translator->addResource($format, array($msgid => 'FAIL'), $locale);
+        $translator->trans($msgid);
+
+        // Now the first translator must still have a useable cache.
+        $translator = new Translator($locale, null, $this->tmpDir, $debug);
+        $translator->addLoader($format, $this->createFailingLoader());
+        $translator->addResource($format, array($msgid => 'OK'), $locale);
+        $this->assertEquals('OK', $translator->trans($msgid), '-> the cache was overwritten by another translator instance in '.($debug ? 'debug' : 'production'));
+    }
+
+    public function testDifferentCacheFilesAreUsedForDifferentSetsOfFallbackLocales()
+    {
+        /*
+         * Because the cache file contains a catalogue including all of its fallback
+         * catalogues, we must take the set of fallback locales into consideration when
+         * loading a catalogue from the cache.
+         */
+        $translator = new Translator('a', null, $this->tmpDir);
+        $translator->setFallbackLocales(array('b'));
+
+        $translator->addLoader('array', new ArrayLoader());
+        $translator->addResource('array', array('foo' => 'foo (a)'), 'a');
+        $translator->addResource('array', array('bar' => 'bar (b)'), 'b');
+
+        $this->assertEquals('bar (b)', $translator->trans('bar'));
+
+        // Remove fallback locale
+        $translator->setFallbackLocales(array());
+        $this->assertEquals('bar', $translator->trans('bar'));
+
+        // Use a fresh translator with no fallback locales, result should be the same
+        $translator = new Translator('a', null, $this->tmpDir);
+
+        $translator->addLoader('array', new ArrayLoader());
+        $translator->addResource('array', array('foo' => 'foo (a)'), 'a');
+        $translator->addResource('array', array('bar' => 'bar (b)'), 'b');
+
+        $this->assertEquals('bar', $translator->trans('bar'));
+    }
+
+    public function testPrimaryAndFallbackCataloguesContainTheSameMessagesRegardlessOfCaching()
+    {
+        /*
+         * As a safeguard against potential BC breaks, make sure that primary and fallback
+         * catalogues (reachable via getFallbackCatalogue()) always contain the full set of
+         * messages provided by the loader. This must also be the case when these catalogues
+         * are (internally) read from a cache.
+         *
+         * Optimizations inside the translator must not change this behaviour.
+         */
+
+        /*
+         * Create a translator that loads two catalogues for two different locales.
+         * The catalogues contain distinct sets of messages.
+         */
+        $translator = new Translator('a', null, $this->tmpDir);
+        $translator->setFallbackLocales(array('b'));
+
+        $translator->addLoader('array', new ArrayLoader());
+        $translator->addResource('array', array('foo' => 'foo (a)'), 'a');
+        $translator->addResource('array', array('foo' => 'foo (b)'), 'b');
+        $translator->addResource('array', array('bar' => 'bar (b)'), 'b');
+
+        $catalogue = $translator->getCatalogue('a');
+        $this->assertFalse($catalogue->defines('bar')); // Sure, the "a" catalogue does not contain that message.
+
+        $fallback = $catalogue->getFallbackCatalogue();
+        $this->assertTrue($fallback->defines('foo')); // "foo" is present in "a" and "b"
+
+        /*
+         * Now, repeat the same test.
+         * Behind the scenes, the cache is used. But that should not matter, right?
+         */
+        $translator = new Translator('a', null, $this->tmpDir);
+        $translator->setFallbackLocales(array('b'));
+
+        $translator->addLoader('array', new ArrayLoader());
+        $translator->addResource('array', array('foo' => 'foo (a)'), 'a');
+        $translator->addResource('array', array('foo' => 'foo (b)'), 'b');
+        $translator->addResource('array', array('bar' => 'bar (b)'), 'b');
+
+        $catalogue = $translator->getCatalogue('a');
+        $this->assertFalse($catalogue->defines('bar'));
+
+        $fallback = $catalogue->getFallbackCatalogue();
+        $this->assertTrue($fallback->defines('foo'));
+    }
+
+    public function testRefreshCacheWhenResourcesAreNoLongerFresh()
+    {
+        $resource = $this->getMock('Symfony\Component\Config\Resource\ResourceInterface');
+        $loader = $this->getMock('Symfony\Component\Translation\Loader\LoaderInterface');
+        $resource->method('isFresh')->will($this->returnValue(false));
+        $loader
+            ->expects($this->exactly(2))
+            ->method('load')
+            ->will($this->returnValue($this->getCatalogue('fr', array(), array($resource))));
+
+        // prime the cache
+        $translator = new Translator('fr', null, $this->tmpDir, true);
+        $translator->addLoader('loader', $loader);
+        $translator->addResource('loader', 'foo', 'fr');
+        $translator->trans('foo');
+
+        // prime the cache second time
+        $translator = new Translator('fr', null, $this->tmpDir, true);
+        $translator->addLoader('loader', $loader);
+        $translator->addResource('loader', 'foo', 'fr');
+        $translator->trans('foo');
+    }
+
+    protected function getCatalogue($locale, $messages, $resources = array())
+    {
+        $catalogue = new MessageCatalogue($locale);
+        foreach ($messages as $key => $translation) {
+            $catalogue->set($key, $translation);
+        }
+        foreach ($resources as $resource) {
+            $catalogue->addResource($resource);
+        }
+
+        return $catalogue;
+    }
+
+    public function runForDebugAndProduction()
+    {
+        return array(array(true), array(false));
+    }
+
+    /**
+     * @return LoaderInterface
+     */
+    private function createFailingLoader()
+    {
+        $loader = $this->getMock('Symfony\Component\Translation\Loader\LoaderInterface');
+        $loader
+            ->expects($this->never())
+            ->method('load');
+
+        return $loader;
+    }
+}
+
+class StaleResource implements ResourceInterface
+{
+    public function isFresh($timestamp)
+    {
+        return false;
+    }
+
+    public function getResource()
+    {
+    }
+
+    public function __toString()
+    {
+        return '';
+    }
+}
diff --git a/core/vendor/symfony/translation/Tests/TranslatorTest.php b/core/vendor/symfony/translation/Tests/TranslatorTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..cb361831883e90f721b1508160c389fc12b670d7
--- /dev/null
+++ b/core/vendor/symfony/translation/Tests/TranslatorTest.php
@@ -0,0 +1,627 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation\Tests;
+
+use Symfony\Component\Translation\Translator;
+use Symfony\Component\Translation\MessageSelector;
+use Symfony\Component\Translation\Loader\ArrayLoader;
+use Symfony\Component\Translation\MessageCatalogue;
+
+class TranslatorTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @dataProvider      getInvalidLocalesTests
+     * @expectedException \InvalidArgumentException
+     */
+    public function testConstructorInvalidLocale($locale)
+    {
+        $translator = new Translator($locale, new MessageSelector());
+    }
+
+    /**
+     * @dataProvider getValidLocalesTests
+     */
+    public function testConstructorValidLocale($locale)
+    {
+        $translator = new Translator($locale, new MessageSelector());
+
+        $this->assertEquals($locale, $translator->getLocale());
+    }
+
+    public function testConstructorWithoutLocale()
+    {
+        $translator = new Translator(null, new MessageSelector());
+
+        $this->assertNull($translator->getLocale());
+    }
+
+    public function testSetGetLocale()
+    {
+        $translator = new Translator('en');
+
+        $this->assertEquals('en', $translator->getLocale());
+
+        $translator->setLocale('fr');
+        $this->assertEquals('fr', $translator->getLocale());
+    }
+
+    /**
+     * @dataProvider      getInvalidLocalesTests
+     * @expectedException \InvalidArgumentException
+     */
+    public function testSetInvalidLocale($locale)
+    {
+        $translator = new Translator('fr', new MessageSelector());
+        $translator->setLocale($locale);
+    }
+
+    /**
+     * @dataProvider getValidLocalesTests
+     */
+    public function testSetValidLocale($locale)
+    {
+        $translator = new Translator($locale, new MessageSelector());
+        $translator->setLocale($locale);
+
+        $this->assertEquals($locale, $translator->getLocale());
+    }
+
+    public function testGetCatalogue()
+    {
+        $translator = new Translator('en');
+
+        $this->assertEquals(new MessageCatalogue('en'), $translator->getCatalogue());
+
+        $translator->setLocale('fr');
+        $this->assertEquals(new MessageCatalogue('fr'), $translator->getCatalogue('fr'));
+    }
+
+    public function testGetCatalogueReturnsConsolidatedCatalogue()
+    {
+        /*
+         * This will be useful once we refactor so that different domains will be loaded lazily (on-demand).
+         * In that case, getCatalogue() will probably have to load all missing domains in order to return
+         * one complete catalogue.
+         */
+
+        $locale = 'whatever';
+        $translator = new Translator($locale);
+        $translator->addLoader('loader-a', new ArrayLoader());
+        $translator->addLoader('loader-b', new ArrayLoader());
+        $translator->addResource('loader-a', array('foo' => 'foofoo'), $locale, 'domain-a');
+        $translator->addResource('loader-b', array('bar' => 'foobar'), $locale, 'domain-b');
+
+        /*
+         * Test that we get a single catalogue comprising messages
+         * from different loaders and different domains
+         */
+        $catalogue = $translator->getCatalogue($locale);
+        $this->assertTrue($catalogue->defines('foo', 'domain-a'));
+        $this->assertTrue($catalogue->defines('bar', 'domain-b'));
+    }
+
+    public function testSetFallbackLocales()
+    {
+        $translator = new Translator('en');
+        $translator->addLoader('array', new ArrayLoader());
+        $translator->addResource('array', array('foo' => 'foofoo'), 'en');
+        $translator->addResource('array', array('bar' => 'foobar'), 'fr');
+
+        // force catalogue loading
+        $translator->trans('bar');
+
+        $translator->setFallbackLocales(array('fr'));
+        $this->assertEquals('foobar', $translator->trans('bar'));
+    }
+
+    public function testSetFallbackLocalesMultiple()
+    {
+        $translator = new Translator('en');
+        $translator->addLoader('array', new ArrayLoader());
+        $translator->addResource('array', array('foo' => 'foo (en)'), 'en');
+        $translator->addResource('array', array('bar' => 'bar (fr)'), 'fr');
+
+        // force catalogue loading
+        $translator->trans('bar');
+
+        $translator->setFallbackLocales(array('fr_FR', 'fr'));
+        $this->assertEquals('bar (fr)', $translator->trans('bar'));
+    }
+
+    /**
+     * @dataProvider      getInvalidLocalesTests
+     * @expectedException \InvalidArgumentException
+     */
+    public function testSetFallbackInvalidLocales($locale)
+    {
+        $translator = new Translator('fr', new MessageSelector());
+        $translator->setFallbackLocales(array('fr', $locale));
+    }
+
+    /**
+     * @dataProvider getValidLocalesTests
+     */
+    public function testSetFallbackValidLocales($locale)
+    {
+        $translator = new Translator($locale, new MessageSelector());
+        $translator->setFallbackLocales(array('fr', $locale));
+        // no assertion. this method just asserts that no exception is thrown
+    }
+
+    public function testTransWithFallbackLocale()
+    {
+        $translator = new Translator('fr_FR');
+        $translator->setFallbackLocales(array('en'));
+
+        $translator->addLoader('array', new ArrayLoader());
+        $translator->addResource('array', array('bar' => 'foobar'), 'en');
+
+        $this->assertEquals('foobar', $translator->trans('bar'));
+    }
+
+    /**
+     * @dataProvider      getInvalidLocalesTests
+     * @expectedException \InvalidArgumentException
+     */
+    public function testAddResourceInvalidLocales($locale)
+    {
+        $translator = new Translator('fr', new MessageSelector());
+        $translator->addResource('array', array('foo' => 'foofoo'), $locale);
+    }
+
+    /**
+     * @dataProvider getValidLocalesTests
+     */
+    public function testAddResourceValidLocales($locale)
+    {
+        $translator = new Translator('fr', new MessageSelector());
+        $translator->addResource('array', array('foo' => 'foofoo'), $locale);
+        // no assertion. this method just asserts that no exception is thrown
+    }
+
+    public function testAddResourceAfterTrans()
+    {
+        $translator = new Translator('fr');
+        $translator->addLoader('array', new ArrayLoader());
+
+        $translator->setFallbackLocales(array('en'));
+
+        $translator->addResource('array', array('foo' => 'foofoo'), 'en');
+        $this->assertEquals('foofoo', $translator->trans('foo'));
+
+        $translator->addResource('array', array('bar' => 'foobar'), 'en');
+        $this->assertEquals('foobar', $translator->trans('bar'));
+    }
+
+    /**
+     * @dataProvider      getTransFileTests
+     * @expectedException \Symfony\Component\Translation\Exception\NotFoundResourceException
+     */
+    public function testTransWithoutFallbackLocaleFile($format, $loader)
+    {
+        $loaderClass = 'Symfony\\Component\\Translation\\Loader\\'.$loader;
+        $translator = new Translator('en');
+        $translator->addLoader($format, new $loaderClass());
+        $translator->addResource($format, __DIR__.'/fixtures/non-existing', 'en');
+        $translator->addResource($format, __DIR__.'/fixtures/resources.'.$format, 'en');
+
+        // force catalogue loading
+        $translator->trans('foo');
+    }
+
+    /**
+     * @dataProvider getTransFileTests
+     */
+    public function testTransWithFallbackLocaleFile($format, $loader)
+    {
+        $loaderClass = 'Symfony\\Component\\Translation\\Loader\\'.$loader;
+        $translator = new Translator('en_GB');
+        $translator->addLoader($format, new $loaderClass());
+        $translator->addResource($format, __DIR__.'/fixtures/non-existing', 'en_GB');
+        $translator->addResource($format, __DIR__.'/fixtures/resources.'.$format, 'en', 'resources');
+
+        $this->assertEquals('bar', $translator->trans('foo', array(), 'resources'));
+    }
+
+    public function testTransWithFallbackLocaleBis()
+    {
+        $translator = new Translator('en_US');
+        $translator->addLoader('array', new ArrayLoader());
+        $translator->addResource('array', array('foo' => 'foofoo'), 'en_US');
+        $translator->addResource('array', array('bar' => 'foobar'), 'en');
+        $this->assertEquals('foobar', $translator->trans('bar'));
+    }
+
+    public function testTransWithFallbackLocaleTer()
+    {
+        $translator = new Translator('fr_FR');
+        $translator->addLoader('array', new ArrayLoader());
+        $translator->addResource('array', array('foo' => 'foo (en_US)'), 'en_US');
+        $translator->addResource('array', array('bar' => 'bar (en)'), 'en');
+
+        $translator->setFallbackLocales(array('en_US', 'en'));
+
+        $this->assertEquals('foo (en_US)', $translator->trans('foo'));
+        $this->assertEquals('bar (en)', $translator->trans('bar'));
+    }
+
+    public function testTransNonExistentWithFallback()
+    {
+        $translator = new Translator('fr');
+        $translator->setFallbackLocales(array('en'));
+        $translator->addLoader('array', new ArrayLoader());
+        $this->assertEquals('non-existent', $translator->trans('non-existent'));
+    }
+
+    /**
+     * @expectedException \RuntimeException
+     */
+    public function testWhenAResourceHasNoRegisteredLoader()
+    {
+        $translator = new Translator('en');
+        $translator->addResource('array', array('foo' => 'foofoo'), 'en');
+
+        $translator->trans('foo');
+    }
+
+    /**
+     * @dataProvider getTransTests
+     */
+    public function testTrans($expected, $id, $translation, $parameters, $locale, $domain)
+    {
+        $translator = new Translator('en');
+        $translator->addLoader('array', new ArrayLoader());
+        $translator->addResource('array', array((string) $id => $translation), $locale, $domain);
+
+        $this->assertEquals($expected, $translator->trans($id, $parameters, $domain, $locale));
+    }
+
+    /**
+     * @dataProvider      getInvalidLocalesTests
+     * @expectedException \InvalidArgumentException
+     */
+    public function testTransInvalidLocale($locale)
+    {
+        $translator = new Translator('en', new MessageSelector());
+        $translator->addLoader('array', new ArrayLoader());
+        $translator->addResource('array', array('foo' => 'foofoo'), 'en');
+
+        $translator->trans('foo', array(), '', $locale);
+    }
+
+    /**
+     * @dataProvider      getValidLocalesTests
+     */
+    public function testTransValidLocale($locale)
+    {
+        $translator = new Translator($locale, new MessageSelector());
+        $translator->addLoader('array', new ArrayLoader());
+        $translator->addResource('array', array('test' => 'OK'), $locale);
+
+        $this->assertEquals('OK', $translator->trans('test'));
+        $this->assertEquals('OK', $translator->trans('test', array(), null, $locale));
+    }
+
+    /**
+     * @dataProvider getFlattenedTransTests
+     */
+    public function testFlattenedTrans($expected, $messages, $id)
+    {
+        $translator = new Translator('en');
+        $translator->addLoader('array', new ArrayLoader());
+        $translator->addResource('array', $messages, 'fr', '');
+
+        $this->assertEquals($expected, $translator->trans($id, array(), '', 'fr'));
+    }
+
+    /**
+     * @dataProvider getTransChoiceTests
+     */
+    public function testTransChoice($expected, $id, $translation, $number, $parameters, $locale, $domain)
+    {
+        $translator = new Translator('en');
+        $translator->addLoader('array', new ArrayLoader());
+        $translator->addResource('array', array((string) $id => $translation), $locale, $domain);
+
+        $this->assertEquals($expected, $translator->transChoice($id, $number, $parameters, $domain, $locale));
+    }
+
+    /**
+     * @dataProvider      getInvalidLocalesTests
+     * @expectedException \InvalidArgumentException
+     */
+    public function testTransChoiceInvalidLocale($locale)
+    {
+        $translator = new Translator('en', new MessageSelector());
+        $translator->addLoader('array', new ArrayLoader());
+        $translator->addResource('array', array('foo' => 'foofoo'), 'en');
+
+        $translator->transChoice('foo', 1, array(), '', $locale);
+    }
+
+    /**
+     * @dataProvider      getValidLocalesTests
+     */
+    public function testTransChoiceValidLocale($locale)
+    {
+        $translator = new Translator('en', new MessageSelector());
+        $translator->addLoader('array', new ArrayLoader());
+        $translator->addResource('array', array('foo' => 'foofoo'), 'en');
+
+        $translator->transChoice('foo', 1, array(), '', $locale);
+        // no assertion. this method just asserts that no exception is thrown
+    }
+
+    public function getTransFileTests()
+    {
+        return array(
+            array('csv', 'CsvFileLoader'),
+            array('ini', 'IniFileLoader'),
+            array('mo', 'MoFileLoader'),
+            array('po', 'PoFileLoader'),
+            array('php', 'PhpFileLoader'),
+            array('ts', 'QtFileLoader'),
+            array('xlf', 'XliffFileLoader'),
+            array('yml', 'YamlFileLoader'),
+            array('json', 'JsonFileLoader'),
+        );
+    }
+
+    public function getTransTests()
+    {
+        return array(
+            array('Symfony est super !', 'Symfony is great!', 'Symfony est super !', array(), 'fr', ''),
+            array('Symfony est awesome !', 'Symfony is %what%!', 'Symfony est %what% !', array('%what%' => 'awesome'), 'fr', ''),
+            array('Symfony est super !', new StringClass('Symfony is great!'), 'Symfony est super !', array(), 'fr', ''),
+        );
+    }
+
+    public function getFlattenedTransTests()
+    {
+        $messages = array(
+            'symfony' => array(
+                'is' => array(
+                    'great' => 'Symfony est super!',
+                ),
+            ),
+            'foo' => array(
+                'bar' => array(
+                    'baz' => 'Foo Bar Baz',
+                ),
+                'baz' => 'Foo Baz',
+            ),
+        );
+
+        return array(
+            array('Symfony est super!', $messages, 'symfony.is.great'),
+            array('Foo Bar Baz', $messages, 'foo.bar.baz'),
+            array('Foo Baz', $messages, 'foo.baz'),
+        );
+    }
+
+    public function getTransChoiceTests()
+    {
+        return array(
+            array('Il y a 0 pomme', '{0} There are no appless|{1} There is one apple|]1,Inf] There is %count% apples', '[0,1] Il y a %count% pomme|]1,Inf] Il y a %count% pommes', 0, array('%count%' => 0), 'fr', ''),
+            array('Il y a 1 pomme', '{0} There are no appless|{1} There is one apple|]1,Inf] There is %count% apples', '[0,1] Il y a %count% pomme|]1,Inf] Il y a %count% pommes', 1, array('%count%' => 1), 'fr', ''),
+            array('Il y a 10 pommes', '{0} There are no appless|{1} There is one apple|]1,Inf] There is %count% apples', '[0,1] Il y a %count% pomme|]1,Inf] Il y a %count% pommes', 10, array('%count%' => 10), 'fr', ''),
+
+            array('Il y a 0 pomme', 'There is one apple|There is %count% apples', 'Il y a %count% pomme|Il y a %count% pommes', 0, array('%count%' => 0), 'fr', ''),
+            array('Il y a 1 pomme', 'There is one apple|There is %count% apples', 'Il y a %count% pomme|Il y a %count% pommes', 1, array('%count%' => 1), 'fr', ''),
+            array('Il y a 10 pommes', 'There is one apple|There is %count% apples', 'Il y a %count% pomme|Il y a %count% pommes', 10, array('%count%' => 10), 'fr', ''),
+
+            array('Il y a 0 pomme', 'one: There is one apple|more: There is %count% apples', 'one: Il y a %count% pomme|more: Il y a %count% pommes', 0, array('%count%' => 0), 'fr', ''),
+            array('Il y a 1 pomme', 'one: There is one apple|more: There is %count% apples', 'one: Il y a %count% pomme|more: Il y a %count% pommes', 1, array('%count%' => 1), 'fr', ''),
+            array('Il y a 10 pommes', 'one: There is one apple|more: There is %count% apples', 'one: Il y a %count% pomme|more: Il y a %count% pommes', 10, array('%count%' => 10), 'fr', ''),
+
+            array('Il n\'y a aucune pomme', '{0} There are no apples|one: There is one apple|more: There is %count% apples', '{0} Il n\'y a aucune pomme|one: Il y a %count% pomme|more: Il y a %count% pommes', 0, array('%count%' => 0), 'fr', ''),
+            array('Il y a 1 pomme', '{0} There are no apples|one: There is one apple|more: There is %count% apples', '{0} Il n\'y a aucune pomme|one: Il y a %count% pomme|more: Il y a %count% pommes', 1, array('%count%' => 1), 'fr', ''),
+            array('Il y a 10 pommes', '{0} There are no apples|one: There is one apple|more: There is %count% apples', '{0} Il n\'y a aucune pomme|one: Il y a %count% pomme|more: Il y a %count% pommes', 10, array('%count%' => 10), 'fr', ''),
+
+            array('Il y a 0 pomme', new StringClass('{0} There are no appless|{1} There is one apple|]1,Inf] There is %count% apples'), '[0,1] Il y a %count% pomme|]1,Inf] Il y a %count% pommes', 0, array('%count%' => 0), 'fr', ''),
+        );
+    }
+
+    public function getInvalidLocalesTests()
+    {
+        return array(
+            array('fr FR'),
+            array('français'),
+            array('fr+en'),
+            array('utf#8'),
+            array('fr&en'),
+            array('fr~FR'),
+            array(' fr'),
+            array('fr '),
+            array('fr*'),
+            array('fr/FR'),
+            array('fr\\FR'),
+        );
+    }
+
+    public function getValidLocalesTests()
+    {
+        return array(
+            array(''),
+            array(null),
+            array('fr'),
+            array('francais'),
+            array('FR'),
+            array('frFR'),
+            array('fr-FR'),
+            array('fr_FR'),
+            array('fr.FR'),
+            array('fr-FR.UTF8'),
+            array('sr@latin'),
+        );
+    }
+
+    public function testTransChoiceFallback()
+    {
+        $translator = new Translator('ru');
+        $translator->setFallbackLocales(array('en'));
+        $translator->addLoader('array', new ArrayLoader());
+        $translator->addResource('array', array('some_message2' => 'one thing|%count% things'), 'en');
+
+        $this->assertEquals('10 things', $translator->transChoice('some_message2', 10, array('%count%' => 10)));
+    }
+
+    public function testTransChoiceFallbackBis()
+    {
+        $translator = new Translator('ru');
+        $translator->setFallbackLocales(array('en_US', 'en'));
+        $translator->addLoader('array', new ArrayLoader());
+        $translator->addResource('array', array('some_message2' => 'one thing|%count% things'), 'en_US');
+
+        $this->assertEquals('10 things', $translator->transChoice('some_message2', 10, array('%count%' => 10)));
+    }
+
+    public function testTransChoiceFallbackWithNoTranslation()
+    {
+        $translator = new Translator('ru');
+        $translator->setFallbackLocales(array('en'));
+        $translator->addLoader('array', new ArrayLoader());
+
+        // consistent behavior with Translator::trans(), which returns the string
+        // unchanged if it can't be found
+        $this->assertEquals('some_message2', $translator->transChoice('some_message2', 10, array('%count%' => 10)));
+    }
+
+    /**
+     * @dataProvider dataProviderGetMessages
+     */
+    public function testGetMessages($resources, $locale, $expected)
+    {
+        $locales = array_keys($resources);
+        $_locale = null !== $locale ? $locale : reset($locales);
+        $locales = array_slice($locales, 0, array_search($_locale, $locales));
+
+        $translator = new Translator($_locale, new MessageSelector());
+        $translator->setFallbackLocales(array_reverse($locales));
+        $translator->addLoader('array', new ArrayLoader());
+        foreach ($resources as $_locale => $domainMessages) {
+            foreach ($domainMessages as $domain => $messages) {
+                $translator->addResource('array', $messages, $_locale, $domain);
+            }
+        }
+        $result = $translator->getMessages($locale);
+
+        $this->assertEquals($expected, $result);
+    }
+
+    public function dataProviderGetMessages()
+    {
+        $resources = array(
+            'en' => array(
+                'jsmessages' => array(
+                    'foo' => 'foo (EN)',
+                    'bar' => 'bar (EN)',
+                ),
+                'messages' => array(
+                    'foo' => 'foo messages (EN)',
+                ),
+                'validators' => array(
+                    'int' => 'integer (EN)',
+                ),
+            ),
+            'pt-PT' => array(
+                'messages' => array(
+                    'foo' => 'foo messages (PT)',
+                ),
+                'validators' => array(
+                    'str' => 'integer (PT)',
+                ),
+            ),
+            'pt_BR' => array(
+                'validators' => array(
+                    'int' => 'integer (BR)',
+                ),
+            ),
+        );
+
+        return array(
+            array($resources, null,
+                array(
+                    'jsmessages' => array(
+                        'foo' => 'foo (EN)',
+                        'bar' => 'bar (EN)',
+                    ),
+                    'messages' => array(
+                        'foo' => 'foo messages (EN)',
+                    ),
+                    'validators' => array(
+                        'int' => 'integer (EN)',
+                    ),
+                ),
+            ),
+            array($resources, 'en',
+                array(
+                    'jsmessages' => array(
+                        'foo' => 'foo (EN)',
+                        'bar' => 'bar (EN)',
+                    ),
+                    'messages' => array(
+                        'foo' => 'foo messages (EN)',
+                    ),
+                    'validators' => array(
+                        'int' => 'integer (EN)',
+                    ),
+                ),
+            ),
+            array($resources, 'pt-PT',
+                array(
+                    'jsmessages' => array(
+                        'foo' => 'foo (EN)',
+                        'bar' => 'bar (EN)',
+                    ),
+                    'messages' => array(
+                        'foo' => 'foo messages (PT)',
+                    ),
+                    'validators' => array(
+                        'int' => 'integer (EN)',
+                        'str' => 'integer (PT)',
+                    ),
+                ),
+            ),
+            array($resources, 'pt_BR',
+                array(
+                    'jsmessages' => array(
+                        'foo' => 'foo (EN)',
+                        'bar' => 'bar (EN)',
+                    ),
+                    'messages' => array(
+                        'foo' => 'foo messages (PT)',
+                    ),
+                    'validators' => array(
+                        'int' => 'integer (BR)',
+                        'str' => 'integer (PT)',
+                    ),
+                ),
+            ),
+        );
+    }
+}
+
+class StringClass
+{
+    protected $str;
+
+    public function __construct($str)
+    {
+        $this->str = $str;
+    }
+
+    public function __toString()
+    {
+        return $this->str;
+    }
+}
diff --git a/core/vendor/symfony/translation/Tests/fixtures/empty-translation.mo b/core/vendor/symfony/translation/Tests/fixtures/empty-translation.mo
new file mode 100644
index 0000000000000000000000000000000000000000..ed01000c9b1b3fdf40fc2369a7799e72e41a1edf
Binary files /dev/null and b/core/vendor/symfony/translation/Tests/fixtures/empty-translation.mo differ
diff --git a/core/vendor/symfony/translation/Tests/fixtures/empty-translation.po b/core/vendor/symfony/translation/Tests/fixtures/empty-translation.po
new file mode 100644
index 0000000000000000000000000000000000000000..ff6f22afb1c98ce736da5876cdb7dcbbb3219417
--- /dev/null
+++ b/core/vendor/symfony/translation/Tests/fixtures/empty-translation.po
@@ -0,0 +1,3 @@
+msgid "foo"
+msgstr ""
+
diff --git a/core/vendor/symfony/translation/Tests/fixtures/empty.csv b/core/vendor/symfony/translation/Tests/fixtures/empty.csv
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/core/vendor/symfony/translation/Tests/fixtures/empty.ini b/core/vendor/symfony/translation/Tests/fixtures/empty.ini
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/core/vendor/symfony/translation/Tests/fixtures/empty.json b/core/vendor/symfony/translation/Tests/fixtures/empty.json
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/core/vendor/symfony/translation/Tests/fixtures/empty.mo b/core/vendor/symfony/translation/Tests/fixtures/empty.mo
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/core/vendor/symfony/translation/Tests/fixtures/empty.po b/core/vendor/symfony/translation/Tests/fixtures/empty.po
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/core/vendor/symfony/translation/Tests/fixtures/empty.xlf b/core/vendor/symfony/translation/Tests/fixtures/empty.xlf
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/core/vendor/symfony/translation/Tests/fixtures/empty.yml b/core/vendor/symfony/translation/Tests/fixtures/empty.yml
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/core/vendor/symfony/translation/Tests/fixtures/encoding.xlf b/core/vendor/symfony/translation/Tests/fixtures/encoding.xlf
new file mode 100644
index 0000000000000000000000000000000000000000..0a88f9265052e53c6cc080ce040660e8e20b331a
--- /dev/null
+++ b/core/vendor/symfony/translation/Tests/fixtures/encoding.xlf
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
+  <file source-language="en" datatype="plaintext" original="file.ext">
+    <body>
+      <trans-unit id="1" resname="foo">
+        <source>foo</source>
+        <target>bär</target>
+        <note>bäz</note>
+      </trans-unit>
+      <trans-unit id="2" resname="bar">
+        <source>bar</source>
+        <target>föö</target>
+      </trans-unit>
+    </body>
+  </file>
+</xliff>
diff --git a/core/vendor/symfony/translation/Tests/fixtures/escaped-id-plurals.po b/core/vendor/symfony/translation/Tests/fixtures/escaped-id-plurals.po
new file mode 100644
index 0000000000000000000000000000000000000000..c412aa26ec89c9a7a5cc5da72e10d68158c9145d
--- /dev/null
+++ b/core/vendor/symfony/translation/Tests/fixtures/escaped-id-plurals.po
@@ -0,0 +1,10 @@
+msgid ""
+msgstr ""
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: en\n"
+
+msgid "escaped \"foo\""
+msgid_plural "escaped \"foos\""
+msgstr[0] "escaped \"bar\""
+msgstr[1] "escaped \"bars\""
diff --git a/core/vendor/symfony/translation/Tests/fixtures/escaped-id.po b/core/vendor/symfony/translation/Tests/fixtures/escaped-id.po
new file mode 100644
index 0000000000000000000000000000000000000000..308eadd92659e0faad84c40cf3e254e48ad77538
--- /dev/null
+++ b/core/vendor/symfony/translation/Tests/fixtures/escaped-id.po
@@ -0,0 +1,8 @@
+msgid ""
+msgstr ""
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: en\n"
+
+msgid "escaped \"foo\""
+msgstr "escaped \"bar\""
diff --git a/core/vendor/symfony/translation/Tests/fixtures/invalid-xml-resources.xlf b/core/vendor/symfony/translation/Tests/fixtures/invalid-xml-resources.xlf
new file mode 100644
index 0000000000000000000000000000000000000000..7bf6c98ba3309950f94204558750a1ac27dc83fe
--- /dev/null
+++ b/core/vendor/symfony/translation/Tests/fixtures/invalid-xml-resources.xlf
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
+    <file source-language="en" datatype="plaintext" original="file.ext">
+        <body>
+            <trans-unit id="1">
+                <source>foo</source>
+                <target>bar
+            </trans-unit>
+            <trans-unit id="2">
+                <source>extra</source>
+            </trans-unit>
+            <trans-unit id="3">
+                <source>key</source>
+                <target></target>
+            </trans-unit>
+            <trans-unit id="4">
+                <source>test</source>
+                <target>with</target>
+                <note>note</note>
+            </trans-unit>
+        </body>
+    </file>
+</xliff>
diff --git a/core/vendor/symfony/translation/Tests/fixtures/malformed.json b/core/vendor/symfony/translation/Tests/fixtures/malformed.json
new file mode 100644
index 0000000000000000000000000000000000000000..4563ec6da8d9fe2357bd7cf6a3d9524ec629ff8f
--- /dev/null
+++ b/core/vendor/symfony/translation/Tests/fixtures/malformed.json
@@ -0,0 +1,3 @@
+{
+    "foo" "bar"
+}
\ No newline at end of file
diff --git a/core/vendor/symfony/translation/Tests/fixtures/non-valid.xlf b/core/vendor/symfony/translation/Tests/fixtures/non-valid.xlf
new file mode 100644
index 0000000000000000000000000000000000000000..734fc97e413c736c14f2dca3aed47ad780fde20e
--- /dev/null
+++ b/core/vendor/symfony/translation/Tests/fixtures/non-valid.xlf
@@ -0,0 +1,11 @@
+<?xml version="1.0"?>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+    <file source-language="en" datatype="plaintext" original="file.ext">
+        <body>
+            <trans-unit>
+                <source>foo</source>
+                <target>bar</target>
+            </trans-unit>
+        </body>
+    </file>
+</xliff>
diff --git a/core/vendor/symfony/translation/Tests/fixtures/non-valid.yml b/core/vendor/symfony/translation/Tests/fixtures/non-valid.yml
new file mode 100644
index 0000000000000000000000000000000000000000..257cc5642cb1a054f08cc83f2d943e56fd3ebe99
--- /dev/null
+++ b/core/vendor/symfony/translation/Tests/fixtures/non-valid.yml
@@ -0,0 +1 @@
+foo
diff --git a/core/vendor/symfony/translation/Tests/fixtures/plurals.mo b/core/vendor/symfony/translation/Tests/fixtures/plurals.mo
new file mode 100644
index 0000000000000000000000000000000000000000..6445e77beab595289cd154ea253c4e49dfd6af47
Binary files /dev/null and b/core/vendor/symfony/translation/Tests/fixtures/plurals.mo differ
diff --git a/core/vendor/symfony/translation/Tests/fixtures/plurals.po b/core/vendor/symfony/translation/Tests/fixtures/plurals.po
new file mode 100644
index 0000000000000000000000000000000000000000..439c41ad7fef4bc29f09cb011c01e15e54b1c778
--- /dev/null
+++ b/core/vendor/symfony/translation/Tests/fixtures/plurals.po
@@ -0,0 +1,5 @@
+msgid "foo"
+msgid_plural "foos"
+msgstr[0] "bar"
+msgstr[1] "bars"
+
diff --git a/core/vendor/symfony/translation/Tests/fixtures/resname.xlf b/core/vendor/symfony/translation/Tests/fixtures/resname.xlf
new file mode 100644
index 0000000000000000000000000000000000000000..2df16af942f4348158a46090268b9b8a4631413d
--- /dev/null
+++ b/core/vendor/symfony/translation/Tests/fixtures/resname.xlf
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
+  <file source-language="en" datatype="plaintext" original="file.ext">
+    <body>
+      <trans-unit id="1" resname="foo">
+        <source></source>
+        <target>bar</target>
+      </trans-unit>
+      <trans-unit id="2" resname="bar">
+        <source>bar source</source>
+        <target>baz</target>
+      </trans-unit>
+      <trans-unit id="3">
+        <source>baz</source>
+        <target>foo</target>
+      </trans-unit>
+    </body>
+  </file>
+</xliff>
diff --git a/core/vendor/symfony/translation/Tests/fixtures/resourcebundle/corrupted/resources.dat b/core/vendor/symfony/translation/Tests/fixtures/resourcebundle/corrupted/resources.dat
new file mode 100644
index 0000000000000000000000000000000000000000..391250caa0ad639a4ff3420607b7cef8241a15ae
--- /dev/null
+++ b/core/vendor/symfony/translation/Tests/fixtures/resourcebundle/corrupted/resources.dat
@@ -0,0 +1 @@
+XXX
\ No newline at end of file
diff --git a/core/vendor/symfony/translation/Tests/fixtures/resourcebundle/dat/en.res b/core/vendor/symfony/translation/Tests/fixtures/resourcebundle/dat/en.res
new file mode 100644
index 0000000000000000000000000000000000000000..1fc1436d6641b7290ad5d9f4d331111e4a0419dd
Binary files /dev/null and b/core/vendor/symfony/translation/Tests/fixtures/resourcebundle/dat/en.res differ
diff --git a/core/vendor/symfony/translation/Tests/fixtures/resourcebundle/dat/en.txt b/core/vendor/symfony/translation/Tests/fixtures/resourcebundle/dat/en.txt
new file mode 100644
index 0000000000000000000000000000000000000000..3d9e9eae1c95686295064d6859ffbfd9b84fd49e
--- /dev/null
+++ b/core/vendor/symfony/translation/Tests/fixtures/resourcebundle/dat/en.txt
@@ -0,0 +1,3 @@
+en{
+    symfony{"Symfony is great"}
+}
\ No newline at end of file
diff --git a/core/vendor/symfony/translation/Tests/fixtures/resourcebundle/dat/fr.res b/core/vendor/symfony/translation/Tests/fixtures/resourcebundle/dat/fr.res
new file mode 100644
index 0000000000000000000000000000000000000000..f58416094be89f5fb64f78f6c3b873c6458696d0
Binary files /dev/null and b/core/vendor/symfony/translation/Tests/fixtures/resourcebundle/dat/fr.res differ
diff --git a/core/vendor/symfony/translation/Tests/fixtures/resourcebundle/dat/fr.txt b/core/vendor/symfony/translation/Tests/fixtures/resourcebundle/dat/fr.txt
new file mode 100644
index 0000000000000000000000000000000000000000..182d0a0de3f7e6e9c6a0561d640d013f2d3b8502
--- /dev/null
+++ b/core/vendor/symfony/translation/Tests/fixtures/resourcebundle/dat/fr.txt
@@ -0,0 +1,3 @@
+fr{
+    symfony{"Symfony est génial"}
+}
\ No newline at end of file
diff --git a/core/vendor/symfony/translation/Tests/fixtures/resourcebundle/dat/packagelist.txt b/core/vendor/symfony/translation/Tests/fixtures/resourcebundle/dat/packagelist.txt
new file mode 100644
index 0000000000000000000000000000000000000000..c5783ed4315abfd9186c4c5c4459c283de0b5f07
--- /dev/null
+++ b/core/vendor/symfony/translation/Tests/fixtures/resourcebundle/dat/packagelist.txt
@@ -0,0 +1,2 @@
+en.res
+fr.res
diff --git a/core/vendor/symfony/translation/Tests/fixtures/resourcebundle/dat/resources.dat b/core/vendor/symfony/translation/Tests/fixtures/resourcebundle/dat/resources.dat
new file mode 100644
index 0000000000000000000000000000000000000000..563b0eaef2e5a0a6e9623bf7b93b44beb0a7dc27
Binary files /dev/null and b/core/vendor/symfony/translation/Tests/fixtures/resourcebundle/dat/resources.dat differ
diff --git a/core/vendor/symfony/translation/Tests/fixtures/resourcebundle/res/en.res b/core/vendor/symfony/translation/Tests/fixtures/resourcebundle/res/en.res
new file mode 100644
index 0000000000000000000000000000000000000000..ad894a92be2d5392136de413bc2cb5ea8a94bfb1
Binary files /dev/null and b/core/vendor/symfony/translation/Tests/fixtures/resourcebundle/res/en.res differ
diff --git a/core/vendor/symfony/translation/Tests/fixtures/resources-clean.xlf b/core/vendor/symfony/translation/Tests/fixtures/resources-clean.xlf
new file mode 100644
index 0000000000000000000000000000000000000000..4ce15af2f5f71daea2f468b12ec079fd8492a2c0
--- /dev/null
+++ b/core/vendor/symfony/translation/Tests/fixtures/resources-clean.xlf
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
+  <file source-language="fr-FR" target-language="en-US" datatype="plaintext" original="file.ext">
+    <body>
+      <trans-unit id="acbd18db4cc2f85cedef654fccc4a4d8" resname="foo">
+        <source>foo</source>
+        <target>bar</target>
+        <note priority="1" from="bar">baz</note>
+      </trans-unit>
+      <trans-unit id="3c6e0b8a9c15224a8228b9a98ca1531d" resname="key">
+        <source>key</source>
+        <target></target>
+        <note>baz</note>
+        <note>qux</note>
+      </trans-unit>
+      <trans-unit id="18e6a493872558d949b4c16ea1fa6ab6" resname="key.with.cdata">
+        <source>key.with.cdata</source>
+        <target><![CDATA[<source> & <target>]]></target>
+      </trans-unit>
+    </body>
+  </file>
+</xliff>
diff --git a/core/vendor/symfony/translation/Tests/fixtures/resources.csv b/core/vendor/symfony/translation/Tests/fixtures/resources.csv
new file mode 100644
index 0000000000000000000000000000000000000000..374b9eb5eb68e8f20ee26def7ea8bbf9c18ebd0f
--- /dev/null
+++ b/core/vendor/symfony/translation/Tests/fixtures/resources.csv
@@ -0,0 +1,4 @@
+"foo"; "bar"
+#"bar"; "foo"
+"incorrect"; "number"; "columns"; "will"; "be"; "ignored"
+"incorrect"
\ No newline at end of file
diff --git a/core/vendor/symfony/translation/Tests/fixtures/resources.ini b/core/vendor/symfony/translation/Tests/fixtures/resources.ini
new file mode 100644
index 0000000000000000000000000000000000000000..4953062e69e5d3ba43f30765783621197fa45529
--- /dev/null
+++ b/core/vendor/symfony/translation/Tests/fixtures/resources.ini
@@ -0,0 +1 @@
+foo="bar"
diff --git a/core/vendor/symfony/translation/Tests/fixtures/resources.json b/core/vendor/symfony/translation/Tests/fixtures/resources.json
new file mode 100644
index 0000000000000000000000000000000000000000..8a79687628fe86b467ec0e87e7e155c4661caa4f
--- /dev/null
+++ b/core/vendor/symfony/translation/Tests/fixtures/resources.json
@@ -0,0 +1,3 @@
+{
+    "foo": "bar"
+}
\ No newline at end of file
diff --git a/core/vendor/symfony/translation/Tests/fixtures/resources.mo b/core/vendor/symfony/translation/Tests/fixtures/resources.mo
new file mode 100644
index 0000000000000000000000000000000000000000..0a9660257c07afef243a011d9806d6217e4f1379
Binary files /dev/null and b/core/vendor/symfony/translation/Tests/fixtures/resources.mo differ
diff --git a/core/vendor/symfony/translation/Tests/fixtures/resources.php b/core/vendor/symfony/translation/Tests/fixtures/resources.php
new file mode 100644
index 0000000000000000000000000000000000000000..c2913985391cb6d33df2ccadc187876b516d310d
--- /dev/null
+++ b/core/vendor/symfony/translation/Tests/fixtures/resources.php
@@ -0,0 +1,5 @@
+<?php
+
+return array (
+  'foo' => 'bar',
+);
diff --git a/core/vendor/symfony/translation/Tests/fixtures/resources.po b/core/vendor/symfony/translation/Tests/fixtures/resources.po
new file mode 100644
index 0000000000000000000000000000000000000000..ccfce6bb98d466a78252d2d0b420213d213c495c
--- /dev/null
+++ b/core/vendor/symfony/translation/Tests/fixtures/resources.po
@@ -0,0 +1,8 @@
+msgid ""
+msgstr ""
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: en\n"
+
+msgid "foo"
+msgstr "bar"
\ No newline at end of file
diff --git a/core/vendor/symfony/translation/Tests/fixtures/resources.ts b/core/vendor/symfony/translation/Tests/fixtures/resources.ts
new file mode 100644
index 0000000000000000000000000000000000000000..40e18522c85b61912b25b052d061c957b8cc2336
--- /dev/null
+++ b/core/vendor/symfony/translation/Tests/fixtures/resources.ts
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<TS>
+  <context>
+    <name>resources</name>
+    <message>
+      <source>foo</source>
+      <translation>bar</translation>
+    </message>
+  </context>
+</TS>
diff --git a/core/vendor/symfony/translation/Tests/fixtures/resources.xlf b/core/vendor/symfony/translation/Tests/fixtures/resources.xlf
new file mode 100644
index 0000000000000000000000000000000000000000..b0e59880f889414f3734de99c19d5abbc6c67ecd
--- /dev/null
+++ b/core/vendor/symfony/translation/Tests/fixtures/resources.xlf
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
+  <file source-language="en" datatype="plaintext" original="file.ext">
+    <body>
+      <trans-unit id="1">
+        <source>foo</source>
+        <target>bar</target>
+      </trans-unit>
+      <trans-unit id="2">
+        <source>extra</source>
+      </trans-unit>
+      <trans-unit id="3">
+        <source>key</source>
+        <target></target>
+      </trans-unit>
+      <trans-unit id="4">
+        <source>test</source>
+        <target>with</target>
+        <note>note</note>
+      </trans-unit>
+    </body>
+  </file>
+</xliff>
diff --git a/core/vendor/symfony/translation/Tests/fixtures/resources.yml b/core/vendor/symfony/translation/Tests/fixtures/resources.yml
new file mode 100644
index 0000000000000000000000000000000000000000..20e9ff3feaa8ede30f707e5f1b4356e3c02bb7ec
--- /dev/null
+++ b/core/vendor/symfony/translation/Tests/fixtures/resources.yml
@@ -0,0 +1 @@
+foo: bar
diff --git a/core/vendor/symfony/translation/Tests/fixtures/valid.csv b/core/vendor/symfony/translation/Tests/fixtures/valid.csv
new file mode 100644
index 0000000000000000000000000000000000000000..59882e5da4d94c9643a3d8680154ce6981c9a977
--- /dev/null
+++ b/core/vendor/symfony/translation/Tests/fixtures/valid.csv
@@ -0,0 +1,4 @@
+foo;bar
+bar;"foo
+foo"
+"foo;foo";bar
diff --git a/core/vendor/symfony/translation/Tests/fixtures/withdoctype.xlf b/core/vendor/symfony/translation/Tests/fixtures/withdoctype.xlf
new file mode 100644
index 0000000000000000000000000000000000000000..f83e834ddc4772f66498c0cb44262708f683d2b2
--- /dev/null
+++ b/core/vendor/symfony/translation/Tests/fixtures/withdoctype.xlf
@@ -0,0 +1,12 @@
+<?xml version="1.0"?>
+<!DOCTYPE foo>
+<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
+    <file source-language="en" datatype="plaintext" original="file.ext">
+        <body>
+            <trans-unit id="1">
+                <source>foo</source>
+                <target>bar</target>
+            </trans-unit>
+        </body>
+    </file>
+</xliff>
diff --git a/core/vendor/symfony/translation/Tests/fixtures/withnote.xlf b/core/vendor/symfony/translation/Tests/fixtures/withnote.xlf
new file mode 100644
index 0000000000000000000000000000000000000000..b1d3f83a0c7148aee05e70eac73d553029c630d2
--- /dev/null
+++ b/core/vendor/symfony/translation/Tests/fixtures/withnote.xlf
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
+  <file source-language="en" datatype="plaintext" original="file.ext">
+    <body>
+      <trans-unit id="1">
+        <source>foo</source>
+        <target>bar</target>
+        <note priority="1">foo</note>
+      </trans-unit>
+      <trans-unit id="2">
+        <source>extra</source>
+        <note from="foo">bar</note>
+      </trans-unit>
+      <trans-unit id="3">
+        <source>key</source>
+        <target></target>
+        <note>baz</note>
+        <note priority="2" from="bar">qux</note>
+      </trans-unit>
+    </body>
+  </file>
+</xliff>
diff --git a/core/vendor/symfony/translation/Translator.php b/core/vendor/symfony/translation/Translator.php
new file mode 100644
index 0000000000000000000000000000000000000000..63e116491f5e02b5cf043d11aead27acc949cca5
--- /dev/null
+++ b/core/vendor/symfony/translation/Translator.php
@@ -0,0 +1,500 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation;
+
+use Symfony\Component\Translation\Loader\LoaderInterface;
+use Symfony\Component\Translation\Exception\NotFoundResourceException;
+use Symfony\Component\Config\ConfigCacheInterface;
+use Symfony\Component\Config\ConfigCacheFactoryInterface;
+use Symfony\Component\Config\ConfigCacheFactory;
+
+/**
+ * Translator.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ *
+ * @api
+ */
+class Translator implements TranslatorInterface, TranslatorBagInterface
+{
+    /**
+     * @var MessageCatalogueInterface[]
+     */
+    protected $catalogues = array();
+
+    /**
+     * @var string
+     */
+    protected $locale;
+
+    /**
+     * @var array
+     */
+    private $fallbackLocales = array();
+
+    /**
+     * @var LoaderInterface[]
+     */
+    private $loaders = array();
+
+    /**
+     * @var array
+     */
+    private $resources = array();
+
+    /**
+     * @var MessageSelector
+     */
+    private $selector;
+
+    /**
+     * @var string
+     */
+    private $cacheDir;
+
+    /**
+     * @var bool
+     */
+    private $debug;
+
+    /**
+     * @var ConfigCacheFactoryInterface|null
+     */
+    private $configCacheFactory;
+
+    /**
+     * Constructor.
+     *
+     * @param string               $locale   The locale
+     * @param MessageSelector|null $selector The message selector for pluralization
+     * @param string|null          $cacheDir The directory to use for the cache
+     * @param bool                 $debug    Use cache in debug mode ?
+     *
+     * @throws \InvalidArgumentException If a locale contains invalid characters
+     *
+     * @api
+     */
+    public function __construct($locale, MessageSelector $selector = null, $cacheDir = null, $debug = false)
+    {
+        $this->setLocale($locale);
+        $this->selector = $selector ?: new MessageSelector();
+        $this->cacheDir = $cacheDir;
+        $this->debug = $debug;
+    }
+
+    /**
+     * Sets the ConfigCache factory to use.
+     *
+     * @param ConfigCacheFactoryInterface $configCacheFactory
+     */
+    public function setConfigCacheFactory(ConfigCacheFactoryInterface $configCacheFactory)
+    {
+        $this->configCacheFactory = $configCacheFactory;
+    }
+
+    /**
+     * Adds a Loader.
+     *
+     * @param string          $format The name of the loader (@see addResource())
+     * @param LoaderInterface $loader A LoaderInterface instance
+     *
+     * @api
+     */
+    public function addLoader($format, LoaderInterface $loader)
+    {
+        $this->loaders[$format] = $loader;
+    }
+
+    /**
+     * Adds a Resource.
+     *
+     * @param string $format   The name of the loader (@see addLoader())
+     * @param mixed  $resource The resource name
+     * @param string $locale   The locale
+     * @param string $domain   The domain
+     *
+     * @throws \InvalidArgumentException If the locale contains invalid characters
+     *
+     * @api
+     */
+    public function addResource($format, $resource, $locale, $domain = null)
+    {
+        if (null === $domain) {
+            $domain = 'messages';
+        }
+
+        $this->assertValidLocale($locale);
+
+        $this->resources[$locale][] = array($format, $resource, $domain);
+
+        if (in_array($locale, $this->fallbackLocales)) {
+            $this->catalogues = array();
+        } else {
+            unset($this->catalogues[$locale]);
+        }
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @api
+     */
+    public function setLocale($locale)
+    {
+        $this->assertValidLocale($locale);
+        $this->locale = $locale;
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @api
+     */
+    public function getLocale()
+    {
+        return $this->locale;
+    }
+
+    /**
+     * Sets the fallback locale(s).
+     *
+     * @param string|array $locales The fallback locale(s)
+     *
+     * @throws \InvalidArgumentException If a locale contains invalid characters
+     *
+     * @deprecated since version 2.3, to be removed in 3.0. Use setFallbackLocales() instead.
+     *
+     * @api
+     */
+    public function setFallbackLocale($locales)
+    {
+        @trigger_error('The '.__METHOD__.' method is deprecated since version 2.3 and will be removed in 3.0. Use the setFallbackLocales() method instead.', E_USER_DEPRECATED);
+
+        $this->setFallbackLocales(is_array($locales) ? $locales : array($locales));
+    }
+
+    /**
+     * Sets the fallback locales.
+     *
+     * @param array $locales The fallback locales
+     *
+     * @throws \InvalidArgumentException If a locale contains invalid characters
+     *
+     * @api
+     */
+    public function setFallbackLocales(array $locales)
+    {
+        // needed as the fallback locales are linked to the already loaded catalogues
+        $this->catalogues = array();
+
+        foreach ($locales as $locale) {
+            $this->assertValidLocale($locale);
+        }
+
+        $this->fallbackLocales = $locales;
+    }
+
+    /**
+     * Gets the fallback locales.
+     *
+     * @return array $locales The fallback locales
+     *
+     * @api
+     */
+    public function getFallbackLocales()
+    {
+        return $this->fallbackLocales;
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @api
+     */
+    public function trans($id, array $parameters = array(), $domain = null, $locale = null)
+    {
+        if (null === $domain) {
+            $domain = 'messages';
+        }
+
+        return strtr($this->getCatalogue($locale)->get((string) $id, $domain), $parameters);
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @api
+     */
+    public function transChoice($id, $number, array $parameters = array(), $domain = null, $locale = null)
+    {
+        if (null === $domain) {
+            $domain = 'messages';
+        }
+
+        $id = (string) $id;
+        $catalogue = $this->getCatalogue($locale);
+        $locale = $catalogue->getLocale();
+        while (!$catalogue->defines($id, $domain)) {
+            if ($cat = $catalogue->getFallbackCatalogue()) {
+                $catalogue = $cat;
+                $locale = $catalogue->getLocale();
+            } else {
+                break;
+            }
+        }
+
+        return strtr($this->selector->choose($catalogue->get($id, $domain), (int) $number, $locale), $parameters);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getCatalogue($locale = null)
+    {
+        if (null === $locale) {
+            $locale = $this->getLocale();
+        } else {
+            $this->assertValidLocale($locale);
+        }
+
+        if (!isset($this->catalogues[$locale])) {
+            $this->loadCatalogue($locale);
+        }
+
+        return $this->catalogues[$locale];
+    }
+
+    /**
+     * Gets the loaders.
+     *
+     * @return array LoaderInterface[]
+     */
+    protected function getLoaders()
+    {
+        return $this->loaders;
+    }
+
+    /**
+     * Collects all messages for the given locale.
+     *
+     * @param string|null $locale Locale of translations, by default is current locale
+     *
+     * @return array[array] indexed by catalog
+     */
+    public function getMessages($locale = null)
+    {
+        $catalogue = $this->getCatalogue($locale);
+        $messages = $catalogue->all();
+        while ($catalogue = $catalogue->getFallbackCatalogue()) {
+            $messages = array_replace_recursive($catalogue->all(), $messages);
+        }
+
+        return $messages;
+    }
+
+    /**
+     * @param string $locale
+     */
+    protected function loadCatalogue($locale)
+    {
+        if (null === $this->cacheDir) {
+            $this->initializeCatalogue($locale);
+        } else {
+            $this->initializeCacheCatalogue($locale);
+        }
+    }
+
+    /**
+     * @param string $locale
+     */
+    protected function initializeCatalogue($locale)
+    {
+        $this->assertValidLocale($locale);
+
+        try {
+            $this->doLoadCatalogue($locale);
+        } catch (NotFoundResourceException $e) {
+            if (!$this->computeFallbackLocales($locale)) {
+                throw $e;
+            }
+        }
+        $this->loadFallbackCatalogues($locale);
+    }
+
+    /**
+     * @param string $locale
+     */
+    private function initializeCacheCatalogue($locale)
+    {
+        if (isset($this->catalogues[$locale])) {
+            /* Catalogue already initialized. */
+            return;
+        }
+
+        $this->assertValidLocale($locale);
+        $self = $this; // required for PHP 5.3 where "$this" cannot be use()d in anonymous functions. Change in Symfony 3.0.
+        $cache = $this->getConfigCacheFactory()->cache($this->getCatalogueCachePath($locale),
+            function (ConfigCacheInterface $cache) use ($self, $locale) {
+                $self->dumpCatalogue($locale, $cache);
+            }
+        );
+
+        if (isset($this->catalogues[$locale])) {
+            /* Catalogue has been initialized as it was written out to cache. */
+            return;
+        }
+
+        /* Read catalogue from cache. */
+        $this->catalogues[$locale] = include $cache->getPath();
+    }
+
+    /**
+     * This method is public because it needs to be callable from a closure in PHP 5.3. It should be made protected (or even private, if possible) in 3.0.
+     *
+     * @internal
+     */
+    public function dumpCatalogue($locale, ConfigCacheInterface $cache)
+    {
+        $this->initializeCatalogue($locale);
+        $fallbackContent = $this->getFallbackContent($this->catalogues[$locale]);
+
+        $content = sprintf(<<<EOF
+<?php
+
+use Symfony\Component\Translation\MessageCatalogue;
+
+\$catalogue = new MessageCatalogue('%s', %s);
+
+%s
+return \$catalogue;
+
+EOF
+            ,
+            $locale,
+            var_export($this->catalogues[$locale]->all(), true),
+            $fallbackContent
+        );
+
+        $cache->write($content, $this->catalogues[$locale]->getResources());
+    }
+
+    private function getFallbackContent(MessageCatalogue $catalogue)
+    {
+        $fallbackContent = '';
+        $current = '';
+        $replacementPattern = '/[^a-z0-9_]/i';
+        $fallbackCatalogue = $catalogue->getFallbackCatalogue();
+        while ($fallbackCatalogue) {
+            $fallback = $fallbackCatalogue->getLocale();
+            $fallbackSuffix = ucfirst(preg_replace($replacementPattern, '_', $fallback));
+            $currentSuffix = ucfirst(preg_replace($replacementPattern, '_', $current));
+
+            $fallbackContent .= sprintf(<<<EOF
+\$catalogue%s = new MessageCatalogue('%s', %s);
+\$catalogue%s->addFallbackCatalogue(\$catalogue%s);
+
+EOF
+                ,
+                $fallbackSuffix,
+                $fallback,
+                var_export($fallbackCatalogue->all(), true),
+                $currentSuffix,
+                $fallbackSuffix
+            );
+            $current = $fallbackCatalogue->getLocale();
+            $fallbackCatalogue = $fallbackCatalogue->getFallbackCatalogue();
+        }
+
+        return $fallbackContent;
+    }
+
+    private function getCatalogueCachePath($locale)
+    {
+        return $this->cacheDir.'/catalogue.'.$locale.'.'.sha1(serialize($this->fallbackLocales)).'.php';
+    }
+
+    private function doLoadCatalogue($locale)
+    {
+        $this->catalogues[$locale] = new MessageCatalogue($locale);
+
+        if (isset($this->resources[$locale])) {
+            foreach ($this->resources[$locale] as $resource) {
+                if (!isset($this->loaders[$resource[0]])) {
+                    throw new \RuntimeException(sprintf('The "%s" translation loader is not registered.', $resource[0]));
+                }
+                $this->catalogues[$locale]->addCatalogue($this->loaders[$resource[0]]->load($resource[1], $locale, $resource[2]));
+            }
+        }
+    }
+
+    private function loadFallbackCatalogues($locale)
+    {
+        $current = $this->catalogues[$locale];
+
+        foreach ($this->computeFallbackLocales($locale) as $fallback) {
+            if (!isset($this->catalogues[$fallback])) {
+                $this->doLoadCatalogue($fallback);
+            }
+
+            $fallbackCatalogue = new MessageCatalogue($fallback, $this->catalogues[$fallback]->all());
+            $current->addFallbackCatalogue($fallbackCatalogue);
+            $current = $fallbackCatalogue;
+        }
+    }
+
+    protected function computeFallbackLocales($locale)
+    {
+        $locales = array();
+        foreach ($this->fallbackLocales as $fallback) {
+            if ($fallback === $locale) {
+                continue;
+            }
+
+            $locales[] = $fallback;
+        }
+
+        if (strrchr($locale, '_') !== false) {
+            array_unshift($locales, substr($locale, 0, -strlen(strrchr($locale, '_'))));
+        }
+
+        return array_unique($locales);
+    }
+
+    /**
+     * Asserts that the locale is valid, throws an Exception if not.
+     *
+     * @param string $locale Locale to tests
+     *
+     * @throws \InvalidArgumentException If the locale contains invalid characters
+     */
+    protected function assertValidLocale($locale)
+    {
+        if (1 !== preg_match('/^[a-z0-9@_\\.\\-]*$/i', $locale)) {
+            throw new \InvalidArgumentException(sprintf('Invalid "%s" locale.', $locale));
+        }
+    }
+
+    /**
+     * Provides the ConfigCache factory implementation, falling back to a
+     * default implementation if necessary.
+     *
+     * @return ConfigCacheFactoryInterface $configCacheFactory
+     */
+    private function getConfigCacheFactory()
+    {
+        if (!$this->configCacheFactory) {
+            $this->configCacheFactory = new ConfigCacheFactory($this->debug);
+        }
+
+        return $this->configCacheFactory;
+    }
+}
diff --git a/core/vendor/symfony/translation/TranslatorBagInterface.php b/core/vendor/symfony/translation/TranslatorBagInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..6f650b5ee0f88ee1fc6a442e4948370c7612b2a7
--- /dev/null
+++ b/core/vendor/symfony/translation/TranslatorBagInterface.php
@@ -0,0 +1,31 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Translation;
+
+/**
+ * TranslatorBagInterface.
+ *
+ * @author Abdellatif Ait boudad <a.aitboudad@gmail.com>
+ */
+interface TranslatorBagInterface
+{
+    /**
+     * Gets the catalogue by locale.
+     *
+     * @param string|null $locale The locale or null to use the default
+     *
+     * @throws \InvalidArgumentException If the locale contains invalid characters
+     *
+     * @return MessageCatalogueInterface
+     */
+    public function getCatalogue($locale = null);
+}
diff --git a/core/lib/Symfony/Component/Translation/TranslatorInterface.php b/core/vendor/symfony/translation/TranslatorInterface.php
similarity index 100%
rename from core/lib/Symfony/Component/Translation/TranslatorInterface.php
rename to core/vendor/symfony/translation/TranslatorInterface.php
diff --git a/core/vendor/symfony/translation/Writer/TranslationWriter.php b/core/vendor/symfony/translation/Writer/TranslationWriter.php
new file mode 100644
index 0000000000000000000000000000000000000000..44ac182d74a16c435b03ed7b75f8fc73a5e9bb1e
--- /dev/null
+++ b/core/vendor/symfony/translation/Writer/TranslationWriter.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 Symfony\Component\Translation\Writer;
+
+use Symfony\Component\Translation\MessageCatalogue;
+use Symfony\Component\Translation\Dumper\DumperInterface;
+
+/**
+ * TranslationWriter writes translation messages.
+ *
+ * @author Michel Salib <michelsalib@hotmail.com>
+ */
+class TranslationWriter
+{
+    /**
+     * Dumpers used for export.
+     *
+     * @var array
+     */
+    private $dumpers = array();
+
+    /**
+     * Adds a dumper to the writer.
+     *
+     * @param string          $format The format of the dumper
+     * @param DumperInterface $dumper The dumper
+     */
+    public function addDumper($format, DumperInterface $dumper)
+    {
+        $this->dumpers[$format] = $dumper;
+    }
+
+    /**
+     * Disables dumper backup.
+     */
+    public function disableBackup()
+    {
+        foreach ($this->dumpers as $dumper) {
+            $dumper->setBackup(false);
+        }
+    }
+
+    /**
+     * Obtains the list of supported formats.
+     *
+     * @return array
+     */
+    public function getFormats()
+    {
+        return array_keys($this->dumpers);
+    }
+
+    /**
+     * Writes translation from the catalogue according to the selected format.
+     *
+     * @param MessageCatalogue $catalogue The message catalogue to dump
+     * @param string           $format    The format to use to dump the messages
+     * @param array            $options   Options that are passed to the dumper
+     *
+     * @throws \InvalidArgumentException
+     */
+    public function writeTranslations(MessageCatalogue $catalogue, $format, $options = array())
+    {
+        if (!isset($this->dumpers[$format])) {
+            throw new \InvalidArgumentException(sprintf('There is no dumper associated with format "%s".', $format));
+        }
+
+        // get the right dumper
+        $dumper = $this->dumpers[$format];
+
+        if (isset($options['path']) && !is_dir($options['path'])) {
+            mkdir($options['path'], 0777, true);
+        }
+
+        // save
+        $dumper->dump($catalogue, $options);
+    }
+}
diff --git a/core/vendor/symfony/translation/composer.json b/core/vendor/symfony/translation/composer.json
new file mode 100644
index 0000000000000000000000000000000000000000..e2e1587e0a4f3222e28bbf5be1388764f5ac1c8b
--- /dev/null
+++ b/core/vendor/symfony/translation/composer.json
@@ -0,0 +1,45 @@
+{
+    "name": "symfony/translation",
+    "type": "library",
+    "description": "Symfony Translation Component",
+    "keywords": [],
+    "homepage": "https://symfony.com",
+    "license": "MIT",
+    "authors": [
+        {
+            "name": "Fabien Potencier",
+            "email": "fabien@symfony.com"
+        },
+        {
+            "name": "Symfony Community",
+            "homepage": "https://symfony.com/contributors"
+        }
+    ],
+    "require": {
+        "php": ">=5.3.9"
+    },
+    "require-dev": {
+        "symfony/phpunit-bridge": "~2.7",
+        "symfony/config": "~2.7",
+        "symfony/intl": "~2.4",
+        "symfony/yaml": "~2.2",
+        "psr/log": "~1.0"
+    },
+    "conflict": {
+        "symfony/config": "<2.7"
+    },
+    "suggest": {
+        "symfony/config": "",
+        "symfony/yaml": "",
+        "psr/log": "To use logging capability in translator"
+    },
+    "autoload": {
+        "psr-4": { "Symfony\\Component\\Translation\\": "" }
+    },
+    "minimum-stability": "dev",
+    "extra": {
+        "branch-alias": {
+            "dev-master": "2.7-dev"
+        }
+    }
+}
diff --git a/core/vendor/symfony/translation/phpunit.xml.dist b/core/vendor/symfony/translation/phpunit.xml.dist
new file mode 100644
index 0000000000000000000000000000000000000000..16cca4afb7c69ec317af617da65cd044d78dd693
--- /dev/null
+++ b/core/vendor/symfony/translation/phpunit.xml.dist
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.1/phpunit.xsd"
+         backupGlobals="false"
+         colors="true"
+         bootstrap="vendor/autoload.php"
+>
+    <php>
+        <ini name="error_reporting" value="-1" />
+    </php>
+
+    <testsuites>
+        <testsuite name="Symfony Translation Component Test Suite">
+            <directory>./Tests/</directory>
+        </testsuite>
+    </testsuites>
+
+    <filter>
+        <whitelist>
+            <directory>./</directory>
+            <exclude>
+                <directory>./vendor</directory>
+                <directory>./Tests</directory>
+            </exclude>
+        </whitelist>
+    </filter>
+</phpunit>