diff --git a/core/includes/gettext.inc b/core/includes/gettext.inc
index 2355157..e3a85ae 100644
--- a/core/includes/gettext.inc
+++ b/core/includes/gettext.inc
@@ -1,5 +1,8 @@
 <?php
 
+use Symfony\Component\Translation\Loader\PoFileLoader;
+use Symfony\Component\Translation\Gettext;
+
 /**
  * @file
  * Gettext parsing and generating API.
@@ -17,6 +20,65 @@
  */
 
 /**
+ * Reads all messages from the given file.
+ *
+ * TODO:
+ * - do we need to filter on context?
+ * - context is not supported yet by Symfony
+ *
+ * @param type $file
+ * @param type $langcode
+ * @return array containing header and all messages.
+ */
+function gettext_read_messages_from_po_file($file, $langcode) {
+  $loader = new PoFileLoader();
+  $resource = $file->uri;
+  $catalogue = $loader->load($resource, $langcode);
+  $messages = $catalogue->all();
+  // TODO: Hmmm tricky knowledge (a sub array)
+  $header = Gettext::getHeader($messages['messages']);
+  // Delete Header from messages.
+  Gettext::delHeader($messages['messages']);
+  return array('header' => $header, 'messages' => $messages);
+}
+
+/**
+ * Write all ginve domains to the database
+ *
+ * TODO:
+ * - we should move args into a $options array?
+ * - we should write all items at once?
+ *
+ * @param type $domains
+ * @param type $langcode
+ * @param type $overwrite_options
+ * @param type $customized
+ * @param type $header
+ */
+function gettext_write_messages_to_database($domains, $langcode, $overwrite_options = array(), $customized = LOCALE_NOT_CUSTOMIZED, $header = array()) {
+  if (!empty($header)) {
+    $current = array();
+    $current['msgid'] = '';
+    $current['msgstr'] = $header;
+    // TODO: why is file needed?
+    $file = (object) array('uri' => 'file-is-only-needed-when-report-header-parsing-error');
+    _locale_import_one_string('db-store', $current, $overwrite_options, $langcode, $file, $customized);
+  }
+
+  foreach ($domains as $domain => $messages) {
+    foreach($messages as $source => $translation) {
+      $current = array();
+      $current['msgid'] = $source;
+      $current['msgstr'] = $translation;
+      $current['msgctxt'] = $domain == 'messages' ? '' : $domain;
+      // TODO: why is file needed?
+      $file = (object) array('uri' => 'file-is-only-needed-when-report-header-parsing-error');
+      _locale_import_one_string('db-store', $current, $overwrite_options, $langcode, $file, $customized);
+    }
+  }
+}
+
+/**
  * Parses Gettext Portable Object information and inserts it into the database.
  *
  * @param $file
@@ -43,11 +105,9 @@ function _locale_import_po($file, $langcode, $overwrite_options, $customized = L
   }
 
   // Get strings from file (returns on failure after a partial import, or on success)
-  $status = _locale_import_read_po('db-store', $file, $overwrite_options, $langcode, $customized);
-  if ($status === FALSE) {
-    // Error messages are set in _locale_import_read_po().
-    return FALSE;
-  }
+  $result = gettext_read_messages_from_po_file($file, $langcode);
+  $header = $result['header'];
+  gettext_write_messages_to_database($result['messages'], $langcode, $overwrite_options, $customized, $header);
 
   // Get status information on import process.
   list($header_done, $additions, $updates, $deletes, $skips) = _locale_import_one_string('db-report');
@@ -79,271 +139,6 @@ function _locale_import_po($file, $langcode, $overwrite_options, $customized = L
 }
 
 /**
- * Parses a Gettext Portable Object file into an array.
- *
- * @param $op
- *   Storage operation type: db-store or mem-store.
- * @param $file
- *   Drupal file object corresponding to the PO file to import.
- * @param $overwrite_options
- *   An associative array indicating what data should be overwritten, if any.
- *   - not_customized: not customized strings should be overwritten.
- *   - customized: customized strings should be overwritten.
- * @param $lang
- *   Language code.
- * @param $customized
- *   Whether the strings being imported should be saved as customized.
- *   Use LOCALE_CUSTOMIZED or LOCALE_NOT_CUSTOMIZED.
- */
-function _locale_import_read_po($op, $file, $overwrite_options = NULL, $lang = NULL, $customized = LOCALE_NOT_CUSTOMIZED) {
-
-  // The file will get closed by PHP on returning from this function.
-  $fd = fopen($file->uri, 'rb');
-  if (!$fd) {
-    _locale_import_message('The translation import failed because the file %filename could not be read.', $file);
-    return FALSE;
-  }
-
-  /*
-   * The parser context. Can be:
-   *  - 'COMMENT' (#)
-   *  - 'MSGID' (msgid)
-   *  - 'MSGID_PLURAL' (msgid_plural)
-   *  - 'MSGCTXT' (msgctxt)
-   *  - 'MSGSTR' (msgstr or msgstr[])
-   *  - 'MSGSTR_ARR' (msgstr_arg)
-   */
-  $context = 'COMMENT';
-
-  // Current entry being read.
-  $current = array();
-
-  // Current plurality for 'msgstr[]'.
-  $plural = 0;
-
-  // Current line.
-  $lineno = 0;
-
-  while (!feof($fd)) {
-    // A line should not be longer than 10 * 1024.
-    $line = fgets($fd, 10 * 1024);
-
-    if ($lineno == 0) {
-      // The first line might come with a UTF-8 BOM, which should be removed.
-      $line = str_replace("\xEF\xBB\xBF", '', $line);
-    }
-
-    $lineno++;
-
-    // Trim away the linefeed.
-    $line = trim(strtr($line, array("\\\n" => "")));
-
-    if (!strncmp('#', $line, 1)) {
-      // Lines starting with '#' are comments.
-
-      if ($context == 'COMMENT') {
-        // Already in comment token, insert the comment.
-        $current['#'][] = substr($line, 1);
-      }
-      elseif (($context == 'MSGSTR') || ($context == 'MSGSTR_ARR')) {
-        // We are currently in string token, close it out.
-        _locale_import_one_string($op, $current, $overwrite_options, $lang, $file, $customized);
-
-        // Start a new entry for the comment.
-        $current         = array();
-        $current['#'][]  = substr($line, 1);
-
-        $context = 'COMMENT';
-      }
-      else {
-        // A comment following any other token is a syntax error.
-        _locale_import_message('The translation file %filename contains an error: "msgstr" was expected but not found on line %line.', $file, $lineno);
-        return FALSE;
-      }
-    }
-    elseif (!strncmp('msgid_plural', $line, 12)) {
-      // A plural form for the current message.
-
-      if ($context != 'MSGID') {
-        // A plural form cannot be added to anything else but the id directly.
-        _locale_import_message('The translation file %filename contains an error: "msgid_plural" was expected but not found on line %line.', $file, $lineno);
-        return FALSE;
-      }
-
-      // Remove 'msgid_plural' and trim away whitespace.
-      $line = trim(substr($line, 12));
-      // At this point, $line should now contain only the plural form.
-
-      $quoted = _locale_import_parse_quoted($line);
-      if ($quoted === FALSE) {
-        // The plural form must be wrapped in quotes.
-        _locale_import_message('The translation file %filename contains a syntax error on line %line.', $file, $lineno);
-        return FALSE;
-      }
-
-      // Append the plural form to the current entry.
-      $current['msgid'] .= LOCALE_PLURAL_DELIMITER . $quoted;
-
-      $context = 'MSGID_PLURAL';
-    }
-    elseif (!strncmp('msgid', $line, 5)) {
-      // Starting a new message.
-
-      if (($context == 'MSGSTR') || ($context == 'MSGSTR_ARR')) {
-        // We are currently in a message string, close it out.
-        _locale_import_one_string($op, $current, $overwrite_options, $lang, $file, $customized);
-
-        // Start a new context for the id.
-        $current = array();
-      }
-      elseif ($context == 'MSGID') {
-        // We are currently already in the context, meaning we passed an id with no data.
-        _locale_import_message('The translation file %filename contains an error: "msgid" is unexpected on line %line.', $file, $lineno);
-        return FALSE;
-      }
-
-      // Remove 'msgid' and trim away whitespace.
-      $line = trim(substr($line, 5));
-      // At this point, $line should now contain only the message id.
-
-      $quoted = _locale_import_parse_quoted($line);
-      if ($quoted === FALSE) {
-        // The message id must be wrapped in quotes.
-        _locale_import_message('The translation file %filename contains a syntax error on line %line.', $file, $lineno);
-        return FALSE;
-      }
-
-      $current['msgid'] = $quoted;
-      $context = 'MSGID';
-    }
-    elseif (!strncmp('msgctxt', $line, 7)) {
-      // Starting a new context.
-
-      if (($context == 'MSGSTR') || ($context == 'MSGSTR_ARR')) {
-        // We are currently in a message, start a new one.
-        _locale_import_one_string($op, $current, $overwrite_options, $lang, $file, $customized);
-        $current = array();
-      }
-      elseif (!empty($current['msgctxt'])) {
-        // A context cannot apply to another context.
-        _locale_import_message('The translation file %filename contains an error: "msgctxt" is unexpected on line %line.', $file, $lineno);
-        return FALSE;
-      }
-
-      // Remove 'msgctxt' and trim away whitespaces.
-      $line = trim(substr($line, 7));
-      // At this point, $line should now contain the context.
-
-      $quoted = _locale_import_parse_quoted($line);
-      if ($quoted === FALSE) {
-        // The context string must be quoted.
-        _locale_import_message('The translation file %filename contains a syntax error on line %line.', $file, $lineno);
-        return FALSE;
-      }
-
-      $current['msgctxt'] = $quoted;
-
-      $context = 'MSGCTXT';
-    }
-    elseif (!strncmp('msgstr[', $line, 7)) {
-      // A message string for a specific plurality.
-
-      if (($context != 'MSGID') && ($context != 'MSGCTXT') && ($context != 'MSGID_PLURAL') && ($context != 'MSGSTR_ARR')) {
-        // Message strings must come after msgid, msgxtxt, msgid_plural, or other msgstr[] entries.
-        _locale_import_message('The translation file %filename contains an error: "msgstr[]" is unexpected on line %line.', $file, $lineno);
-        return FALSE;
-      }
-
-      // Ensure the plurality is terminated.
-      if (strpos($line, ']') === FALSE) {
-        _locale_import_message('The translation file %filename contains a syntax error on line %line.', $file, $lineno);
-        return FALSE;
-      }
-
-      // Extract the plurality.
-      $frombracket = strstr($line, '[');
-      $plural = substr($frombracket, 1, strpos($frombracket, ']') - 1);
-
-      // Skip to the next whitespace and trim away any further whitespace, bringing $line to the message data.
-      $line = trim(strstr($line, " "));
-
-      $quoted = _locale_import_parse_quoted($line);
-      if ($quoted === FALSE) {
-        // The string must be quoted.
-        _locale_import_message('The translation file %filename contains a syntax error on line %line.', $file, $lineno);
-        return FALSE;
-      }
-
-      $current['msgstr'][$plural] = $quoted;
-
-      $context = 'MSGSTR_ARR';
-    }
-    elseif (!strncmp("msgstr", $line, 6)) {
-      // A string for the an id or context.
-
-      if (($context != 'MSGID') && ($context != 'MSGCTXT')) {
-        // Strings are only valid within an id or context scope.
-        _locale_import_message('The translation file %filename contains an error: "msgstr" is unexpected on line %line.', $file, $lineno);
-        return FALSE;
-      }
-
-      // Remove 'msgstr' and trim away away whitespaces.
-      $line = trim(substr($line, 6));
-      // At this point, $line should now contain the message.
-
-      $quoted = _locale_import_parse_quoted($line);
-      if ($quoted === FALSE) {
-        // The string must be quoted.
-        _locale_import_message('The translation file %filename contains a syntax error on line %line.', $file, $lineno);
-        return FALSE;
-      }
-
-      $current['msgstr'] = $quoted;
-
-      $context = 'MSGSTR';
-    }
-    elseif ($line != '') {
-      // Anything that is not a token may be a continuation of a previous token.
-
-      $quoted = _locale_import_parse_quoted($line);
-      if ($quoted === FALSE) {
-        // The string must be quoted.
-        _locale_import_message('The translation file %filename contains a syntax error on line %line.', $file, $lineno);
-        return FALSE;
-      }
-
-      // Append the string to the current context.
-      if (($context == 'MSGID') || ($context == 'MSGID_PLURAL')) {
-        $current['msgid'] .= $quoted;
-      }
-      elseif ($context == 'MSGCTXT') {
-        $current['msgctxt'] .= $quoted;
-      }
-      elseif ($context == 'MSGSTR') {
-        $current['msgstr'] .= $quoted;
-      }
-      elseif ($context == 'MSGSTR_ARR') {
-        $current['msgstr'][$plural] .= $quoted;
-      }
-      else {
-        // No valid context to append to.
-        _locale_import_message('The translation file %filename contains an error: there is an unexpected string on line %line.', $file, $lineno);
-        return FALSE;
-      }
-    }
-  }
-
-  // End of PO file, closed out the last entry.
-  if (($context == 'MSGSTR') || ($context == 'MSGSTR_ARR')) {
-    _locale_import_one_string($op, $current, $overwrite_options, $lang, $file, $customized);
-  }
-  elseif ($context != 'COMMENT') {
-    _locale_import_message('The translation file %filename ended unexpectedly at line %line.', $file, $lineno);
-    return FALSE;
-  }
-}
-
-/**
  * Sets an error message if an error occurred during locale file parsing.
  *
  * @param $message
@@ -385,17 +180,8 @@ function _locale_import_message($message, $file, $lineno = NULL) {
 function _locale_import_one_string($op, $value = NULL, $overwrite_options = NULL, $lang = NULL, $file = NULL, $customized = LOCALE_NOT_CUSTOMIZED) {
   $report = &drupal_static(__FUNCTION__, array('additions' => 0, 'updates' => 0, 'deletes' => 0, 'skips' => 0));
   $header_done = &drupal_static(__FUNCTION__ . ':header_done', FALSE);
-  $strings = &drupal_static(__FUNCTION__ . ':strings', array());
 
   switch ($op) {
-    // Return stored strings
-    case 'mem-report':
-      return $strings;
-
-    // Store string in memory (only supports single strings)
-    case 'mem-store':
-      $strings[isset($value['msgctxt']) ? $value['msgctxt'] : ''][$value['msgid']] = $value['msgstr'];
-      return;
 
     // Called at end of import to inform the user
     case 'db-report':
diff --git a/core/includes/install.inc b/core/includes/install.inc
index f278a6a..96f720a 100644
--- a/core/includes/install.inc
+++ b/core/includes/install.inc
@@ -718,23 +718,27 @@ function st($string, array $args = array(), array $options = array()) {
   global $install_state;
 
   if (empty($options['context'])) {
-    $options['context'] = '';
+    $domain = 'messages';
+  }
+  else {
+    $domain = $options['context'];
   }
-
   if (!isset($strings)) {
     $strings = array();
     if (isset($install_state['parameters']['langcode'])) {
+      $langcode = $install_state['parameters']['langcode'];
       // If the given langcode was selected, there should be at least one .po file
       // with its name ending in install.{$install_state['parameters']['langcode']}.po
       // This might or might not be the entire filename. It is also possible
       // that multiple files end with the same extension, even if unlikely.
       $files = install_find_translation_files($install_state['parameters']['langcode']);
+      require_once DRUPAL_ROOT . '/core/includes/gettext.inc';
       if (!empty($files)) {
-        require_once DRUPAL_ROOT . '/core/includes/gettext.inc';
         foreach ($files as $file) {
-          _locale_import_read_po('mem-store', $file);
+          $result = gettext_read_messages_from_po_file($file, $langcode);
+          // TODO: this should be a array merge
+          $strings = $result['messages'];
         }
-        $strings = _locale_import_one_string('mem-report');
       }
     }
   }
@@ -756,7 +760,7 @@ function st($string, array $args = array(), array $options = array()) {
       case '!':
     }
   }
-  return strtr((!empty($strings[$options['context']][$string]) ? $strings[$options['context']][$string] : $string), $args);
+  return strtr((!empty($strings[$domain][$string]) ? $strings[$domain][$string] : $string), $args);
 }
 
 /**
diff --git a/core/modules/locale/locale.bulk.inc b/core/modules/locale/locale.bulk.inc
index 8cd4fd1..8cb161f 100644
--- a/core/modules/locale/locale.bulk.inc
+++ b/core/modules/locale/locale.bulk.inc
@@ -296,9 +296,11 @@ function locale_translate_batch_build($files, $finish_feedback = FALSE) {
 function locale_translate_batch_import($filepath, &$context) {
   // The filename is either {langcode}.po or {prefix}.{langcode}.po, so
   // we can extract the language code to use for the import from the end.
-  if (preg_match('!(/|\.)([^\./]+)\.po$!', $filepath, $langcode)) {
+  if (preg_match('!(/|\.)([^\./]+)\.po$!', $filepath, $match)) {
     $file = (object) array('filename' => drupal_basename($filepath), 'uri' => $filepath);
-    _locale_import_read_po('db-store', $file, array(), $langcode[2]);
+    $langcode = $match[2];
+    $result = gettext_read_messages_from_po_file($file, $langcode);
+    gettext_write_messages_to_database($result['messages'], $langcode, array(), LOCALE_NOT_CUSTOMIZED, $result['header']);
     $context['results'][] = $filepath;
   }
 }
diff --git a/core/vendor/Symfony/Component/Config/CHANGELOG.md b/core/vendor/Symfony/Component/Config/CHANGELOG.md
new file mode 100644
index 0000000..27dd931
--- /dev/null
+++ b/core/vendor/Symfony/Component/Config/CHANGELOG.md
@@ -0,0 +1,10 @@
+CHANGELOG
+=========
+
+2.1.0
+-----
+
+ * added a way to add documentation on configuration
+ * implemented `Serializable` on resources
+ * LoaderResolverInterface is now used instead of LoaderResolver for type
+   hinting
diff --git a/core/vendor/Symfony/Component/Config/ConfigCache.php b/core/vendor/Symfony/Component/Config/ConfigCache.php
new file mode 100644
index 0000000..8fb67d1
--- /dev/null
+++ b/core/vendor/Symfony/Component/Config/ConfigCache.php
@@ -0,0 +1,117 @@
+<?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\Config;
+
+/**
+ * ConfigCache manages PHP cache files.
+ *
+ * When debug is enabled, it knows when to flush the cache
+ * thanks to an array of ResourceInterface instances.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class ConfigCache
+{
+    private $debug;
+    private $file;
+
+    /**
+     * Constructor.
+     *
+     * @param string  $file     The absolute cache path
+     * @param Boolean $debug    Whether debugging is enabled or not
+     */
+    public function __construct($file, $debug)
+    {
+        $this->file = $file;
+        $this->debug = (Boolean) $debug;
+    }
+
+    /**
+     * Gets the cache file path.
+     *
+     * @return string The cache file path
+     */
+    public function __toString()
+    {
+        return $this->file;
+    }
+
+    /**
+     * Checks if the cache is still fresh.
+     *
+     * This method always returns true when debug is off and the
+     * cache file exists.
+     *
+     * @return Boolean true if the cache is fresh, false otherwise
+     */
+    public function isFresh()
+    {
+        if (!is_file($this->file)) {
+            return false;
+        }
+
+        if (!$this->debug) {
+            return true;
+        }
+
+        $metadata = $this->file.'.meta';
+        if (!is_file($metadata)) {
+            return false;
+        }
+
+        $time = filemtime($this->file);
+        $meta = unserialize(file_get_contents($metadata));
+        foreach ($meta as $resource) {
+            if (!$resource->isFresh($time)) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * Writes cache.
+     *
+     * @param string $content  The content to write in the cache
+     * @param array  $metadata An array of ResourceInterface instances
+     *
+     * @throws \RuntimeException When cache file can't be wrote
+     */
+    public function write($content, array $metadata = null)
+    {
+        $dir = dirname($this->file);
+        if (!is_dir($dir)) {
+            if (false === @mkdir($dir, 0777, true)) {
+                throw new \RuntimeException(sprintf('Unable to create the %s directory', $dir));
+            }
+        } elseif (!is_writable($dir)) {
+            throw new \RuntimeException(sprintf('Unable to write in the %s directory', $dir));
+        }
+
+        $tmpFile = tempnam(dirname($this->file), basename($this->file));
+        if (false !== @file_put_contents($tmpFile, $content) && @rename($tmpFile, $this->file)) {
+            chmod($this->file, 0666 & ~umask());
+        } else {
+            throw new \RuntimeException(sprintf('Failed to write cache file "%s".', $this->file));
+        }
+
+        if (null !== $metadata && true === $this->debug) {
+            $file = $this->file.'.meta';
+            $tmpFile = tempnam(dirname($file), basename($file));
+            if (false !== @file_put_contents($tmpFile, serialize($metadata)) && @rename($tmpFile, $file)) {
+                chmod($file, 0666 & ~umask());
+            }
+        }
+    }
+}
diff --git a/core/vendor/Symfony/Component/Config/Definition/ArrayNode.php b/core/vendor/Symfony/Component/Config/Definition/ArrayNode.php
new file mode 100644
index 0000000..22ec092
--- /dev/null
+++ b/core/vendor/Symfony/Component/Config/Definition/ArrayNode.php
@@ -0,0 +1,363 @@
+<?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\Config\Definition;
+
+
+use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
+use Symfony\Component\Config\Definition\Exception\InvalidTypeException;
+use Symfony\Component\Config\Definition\Exception\UnsetKeyException;
+
+/**
+ * Represents an Array node in the config tree.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+class ArrayNode extends BaseNode implements PrototypeNodeInterface
+{
+    protected $xmlRemappings;
+    protected $children;
+    protected $allowFalse;
+    protected $allowNewKeys;
+    protected $addIfNotSet;
+    protected $performDeepMerging;
+    protected $ignoreExtraKeys;
+
+    /**
+     * Constructor.
+     *
+     * @param string $name The Node's name
+     * @param NodeInterface $parent The node parent
+     */
+    public function __construct($name, NodeInterface $parent = null)
+    {
+        parent::__construct($name, $parent);
+
+        $this->children = array();
+        $this->xmlRemappings = array();
+        $this->removeKeyAttribute = true;
+        $this->allowFalse = false;
+        $this->addIfNotSet = false;
+        $this->allowNewKeys = true;
+        $this->performDeepMerging = true;
+    }
+
+    /**
+     * Retrieves the children of this node.
+     *
+     * @return array The children
+     */
+    public function getChildren()
+    {
+        return $this->children;
+    }
+
+    /**
+     * Sets the xml remappings that should be performed.
+     *
+     * @param array $remappings an array of the form array(array(string, string))
+     */
+    public function setXmlRemappings(array $remappings)
+    {
+        $this->xmlRemappings = $remappings;
+    }
+
+    /**
+     * Sets whether to add default values for this array if it has not been
+     * defined in any of the configuration files.
+     *
+     * @param Boolean $boolean
+     */
+    public function setAddIfNotSet($boolean)
+    {
+        $this->addIfNotSet = (Boolean) $boolean;
+    }
+
+    /**
+     * Sets whether false is allowed as value indicating that the array should be unset.
+     *
+     * @param Boolean $allow
+     */
+    public function setAllowFalse($allow)
+    {
+        $this->allowFalse = (Boolean) $allow;
+    }
+
+    /**
+     * Sets whether new keys can be defined in subsequent configurations.
+     *
+     * @param Boolean $allow
+     */
+    public function setAllowNewKeys($allow)
+    {
+        $this->allowNewKeys = (Boolean) $allow;
+    }
+
+    /**
+     * Sets if deep merging should occur.
+     *
+     * @param Boolean $boolean
+     */
+    public function setPerformDeepMerging($boolean)
+    {
+        $this->performDeepMerging = (Boolean) $boolean;
+    }
+
+    /**
+     * Whether extra keys should just be ignore without an exception.
+     *
+     * @param Boolean $boolean To allow extra keys
+     */
+    public function setIgnoreExtraKeys($boolean)
+    {
+        $this->ignoreExtraKeys = (Boolean) $boolean;
+    }
+
+    /**
+     * Sets the node Name.
+     *
+     * @param string $name The node's name
+     */
+    public function setName($name)
+    {
+        $this->name = $name;
+    }
+
+    /**
+     * Checks if the node has a default value.
+     *
+     * @return Boolean
+     */
+    public function hasDefaultValue()
+    {
+        return $this->addIfNotSet;
+    }
+
+    /**
+     * Retrieves the default value.
+     *
+     * @return array The default value
+     *
+     * @throws \RuntimeException if the node has no default value
+     */
+    public function getDefaultValue()
+    {
+        if (!$this->hasDefaultValue()) {
+            throw new \RuntimeException(sprintf('The node at path "%s" has no default value.', $this->getPath()));
+        }
+
+        $defaults = array();
+        foreach ($this->children as $name => $child) {
+            if ($child->hasDefaultValue()) {
+                $defaults[$name] = $child->getDefaultValue();
+            }
+        }
+
+        return $defaults;
+    }
+
+    /**
+     * Adds a child node.
+     *
+     * @param NodeInterface $node The child node to add
+     *
+     * @throws \InvalidArgumentException when the child node has no name
+     * @throws \InvalidArgumentException when the child node's name is not unique
+     */
+    public function addChild(NodeInterface $node)
+    {
+        $name = $node->getName();
+        if (empty($name)) {
+            throw new \InvalidArgumentException('Child nodes must be named.');
+        }
+        if (isset($this->children[$name])) {
+            throw new \InvalidArgumentException(sprintf('A child node named "%s" already exists.', $name));
+        }
+
+        $this->children[$name] = $node;
+    }
+
+    /**
+     * Finalizes the value of this node.
+     *
+     * @param mixed $value
+     *
+     * @return mixed The finalised value
+     *
+     * @throws UnsetKeyException
+     * @throws InvalidConfigurationException if the node doesn't have enough children
+     */
+    protected function finalizeValue($value)
+    {
+        if (false === $value) {
+            $msg = sprintf('Unsetting key for path "%s", value: %s', $this->getPath(), json_encode($value));
+            throw new UnsetKeyException($msg);
+        }
+
+        foreach ($this->children as $name => $child) {
+            if (!array_key_exists($name, $value)) {
+                if ($child->isRequired()) {
+                    $msg = sprintf('The child node "%s" at path "%s" must be configured.', $name, $this->getPath());
+                    $ex = new InvalidConfigurationException($msg);
+                    $ex->setPath($this->getPath());
+
+                    throw $ex;
+                }
+
+                if ($child->hasDefaultValue()) {
+                    $value[$name] = $child->getDefaultValue();
+                }
+
+                continue;
+            }
+
+            try {
+                $value[$name] = $child->finalize($value[$name]);
+            } catch (UnsetKeyException $unset) {
+                unset($value[$name]);
+            }
+        }
+
+        return $value;
+    }
+
+    /**
+     * Validates the type of the value.
+     *
+     * @param mixed $value
+     *
+     * @throws InvalidTypeException
+     */
+    protected function validateType($value)
+    {
+        if (!is_array($value) && (!$this->allowFalse || false !== $value)) {
+            $ex = new InvalidTypeException(sprintf(
+                'Invalid type for path "%s". Expected array, but got %s',
+                $this->getPath(),
+                gettype($value)
+            ));
+            $ex->setPath($this->getPath());
+
+            throw $ex;
+        }
+    }
+
+    /**
+     * Normalizes the value.
+     *
+     * @param mixed $value The value to normalize
+     *
+     * @return mixed The normalized value
+     */
+    protected function normalizeValue($value)
+    {
+        if (false === $value) {
+            return $value;
+        }
+
+        $value = $this->remapXml($value);
+
+        $normalized = array();
+        foreach ($this->children as $name => $child) {
+            if (array_key_exists($name, $value)) {
+                $normalized[$name] = $child->normalize($value[$name]);
+                unset($value[$name]);
+            }
+        }
+
+        // if extra fields are present, throw exception
+        if (count($value) && !$this->ignoreExtraKeys) {
+            $msg = sprintf('Unrecognized options "%s" under "%s"', implode(', ', array_keys($value)), $this->getPath());
+            $ex = new InvalidConfigurationException($msg);
+            $ex->setPath($this->getPath());
+
+            throw $ex;
+        }
+
+        return $normalized;
+    }
+
+    /**
+     * Remaps multiple singular values to a single plural value.
+     *
+     * @param array $value The source values
+     *
+     * @return array The remapped values
+     */
+    protected function remapXml($value)
+    {
+        foreach ($this->xmlRemappings as $transformation) {
+            list($singular, $plural) = $transformation;
+
+            if (!isset($value[$singular])) {
+                continue;
+            }
+
+            $value[$plural] = Processor::normalizeConfig($value, $singular, $plural);
+            unset($value[$singular]);
+        }
+
+        return $value;
+    }
+
+    /**
+     * Merges values together.
+     *
+     * @param mixed $leftSide The left side to merge.
+     * @param mixed $rightSide The right side to merge.
+     *
+     * @return mixed The merged values
+     *
+     * @throws InvalidConfigurationException
+     * @throws \RuntimeException
+     */
+    protected function mergeValues($leftSide, $rightSide)
+    {
+        if (false === $rightSide) {
+            // if this is still false after the last config has been merged the
+            // finalization pass will take care of removing this key entirely
+            return false;
+        }
+
+        if (false === $leftSide || !$this->performDeepMerging) {
+            return $rightSide;
+        }
+
+        foreach ($rightSide as $k => $v) {
+            // no conflict
+            if (!array_key_exists($k, $leftSide)) {
+                if (!$this->allowNewKeys) {
+                    $ex = new InvalidConfigurationException(sprintf(
+                        'You are not allowed to define new elements for path "%s". '
+                       .'Please define all elements for this path in one config file. '
+                       .'If you are trying to overwrite an element, make sure you redefine it '
+                       .'with the same name.',
+                        $this->getPath()
+                    ));
+                    $ex->setPath($this->getPath());
+
+                    throw $ex;
+                }
+
+                $leftSide[$k] = $v;
+                continue;
+            }
+
+            if (!isset($this->children[$k])) {
+                throw new \RuntimeException('merge() expects a normalized config array.');
+            }
+
+            $leftSide[$k] = $this->children[$k]->merge($leftSide[$k], $v);
+        }
+
+        return $leftSide;
+    }
+}
diff --git a/core/vendor/Symfony/Component/Config/Definition/BaseNode.php b/core/vendor/Symfony/Component/Config/Definition/BaseNode.php
new file mode 100644
index 0000000..cd533e1
--- /dev/null
+++ b/core/vendor/Symfony/Component/Config/Definition/BaseNode.php
@@ -0,0 +1,308 @@
+<?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\Config\Definition;
+
+use Symfony\Component\Config\Definition\Exception\Exception;
+use Symfony\Component\Config\Definition\Exception\ForbiddenOverwriteException;
+use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
+
+/**
+ * The base node class
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+abstract class BaseNode implements NodeInterface
+{
+    protected $name;
+    protected $parent;
+    protected $normalizationClosures;
+    protected $finalValidationClosures;
+    protected $allowOverwrite;
+    protected $required;
+    protected $equivalentValues;
+    protected $info;
+    protected $example;
+
+    /**
+     * Constructor.
+     *
+     * @param string $name The name of the node
+     * @param NodeInterface $parent The parent of this node
+     *
+     * @throws \InvalidArgumentException if the name contains a period.
+     */
+    public function __construct($name, NodeInterface $parent = null)
+    {
+        if (false !== strpos($name, '.')) {
+            throw new \InvalidArgumentException('The name must not contain ".".');
+        }
+
+        $this->name = $name;
+        $this->parent = $parent;
+        $this->normalizationClosures = array();
+        $this->finalValidationClosures = array();
+        $this->allowOverwrite = true;
+        $this->required = false;
+        $this->equivalentValues = array();
+    }
+
+    /**
+     * Sets info message.
+     *
+     * @param string $info The info text
+     */
+    public function setInfo($info)
+    {
+        $this->info = $info;
+    }
+
+    /**
+     * Returns info message.
+     *
+     * @return string The info text
+     */
+    public function getInfo()
+    {
+        return $this->info;
+    }
+
+    /**
+     * Sets the example configuration for this node.
+     *
+     * @param string|array $example
+     */
+    public function setExample($example)
+    {
+        $this->example = $example;
+    }
+
+    /**
+     * Retrieves the example configuration for this node.
+     *
+     * @return string|array The example
+     */
+    public function getExample()
+    {
+        return $this->example;
+    }
+
+    /**
+     * Adds an equivalent value.
+     *
+     * @param mixed $originalValue
+     * @param mixed $equivalentValue
+     */
+    public function addEquivalentValue($originalValue, $equivalentValue)
+    {
+        $this->equivalentValues[] = array($originalValue, $equivalentValue);
+    }
+
+    /**
+     * Set this node as required.
+     *
+     * @param Boolean $boolean Required node
+     */
+    public function setRequired($boolean)
+    {
+        $this->required = (Boolean) $boolean;
+    }
+
+    /**
+     * Sets if this node can be overridden.
+     *
+     * @param Boolean $allow
+     */
+    public function setAllowOverwrite($allow)
+    {
+        $this->allowOverwrite = (Boolean) $allow;
+    }
+
+    /**
+     * Sets the closures used for normalization.
+     *
+     * @param array $closures An array of Closures used for normalization
+     */
+    public function setNormalizationClosures(array $closures)
+    {
+        $this->normalizationClosures = $closures;
+    }
+
+    /**
+     * Sets the closures used for final validation.
+     *
+     * @param array $closures An array of Closures used for final validation
+     */
+    public function setFinalValidationClosures(array $closures)
+    {
+        $this->finalValidationClosures = $closures;
+    }
+
+    /**
+     * Checks if this node is required.
+     *
+     * @return Boolean
+     */
+    public function isRequired()
+    {
+        return $this->required;
+    }
+
+    /**
+     * Returns the name of this node
+     *
+     * @return string The Node's name.
+     */
+    public function getName()
+    {
+        return $this->name;
+    }
+
+    /**
+     * Retrieves the path of this node.
+     *
+     * @return string The Node's path
+     */
+    public function getPath()
+    {
+        $path = $this->name;
+
+        if (null !== $this->parent) {
+            $path = $this->parent->getPath().'.'.$path;
+        }
+
+        return $path;
+    }
+
+    /**
+     * Merges two values together.
+     *
+     * @param mixed $leftSide
+     * @param mixed $rightSide
+     *
+     * @return mixed The merged value
+     *
+     * @throws ForbiddenOverwriteException
+     */
+    public final function merge($leftSide, $rightSide)
+    {
+        if (!$this->allowOverwrite) {
+            throw new ForbiddenOverwriteException(sprintf(
+                'Configuration path "%s" cannot be overwritten. You have to '
+               .'define all options for this path, and any of its sub-paths in '
+               .'one configuration section.',
+                $this->getPath()
+            ));
+        }
+
+        $this->validateType($leftSide);
+        $this->validateType($rightSide);
+
+        return $this->mergeValues($leftSide, $rightSide);
+    }
+
+    /**
+     * Normalizes a value, applying all normalization closures.
+     *
+     * @param mixed $value Value to normalize.
+     *
+     * @return mixed The normalized value.
+     */
+    public final function normalize($value)
+    {
+        // run custom normalization closures
+        foreach ($this->normalizationClosures as $closure) {
+            $value = $closure($value);
+        }
+
+        // replace value with their equivalent
+        foreach ($this->equivalentValues as $data) {
+            if ($data[0] === $value) {
+                $value = $data[1];
+            }
+        }
+
+        // validate type
+        $this->validateType($value);
+
+        // normalize value
+        return $this->normalizeValue($value);
+    }
+
+    /**
+     * Finalizes a value, applying all finalization closures.
+     *
+     * @param mixed $value The value to finalize
+     *
+     * @return mixed The finalized value
+     */
+    public final function finalize($value)
+    {
+        $this->validateType($value);
+
+        $value = $this->finalizeValue($value);
+
+        // Perform validation on the final value if a closure has been set.
+        // The closure is also allowed to return another value.
+        foreach ($this->finalValidationClosures as $closure) {
+            try {
+                $value = $closure($value);
+            } catch (Exception $correctEx) {
+                throw $correctEx;
+            } catch (\Exception $invalid) {
+                throw new InvalidConfigurationException(sprintf(
+                    'Invalid configuration for path "%s": %s',
+                    $this->getPath(),
+                    $invalid->getMessage()
+                ), $invalid->getCode(), $invalid);
+            }
+        }
+
+        return $value;
+    }
+
+    /**
+     * Validates the type of a Node.
+     *
+     * @param mixed $value The value to validate
+     *
+     * @throws InvalidTypeException when the value is invalid
+     */
+    abstract protected function validateType($value);
+
+    /**
+     * Normalizes the value.
+     *
+     * @param mixed $value The value to normalize.
+     *
+     * @return mixed The normalized value
+     */
+    abstract protected function normalizeValue($value);
+
+    /**
+     * Merges two values together.
+     *
+     * @param mixed $leftSide
+     * @param mixed $rightSide
+     *
+     * @return mixed The merged value
+     */
+    abstract protected function mergeValues($leftSide, $rightSide);
+
+    /**
+     * Finalizes a value.
+     *
+     * @param mixed $value The value to finalize
+     *
+     * @return mixed The finalized value
+     */
+    abstract protected function finalizeValue($value);
+}
diff --git a/core/vendor/Symfony/Component/Config/Definition/BooleanNode.php b/core/vendor/Symfony/Component/Config/Definition/BooleanNode.php
new file mode 100644
index 0000000..fb37d62
--- /dev/null
+++ b/core/vendor/Symfony/Component/Config/Definition/BooleanNode.php
@@ -0,0 +1,39 @@
+<?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\Config\Definition;
+
+use Symfony\Component\Config\Definition\Exception\InvalidTypeException;
+
+/**
+ * This node represents a Boolean value in the config tree.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+class BooleanNode extends ScalarNode
+{
+    /**
+     * {@inheritDoc}
+     */
+    protected function validateType($value)
+    {
+        if (!is_bool($value)) {
+            $ex = new InvalidTypeException(sprintf(
+                'Invalid type for path "%s". Expected boolean, but got %s.',
+                $this->getPath(),
+                gettype($value)
+            ));
+            $ex->setPath($this->getPath());
+
+            throw $ex;
+        }
+    }
+}
diff --git a/core/vendor/Symfony/Component/Config/Definition/Builder/ArrayNodeDefinition.php b/core/vendor/Symfony/Component/Config/Definition/Builder/ArrayNodeDefinition.php
new file mode 100644
index 0000000..28c93d4
--- /dev/null
+++ b/core/vendor/Symfony/Component/Config/Definition/Builder/ArrayNodeDefinition.php
@@ -0,0 +1,417 @@
+<?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\Config\Definition\Builder;
+
+use Symfony\Component\Config\Definition\ArrayNode;
+use Symfony\Component\Config\Definition\PrototypedArrayNode;
+use Symfony\Component\Config\Definition\Exception\InvalidDefinitionException;
+
+/**
+ * This class provides a fluent interface for defining an array node.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+class ArrayNodeDefinition extends NodeDefinition implements ParentNodeDefinitionInterface
+{
+    protected $performDeepMerging;
+    protected $ignoreExtraKeys;
+    protected $children;
+    protected $prototype;
+    protected $atLeastOne;
+    protected $allowNewKeys;
+    protected $key;
+    protected $removeKeyItem;
+    protected $addDefaults;
+    protected $addDefaultChildren;
+    protected $nodeBuilder;
+
+    /**
+     * {@inheritDoc}
+     */
+    public function __construct($name, NodeParentInterface $parent = null)
+    {
+        parent::__construct($name, $parent);
+
+        $this->children = array();
+        $this->addDefaults = false;
+        $this->addDefaultChildren = false;
+        $this->allowNewKeys = true;
+        $this->atLeastOne = false;
+        $this->allowEmptyValue = true;
+        $this->performDeepMerging = true;
+        $this->nullEquivalent = array();
+        $this->trueEquivalent = array();
+    }
+
+    /**
+     * Sets a custom children builder.
+     *
+     * @param NodeBuilder $builder A custom NodeBuilder
+     */
+    public function setBuilder(NodeBuilder $builder)
+    {
+        $this->nodeBuilder = $builder;
+    }
+
+    /**
+     * Returns a builder to add children nodes.
+     *
+     * @return NodeBuilder
+     */
+    public function children()
+    {
+        return $this->getNodeBuilder();
+    }
+
+    /**
+     * Sets a prototype for child nodes.
+     *
+     * @param string $type the type of node
+     *
+     * @return NodeDefinition
+     */
+    public function prototype($type)
+    {
+        return $this->prototype = $this->getNodeBuilder()->node(null, $type)->setParent($this);
+    }
+
+    /**
+     * Adds the default value if the node is not set in the configuration.
+     *
+     * This method is applicable to concrete nodes only (not to prototype nodes).
+     * If this function has been called and the node is not set during the finalization
+     * phase, it's default value will be derived from its children default values.
+     *
+     * @return ArrayNodeDefinition
+     */
+    public function addDefaultsIfNotSet()
+    {
+        $this->addDefaults = true;
+
+        return $this;
+    }
+
+    /**
+     * Adds children with a default value when none are defined.
+     *
+     * @param integer|string|array|null $children The number of children|The child name|The children names to be added
+     *
+     * This method is applicable to prototype nodes only.
+     *
+     * @return ArrayNodeDefinition
+     */
+    public function addDefaultChildrenIfNoneSet($children = null)
+    {
+        $this->addDefaultChildren = $children;
+
+        return $this;
+    }
+
+    /**
+     * Requires the node to have at least one element.
+     *
+     * This method is applicable to prototype nodes only.
+     *
+     * @return ArrayNodeDefinition
+     */
+    public function requiresAtLeastOneElement()
+    {
+        $this->atLeastOne = true;
+
+        return $this;
+    }
+
+    /**
+     * Disallows adding news keys in a subsequent configuration.
+     *
+     * If used all keys have to be defined in the same configuration file.
+     *
+     * @return ArrayNodeDefinition
+     */
+    public function disallowNewKeysInSubsequentConfigs()
+    {
+        $this->allowNewKeys = false;
+
+        return $this;
+    }
+
+    /**
+     * Sets a normalization rule for XML configurations.
+     *
+     * @param string $singular The key to remap
+     * @param string $plural   The plural of the key for irregular plurals
+     *
+     * @return ArrayNodeDefinition
+     */
+    public function fixXmlConfig($singular, $plural = null)
+    {
+        $this->normalization()->remap($singular, $plural);
+
+        return $this;
+    }
+
+    /**
+     * Sets the attribute which value is to be used as key.
+     *
+     * This is useful when you have an indexed array that should be an
+     * associative array. You can select an item from within the array
+     * to be the key of the particular item. For example, if "id" is the
+     * "key", then:
+     *
+     *     array(
+     *         array('id' => 'my_name', 'foo' => 'bar'),
+     *     );
+     *
+     *   becomes
+     *
+     *     array(
+     *         'my_name' => array('foo' => 'bar'),
+     *     );
+     *
+     * If you'd like "'id' => 'my_name'" to still be present in the resulting
+     * array, then you can set the second argument of this method to false.
+     *
+     * This method is applicable to prototype nodes only.
+     *
+     * @param string  $name          The name of the key
+     * @param Boolean $removeKeyItem Whether or not the key item should be removed.
+     *
+     * @return ArrayNodeDefinition
+     */
+    public function useAttributeAsKey($name, $removeKeyItem = true)
+    {
+        $this->key = $name;
+        $this->removeKeyItem = $removeKeyItem;
+
+        return $this;
+    }
+
+    /**
+     * Sets whether the node can be unset.
+     *
+     * @param Boolean $allow
+     *
+     * @return ArrayNodeDefinition
+     */
+    public function canBeUnset($allow = true)
+    {
+        $this->merge()->allowUnset($allow);
+
+        return $this;
+    }
+
+    /**
+     * Disables the deep merging of the node.
+     *
+     * @return ArrayNodeDefinition
+     */
+    public function performNoDeepMerging()
+    {
+        $this->performDeepMerging = false;
+
+        return $this;
+    }
+
+    /**
+     * Allows extra config keys to be specified under an array without
+     * throwing an exception.
+     *
+     * Those config values are simply ignored. This should be used only
+     * in special cases where you want to send an entire configuration
+     * array through a special tree that processes only part of the array.
+     *
+     * @return ArrayNodeDefinition
+     */
+    public function ignoreExtraKeys()
+    {
+        $this->ignoreExtraKeys = true;
+
+        return $this;
+    }
+
+    /**
+     * Appends a node definition.
+     *
+     *     $node = new ArrayNodeDefinition()
+     *         ->children()
+     *             ->scalarNode('foo')->end()
+     *             ->scalarNode('baz')->end()
+     *         ->end()
+     *         ->append($this->getBarNodeDefinition())
+     *     ;
+     *
+     * @return ArrayNodeDefinition This node
+     */
+    public function append(NodeDefinition $node)
+    {
+        $this->children[$node->name] = $node->setParent($this);
+
+        return $this;
+    }
+
+    /**
+     * Returns a node builder to be used to add children and prototype
+     *
+     * @return NodeBuilder The node builder
+     */
+    protected function getNodeBuilder()
+    {
+        if (null === $this->nodeBuilder) {
+            $this->nodeBuilder = new NodeBuilder();
+        }
+
+        return $this->nodeBuilder->setParent($this);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected function createNode()
+    {
+        if (null === $this->prototype) {
+            $node = new ArrayNode($this->name, $this->parent);
+
+            $this->validateConcreteNode($node);
+
+            $node->setAddIfNotSet($this->addDefaults);
+
+            foreach ($this->children as $child) {
+                $child->parent = $node;
+                $node->addChild($child->getNode());
+            }
+        } else {
+            $node = new PrototypedArrayNode($this->name, $this->parent);
+
+            $this->validatePrototypeNode($node);
+
+            if (null !== $this->key) {
+                $node->setKeyAttribute($this->key, $this->removeKeyItem);
+            }
+
+            if (true === $this->atLeastOne) {
+                $node->setMinNumberOfElements(1);
+            }
+
+            if ($this->default) {
+                $node->setDefaultValue($this->defaultValue);
+            }
+
+            if (false !== $this->addDefaultChildren) {
+                $node->setAddChildrenIfNoneSet($this->addDefaultChildren);
+                if ($this->prototype instanceof static && null === $this->prototype->prototype) {
+                    $this->prototype->addDefaultsIfNotSet();
+                }
+            }
+
+            $this->prototype->parent = $node;
+            $node->setPrototype($this->prototype->getNode());
+        }
+
+        $node->setAllowNewKeys($this->allowNewKeys);
+        $node->addEquivalentValue(null, $this->nullEquivalent);
+        $node->addEquivalentValue(true, $this->trueEquivalent);
+        $node->addEquivalentValue(false, $this->falseEquivalent);
+        $node->setPerformDeepMerging($this->performDeepMerging);
+        $node->setRequired($this->required);
+        $node->setIgnoreExtraKeys($this->ignoreExtraKeys);
+
+        if (null !== $this->normalization) {
+            $node->setNormalizationClosures($this->normalization->before);
+            $node->setXmlRemappings($this->normalization->remappings);
+        }
+
+        if (null !== $this->merge) {
+            $node->setAllowOverwrite($this->merge->allowOverwrite);
+            $node->setAllowFalse($this->merge->allowFalse);
+        }
+
+        if (null !== $this->validation) {
+            $node->setFinalValidationClosures($this->validation->rules);
+        }
+
+        return $node;
+    }
+
+    /**
+     * Validate the confifuration of a concrete node.
+     *
+     * @param NodeInterface $node The related node
+     *
+     * @throws InvalidDefinitionException When an error is detected in the configuration
+     */
+    protected function validateConcreteNode(ArrayNode $node)
+    {
+        $path = $node->getPath();
+
+        if (null !== $this->key) {
+            throw new InvalidDefinitionException(
+                sprintf('->useAttributeAsKey() is not applicable to concrete nodes at path "%s"', $path)
+            );
+        }
+
+        if (true === $this->atLeastOne) {
+            throw new InvalidDefinitionException(
+                sprintf('->requiresAtLeastOneElement() is not applicable to concrete nodes at path "%s"', $path)
+            );
+        }
+
+        if ($this->default) {
+            throw new InvalidDefinitionException(
+                sprintf('->defaultValue() is not applicable to concrete nodes at path "%s"', $path)
+            );
+        }
+
+        if (false !== $this->addDefaultChildren) {
+            throw new InvalidDefinitionException(
+                sprintf('->addDefaultChildrenIfNoneSet() is not applicable to concrete nodes at path "%s"', $path)
+            );
+        }
+    }
+
+    /**
+     * Validate the configuration of a prototype node.
+     *
+     * @param NodeInterface $node The related node
+     *
+     * @throws InvalidDefinitionException When an error is detected in the configuration
+     */
+    protected function validatePrototypeNode(PrototypedArrayNode $node)
+    {
+        $path = $node->getPath();
+
+        if ($this->addDefaults) {
+            throw new InvalidDefinitionException(
+                sprintf('->addDefaultsIfNotSet() is not applicable to prototype nodes at path "%s"', $path)
+            );
+        }
+
+        if (false !== $this->addDefaultChildren) {
+            if ($this->default) {
+                throw new InvalidDefinitionException(
+                    sprintf('A default value and default children might not be used together at path "%s"', $path)
+                );
+            }
+
+            if (null !== $this->key && (null === $this->addDefaultChildren || is_integer($this->addDefaultChildren) && $this->addDefaultChildren > 0)) {
+                throw new InvalidDefinitionException(
+                    sprintf('->addDefaultChildrenIfNoneSet() should set default children names as ->useAttributeAsKey() is used at path "%s"', $path)
+                );
+            }
+
+            if (null === $this->key && (is_string($this->addDefaultChildren) || is_array($this->addDefaultChildren))) {
+                throw new InvalidDefinitionException(
+                    sprintf('->addDefaultChildrenIfNoneSet() might not set default children names as ->useAttributeAsKey() is not used at path "%s"', $path)
+                );
+            }
+        }
+    }
+}
diff --git a/core/vendor/Symfony/Component/Config/Definition/Builder/BooleanNodeDefinition.php b/core/vendor/Symfony/Component/Config/Definition/Builder/BooleanNodeDefinition.php
new file mode 100644
index 0000000..7ee4d4d
--- /dev/null
+++ b/core/vendor/Symfony/Component/Config/Definition/Builder/BooleanNodeDefinition.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\Config\Definition\Builder;
+
+use Symfony\Component\Config\Definition\BooleanNode;
+
+/**
+ * This class provides a fluent interface for defining a node.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+class BooleanNodeDefinition extends ScalarNodeDefinition
+{
+    /**
+     * {@inheritDoc}
+     */
+    public function __construct($name, NodeParentInterface $parent = null)
+    {
+        parent::__construct($name, $parent);
+
+        $this->nullEquivalent = true;
+    }
+
+    /**
+     * Instantiate a Node
+     *
+     * @return BooleanNode The node
+     */
+    protected function instantiateNode()
+    {
+        return new BooleanNode($this->name, $this->parent);
+    }
+
+}
diff --git a/core/vendor/Symfony/Component/Config/Definition/Builder/ExprBuilder.php b/core/vendor/Symfony/Component/Config/Definition/Builder/ExprBuilder.php
new file mode 100644
index 0000000..7bf87db
--- /dev/null
+++ b/core/vendor/Symfony/Component/Config/Definition/Builder/ExprBuilder.php
@@ -0,0 +1,227 @@
+<?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\Config\Definition\Builder;
+use Symfony\Component\Config\Definition\Exception\UnsetKeyException;
+
+/**
+ * This class builds an if expression.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ * @author Christophe Coevoet <stof@notk.org>
+ */
+class ExprBuilder
+{
+    protected $node;
+    public $ifPart;
+    public $thenPart;
+
+    /**
+     * Constructor
+     *
+     * @param NodeDefinition $node The related node
+     */
+    public function __construct(NodeDefinition $node)
+    {
+        $this->node = $node;
+    }
+
+    /**
+     * Marks the expression as being always used.
+     *
+     * @return ExprBuilder
+     */
+    public function always(\Closure $then = null)
+    {
+        $this->ifPart = function($v) { return true; };
+
+        if (null !== $then) {
+            $this->thenPart = $then;
+        }
+
+        return $this;
+    }
+
+    /**
+     * Sets a closure to use as tests.
+     *
+     * The default one tests if the value is true.
+     *
+     * @param \Closure $closure
+     *
+     * @return ExprBuilder
+     */
+    public function ifTrue(\Closure $closure = null)
+    {
+        if (null === $closure) {
+            $closure = function($v) { return true === $v; };
+        }
+
+        $this->ifPart = $closure;
+
+        return $this;
+    }
+
+    /**
+     * Tests if the value is a string.
+     *
+     * @return ExprBuilder
+     */
+    public function ifString()
+    {
+        $this->ifPart = function($v) { return is_string($v); };
+
+        return $this;
+    }
+
+    /**
+     * Tests if the value is null.
+     *
+     * @return ExprBuilder
+     */
+    public function ifNull()
+    {
+        $this->ifPart = function($v) { return null === $v; };
+
+        return $this;
+    }
+
+    /**
+     * Tests if the value is an array.
+     *
+     * @return ExprBuilder
+     */
+    public function ifArray()
+    {
+        $this->ifPart = function($v) { return is_array($v); };
+
+        return $this;
+    }
+
+    /**
+     * Tests if the value is in an array.
+     *
+     * @param array $array
+     *
+     * @return ExprBuilder
+     */
+    public function ifInArray(array $array)
+    {
+        $this->ifPart = function($v) use ($array) { return in_array($v, $array, true); };
+
+        return $this;
+    }
+
+    /**
+     * Tests if the value is not in an array.
+     *
+     * @param array $array
+     *
+     * @return ExprBuilder
+     */
+    public function ifNotInArray(array $array)
+    {
+        $this->ifPart = function($v) use ($array) { return !in_array($v, $array, true); };
+
+        return $this;
+    }
+
+    /**
+     * Sets the closure to run if the test pass.
+     *
+     * @param \Closure $closure
+     *
+     * @return ExprBuilder
+     */
+    public function then(\Closure $closure)
+    {
+        $this->thenPart = $closure;
+
+        return $this;
+    }
+
+    /**
+     * Sets a closure returning an empty array.
+     *
+     * @return ExprBuilder
+     */
+    public function thenEmptyArray()
+    {
+        $this->thenPart = function($v) { return array(); };
+
+        return $this;
+    }
+
+    /**
+     * Sets a closure marking the value as invalid at validation time.
+     *
+     * if you want to add the value of the node in your message just use a %s placeholder.
+     *
+     * @param string $message
+     *
+     * @return ExprBuilder
+     */
+    public function thenInvalid($message)
+    {
+        $this->thenPart = function ($v) use ($message) {throw new \InvalidArgumentException(sprintf($message, json_encode($v))); };
+
+        return $this;
+    }
+
+    /**
+     * Sets a closure unsetting this key of the array at validation time.
+     *
+     * @return ExprBuilder
+     */
+    public function thenUnset()
+    {
+        $this->thenPart = function ($v) { throw new UnsetKeyException('Unsetting key'); };
+
+        return $this;
+    }
+
+    /**
+     * Returns the related node
+     *
+     * @return NodeDefinition
+     */
+    public function end()
+    {
+        if (null === $this->ifPart) {
+            throw new \RuntimeException('You must specify an if part.');
+        }
+        if (null === $this->thenPart) {
+            throw new \RuntimeException('You must specify a then part.');
+        }
+
+        return $this->node;
+    }
+
+    /**
+     * Builds the expressions.
+     *
+     * @param array $expressions An array of ExprBuilder instances to build
+     *
+     * @return array
+     */
+    static public function buildExpressions(array $expressions)
+    {
+        foreach ($expressions as $k => $expr) {
+            if ($expr instanceof ExprBuilder) {
+                $expressions[$k] = function($v) use($expr) {
+                    return call_user_func($expr->ifPart, $v) ? call_user_func($expr->thenPart, $v) : $v;
+                };
+            }
+        }
+
+        return $expressions;
+    }
+}
diff --git a/core/vendor/Symfony/Component/Config/Definition/Builder/MergeBuilder.php b/core/vendor/Symfony/Component/Config/Definition/Builder/MergeBuilder.php
new file mode 100644
index 0000000..5e09ff5
--- /dev/null
+++ b/core/vendor/Symfony/Component/Config/Definition/Builder/MergeBuilder.php
@@ -0,0 +1,74 @@
+<?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\Config\Definition\Builder;
+
+/**
+ * This class builds merge conditions.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+class MergeBuilder
+{
+    protected $node;
+    public $allowFalse;
+    public $allowOverwrite;
+
+    /**
+     * Constructor
+     *
+     * @param NodeDefinition $node The related node
+     */
+    public function __construct(NodeDefinition $node)
+    {
+        $this->node = $node;
+        $this->allowFalse = false;
+        $this->allowOverwrite = true;
+    }
+
+    /**
+     * Sets whether the node can be unset.
+     *
+     * @param Boolean $allow
+     *
+     * @return MergeBuilder
+     */
+    public function allowUnset($allow = true)
+    {
+        $this->allowFalse = $allow;
+
+        return $this;
+    }
+
+    /**
+     * Sets whether the node can be overwritten.
+     *
+     * @param Boolean $deny Whether the overwriting is forbidden or not
+     *
+     * @return MergeBuilder
+     */
+    public function denyOverwrite($deny = true)
+    {
+        $this->allowOverwrite = !$deny;
+
+        return $this;
+    }
+
+    /**
+     * Returns the related node.
+     *
+     * @return NodeDefinition
+     */
+    public function end()
+    {
+        return $this->node;
+    }
+}
diff --git a/core/vendor/Symfony/Component/Config/Definition/Builder/NodeBuilder.php b/core/vendor/Symfony/Component/Config/Definition/Builder/NodeBuilder.php
new file mode 100644
index 0000000..3212040
--- /dev/null
+++ b/core/vendor/Symfony/Component/Config/Definition/Builder/NodeBuilder.php
@@ -0,0 +1,206 @@
+<?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\Config\Definition\Builder;
+
+/**
+ * This class provides a fluent interface for building a node.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+class NodeBuilder implements NodeParentInterface
+{
+    protected $parent;
+    protected $nodeMapping;
+
+    /**
+     * Constructor
+     *
+     */
+    public function __construct()
+    {
+        $this->nodeMapping = array(
+            'variable'    => __NAMESPACE__.'\\VariableNodeDefinition',
+            'scalar'      => __NAMESPACE__.'\\ScalarNodeDefinition',
+            'boolean'     => __NAMESPACE__.'\\BooleanNodeDefinition',
+            'array'       => __NAMESPACE__.'\\ArrayNodeDefinition',
+        );
+    }
+
+    /**
+     * Set the parent node.
+     *
+     * @param ParentNodeDefinitionInterface $parent The parent node
+     *
+     * @return NodeBuilder This node builder
+     */
+    public function setParent(ParentNodeDefinitionInterface $parent = null)
+    {
+        $this->parent = $parent;
+
+        return $this;
+    }
+
+    /**
+     * Creates a child array node.
+     *
+     * @param string $name The name of the node
+     *
+     * @return ArrayNodeDefinition The child node
+     */
+    public function arrayNode($name)
+    {
+        return $this->node($name, 'array');
+    }
+
+    /**
+     * Creates a child scalar node.
+     *
+     * @param string $name the name of the node
+     *
+     * @return ScalarNodeDefinition The child node
+     */
+    public function scalarNode($name)
+    {
+        return $this->node($name, 'scalar');
+    }
+
+    /**
+     * Creates a child Boolean node.
+     *
+     * @param string $name The name of the node
+     *
+     * @return BooleanNodeDefinition The child node
+     */
+    public function booleanNode($name)
+    {
+        return $this->node($name, 'boolean');
+    }
+
+    /**
+     * Creates a child variable node.
+     *
+     * @param string $name The name of the node
+     *
+     * @return VariableNodeDefinition The builder of the child node
+     */
+    public function variableNode($name)
+    {
+        return $this->node($name, 'variable');
+    }
+
+    /**
+     * Returns the parent node.
+     *
+     * @return ParentNodeDefinitionInterface The parent node
+     */
+    public function end()
+    {
+        return $this->parent;
+    }
+
+    /**
+     * Creates a child node.
+     *
+     * @param string $name The name of the node
+     * @param string $type The type of the node
+     *
+     * @return NodeDefinition The child node
+     *
+     * @throws \RuntimeException When the node type is not registered
+     * @throws \RuntimeException When the node class is not found
+     */
+    public function node($name, $type)
+    {
+        $class = $this->getNodeClass($type);
+
+        $node = new $class($name);
+
+        $this->append($node);
+
+        return $node;
+    }
+
+    /**
+     * Appends a node definition.
+     *
+     * Usage:
+     *
+     *     $node = new ArrayNodeDefinition('name')
+     *         ->children()
+     *             ->scalarNode('foo')->end()
+     *             ->scalarNode('baz')->end()
+     *             ->append($this->getBarNodeDefinition())
+     *         ->end()
+     *     ;
+     *
+     * @return NodeBuilder This node builder
+     */
+    public function append(NodeDefinition $node)
+    {
+        if ($node instanceof ParentNodeDefinitionInterface) {
+            $builder = clone $this;
+            $builder->setParent(null);
+            $node->setBuilder($builder);
+        }
+
+        if (null !== $this->parent) {
+            $this->parent->append($node);
+            // Make this builder the node parent to allow for a fluid interface
+            $node->setParent($this);
+        }
+
+        return $this;
+    }
+
+    /**
+     * Adds or overrides a node Type.
+     *
+     * @param string $type The name of the type
+     * @param string $class The fully qualified name the node definition class
+     *
+     * @return NodeBuilder This node builder
+     */
+    public function setNodeClass($type, $class)
+    {
+        $this->nodeMapping[strtolower($type)] = $class;
+
+        return $this;
+    }
+
+    /**
+     * Returns the class name of the node definition.
+     *
+     * @param string $type The node type
+     *
+     * @return string The node definition class name
+     *
+     * @throws \RuntimeException When the node type is not registered
+     * @throws \RuntimeException When the node class is not found
+     */
+    protected function getNodeClass($type)
+    {
+        $type = strtolower($type);
+
+        if (!isset($this->nodeMapping[$type])) {
+            throw new \RuntimeException(sprintf('The node type "%s" is not registered.', $type));
+        }
+
+        $class = $this->nodeMapping[$type];
+
+        if (!class_exists($class)) {
+            throw new \RuntimeException(sprintf('The node class "%s" does not exist.', $class));
+        }
+
+        return $class;
+    }
+
+}
diff --git a/core/vendor/Symfony/Component/Config/Definition/Builder/NodeDefinition.php b/core/vendor/Symfony/Component/Config/Definition/Builder/NodeDefinition.php
new file mode 100644
index 0000000..561143b
--- /dev/null
+++ b/core/vendor/Symfony/Component/Config/Definition/Builder/NodeDefinition.php
@@ -0,0 +1,333 @@
+<?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\Config\Definition\Builder;
+
+use Symfony\Component\Config\Definition\NodeInterface;
+
+/**
+ * This class provides a fluent interface for defining a node.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+abstract class NodeDefinition implements NodeParentInterface
+{
+    protected $name;
+    protected $normalization;
+    protected $validation;
+    protected $defaultValue;
+    protected $default;
+    protected $required;
+    protected $merge;
+    protected $allowEmptyValue;
+    protected $nullEquivalent;
+    protected $trueEquivalent;
+    protected $falseEquivalent;
+    protected $parent;
+    protected $info;
+    protected $example;
+
+    /**
+     * Constructor
+     *
+     * @param string                $name   The name of the node
+     * @param NodeParentInterface   $parent The parent
+     */
+    public function __construct($name, NodeParentInterface $parent = null)
+    {
+        $this->parent = $parent;
+        $this->name = $name;
+        $this->default = false;
+        $this->required = false;
+        $this->trueEquivalent = true;
+        $this->falseEquivalent = false;
+    }
+
+    /**
+     * Sets the parent node.
+     *
+     * @param NodeParentInterface $parent The parent
+     */
+    public function setParent(NodeParentInterface $parent)
+    {
+        $this->parent = $parent;
+
+        return $this;
+    }
+
+    /**
+     * Sets info message.
+     *
+     * @param string $info The info text
+     *
+     * @return NodeDefinition
+     */
+    public function setInfo($info)
+    {
+        $this->info = $info;
+
+        return $this;
+    }
+
+    /**
+     * Sets example configuration.
+     *
+     * @param string|array $example
+     *
+     * @return NodeDefinition
+     */
+    public function setExample($example)
+    {
+        $this->example = $example;
+
+        return $this;
+    }
+
+    /**
+     * Returns the parent node.
+     *
+     * @return NodeParentInterface The builder of the parent node
+     */
+    public function end()
+    {
+        return $this->parent;
+    }
+
+    /**
+     * Creates the node.
+     *
+     * @param Boolean $forceRootNode Whether to force this node as the root node
+     *
+     * @return NodeInterface
+     */
+    public function getNode($forceRootNode = false)
+    {
+        if ($forceRootNode) {
+            $this->parent = null;
+        }
+
+        if (null !== $this->normalization) {
+            $this->normalization->before = ExprBuilder::buildExpressions($this->normalization->before);
+        }
+
+        if (null !== $this->validation) {
+            $this->validation->rules = ExprBuilder::buildExpressions($this->validation->rules);
+        }
+
+        $node = $this->createNode();
+
+        $node->setInfo($this->info);
+        $node->setExample($this->example);
+
+        return $node;
+    }
+
+    /**
+     * Sets the default value.
+     *
+     * @param mixed $value The default value
+     *
+     * @return NodeDefinition
+     */
+    public function defaultValue($value)
+    {
+        $this->default = true;
+        $this->defaultValue = $value;
+
+        return $this;
+    }
+
+    /**
+     * Sets the node as required.
+     *
+     * @return NodeDefinition
+     */
+    public function isRequired()
+    {
+        $this->required = true;
+
+        return $this;
+    }
+
+    /**
+     * Sets the equivalent value used when the node contains null.
+     *
+     * @param mixed $value
+     *
+     * @return NodeDefinition
+     */
+    public function treatNullLike($value)
+    {
+        $this->nullEquivalent = $value;
+
+        return $this;
+    }
+
+    /**
+     * Sets the equivalent value used when the node contains true.
+     *
+     * @param mixed $value
+     *
+     * @return NodeDefinition
+     */
+    public function treatTrueLike($value)
+    {
+        $this->trueEquivalent = $value;
+
+        return $this;
+    }
+
+    /**
+     * Sets the equivalent value used when the node contains false.
+     *
+     * @param mixed $value
+     *
+     * @return NodeDefinition
+     */
+    public function treatFalseLike($value)
+    {
+        $this->falseEquivalent = $value;
+
+        return $this;
+    }
+
+    /**
+     * Sets null as the default value.
+     *
+     * @return NodeDefinition
+     */
+    public function defaultNull()
+    {
+        return $this->defaultValue(null);
+    }
+
+    /**
+     * Sets true as the default value.
+     *
+     * @return NodeDefinition
+     */
+    public function defaultTrue()
+    {
+        return $this->defaultValue(true);
+    }
+
+    /**
+     * Sets false as the default value.
+     *
+     * @return NodeDefinition
+     */
+    public function defaultFalse()
+    {
+        return $this->defaultValue(false);
+    }
+
+    /**
+     * Sets an expression to run before the normalization.
+     *
+     * @return ExprBuilder
+     */
+    public function beforeNormalization()
+    {
+        return $this->normalization()->before();
+    }
+
+    /**
+     * Denies the node value being empty.
+     *
+     * @return NodeDefinition
+     */
+    public function cannotBeEmpty()
+    {
+        $this->allowEmptyValue = false;
+
+        return $this;
+    }
+
+    /**
+     * Sets an expression to run for the validation.
+     *
+     * The expression receives the value of the node and must return it. It can
+     * modify it.
+     * An exception should be thrown when the node is not valid.
+     *
+     * @return ExprBuilder
+     */
+    public function validate()
+    {
+        return $this->validation()->rule();
+    }
+
+    /**
+     * Sets whether the node can be overwritten.
+     *
+     * @param Boolean $deny Whether the overwriting is forbidden or not
+     *
+     * @return NodeDefinition
+     */
+    public function cannotBeOverwritten($deny = true)
+    {
+        $this->merge()->denyOverwrite($deny);
+
+        return $this;
+    }
+
+    /**
+     * Gets the builder for validation rules.
+     *
+     * @return ValidationBuilder
+     */
+    protected function validation()
+    {
+        if (null === $this->validation) {
+            $this->validation = new ValidationBuilder($this);
+        }
+
+        return $this->validation;
+    }
+
+    /**
+     * Gets the builder for merging rules.
+     *
+     * @return MergeBuilder
+     */
+    protected function merge()
+    {
+        if (null === $this->merge) {
+            $this->merge = new MergeBuilder($this);
+        }
+
+        return $this->merge;
+    }
+
+    /**
+     * Gets the builder for normalization rules.
+     *
+     * @return NormalizationBuilder
+     */
+    protected function normalization()
+    {
+        if (null === $this->normalization) {
+            $this->normalization = new NormalizationBuilder($this);
+        }
+
+        return $this->normalization;
+    }
+
+    /**
+     * Instantiate and configure the node according to this definition
+     *
+     * @return NodeInterface $node The node instance
+     *
+     * @throws Symfony\Component\Config\Definition\Exception\InvalidDefinitionException When the definition is invalid
+     */
+    abstract protected function createNode();
+
+}
diff --git a/core/vendor/Symfony/Component/Config/Definition/Builder/NodeParentInterface.php b/core/vendor/Symfony/Component/Config/Definition/Builder/NodeParentInterface.php
new file mode 100644
index 0000000..24f3971
--- /dev/null
+++ b/core/vendor/Symfony/Component/Config/Definition/Builder/NodeParentInterface.php
@@ -0,0 +1,21 @@
+<?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\Config\Definition\Builder;
+
+/**
+ * An interface that must be implemented by all node parents
+ *
+ * @author Victor Berchet <victor@suumit.com>
+ */
+interface NodeParentInterface
+{
+}
diff --git a/core/vendor/Symfony/Component/Config/Definition/Builder/NormalizationBuilder.php b/core/vendor/Symfony/Component/Config/Definition/Builder/NormalizationBuilder.php
new file mode 100644
index 0000000..87f25b7
--- /dev/null
+++ b/core/vendor/Symfony/Component/Config/Definition/Builder/NormalizationBuilder.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\Config\Definition\Builder;
+
+/**
+ * This class builds normalization conditions.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+class NormalizationBuilder
+{
+    protected $node;
+    public $before;
+    public $remappings;
+
+    /**
+     * Constructor
+     *
+     * @param NodeDefinition $node The related node
+     */
+    public function __construct(NodeDefinition $node)
+    {
+        $this->node = $node;
+        $this->keys = false;
+        $this->remappings = array();
+        $this->before = array();
+    }
+
+    /**
+     * Registers a key to remap to its plural form.
+     *
+     * @param string $key    The key to remap
+     * @param string $plural The plural of the key in case of irregular plural
+     *
+     * @return NormalizationBuilder
+     */
+    public function remap($key, $plural = null)
+    {
+        $this->remappings[] = array($key, null === $plural ? $key.'s' : $plural);
+
+        return $this;
+    }
+
+    /**
+     * Registers a closure to run before the normalization or an expression builder to build it if null is provided.
+     *
+     * @param \Closure $closure
+     *
+     * @return ExprBuilder|NormalizationBuilder
+     */
+    public function before(\Closure $closure = null)
+    {
+        if (null !== $closure) {
+            $this->before[] = $closure;
+
+            return $this;
+        }
+
+        return $this->before[] = new ExprBuilder($this->node);
+    }
+}
diff --git a/core/vendor/Symfony/Component/Config/Definition/Builder/ParentNodeDefinitionInterface.php b/core/vendor/Symfony/Component/Config/Definition/Builder/ParentNodeDefinitionInterface.php
new file mode 100644
index 0000000..2d95954
--- /dev/null
+++ b/core/vendor/Symfony/Component/Config/Definition/Builder/ParentNodeDefinitionInterface.php
@@ -0,0 +1,26 @@
+<?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\Config\Definition\Builder;
+
+/**
+ * An interface that must be implemented by nodes which can have children
+ *
+ * @author Victor Berchet <victor@suumit.com>
+ */
+interface ParentNodeDefinitionInterface
+{
+    function children();
+
+    function append(NodeDefinition $node);
+
+    function setBuilder(NodeBuilder $builder);
+}
diff --git a/core/vendor/Symfony/Component/Config/Definition/Builder/ScalarNodeDefinition.php b/core/vendor/Symfony/Component/Config/Definition/Builder/ScalarNodeDefinition.php
new file mode 100644
index 0000000..0307ecd
--- /dev/null
+++ b/core/vendor/Symfony/Component/Config/Definition/Builder/ScalarNodeDefinition.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\Config\Definition\Builder;
+
+use Symfony\Component\Config\Definition\ScalarNode;
+
+/**
+ * This class provides a fluent interface for defining a node.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+class ScalarNodeDefinition extends VariableNodeDefinition
+{
+    /**
+     * Instantiate a Node
+     *
+     * @return ScalarNode The node
+     */
+    protected function instantiateNode()
+    {
+        return new ScalarNode($this->name, $this->parent);
+    }
+
+}
diff --git a/core/vendor/Symfony/Component/Config/Definition/Builder/TreeBuilder.php b/core/vendor/Symfony/Component/Config/Definition/Builder/TreeBuilder.php
new file mode 100644
index 0000000..472cfde
--- /dev/null
+++ b/core/vendor/Symfony/Component/Config/Definition/Builder/TreeBuilder.php
@@ -0,0 +1,59 @@
+<?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\Config\Definition\Builder;
+
+/**
+ * This is the entry class for building a config tree.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+class TreeBuilder implements NodeParentInterface
+{
+    protected $tree;
+    protected $root;
+    protected $builder;
+
+    /**
+     * Creates the root node.
+     *
+     * @param string      $name     The name of the root node
+     * @param string      $type     The type of the root node
+     * @param NodeBuilder $builder  A custom node builder instance
+     *
+     * @return ArrayNodeDefinition|NodeDefinition The root node (as an ArrayNodeDefinition when the type is 'array')
+     *
+     * @throws \RuntimeException When the node type is not supported
+     */
+    public function root($name, $type = 'array', NodeBuilder $builder = null)
+    {
+        $builder = $builder ?: new NodeBuilder();
+
+        return $this->root = $builder->node($name, $type)->setParent($this);
+    }
+
+    /**
+     * Builds the tree.
+     *
+     * @return NodeInterface
+     */
+    public function buildTree()
+    {
+        if (null === $this->root) {
+            throw new \RuntimeException('The configuration tree has no root node.');
+        }
+        if (null !== $this->tree) {
+            return $this->tree;
+        }
+
+        return $this->tree = $this->root->getNode(true);
+    }
+}
diff --git a/core/vendor/Symfony/Component/Config/Definition/Builder/ValidationBuilder.php b/core/vendor/Symfony/Component/Config/Definition/Builder/ValidationBuilder.php
new file mode 100644
index 0000000..22f54a1
--- /dev/null
+++ b/core/vendor/Symfony/Component/Config/Definition/Builder/ValidationBuilder.php
@@ -0,0 +1,53 @@
+<?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\Config\Definition\Builder;
+
+/**
+ * This class builds validation conditions.
+ *
+ * @author Christophe Coevoet <stof@notk.org>
+ */
+class ValidationBuilder
+{
+    protected $node;
+    public $rules;
+
+    /**
+     * Constructor
+     *
+     * @param NodeDefinition $node The related node
+     */
+    public function __construct(NodeDefinition $node)
+    {
+        $this->node = $node;
+
+        $this->rules = array();
+    }
+
+    /**
+     * Registers a closure to run as normalization or an expression builder to build it if null is provided.
+     *
+     * @param \Closure $closure
+     *
+     * @return ExprBuilder|ValidationBuilder
+     */
+    public function rule(\Closure $closure = null)
+    {
+        if (null !== $closure) {
+            $this->rules[] = $closure;
+
+            return $this;
+        }
+
+        return $this->rules[] = new ExprBuilder($this->node);
+    }
+}
diff --git a/core/vendor/Symfony/Component/Config/Definition/Builder/VariableNodeDefinition.php b/core/vendor/Symfony/Component/Config/Definition/Builder/VariableNodeDefinition.php
new file mode 100644
index 0000000..75da3ab
--- /dev/null
+++ b/core/vendor/Symfony/Component/Config/Definition/Builder/VariableNodeDefinition.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\Config\Definition\Builder;
+
+use Symfony\Component\Config\Definition\VariableNode;
+
+/**
+ * This class provides a fluent interface for defining a node.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+class VariableNodeDefinition extends NodeDefinition
+{
+    /**
+     * Instantiate a Node
+     *
+     * @return VariableNode The node
+     */
+    protected function instantiateNode()
+    {
+        return new VariableNode($this->name, $this->parent);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected function createNode()
+    {
+        $node = $this->instantiateNode();
+
+        if (null !== $this->normalization) {
+            $node->setNormalizationClosures($this->normalization->before);
+        }
+
+        if (null !== $this->merge) {
+            $node->setAllowOverwrite($this->merge->allowOverwrite);
+        }
+
+        if (true === $this->default) {
+            $node->setDefaultValue($this->defaultValue);
+        }
+
+        if (false === $this->allowEmptyValue) {
+            $node->setAllowEmptyValue($this->allowEmptyValue);
+        }
+
+        $node->addEquivalentValue(null, $this->nullEquivalent);
+        $node->addEquivalentValue(true, $this->trueEquivalent);
+        $node->addEquivalentValue(false, $this->falseEquivalent);
+        $node->setRequired($this->required);
+
+        if (null !== $this->validation) {
+            $node->setFinalValidationClosures($this->validation->rules);
+        }
+
+        return $node;
+    }
+
+}
diff --git a/core/vendor/Symfony/Component/Config/Definition/ConfigurationInterface.php b/core/vendor/Symfony/Component/Config/Definition/ConfigurationInterface.php
new file mode 100644
index 0000000..dc189e2
--- /dev/null
+++ b/core/vendor/Symfony/Component/Config/Definition/ConfigurationInterface.php
@@ -0,0 +1,27 @@
+<?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\Config\Definition;
+
+/**
+ * Configuration interface
+ *
+ * @author Victor Berchet <victor@suumit.com>
+ */
+interface ConfigurationInterface
+{
+    /**
+     * Generates the configuration tree builder.
+     *
+     * @return \Symfony\Component\Config\Definition\Builder\TreeBuilder The tree builder
+     */
+    function getConfigTreeBuilder();
+}
diff --git a/core/vendor/Symfony/Component/Config/Definition/Exception/DuplicateKeyException.php b/core/vendor/Symfony/Component/Config/Definition/Exception/DuplicateKeyException.php
new file mode 100644
index 0000000..48dd932
--- /dev/null
+++ b/core/vendor/Symfony/Component/Config/Definition/Exception/DuplicateKeyException.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\Config\Definition\Exception;
+
+/**
+ * This exception is thrown whenever the key of an array is not unique. This can
+ * only be the case if the configuration is coming from an XML file.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+class DuplicateKeyException extends InvalidConfigurationException
+{
+}
diff --git a/core/vendor/Symfony/Component/Config/Definition/Exception/Exception.php b/core/vendor/Symfony/Component/Config/Definition/Exception/Exception.php
new file mode 100644
index 0000000..1fda6c2
--- /dev/null
+++ b/core/vendor/Symfony/Component/Config/Definition/Exception/Exception.php
@@ -0,0 +1,21 @@
+<?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\Config\Definition\Exception;
+
+/**
+ * Base exception for all configuration exceptions
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+class Exception extends \RuntimeException
+{
+}
diff --git a/core/vendor/Symfony/Component/Config/Definition/Exception/ForbiddenOverwriteException.php b/core/vendor/Symfony/Component/Config/Definition/Exception/ForbiddenOverwriteException.php
new file mode 100644
index 0000000..726c07f
--- /dev/null
+++ b/core/vendor/Symfony/Component/Config/Definition/Exception/ForbiddenOverwriteException.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\Config\Definition\Exception;
+
+/**
+ * This exception is thrown when a configuration path is overwritten from a
+ * subsequent configuration file, but the entry node specifically forbids this.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+class ForbiddenOverwriteException extends InvalidConfigurationException
+{
+}
diff --git a/core/vendor/Symfony/Component/Config/Definition/Exception/InvalidConfigurationException.php b/core/vendor/Symfony/Component/Config/Definition/Exception/InvalidConfigurationException.php
new file mode 100644
index 0000000..840e3f3
--- /dev/null
+++ b/core/vendor/Symfony/Component/Config/Definition/Exception/InvalidConfigurationException.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\Config\Definition\Exception;
+
+/**
+ * A very general exception which can be thrown whenever non of the more specific
+ * exceptions is suitable.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+class InvalidConfigurationException extends Exception
+{
+    private $path;
+
+    public function setPath($path)
+    {
+        $this->path = $path;
+    }
+
+    public function getPath()
+    {
+        return $this->path;
+    }
+}
diff --git a/core/vendor/Symfony/Component/Config/Definition/Exception/InvalidDefinitionException.php b/core/vendor/Symfony/Component/Config/Definition/Exception/InvalidDefinitionException.php
new file mode 100644
index 0000000..98310da
--- /dev/null
+++ b/core/vendor/Symfony/Component/Config/Definition/Exception/InvalidDefinitionException.php
@@ -0,0 +1,21 @@
+<?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\Config\Definition\Exception;
+
+/**
+ * Thrown when an error is detected in a node Definition.
+ *
+ * @author Victor Berchet <victor.berchet@suumit.com>
+ */
+class InvalidDefinitionException extends Exception
+{
+}
diff --git a/core/vendor/Symfony/Component/Config/Definition/Exception/InvalidTypeException.php b/core/vendor/Symfony/Component/Config/Definition/Exception/InvalidTypeException.php
new file mode 100644
index 0000000..d7ca8c9
--- /dev/null
+++ b/core/vendor/Symfony/Component/Config/Definition/Exception/InvalidTypeException.php
@@ -0,0 +1,21 @@
+<?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\Config\Definition\Exception;
+
+/**
+ * This exception is thrown if an invalid type is encountered.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+class InvalidTypeException extends InvalidConfigurationException
+{
+}
diff --git a/core/vendor/Symfony/Component/Config/Definition/Exception/UnsetKeyException.php b/core/vendor/Symfony/Component/Config/Definition/Exception/UnsetKeyException.php
new file mode 100644
index 0000000..863181a
--- /dev/null
+++ b/core/vendor/Symfony/Component/Config/Definition/Exception/UnsetKeyException.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\Config\Definition\Exception;
+
+/**
+ * This exception is usually not encountered by the end-user, but only used
+ * internally to signal the parent scope to unset a key.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+class UnsetKeyException extends Exception
+{
+}
diff --git a/core/vendor/Symfony/Component/Config/Definition/NodeInterface.php b/core/vendor/Symfony/Component/Config/Definition/NodeInterface.php
new file mode 100644
index 0000000..89c4360
--- /dev/null
+++ b/core/vendor/Symfony/Component/Config/Definition/NodeInterface.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\Config\Definition;
+
+/**
+ * Common Interface among all nodes.
+ *
+ * In most cases, it is better to inherit from BaseNode instead of implementing
+ * this interface yourself.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+interface NodeInterface
+{
+    /**
+     * Returns the name of the node.
+     *
+     * @return string The name of the node
+     */
+    function getName();
+
+    /**
+     * Returns the path of the node.
+     *
+     * @return string The node path
+     */
+    function getPath();
+
+    /**
+     * Returns true when the node is required.
+     *
+     * @return Boolean If the node is required
+     */
+    function isRequired();
+
+    /**
+     * Returns true when the node has a default value.
+     *
+     * @return Boolean If the node has a default value
+     */
+    function hasDefaultValue();
+
+    /**
+     * Returns the default value of the node.
+     *
+     * @return mixed The default value
+     * @throws \RuntimeException if the node has no default value
+     */
+    function getDefaultValue();
+
+    /**
+     * Normalizes the supplied value.
+     *
+     * @param mixed $value The value to normalize
+     *
+     * @return mixed The normalized value
+     */
+    function normalize($value);
+
+    /**
+     * Merges two values together.
+     *
+     * @param mixed $leftSide
+     * @param mixed $rightSide
+     *
+     * @return mixed The merged values
+     */
+    function merge($leftSide, $rightSide);
+
+    /**
+     * Finalizes a value.
+     *
+     * @param mixed $value The value to finalize
+     *
+     * @return mixed The finalized value
+     */
+    function finalize($value);
+}
diff --git a/core/vendor/Symfony/Component/Config/Definition/Processor.php b/core/vendor/Symfony/Component/Config/Definition/Processor.php
new file mode 100644
index 0000000..2ad8d1b
--- /dev/null
+++ b/core/vendor/Symfony/Component/Config/Definition/Processor.php
@@ -0,0 +1,127 @@
+<?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\Config\Definition;
+
+/**
+ * This class is the entry point for config normalization/merging/finalization.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+class Processor
+{
+    /**
+     * Processes an array of configurations.
+     *
+     * @param NodeInterface $configTree The node tree describing the configuration
+     * @param array         $configs    An array of configuration items to process
+     *
+     * @return array The processed configuration
+     */
+    public function process(NodeInterface $configTree, array $configs)
+    {
+        $configs = self::normalizeKeys($configs);
+
+        $currentConfig = array();
+        foreach ($configs as $config) {
+            $config = $configTree->normalize($config);
+            $currentConfig = $configTree->merge($currentConfig, $config);
+        }
+
+        return $configTree->finalize($currentConfig);
+    }
+
+    /**
+     * Processes an array of configurations.
+     *
+     * @param ConfigurationInterface $configuration  The configuration class
+     * @param array                  $configs        An array of configuration items to process
+     *
+     * @return array The processed configuration
+     */
+    public function processConfiguration(ConfigurationInterface $configuration, array $configs)
+    {
+        return $this->process($configuration->getConfigTreeBuilder()->buildTree(), $configs);
+    }
+
+    /**
+     * This method normalizes keys between the different configuration formats
+     *
+     * Namely, you mostly have foo_bar in YAML while you have foo-bar in XML.
+     * After running this method, all keys are normalized to foo_bar.
+     *
+     * If you have a mixed key like foo-bar_moo, it will not be altered.
+     * The key will also not be altered if the target key already exists.
+     *
+     * @param array $config
+     *
+     * @return array the config with normalized keys
+     */
+    static public function normalizeKeys(array $config)
+    {
+        foreach ($config as $key => $value) {
+            if (is_array($value)) {
+                $config[$key] = self::normalizeKeys($value);
+            }
+
+            if (false !== strpos($key, '-') && false === strpos($key, '_') && !array_key_exists($normalizedKey = str_replace('-', '_', $key), $config)) {
+                $config[$normalizedKey] = $config[$key];
+                unset($config[$key]);
+            }
+        }
+
+        return $config;
+    }
+
+    /**
+     * Normalizes a configuration entry.
+     *
+     * This method returns a normalize configuration array for a given key
+     * to remove the differences due to the original format (YAML and XML mainly).
+     *
+     * Here is an example.
+     *
+     * The configuration is XML:
+     *
+     * <twig:extension id="twig.extension.foo" />
+     * <twig:extension id="twig.extension.bar" />
+     *
+     * And the same configuration in YAML:
+     *
+     * twig.extensions: ['twig.extension.foo', 'twig.extension.bar']
+     *
+     * @param array  $config A config array
+     * @param string $key    The key to normalize
+     * @param string $plural The plural form of the key if it is irregular
+     *
+     * @return array
+     */
+    static public function normalizeConfig($config, $key, $plural = null)
+    {
+        if (null === $plural) {
+            $plural = $key.'s';
+        }
+
+        $values = array();
+        if (isset($config[$plural])) {
+            $values = $config[$plural];
+        } elseif (isset($config[$key])) {
+            if (is_string($config[$key]) || !is_int(key($config[$key]))) {
+                // only one
+                $values = array($config[$key]);
+            } else {
+                $values = $config[$key];
+            }
+        }
+
+        return $values;
+    }
+}
diff --git a/core/vendor/Symfony/Component/Config/Definition/PrototypeNodeInterface.php b/core/vendor/Symfony/Component/Config/Definition/PrototypeNodeInterface.php
new file mode 100644
index 0000000..8f08c98
--- /dev/null
+++ b/core/vendor/Symfony/Component/Config/Definition/PrototypeNodeInterface.php
@@ -0,0 +1,27 @@
+<?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\Config\Definition;
+
+/**
+ * This interface must be implemented by nodes which can be used as prototypes.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+interface PrototypeNodeInterface extends NodeInterface
+{
+    /**
+     * Sets the name of the node.
+     *
+     * @param string $name The name of the node
+     */
+    function setName($name);
+}
diff --git a/core/vendor/Symfony/Component/Config/Definition/PrototypedArrayNode.php b/core/vendor/Symfony/Component/Config/Definition/PrototypedArrayNode.php
new file mode 100644
index 0000000..f800a3f
--- /dev/null
+++ b/core/vendor/Symfony/Component/Config/Definition/PrototypedArrayNode.php
@@ -0,0 +1,341 @@
+<?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\Config\Definition;
+
+use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
+use Symfony\Component\Config\Definition\Exception\DuplicateKeyException;
+use Symfony\Component\Config\Definition\Exception\UnsetKeyException;
+use Symfony\Component\Config\Definition\Exception\Exception;
+
+/**
+ * Represents a prototyped Array node in the config tree.
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+class PrototypedArrayNode extends ArrayNode
+{
+    protected $prototype;
+    protected $keyAttribute;
+    protected $removeKeyAttribute;
+    protected $minNumberOfElements;
+    protected $defaultValue;
+    protected $defaultChildren;
+
+    /**
+     * Constructor.
+     *
+     * @param string $name The Node's name
+     * @param NodeInterface $parent The node parent
+     */
+    public function __construct($name, NodeInterface $parent = null)
+    {
+        parent::__construct($name, $parent);
+
+        $this->minNumberOfElements = 0;
+        $this->defaultValue = array();
+    }
+
+    /**
+     * Sets the minimum number of elements that a prototype based node must
+     * contain. By default this is zero, meaning no elements.
+     *
+     * @param integer $number
+     */
+    public function setMinNumberOfElements($number)
+    {
+        $this->minNumberOfElements = $number;
+    }
+
+    /**
+     * Sets the attribute which value is to be used as key.
+     *
+     * This is useful when you have an indexed array that should be an
+     * associative array. You can select an item from within the array
+     * to be the key of the particular item. For example, if "id" is the
+     * "key", then:
+     *
+     *     array(
+     *         array('id' => 'my_name', 'foo' => 'bar'),
+     *     );
+     *
+     *  becomes
+     *
+     *      array(
+     *          'my_name' => array('foo' => 'bar'),
+     *      );
+     *
+     * If you'd like "'id' => 'my_name'" to still be present in the resulting
+     * array, then you can set the second argument of this method to false.
+     *
+     * @param string  $attribute The name of the attribute which value is to be used as a key
+     * @param Boolean $remove Whether or not to remove the key
+     */
+    public function setKeyAttribute($attribute, $remove = true)
+    {
+        $this->keyAttribute = $attribute;
+        $this->removeKeyAttribute = $remove;
+    }
+
+    /**
+     * Retrieves the name of the attribute which value should be used as key.
+     *
+     * @return string The name of the attribute
+     */
+    public function getKeyAttribute()
+    {
+        return $this->keyAttribute;
+    }
+
+    /**
+     * Sets the default value of this node.
+     *
+     * @param string $value
+     *
+     * @throws \InvalidArgumentException if the default value is not an array
+     */
+    public function setDefaultValue($value)
+    {
+        if (!is_array($value)) {
+            throw new \InvalidArgumentException($this->getPath().': the default value of an array node has to be an array.');
+        }
+
+        $this->defaultValue = $value;
+    }
+
+    /**
+     * Checks if the node has a default value.
+     *
+     * @return Boolean
+     */
+    public function hasDefaultValue()
+    {
+        return true;
+    }
+
+    /**
+     * Adds default children when none are set.
+     *
+     * @param integer|string|array|null $children The number of children|The child name|The children names to be added
+     */
+    public function setAddChildrenIfNoneSet($children = array('defaults'))
+    {
+        if (null === $children) {
+            $this->defaultChildren = array('defaults');
+        } else {
+            $this->defaultChildren = is_integer($children) && $children > 0 ? range(1, $children) : (array) $children;
+        }
+    }
+
+    /**
+     * Retrieves the default value.
+     *
+     * The default value could be either explicited or derived from the prototype
+     * default value.
+     *
+     * @return array The default value
+     */
+    public function getDefaultValue()
+    {
+        if (null !== $this->defaultChildren) {
+            $default = $this->prototype->hasDefaultValue() ? $this->prototype->getDefaultValue() : array();
+            $defaults = array();
+            foreach (array_values($this->defaultChildren) as $i => $name) {
+                $defaults[null === $this->keyAttribute ? $i : $name] = $default;
+            }
+
+            return $defaults;
+        }
+
+        return $this->defaultValue;
+    }
+
+    /**
+     * Sets the node prototype.
+     *
+     * @param PrototypeNodeInterface $node
+     */
+    public function setPrototype(PrototypeNodeInterface $node)
+    {
+        $this->prototype = $node;
+    }
+
+    /**
+     * Retrieves the prototype
+     *
+     * @return PrototypeNodeInterface The prototype
+     */
+    public function getPrototype()
+    {
+        return $this->prototype;
+    }
+
+    /**
+     * Disable adding concrete children for prototyped nodes.
+     *
+     * @param NodeInterface $node The child node to add
+     *
+     * @throws \RuntimeException Prototyped array nodes can't have concrete children.
+     */
+    public function addChild(NodeInterface $node)
+    {
+        throw new Exception('A prototyped array node can not have concrete children.');
+    }
+
+    /**
+     * Finalizes the value of this node.
+     *
+     * @param mixed $value
+     *
+     * @return mixed The finalized value
+     *
+     * @throws UnsetKeyException
+     * @throws InvalidConfigurationException if the node doesn't have enough children
+     */
+    protected function finalizeValue($value)
+    {
+        if (false === $value) {
+            $msg = sprintf('Unsetting key for path "%s", value: %s', $this->getPath(), json_encode($value));
+            throw new UnsetKeyException($msg);
+        }
+
+        foreach ($value as $k => $v) {
+            $this->prototype->setName($k);
+            try {
+                $value[$k] = $this->prototype->finalize($v);
+            } catch (UnsetKeyException $unset) {
+                unset($value[$k]);
+            }
+        }
+
+        if (count($value) < $this->minNumberOfElements) {
+            $msg = sprintf('The path "%s" should have at least %d element(s) defined.', $this->getPath(), $this->minNumberOfElements);
+            $ex = new InvalidConfigurationException($msg);
+            $ex->setPath($this->getPath());
+
+            throw $ex;
+        }
+
+        return $value;
+    }
+
+    /**
+     * Normalizes the value.
+     *
+     * @param mixed $value The value to normalize
+     *
+     * @return mixed The normalized value
+     */
+    protected function normalizeValue($value)
+    {
+        if (false === $value) {
+            return $value;
+        }
+
+        $value = $this->remapXml($value);
+
+        $normalized = array();
+        foreach ($value as $k => $v) {
+            if (null !== $this->keyAttribute && is_array($v)) {
+                if (!isset($v[$this->keyAttribute]) && is_int($k)) {
+                    $msg = sprintf('The attribute "%s" must be set for path "%s".', $this->keyAttribute, $this->getPath());
+                    $ex = new InvalidConfigurationException($msg);
+                    $ex->setPath($this->getPath());
+
+                    throw $ex;
+                } elseif (isset($v[$this->keyAttribute])) {
+                    $k = $v[$this->keyAttribute];
+
+                    // remove the key attribute when required
+                    if ($this->removeKeyAttribute) {
+                        unset($v[$this->keyAttribute]);
+                    }
+
+                    // if only "value" is left
+                    if (1 == count($v) && isset($v['value'])) {
+                        $v = $v['value'];
+                    }
+                }
+
+                if (array_key_exists($k, $normalized)) {
+                    $msg = sprintf('Duplicate key "%s" for path "%s".', $k, $this->getPath());
+                    $ex = new DuplicateKeyException($msg);
+                    $ex->setPath($this->getPath());
+
+                    throw $ex;
+                }
+            }
+
+            $this->prototype->setName($k);
+            if (null !== $this->keyAttribute) {
+                $normalized[$k] = $this->prototype->normalize($v);
+            } else {
+                $normalized[] = $this->prototype->normalize($v);
+            }
+        }
+
+        return $normalized;
+    }
+
+    /**
+     * Merges values together.
+     *
+     * @param mixed $leftSide The left side to merge.
+     * @param mixed $rightSide The right side to merge.
+     *
+     * @return mixed The merged values
+     *
+     * @throws InvalidConfigurationException
+     * @throws \RuntimeException
+     */
+    protected function mergeValues($leftSide, $rightSide)
+    {
+        if (false === $rightSide) {
+            // if this is still false after the last config has been merged the
+            // finalization pass will take care of removing this key entirely
+            return false;
+        }
+
+        if (false === $leftSide || !$this->performDeepMerging) {
+            return $rightSide;
+        }
+
+        foreach ($rightSide as $k => $v) {
+            // prototype, and key is irrelevant, so simply append the element
+            if (null === $this->keyAttribute) {
+                $leftSide[] = $v;
+                continue;
+            }
+
+            // no conflict
+            if (!array_key_exists($k, $leftSide)) {
+                if (!$this->allowNewKeys) {
+                    $ex = new InvalidConfigurationException(sprintf(
+                        'You are not allowed to define new elements for path "%s". ' .
+                        'Please define all elements for this path in one config file.',
+                        $this->getPath()
+                    ));
+                    $ex->setPath($this->getPath());
+
+                    throw $ex;
+                }
+
+                $leftSide[$k] = $v;
+                continue;
+            }
+
+            $this->prototype->setName($k);
+            $leftSide[$k] = $this->prototype->merge($leftSide[$k], $v);
+        }
+
+        return $leftSide;
+    }
+}
diff --git a/core/vendor/Symfony/Component/Config/Definition/ScalarNode.php b/core/vendor/Symfony/Component/Config/Definition/ScalarNode.php
new file mode 100644
index 0000000..51141c4
--- /dev/null
+++ b/core/vendor/Symfony/Component/Config/Definition/ScalarNode.php
@@ -0,0 +1,47 @@
+<?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\Config\Definition;
+
+use Symfony\Component\Config\Definition\VariableNode;
+use Symfony\Component\Config\Definition\Exception\InvalidTypeException;
+
+/**
+ * This node represents a scalar value in the config tree.
+ *
+ * The following values are considered scalars:
+ *   * booleans
+ *   * strings
+ *   * null
+ *   * integers
+ *   * floats
+ *
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
+ */
+class ScalarNode extends VariableNode
+{
+    /**
+     * {@inheritDoc}
+     */
+    protected function validateType($value)
+    {
+        if (!is_scalar($value) && null !== $value) {
+            $ex = new InvalidTypeException(sprintf(
+                'Invalid type for path "%s". Expected scalar, but got %s.',
+                $this->getPath(),
+                gettype($value)
+            ));
+            $ex->setPath($this->getPath());
+
+            throw $ex;
+        }
+    }
+}
diff --git a/core/vendor/Symfony/Component/Config/Definition/VariableNode.php b/core/vendor/Symfony/Component/Config/Definition/VariableNode.php
new file mode 100644
index 0000000..69dfea6
--- /dev/null
+++ b/core/vendor/Symfony/Component/Config/Definition/VariableNode.php
@@ -0,0 +1,114 @@
+<?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\Config\Definition;
+
+use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
+
+/**
+ * This node represents a value of variable type in the config tree.
+ *
+ * This node is intended for values of arbitrary type.
+ * Any PHP type is accepted as a value.
+ *
+ * @author Jeremy Mikola <jmikola@gmail.com>
+ */
+class VariableNode extends BaseNode implements PrototypeNodeInterface
+{
+    protected $defaultValueSet = false;
+    protected $defaultValue;
+    protected $allowEmptyValue = true;
+
+    /**
+     * {@inheritDoc}
+     */
+    public function setDefaultValue($value)
+    {
+        $this->defaultValueSet = true;
+        $this->defaultValue = $value;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function hasDefaultValue()
+    {
+        return $this->defaultValueSet;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getDefaultValue()
+    {
+        return $this->defaultValue instanceof \Closure ? call_user_func($this->defaultValue) : $this->defaultValue;
+    }
+
+    /**
+     * Sets if this node is allowed to have an empty value.
+     *
+     * @param Boolean $boolean True if this entity will accept empty values.
+     */
+    public function setAllowEmptyValue($boolean)
+    {
+        $this->allowEmptyValue = (Boolean) $boolean;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function setName($name)
+    {
+        $this->name = $name;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected function validateType($value)
+    {
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected function finalizeValue($value)
+    {
+        if (!$this->allowEmptyValue && empty($value)) {
+            $ex = new InvalidConfigurationException(sprintf(
+                'The path "%s" cannot contain an empty value, but got %s.',
+                $this->getPath(),
+                json_encode($value)
+            ));
+            $ex->setPath($this->getPath());
+
+            throw $ex;
+        }
+
+        return $value;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected function normalizeValue($value)
+    {
+        return $value;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected function mergeValues($leftSide, $rightSide)
+    {
+        return $rightSide;
+    }
+}
diff --git a/core/vendor/Symfony/Component/Config/Exception/FileLoaderImportCircularReferenceException.php b/core/vendor/Symfony/Component/Config/Exception/FileLoaderImportCircularReferenceException.php
new file mode 100644
index 0000000..b1ad442
--- /dev/null
+++ b/core/vendor/Symfony/Component/Config/Exception/FileLoaderImportCircularReferenceException.php
@@ -0,0 +1,27 @@
+<?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\Config\Exception;
+
+/**
+ * Exception class for when a circular reference is detected when importing resources.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class FileLoaderImportCircularReferenceException extends FileLoaderLoadException
+{
+    public function __construct(array $resources, $code = null, $previous = null)
+    {
+        $message = sprintf('Circular reference detected in "%s" ("%s" > "%s").', $this->varToString($resources[0]), implode('" > "', $resources), $resources[0]);
+
+        call_user_func('Exception::__construct', $message, $code, $previous);
+    }
+}
diff --git a/core/vendor/Symfony/Component/Config/Exception/FileLoaderLoadException.php b/core/vendor/Symfony/Component/Config/Exception/FileLoaderLoadException.php
new file mode 100644
index 0000000..3216b4b
--- /dev/null
+++ b/core/vendor/Symfony/Component/Config/Exception/FileLoaderLoadException.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\Config\Exception;
+
+/**
+ * Exception class for when a resource cannot be loaded or imported.
+ *
+ * @author Ryan Weaver <ryan@thatsquality.com>
+ */
+class FileLoaderLoadException extends \Exception
+{
+    /**
+     * @param  string    $resource The resource that could not be imported
+     * @param  string    $sourceResource The original resource importing the new resource
+     * @param  integer   $code     The error code
+     * @param  Exception $previous A previous exception
+     */
+    public function __construct($resource, $sourceResource = null, $code = null, $previous = null)
+    {
+        if (null === $sourceResource) {
+            $message = sprintf('Cannot load resource "%s".', $this->varToString($resource));
+        } else {
+            $message = sprintf('Cannot import resource "%s" from "%s".', $this->varToString($resource), $this->varToString($sourceResource));
+        }
+
+        // Is the resource located inside a bundle?
+        if ('@' === $resource[0]) {
+            $parts = explode(DIRECTORY_SEPARATOR, $resource);
+            $bundle = substr($parts[0], 1);
+            $message .= ' '.sprintf('Make sure the "%s" bundle is correctly registered and loaded in the application kernel class.', $bundle);
+        }
+
+        parent::__construct($message, $code, $previous);
+    }
+
+    protected function varToString($var)
+    {
+        if (is_object($var)) {
+            return sprintf('Object(%s)', get_class($var));
+        }
+
+        if (is_array($var)) {
+            $a = array();
+            foreach ($var as $k => $v) {
+                $a[] = sprintf('%s => %s', $k, $this->varToString($v));
+            }
+
+            return sprintf("Array(%s)", implode(', ', $a));
+        }
+
+        if (is_resource($var)) {
+            return sprintf('Resource(%s)', get_resource_type($var));
+        }
+
+        if (null === $var) {
+            return 'null';
+        }
+
+        if (false === $var) {
+            return 'false';
+        }
+
+        if (true === $var) {
+            return 'true';
+        }
+
+        return (string) $var;
+    }
+}
diff --git a/core/vendor/Symfony/Component/Config/FileLocator.php b/core/vendor/Symfony/Component/Config/FileLocator.php
new file mode 100644
index 0000000..7f9dadc
--- /dev/null
+++ b/core/vendor/Symfony/Component/Config/FileLocator.php
@@ -0,0 +1,99 @@
+<?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\Config;
+
+/**
+ * FileLocator uses an array of pre-defined paths to find files.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class FileLocator implements FileLocatorInterface
+{
+    protected $paths;
+
+    /**
+     * Constructor.
+     *
+     * @param string|array $paths A path or an array of paths where to look for resources
+     */
+    public function __construct($paths = array())
+    {
+        $this->paths = (array) $paths;
+    }
+
+    /**
+     * Returns a full path for a given file name.
+     *
+     * @param mixed   $name        The file name to locate
+     * @param string  $currentPath The current path
+     * @param Boolean $first       Whether to return the first occurrence or an array of filenames
+     *
+     * @return string|array The full path to the file|An array of file paths
+     *
+     * @throws \InvalidArgumentException When file is not found
+     */
+    public function locate($name, $currentPath = null, $first = true)
+    {
+        if ($this->isAbsolutePath($name)) {
+            if (!file_exists($name)) {
+                throw new \InvalidArgumentException(sprintf('The file "%s" does not exist.', $name));
+            }
+
+            return $name;
+        }
+
+        $filepaths = array();
+        if (null !== $currentPath && file_exists($file = $currentPath.DIRECTORY_SEPARATOR.$name)) {
+            if (true === $first) {
+                return $file;
+            }
+            $filepaths[] = $file;
+        }
+
+        foreach ($this->paths as $path) {
+            if (file_exists($file = $path.DIRECTORY_SEPARATOR.$name)) {
+                if (true === $first) {
+                    return $file;
+                }
+                $filepaths[] = $file;
+            }
+        }
+
+        if (!$filepaths) {
+            throw new \InvalidArgumentException(sprintf('The file "%s" does not exist (in: %s%s).', $name, null !== $currentPath ? $currentPath.', ' : '', implode(', ', $this->paths)));
+        }
+
+        return array_values(array_unique($filepaths));
+    }
+
+    /**
+     * Returns whether the file path is an absolute path.
+     *
+     * @param string $file A file path
+     *
+     * @return Boolean
+     */
+    private function isAbsolutePath($file)
+    {
+        if ($file[0] == '/' || $file[0] == '\\'
+            || (strlen($file) > 3 && ctype_alpha($file[0])
+                && $file[1] == ':'
+                && ($file[2] == '\\' || $file[2] == '/')
+            )
+            || null !== parse_url($file, PHP_URL_SCHEME)
+        ) {
+            return true;
+        }
+
+        return false;
+    }
+}
diff --git a/core/vendor/Symfony/Component/Config/FileLocatorInterface.php b/core/vendor/Symfony/Component/Config/FileLocatorInterface.php
new file mode 100644
index 0000000..d756b83
--- /dev/null
+++ b/core/vendor/Symfony/Component/Config/FileLocatorInterface.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\Config;
+
+/**
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+interface FileLocatorInterface
+{
+    /**
+     * Returns a full path for a given file name.
+     *
+     * @param mixed   $name        The file name to locate
+     * @param string  $currentPath The current path
+     * @param Boolean $first       Whether to return the first occurrence or an array of filenames
+     *
+     * @return string|array The full path to the file|An array of file paths
+     *
+     * @throws \InvalidArgumentException When file is not found
+     */
+    function locate($name, $currentPath = null, $first = true);
+}
diff --git a/core/vendor/Symfony/Component/Config/LICENSE b/core/vendor/Symfony/Component/Config/LICENSE
new file mode 100644
index 0000000..cdffe7a
--- /dev/null
+++ b/core/vendor/Symfony/Component/Config/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2004-2012 Fabien Potencier
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/core/vendor/Symfony/Component/Config/Loader/DelegatingLoader.php b/core/vendor/Symfony/Component/Config/Loader/DelegatingLoader.php
new file mode 100644
index 0000000..ca25068
--- /dev/null
+++ b/core/vendor/Symfony/Component/Config/Loader/DelegatingLoader.php
@@ -0,0 +1,65 @@
+<?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\Config\Loader;
+
+use Symfony\Component\Config\Exception\FileLoaderLoadException;
+
+/**
+ * DelegatingLoader delegates loading to other loaders using a loader resolver.
+ *
+ * This loader acts as an array of LoaderInterface objects - each having
+ * a chance to load a given resource (handled by the resolver)
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class DelegatingLoader extends Loader
+{
+    /**
+     * Constructor.
+     *
+     * @param LoaderResolverInterface $resolver A LoaderResolverInterface instance
+     */
+    public function __construct(LoaderResolverInterface $resolver)
+    {
+        $this->resolver = $resolver;
+    }
+
+    /**
+     * Loads a resource.
+     *
+     * @param mixed  $resource A resource
+     * @param string $type     The resource type
+     *
+     * @throws FileLoaderLoadException if no loader is found.
+     */
+    public function load($resource, $type = null)
+    {
+        if (false === $loader = $this->resolver->resolve($resource, $type)) {
+            throw new FileLoaderLoadException($resource);
+        }
+
+        return $loader->load($resource, $type);
+    }
+
+    /**
+     * Returns true if this class supports the given resource.
+     *
+     * @param mixed  $resource A resource
+     * @param string $type     The resource type
+     *
+     * @return Boolean true if this class supports the given resource, false otherwise
+     */
+    public function supports($resource, $type = null)
+    {
+        return false === $this->resolver->resolve($resource, $type) ? false : true;
+    }
+}
diff --git a/core/vendor/Symfony/Component/Config/Loader/FileLoader.php b/core/vendor/Symfony/Component/Config/Loader/FileLoader.php
new file mode 100644
index 0000000..39c36b4
--- /dev/null
+++ b/core/vendor/Symfony/Component/Config/Loader/FileLoader.php
@@ -0,0 +1,93 @@
+<?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\Config\Loader;
+
+use Symfony\Component\Config\FileLocatorInterface;
+use Symfony\Component\Config\Exception\FileLoaderLoadException;
+use Symfony\Component\Config\Exception\FileLoaderImportCircularReferenceException;
+
+/**
+ * FileLoader is the abstract class used by all built-in loaders that are file based.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+abstract class FileLoader extends Loader
+{
+    static protected $loading = array();
+
+    protected $locator;
+
+    private $currentDir;
+
+    /**
+     * Constructor.
+     *
+     * @param FileLocatorInterface $locator A FileLocatorInterface instance
+     */
+    public function __construct(FileLocatorInterface $locator)
+    {
+        $this->locator = $locator;
+    }
+
+    public function setCurrentDir($dir)
+    {
+        $this->currentDir = $dir;
+    }
+
+    public function getLocator()
+    {
+        return $this->locator;
+    }
+
+    /**
+     * Imports a resource.
+     *
+     * @param mixed   $resource       A Resource
+     * @param string  $type           The resource type
+     * @param Boolean $ignoreErrors   Whether to ignore import errors or not
+     * @param string  $sourceResource The original resource importing the new resource
+     *
+     * @return mixed
+     */
+    public function import($resource, $type = null, $ignoreErrors = false, $sourceResource = null)
+    {
+        try {
+            $loader = $this->resolve($resource, $type);
+
+            if ($loader instanceof FileLoader && null !== $this->currentDir) {
+                $resource = $this->locator->locate($resource, $this->currentDir);
+            }
+
+            if (isset(self::$loading[$resource])) {
+                throw new FileLoaderImportCircularReferenceException(array_keys(self::$loading));
+            }
+            self::$loading[$resource] = true;
+
+            $ret = $loader->load($resource);
+
+            unset(self::$loading[$resource]);
+
+            return $ret;
+        } catch (FileLoaderImportCircularReferenceException $e) {
+            throw $e;
+        } catch (\Exception $e) {
+            if (!$ignoreErrors) {
+                // prevent embedded imports from nesting multiple exceptions
+                if ($e instanceof FileLoaderLoadException) {
+                    throw $e;
+                }
+
+                throw new FileLoaderLoadException($resource, $sourceResource, null, $e);
+            }
+        }
+    }
+}
diff --git a/core/vendor/Symfony/Component/Config/Loader/Loader.php b/core/vendor/Symfony/Component/Config/Loader/Loader.php
new file mode 100644
index 0000000..b9c174f
--- /dev/null
+++ b/core/vendor/Symfony/Component/Config/Loader/Loader.php
@@ -0,0 +1,80 @@
+<?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\Config\Loader;
+
+use Symfony\Component\Config\Exception\FileLoaderLoadException;
+
+/**
+ * Loader is the abstract class used by all built-in loaders.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+abstract class Loader implements LoaderInterface
+{
+    protected $resolver;
+
+    /**
+     * Gets the loader resolver.
+     *
+     * @return LoaderResolverInterface A LoaderResolverInterface instance
+     */
+    public function getResolver()
+    {
+        return $this->resolver;
+    }
+
+    /**
+     * Sets the loader resolver.
+     *
+     * @param LoaderResolverInterface $resolver A LoaderResolverInterface instance
+     */
+    public function setResolver(LoaderResolverInterface $resolver)
+    {
+        $this->resolver = $resolver;
+    }
+
+    /**
+     * Imports a resource.
+     *
+     * @param mixed  $resource A Resource
+     * @param string $type     The resource type
+     */
+    public function import($resource, $type = null)
+    {
+        $this->resolve($resource)->load($resource, $type);
+    }
+
+    /**
+     * Finds a loader able to load an imported resource.
+     *
+     * @param mixed  $resource A Resource
+     * @param string $type     The resource type
+     *
+     * @return LoaderInterface A LoaderInterface instance
+     *
+     * @throws FileLoaderLoadException if no loader is found
+     */
+    public function resolve($resource, $type = null)
+    {
+        if ($this->supports($resource, $type)) {
+            return $this;
+        }
+
+        $loader = null === $this->resolver ? false : $this->resolver->resolve($resource, $type);
+
+        if (false === $loader) {
+            throw new FileLoaderLoadException($resource);
+        }
+
+        return $loader;
+    }
+}
diff --git a/core/vendor/Symfony/Component/Config/Loader/LoaderInterface.php b/core/vendor/Symfony/Component/Config/Loader/LoaderInterface.php
new file mode 100644
index 0000000..10bfefc
--- /dev/null
+++ b/core/vendor/Symfony/Component/Config/Loader/LoaderInterface.php
@@ -0,0 +1,53 @@
+<?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\Config\Loader;
+
+/**
+ * LoaderInterface is the interface implemented by all loader classes.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+interface LoaderInterface
+{
+    /**
+     * Loads a resource.
+     *
+     * @param mixed  $resource The resource
+     * @param string $type     The resource type
+     */
+    function load($resource, $type = null);
+
+    /**
+     * Returns true if this class supports the given resource.
+     *
+     * @param mixed  $resource A resource
+     * @param string $type     The resource type
+     *
+     * @return Boolean true if this class supports the given resource, false otherwise
+     */
+    function supports($resource, $type = null);
+
+    /**
+     * Gets the loader resolver.
+     *
+     * @return LoaderResolverInterface A LoaderResolverInterface instance
+     */
+    function getResolver();
+
+    /**
+     * Sets the loader resolver.
+     *
+     * @param LoaderResolverInterface $resolver A LoaderResolverInterface instance
+     */
+    function setResolver(LoaderResolverInterface $resolver);
+
+}
diff --git a/core/vendor/Symfony/Component/Config/Loader/LoaderResolver.php b/core/vendor/Symfony/Component/Config/Loader/LoaderResolver.php
new file mode 100644
index 0000000..2340fe0
--- /dev/null
+++ b/core/vendor/Symfony/Component/Config/Loader/LoaderResolver.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\Config\Loader;
+
+/**
+ * LoaderResolver selects a loader for a given resource.
+ *
+ * A resource can be anything (e.g. a full path to a config file or a Closure).
+ * Each loader determines whether it can load a resource and how.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class LoaderResolver implements LoaderResolverInterface
+{
+    /**
+     * @var LoaderInterface[] An array of LoaderInterface objects
+     */
+    private $loaders;
+
+    /**
+     * Constructor.
+     *
+     * @param LoaderInterface[] $loaders An array of loaders
+     */
+    public function __construct(array $loaders = array())
+    {
+        $this->loaders = array();
+        foreach ($loaders as $loader) {
+            $this->addLoader($loader);
+        }
+    }
+
+    /**
+     * Returns a loader able to load the resource.
+     *
+     * @param mixed  $resource A resource
+     * @param string $type     The resource type
+     *
+     * @return LoaderInterface|false A LoaderInterface instance
+     */
+    public function resolve($resource, $type = null)
+    {
+        foreach ($this->loaders as $loader) {
+            if ($loader->supports($resource, $type)) {
+                return $loader;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Adds a loader.
+     *
+     * @param LoaderInterface $loader A LoaderInterface instance
+     */
+    public function addLoader(LoaderInterface $loader)
+    {
+        $this->loaders[] = $loader;
+        $loader->setResolver($this);
+    }
+
+    /**
+     * Returns the registered loaders.
+     *
+     * @return LoaderInterface[] An array of LoaderInterface instances
+     */
+    public function getLoaders()
+    {
+        return $this->loaders;
+    }
+}
diff --git a/core/vendor/Symfony/Component/Config/Loader/LoaderResolverInterface.php b/core/vendor/Symfony/Component/Config/Loader/LoaderResolverInterface.php
new file mode 100644
index 0000000..f660401
--- /dev/null
+++ b/core/vendor/Symfony/Component/Config/Loader/LoaderResolverInterface.php
@@ -0,0 +1,30 @@
+<?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\Config\Loader;
+
+/**
+ * LoaderResolverInterface selects a loader for a given resource.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+interface LoaderResolverInterface
+{
+    /**
+     * Returns a loader able to load the resource.
+     *
+     * @param mixed  $resource A resource
+     * @param string $type     The resource type
+     *
+     * @return LoaderInterface A LoaderInterface instance
+     */
+    function resolve($resource, $type = null);
+}
diff --git a/core/vendor/Symfony/Component/Config/README.md b/core/vendor/Symfony/Component/Config/README.md
new file mode 100644
index 0000000..e87363d
--- /dev/null
+++ b/core/vendor/Symfony/Component/Config/README.md
@@ -0,0 +1,14 @@
+Config Component
+================
+
+Config provides the infrastructure for loading configurations from different
+data sources and optionally monitoring these data sources for changes. There
+are additional tools for validating, normalizing and handling of defaults that
+can optionally be used to convert from different formats to arrays.
+
+Resources
+---------
+
+You can run the unit tests with the following command:
+
+    phpunit
diff --git a/core/vendor/Symfony/Component/Config/Resource/DirectoryResource.php b/core/vendor/Symfony/Component/Config/Resource/DirectoryResource.php
new file mode 100644
index 0000000..5ccd204
--- /dev/null
+++ b/core/vendor/Symfony/Component/Config/Resource/DirectoryResource.php
@@ -0,0 +1,102 @@
+<?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\Config\Resource;
+
+/**
+ * DirectoryResource represents a resources stored in a subdirectory tree.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class DirectoryResource implements ResourceInterface, \Serializable
+{
+    private $resource;
+    private $pattern;
+
+    /**
+     * Constructor.
+     *
+     * @param string $resource The file path to the resource
+     * @param string $pattern  A pattern to restrict monitored files
+     */
+    public function __construct($resource, $pattern = null)
+    {
+        $this->resource = $resource;
+        $this->pattern = $pattern;
+    }
+
+    /**
+     * Returns a string representation of the Resource.
+     *
+     * @return string A string representation of the Resource
+     */
+    public function __toString()
+    {
+        return (string) $this->resource;
+    }
+
+    /**
+     * Returns the resource tied to this Resource.
+     *
+     * @return mixed The resource
+     */
+    public function getResource()
+    {
+        return $this->resource;
+    }
+
+    public function getPattern()
+    {
+        return $this->pattern;
+    }
+
+    /**
+     * Returns true if the resource has not been updated since the given timestamp.
+     *
+     * @param integer $timestamp The last time the resource was loaded
+     *
+     * @return Boolean true if the resource has not been updated, false otherwise
+     */
+    public function isFresh($timestamp)
+    {
+        if (!is_dir($this->resource)) {
+            return false;
+        }
+
+        $newestMTime = filemtime($this->resource);
+        foreach (new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($this->resource), \RecursiveIteratorIterator::SELF_FIRST) as $file) {
+            // if regex filtering is enabled only check matching files
+            if ($this->pattern && $file->isFile() && !preg_match($this->pattern, $file->getBasename())) {
+                continue;
+            }
+
+            // always monitor directories for changes, except the .. entries
+            // (otherwise deleted files wouldn't get detected)
+            if ($file->isDir() && '/..' === substr($file, -3)) {
+                continue;
+            }
+
+            $newestMTime = max($file->getMTime(), $newestMTime);
+        }
+
+        return $newestMTime < $timestamp;
+    }
+
+    public function serialize()
+    {
+        return serialize(array($this->resource, $this->pattern));
+    }
+
+    public function unserialize($serialized)
+    {
+        list($this->resource, $this->pattern) = unserialize($serialized);
+    }
+}
diff --git a/core/vendor/Symfony/Component/Config/Resource/FileResource.php b/core/vendor/Symfony/Component/Config/Resource/FileResource.php
new file mode 100644
index 0000000..619f84b
--- /dev/null
+++ b/core/vendor/Symfony/Component/Config/Resource/FileResource.php
@@ -0,0 +1,80 @@
+<?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\Config\Resource;
+
+/**
+ * FileResource represents a resource stored on the filesystem.
+ *
+ * The resource can be a file or a directory.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class FileResource implements ResourceInterface, \Serializable
+{
+    private $resource;
+
+    /**
+     * Constructor.
+     *
+     * @param string $resource The file path to the resource
+     */
+    public function __construct($resource)
+    {
+        $this->resource = realpath($resource);
+    }
+
+    /**
+     * Returns a string representation of the Resource.
+     *
+     * @return string A string representation of the Resource
+     */
+    public function __toString()
+    {
+        return (string) $this->resource;
+    }
+
+    /**
+     * Returns the resource tied to this Resource.
+     *
+     * @return mixed The resource
+     */
+    public function getResource()
+    {
+        return $this->resource;
+    }
+
+    /**
+     * Returns true if the resource has not been updated since the given timestamp.
+     *
+     * @param integer $timestamp The last time the resource was loaded
+     *
+     * @return Boolean true if the resource has not been updated, false otherwise
+     */
+    public function isFresh($timestamp)
+    {
+        if (!file_exists($this->resource)) {
+            return false;
+        }
+
+        return filemtime($this->resource) < $timestamp;
+    }
+
+    public function serialize()
+    {
+        return serialize($this->resource);
+    }
+
+    public function unserialize($serialized)
+    {
+        $this->resource = unserialize($serialized);
+    }
+}
diff --git a/core/vendor/Symfony/Component/Config/Resource/ResourceInterface.php b/core/vendor/Symfony/Component/Config/Resource/ResourceInterface.php
new file mode 100644
index 0000000..024f2e9
--- /dev/null
+++ b/core/vendor/Symfony/Component/Config/Resource/ResourceInterface.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\Config\Resource;
+
+/**
+ * ResourceInterface is the interface that must be implemented by all Resource classes.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+interface ResourceInterface
+{
+    /**
+     * Returns a string representation of the Resource.
+     *
+     * @return string A string representation of the Resource
+     */
+    function __toString();
+
+    /**
+     * Returns true if the resource has not been updated since the given timestamp.
+     *
+     * @param integer $timestamp The last time the resource was loaded
+     *
+     * @return Boolean true if the resource has not been updated, false otherwise
+     */
+    function isFresh($timestamp);
+
+    /**
+     * Returns the resource tied to this Resource.
+     *
+     * @return mixed The resource
+     */
+    function getResource();
+}
diff --git a/core/vendor/Symfony/Component/Config/Tests/Definition/ArrayNodeTest.php b/core/vendor/Symfony/Component/Config/Tests/Definition/ArrayNodeTest.php
new file mode 100644
index 0000000..932d742
--- /dev/null
+++ b/core/vendor/Symfony/Component/Config/Tests/Definition/ArrayNodeTest.php
@@ -0,0 +1,58 @@
+<?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\Config\Tests\Definition;
+
+use Symfony\Component\Config\Definition\ArrayNode;
+
+class ArrayNodeTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @expectedException Symfony\Component\Config\Definition\Exception\InvalidTypeException
+     */
+    public function testNormalizeThrowsExceptionWhenFalseIsNotAllowed()
+    {
+        $node = new ArrayNode('root');
+        $node->normalize(false);
+    }
+
+    /**
+     * normalize() should protect against child values with no corresponding node
+     */
+    public function testExceptionThrownOnUnrecognizedChild()
+    {
+        $node = new ArrayNode('root');
+
+        try
+        {
+            $node->normalize(array('foo' => 'bar'));
+            $this->fail('An exception should have been throw for a bad child node');
+        } catch (\Exception $e) {
+            $this->assertInstanceOf('Symfony\Component\Config\Definition\Exception\InvalidConfigurationException', $e);
+            $this->assertEquals('Unrecognized options "foo" under "root"', $e->getMessage());
+        }
+    }
+
+    /**
+     * Tests that no exception is thrown for an unrecognized child if the
+     * ignoreExtraKeys option is set to true.
+     *
+     * Related to testExceptionThrownOnUnrecognizedChild
+     */
+    public function testIgnoreExtraKeysNoException()
+    {
+        $node = new ArrayNode('roo');
+        $node->setIgnoreExtraKeys(true);
+
+        $node->normalize(array('foo' => 'bar'));
+        $this->assertTrue(true, 'No exception was thrown when setIgnoreExtraKeys is true');
+    }
+}
diff --git a/core/vendor/Symfony/Component/Config/Tests/Definition/BooleanNodeTest.php b/core/vendor/Symfony/Component/Config/Tests/Definition/BooleanNodeTest.php
new file mode 100644
index 0000000..8369f71
--- /dev/null
+++ b/core/vendor/Symfony/Component/Config/Tests/Definition/BooleanNodeTest.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\Config\Tests\Definition;
+
+use Symfony\Component\Config\Definition\BooleanNode;
+
+class BooleanNodeTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @dataProvider getValidValues
+     */
+    public function testNormalize($value)
+    {
+        $node = new BooleanNode('test');
+        $this->assertSame($value, $node->normalize($value));
+    }
+
+    public function getValidValues()
+    {
+        return array(
+            array(false),
+            array(true),
+        );
+    }
+
+    /**
+     * @dataProvider getInvalidValues
+     * @expectedException Symfony\Component\Config\Definition\Exception\InvalidTypeException
+     */
+    public function testNormalizeThrowsExceptionOnInvalidValues($value)
+    {
+        $node = new BooleanNode('test');
+        $node->normalize($value);
+    }
+
+    public function getInvalidValues()
+    {
+        return array(
+            array(null),
+            array(''),
+            array('foo'),
+            array(0),
+            array(1),
+            array(0.0),
+            array(0.1),
+            array(array()),
+            array(array('foo' => 'bar')),
+            array(new \stdClass()),
+        );
+    }
+}
+
diff --git a/core/vendor/Symfony/Component/Config/Tests/Definition/Builder/ArrayNodeDefinitionTest.php b/core/vendor/Symfony/Component/Config/Tests/Definition/Builder/ArrayNodeDefinitionTest.php
new file mode 100644
index 0000000..3c298a4
--- /dev/null
+++ b/core/vendor/Symfony/Component/Config/Tests/Definition/Builder/ArrayNodeDefinitionTest.php
@@ -0,0 +1,159 @@
+<?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\Config\Tests\Definition\Builder;
+
+use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
+use Symfony\Component\Config\Definition\Builder\ScalarNodeDefinition;
+use Symfony\Component\Config\Definition\Exception\InvalidDefinitionException;
+
+class ArrayNodeDefinitionTest extends \PHPUnit_Framework_TestCase
+{
+    public function testAppendingSomeNode()
+    {
+        $parent = new ArrayNodeDefinition('root');
+        $child = new ScalarNodeDefinition('child');
+
+        $parent
+            ->children()
+                ->scalarNode('foo')->end()
+                ->scalarNode('bar')->end()
+            ->end()
+            ->append($child);
+
+        $this->assertCount(3, $this->getField($parent, 'children'));
+        $this->assertTrue(in_array($child, $this->getField($parent, 'children')));
+    }
+
+    /**
+     * @expectedException Symfony\Component\Config\Definition\Exception\InvalidDefinitionException
+     * @dataProvider providePrototypeNodeSpecificCalls
+     */
+    public function testPrototypeNodeSpecificOption($method, $args)
+    {
+        $node = new ArrayNodeDefinition('root');
+
+        call_user_func_array(array($node, $method), $args);
+
+        $node->getNode();
+    }
+
+    public function providePrototypeNodeSpecificCalls()
+    {
+        return array(
+            array('defaultValue', array(array())),
+            array('addDefaultChildrenIfNoneSet', array()),
+            array('requiresAtLeastOneElement', array()),
+            array('useAttributeAsKey', array('foo'))
+        );
+    }
+
+    /**
+     * @expectedException Symfony\Component\Config\Definition\Exception\InvalidDefinitionException
+     */
+    public function testConcreteNodeSpecificOption()
+    {
+        $node = new ArrayNodeDefinition('root');
+        $node->addDefaultsIfNotSet()->prototype('array');
+        $node->getNode();
+    }
+
+    /**
+     * @expectedException Symfony\Component\Config\Definition\Exception\InvalidDefinitionException
+     */
+    public function testPrototypeNodesCantHaveADefaultValueWhenUsingDefaulChildren()
+    {
+        $node = new ArrayNodeDefinition('root');
+        $node
+            ->defaultValue(array())
+            ->addDefaultChildrenIfNoneSet('foo')
+            ->prototype('array')
+        ;
+        $node->getNode();
+    }
+
+    public function testPrototypedArrayNodeDefaultWhenUsingDefaultChildren()
+    {
+        $node = new ArrayNodeDefinition('root');
+        $node
+            ->addDefaultChildrenIfNoneSet()
+            ->prototype('array')
+        ;
+        $tree = $node->getNode();
+        $this->assertEquals(array(array()), $tree->getDefaultValue());
+    }
+
+    /**
+     * @dataProvider providePrototypedArrayNodeDefaults
+     */
+    public function testPrototypedArrayNodeDefault($args, $shouldThrowWhenUsingAttrAsKey, $shouldThrowWhenNotUsingAttrAsKey, $defaults)
+    {
+        $node = new ArrayNodeDefinition('root');
+        $node
+            ->addDefaultChildrenIfNoneSet($args)
+            ->prototype('array')
+        ;
+
+        try {
+            $tree = $node->getNode();
+            $this->assertFalse($shouldThrowWhenNotUsingAttrAsKey);
+            $this->assertEquals($defaults, $tree->getDefaultValue());
+        } catch (InvalidDefinitionException $e) {
+            $this->assertTrue($shouldThrowWhenNotUsingAttrAsKey);
+        }
+
+        $node = new ArrayNodeDefinition('root');
+        $node
+            ->useAttributeAsKey('attr')
+            ->addDefaultChildrenIfNoneSet($args)
+            ->prototype('array')
+        ;
+
+        try {
+            $tree = $node->getNode();
+            $this->assertFalse($shouldThrowWhenUsingAttrAsKey);
+            $this->assertEquals($defaults, $tree->getDefaultValue());
+        } catch (InvalidDefinitionException $e) {
+            $this->assertTrue($shouldThrowWhenUsingAttrAsKey);
+        }
+    }
+
+    public function providePrototypedArrayNodeDefaults()
+    {
+        return array(
+            array(null, true, false, array(array())),
+            array(2, true, false, array(array(), array())),
+            array('2', false, true, array('2' => array())),
+            array('foo', false, true, array('foo' => array())),
+            array(array('foo'), false, true, array('foo' => array())),
+            array(array('foo', 'bar'), false, true, array('foo' => array(), 'bar' => array())),
+        );
+    }
+
+    public function testNestedPrototypedArrayNodes()
+    {
+        $node = new ArrayNodeDefinition('root');
+        $node
+            ->addDefaultChildrenIfNoneSet()
+            ->prototype('array')
+                  ->prototype('array')
+        ;
+        $node->getNode();
+    }
+
+    protected function getField($object, $field)
+    {
+        $reflection = new \ReflectionProperty($object, $field);
+        $reflection->setAccessible(true);
+
+        return $reflection->getValue($object);
+    }
+}
diff --git a/core/vendor/Symfony/Component/Config/Tests/Definition/Builder/NodeBuilderTest.php b/core/vendor/Symfony/Component/Config/Tests/Definition/Builder/NodeBuilderTest.php
new file mode 100644
index 0000000..c829591
--- /dev/null
+++ b/core/vendor/Symfony/Component/Config/Tests/Definition/Builder/NodeBuilderTest.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\Config\Tests\Definition\Builder;
+
+use Symfony\Component\Config\Definition\Builder\NodeBuilder as BaseNodeBuilder;
+use Symfony\Component\Config\Definition\Builder\VariableNodeDefinition as BaseVariableNodeDefinition;
+
+class NodeBuilderTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @expectedException \RuntimeException
+     */
+    public function testThrowsAnExceptionWhenTryingToCreateANonRegisteredNodeType()
+    {
+        $builder = new BaseNodeBuilder();
+        $builder->node('', 'foobar');
+    }
+
+    /**
+     * @expectedException \RuntimeException
+     */
+    public function testThrowsAnExceptionWhenTheNodeClassIsNotFound()
+    {
+        $builder = new BaseNodeBuilder();
+        $builder
+            ->setNodeClass('noclasstype', '\\foo\\bar\\noclass')
+            ->node('', 'noclasstype');
+    }
+
+    public function testAddingANewNodeType()
+    {
+        $class = __NAMESPACE__.'\\SomeNodeDefinition';
+
+        $builder = new BaseNodeBuilder();
+        $node = $builder
+            ->setNodeClass('newtype', $class)
+            ->node('', 'newtype');
+
+        $this->assertEquals(get_class($node), $class);
+    }
+
+    public function testOverridingAnExistingNodeType()
+    {
+        $class = __NAMESPACE__.'\\SomeNodeDefinition';
+
+        $builder = new BaseNodeBuilder();
+        $node = $builder
+            ->setNodeClass('variable', $class)
+            ->node('', 'variable');
+
+        $this->assertEquals(get_class($node), $class);
+    }
+
+    public function testNodeTypesAreNotCaseSensitive()
+    {
+        $builder = new BaseNodeBuilder();
+
+        $node1 = $builder->node('', 'VaRiAbLe');
+        $node2 = $builder->node('', 'variable');
+
+        $this->assertEquals(get_class($node1), get_class($node2));
+
+        $builder->setNodeClass('CuStOm', __NAMESPACE__.'\\SomeNodeDefinition');
+
+        $node1 = $builder->node('', 'CUSTOM');
+        $node2 = $builder->node('', 'custom');
+
+        $this->assertEquals(get_class($node1), get_class($node2));
+    }
+}
+
+class SomeNodeDefinition extends BaseVariableNodeDefinition
+{
+}
diff --git a/core/vendor/Symfony/Component/Config/Tests/Definition/Builder/TreeBuilderTest.php b/core/vendor/Symfony/Component/Config/Tests/Definition/Builder/TreeBuilderTest.php
new file mode 100644
index 0000000..35aac24
--- /dev/null
+++ b/core/vendor/Symfony/Component/Config/Tests/Definition/Builder/TreeBuilderTest.php
@@ -0,0 +1,127 @@
+<?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\Config\Tests\Definition\Builder;
+
+use Symfony\Component\Config\Tests\Definition\Builder\NodeBuilder as CustomNodeBuilder;
+use Symfony\Component\Config\Definition\Builder\TreeBuilder;
+use Symfony\Component\Config\Definition\Builder\NodeBuilder;
+
+require __DIR__.'/../../Fixtures/Builder/NodeBuilder.php';
+require __DIR__.'/../../Fixtures/Builder/BarNodeDefinition.php';
+require __DIR__.'/../../Fixtures/Builder/VariableNodeDefinition.php';
+
+class TreeBuilderTest extends \PHPUnit_Framework_TestCase
+{
+    public function testUsingACustomNodeBuilder()
+    {
+        $builder = new TreeBuilder();
+        $root = $builder->root('custom', 'array', new CustomNodeBuilder());
+
+        $nodeBuilder = $root->children();
+
+        $this->assertEquals(get_class($nodeBuilder), 'Symfony\Component\Config\Tests\Definition\Builder\NodeBuilder');
+
+        $nodeBuilder = $nodeBuilder->arrayNode('deeper')->children();
+
+        $this->assertEquals(get_class($nodeBuilder), 'Symfony\Component\Config\Tests\Definition\Builder\NodeBuilder');
+    }
+
+    public function testOverrideABuiltInNodeType()
+    {
+        $builder = new TreeBuilder();
+        $root = $builder->root('override', 'array', new CustomNodeBuilder());
+
+        $definition = $root->children()->variableNode('variable');
+
+        $this->assertEquals(get_class($definition), 'Symfony\Component\Config\Tests\Definition\Builder\VariableNodeDefinition');
+    }
+
+    public function testAddANodeType()
+    {
+        $builder = new TreeBuilder();
+        $root = $builder->root('override', 'array', new CustomNodeBuilder());
+
+        $definition = $root->children()->barNode('variable');
+
+        $this->assertEquals(get_class($definition), 'Symfony\Component\Config\Tests\Definition\Builder\BarNodeDefinition');
+    }
+
+    public function testCreateABuiltInNodeTypeWithACustomNodeBuilder()
+    {
+        $builder = new TreeBuilder();
+        $root = $builder->root('builtin', 'array', new CustomNodeBuilder());
+
+        $definition = $root->children()->booleanNode('boolean');
+
+        $this->assertEquals(get_class($definition), 'Symfony\Component\Config\Definition\Builder\BooleanNodeDefinition');
+    }
+
+    public function testPrototypedArrayNodeUseTheCustomNodeBuilder()
+    {
+        $builder = new TreeBuilder();
+        $root = $builder->root('override', 'array', new CustomNodeBuilder());
+
+        $root->prototype('bar')->end();
+    }
+
+    public function testAnExtendedNodeBuilderGetsPropagatedToTheChildren()
+    {
+        $builder = new TreeBuilder();
+
+        $builder->root('propagation')
+            ->children()
+                ->setNodeClass('extended', 'Symfony\Component\Config\Tests\Definition\Builder\VariableNodeDefinition')
+                ->node('foo', 'extended')->end()
+                ->arrayNode('child')
+                    ->children()
+                        ->node('foo', 'extended')
+                    ->end()
+                ->end()
+            ->end()
+        ->end();
+    }
+
+    public function testDefinitionInfoGetsTransferedToNode()
+    {
+        $builder = new TreeBuilder();
+
+        $builder->root('test')->setInfo('root info')
+            ->children()
+                ->node('child', 'variable')->setInfo('child info')->defaultValue('default')
+            ->end()
+        ->end();
+
+        $tree = $builder->buildTree();
+        $children = $tree->getChildren();
+
+        $this->assertEquals('root info', $tree->getInfo());
+        $this->assertEquals('child info', $children['child']->getInfo());
+    }
+
+    public function testDefinitionExampleGetsTransferedToNode()
+    {
+        $builder = new TreeBuilder();
+
+        $builder->root('test')
+            ->setExample(array('key' => 'value'))
+            ->children()
+                ->node('child', 'variable')->setInfo('child info')->defaultValue('default')->setExample('example')
+            ->end()
+        ->end();
+
+        $tree = $builder->buildTree();
+        $children = $tree->getChildren();
+
+        $this->assertTrue(is_array($tree->getExample()));
+        $this->assertEquals('example', $children['child']->getExample());
+    }
+}
diff --git a/core/vendor/Symfony/Component/Config/Tests/Definition/FinalizationTest.php b/core/vendor/Symfony/Component/Config/Tests/Definition/FinalizationTest.php
new file mode 100644
index 0000000..29a556f
--- /dev/null
+++ b/core/vendor/Symfony/Component/Config/Tests/Definition/FinalizationTest.php
@@ -0,0 +1,74 @@
+<?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\Config\Tests\Definition;
+
+use Symfony\Component\Config\Definition\Builder\TreeBuilder;
+use Symfony\Component\Config\Definition\Processor;
+use Symfony\Component\Config\Definition\NodeInterface;
+
+class FinalizationTest extends \PHPUnit_Framework_TestCase
+{
+
+    public function testUnsetKeyWithDeepHierarchy()
+    {
+        $tb = new TreeBuilder();
+        $tree = $tb
+            ->root('config', 'array')
+                ->children()
+                    ->node('level1', 'array')
+                        ->canBeUnset()
+                        ->children()
+                            ->node('level2', 'array')
+                                ->canBeUnset()
+                                ->children()
+                                    ->node('somevalue', 'scalar')->end()
+                                    ->node('anothervalue', 'scalar')->end()
+                                ->end()
+                            ->end()
+                            ->node('level1_scalar', 'scalar')->end()
+                        ->end()
+                    ->end()
+                ->end()
+            ->end()
+            ->buildTree()
+        ;
+
+        $a = array(
+            'level1' => array(
+                'level2' => array(
+                    'somevalue' => 'foo',
+                    'anothervalue' => 'bar',
+                ),
+                'level1_scalar' => 'foo',
+            ),
+        );
+
+        $b = array(
+            'level1' => array(
+                'level2' => false,
+            ),
+        );
+
+        $this->assertEquals(array(
+            'level1' => array(
+                'level1_scalar' => 'foo',
+            ),
+        ), $this->process($tree, array($a, $b)));
+    }
+
+    protected function process(NodeInterface $tree, array $configs)
+    {
+        $processor = new Processor();
+
+        return $processor->process($tree, $configs);
+    }
+}
diff --git a/core/vendor/Symfony/Component/Config/Tests/Definition/MergeTest.php b/core/vendor/Symfony/Component/Config/Tests/Definition/MergeTest.php
new file mode 100644
index 0000000..d90a3a9
--- /dev/null
+++ b/core/vendor/Symfony/Component/Config/Tests/Definition/MergeTest.php
@@ -0,0 +1,195 @@
+<?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\Config\Tests\Definition;
+
+use Symfony\Component\Config\Definition\Builder\TreeBuilder;
+
+class MergeTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @expectedException Symfony\Component\Config\Definition\Exception\ForbiddenOverwriteException
+     */
+    public function testForbiddenOverwrite()
+    {
+        $tb = new TreeBuilder();
+        $tree = $tb
+            ->root('root', 'array')
+                ->children()
+                    ->node('foo', 'scalar')
+                        ->cannotBeOverwritten()
+                    ->end()
+                ->end()
+            ->end()
+            ->buildTree()
+        ;
+
+        $a = array(
+            'foo' => 'bar',
+        );
+
+        $b = array(
+            'foo' => 'moo',
+        );
+
+        $tree->merge($a, $b);
+    }
+
+    public function testUnsetKey()
+    {
+        $tb = new TreeBuilder();
+        $tree = $tb
+            ->root('root', 'array')
+                ->children()
+                    ->node('foo', 'scalar')->end()
+                    ->node('bar', 'scalar')->end()
+                    ->node('unsettable', 'array')
+                        ->canBeUnset()
+                        ->children()
+                            ->node('foo', 'scalar')->end()
+                            ->node('bar', 'scalar')->end()
+                        ->end()
+                    ->end()
+                    ->node('unsetted', 'array')
+                        ->canBeUnset()
+                        ->prototype('scalar')->end()
+                    ->end()
+                ->end()
+            ->end()
+            ->buildTree()
+        ;
+
+        $a = array(
+            'foo' => 'bar',
+            'unsettable' => array(
+                'foo' => 'a',
+                'bar' => 'b',
+            ),
+            'unsetted' => false,
+        );
+
+        $b = array(
+            'foo' => 'moo',
+            'bar' => 'b',
+            'unsettable' => false,
+            'unsetted' => array('a', 'b'),
+        );
+
+        $this->assertEquals(array(
+            'foo' => 'moo',
+            'bar' => 'b',
+            'unsettable' => false,
+            'unsetted' => array('a', 'b'),
+        ), $tree->merge($a, $b));
+    }
+
+    /**
+     * @expectedException Symfony\Component\Config\Definition\Exception\InvalidConfigurationException
+     */
+    public function testDoesNotAllowNewKeysInSubsequentConfigs()
+    {
+        $tb = new TreeBuilder();
+        $tree = $tb
+            ->root('config', 'array')
+                ->children()
+                    ->node('test', 'array')
+                        ->disallowNewKeysInSubsequentConfigs()
+                        ->useAttributeAsKey('key')
+                        ->prototype('array')
+                            ->children()
+                                ->node('value', 'scalar')->end()
+                            ->end()
+                        ->end()
+                    ->end()
+                ->end()
+            ->end()
+            ->buildTree();
+
+        $a = array(
+            'test' => array(
+                'a' => array('value' => 'foo')
+            )
+        );
+
+        $b = array(
+            'test' => array(
+                'b' => array('value' => 'foo')
+            )
+        );
+
+        $tree->merge($a, $b);
+    }
+
+    public function testPerformsNoDeepMerging()
+    {
+        $tb = new TreeBuilder();
+
+        $tree = $tb
+            ->root('config', 'array')
+                ->children()
+                    ->node('no_deep_merging', 'array')
+                        ->performNoDeepMerging()
+                        ->children()
+                            ->node('foo', 'scalar')->end()
+                            ->node('bar', 'scalar')->end()
+                        ->end()
+                    ->end()
+                ->end()
+            ->end()
+            ->buildTree()
+        ;
+
+        $a = array(
+            'no_deep_merging' => array(
+                'foo' => 'a',
+                'bar' => 'b',
+            ),
+        );
+
+        $b = array(
+            'no_deep_merging' => array(
+                'c' => 'd',
+            )
+        );
+
+        $this->assertEquals(array(
+            'no_deep_merging' => array(
+                'c' => 'd',
+            )
+        ), $tree->merge($a, $b));
+    }
+
+    public function testPrototypeWithoutAKeyAttribute()
+    {
+        $tb = new TreeBuilder();
+
+        $tree = $tb
+            ->root('config', 'array')
+                ->children()
+                    ->arrayNode('append_elements')
+                        ->prototype('scalar')->end()
+                    ->end()
+                ->end()
+            ->end()
+            ->buildTree()
+        ;
+
+        $a = array(
+            'append_elements' => array('a', 'b'),
+        );
+
+        $b = array(
+            'append_elements' => array('c', 'd'),
+        );
+
+        $this->assertEquals(array('append_elements' => array('a', 'b', 'c', 'd')), $tree->merge($a, $b));
+    }
+}
diff --git a/core/vendor/Symfony/Component/Config/Tests/Definition/NormalizationTest.php b/core/vendor/Symfony/Component/Config/Tests/Definition/NormalizationTest.php
new file mode 100644
index 0000000..4a475a7
--- /dev/null
+++ b/core/vendor/Symfony/Component/Config/Tests/Definition/NormalizationTest.php
@@ -0,0 +1,144 @@
+<?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\Config\Tests\Definition;
+
+use Symfony\Component\Config\Definition\NodeInterface;
+use Symfony\Component\Config\Definition\Builder\TreeBuilder;
+
+class NormalizerTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @dataProvider getEncoderTests
+     */
+    public function testNormalizeEncoders($denormalized)
+    {
+        $tb = new TreeBuilder();
+        $tree = $tb
+            ->root('root_name', 'array')
+                ->fixXmlConfig('encoder')
+                ->children()
+                    ->node('encoders', 'array')
+                        ->useAttributeAsKey('class')
+                        ->prototype('array')
+                            ->beforeNormalization()->ifString()->then(function($v) { return array('algorithm' => $v); })->end()
+                            ->children()
+                                ->node('algorithm', 'scalar')->end()
+                            ->end()
+                        ->end()
+                    ->end()
+                ->end()
+            ->end()
+            ->buildTree()
+        ;
+
+        $normalized = array(
+            'encoders' => array(
+                'foo' => array('algorithm' => 'plaintext'),
+            ),
+        );
+
+        $this->assertNormalized($tree, $denormalized, $normalized);
+    }
+
+    public function getEncoderTests()
+    {
+        $configs = array();
+
+        // XML
+        $configs[] = array(
+            'encoder' => array(
+                array('class' => 'foo', 'algorithm' => 'plaintext'),
+            ),
+        );
+
+        // XML when only one element of this type
+        $configs[] = array(
+            'encoder' => array('class' => 'foo', 'algorithm' => 'plaintext'),
+        );
+
+        // YAML/PHP
+        $configs[] = array(
+            'encoders' => array(
+                array('class' => 'foo', 'algorithm' => 'plaintext'),
+            ),
+        );
+
+        // YAML/PHP
+        $configs[] = array(
+            'encoders' => array(
+                'foo' => 'plaintext',
+            ),
+        );
+
+        // YAML/PHP
+        $configs[] = array(
+            'encoders' => array(
+                'foo' => array('algorithm' => 'plaintext'),
+            ),
+        );
+
+        return array_map(function($v) {
+            return array($v);
+        }, $configs);
+    }
+
+    /**
+     * @dataProvider getAnonymousKeysTests
+     */
+    public function testAnonymousKeysArray($denormalized)
+    {
+        $tb = new TreeBuilder();
+        $tree = $tb
+            ->root('root', 'array')
+                ->children()
+                    ->node('logout', 'array')
+                        ->fixXmlConfig('handler')
+                        ->children()
+                            ->node('handlers', 'array')
+                                ->prototype('scalar')->end()
+                            ->end()
+                        ->end()
+                    ->end()
+                ->end()
+            ->end()
+            ->buildTree()
+        ;
+
+        $normalized = array('logout' => array('handlers' => array('a', 'b', 'c')));
+
+        $this->assertNormalized($tree, $denormalized, $normalized);
+    }
+
+    public function getAnonymousKeysTests()
+    {
+        $configs = array();
+
+        $configs[] = array(
+            'logout' => array(
+                'handlers' => array('a', 'b', 'c'),
+            ),
+        );
+
+        $configs[] = array(
+            'logout' => array(
+                'handler' => array('a', 'b', 'c'),
+            ),
+        );
+
+        return array_map(function($v) { return array($v); }, $configs);
+    }
+
+    public static function assertNormalized(NodeInterface $tree, $denormalized, $normalized)
+    {
+        self::assertSame($normalized, $tree->normalize($denormalized));
+    }
+}
diff --git a/core/vendor/Symfony/Component/Config/Tests/Definition/ProcessorTest.php b/core/vendor/Symfony/Component/Config/Tests/Definition/ProcessorTest.php
new file mode 100644
index 0000000..56368ac
--- /dev/null
+++ b/core/vendor/Symfony/Component/Config/Tests/Definition/ProcessorTest.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\Config\Tests\Definition;
+
+use Symfony\Component\Config\Definition\Processor;
+
+class ProcessorTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @dataProvider getKeyNormalizationTests
+     */
+    public function testNormalizeKeys($denormalized, $normalized)
+    {
+        $this->assertSame($normalized, Processor::normalizeKeys($denormalized));
+    }
+
+    public function getKeyNormalizationTests()
+    {
+        return array(
+            array(
+                array('foo-bar' => 'foo'),
+                array('foo_bar' => 'foo'),
+            ),
+            array(
+                array('foo-bar_moo' => 'foo'),
+                array('foo-bar_moo' => 'foo'),
+            ),
+            array(
+                array('foo-bar' => null, 'foo_bar' => 'foo'),
+                array('foo-bar' => null, 'foo_bar' => 'foo'),
+            ),
+            array(
+                array('foo-bar' => array('foo-bar' => 'foo')),
+                array('foo_bar' => array('foo_bar' => 'foo')),
+            ),
+            array(
+                array('foo_bar' => array('foo-bar' => 'foo')),
+                array('foo_bar' => array('foo_bar' => 'foo')),
+            )
+        );
+    }
+}
diff --git a/core/vendor/Symfony/Component/Config/Tests/Definition/PrototypedArrayNodeTest.php b/core/vendor/Symfony/Component/Config/Tests/Definition/PrototypedArrayNodeTest.php
new file mode 100644
index 0000000..31d3c89
--- /dev/null
+++ b/core/vendor/Symfony/Component/Config/Tests/Definition/PrototypedArrayNodeTest.php
@@ -0,0 +1,181 @@
+<?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\Config\Tests\Definition;
+
+use Symfony\Component\Config\Definition\PrototypedArrayNode;
+use Symfony\Component\Config\Definition\ArrayNode;
+use Symfony\Component\Config\Definition\ScalarNode;
+
+class PrototypedArrayNodeTest extends \PHPUnit_Framework_TestCase
+{
+
+    public function testGetDefaultValueReturnsAnEmptyArrayForPrototypes()
+    {
+        $node = new PrototypedArrayNode('root');
+        $prototype = new ArrayNode(null, $node);
+        $node->setPrototype($prototype);
+        $this->assertEmpty($node->getDefaultValue());
+    }
+
+    public function testGetDefaultValueReturnsDefaultValueForPrototypes()
+    {
+        $node = new PrototypedArrayNode('root');
+        $prototype = new ArrayNode(null, $node);
+        $node->setPrototype($prototype);
+        $node->setDefaultValue(array ('test'));
+        $this->assertEquals(array ('test'), $node->getDefaultValue());
+    }
+
+    // a remapped key (e.g. "mapping" -> "mappings") should be unset after being used
+    public function testRemappedKeysAreUnset()
+    {
+        $node = new ArrayNode('root');
+        $mappingsNode = new PrototypedArrayNode('mappings');
+        $node->addChild($mappingsNode);
+
+        // each item under mappings is just a scalar
+        $prototype = new ScalarNode(null, $mappingsNode);
+        $mappingsNode->setPrototype($prototype);
+
+        $remappings = array();
+        $remappings[] = array('mapping', 'mappings');
+        $node->setXmlRemappings($remappings);
+
+        $normalized = $node->normalize(array('mapping' => array('foo', 'bar')));
+        $this->assertEquals(array('mappings' => array('foo', 'bar')), $normalized);
+    }
+
+    /**
+     * Tests that when a key attribute is mapped, that key is removed from the array:
+     *
+     *     <things>
+     *         <option id="option1" value="foo">
+     *         <option id="option2" value="bar">
+     *     </things>
+     *
+     * The above should finally be mapped to an array that looks like this
+     * (because "id" is the key attribute).
+     *
+     *     array(
+     *         'things' => array(
+     *             'option1' => 'foo',
+     *             'option2' => 'bar',
+     *         )
+     *     )
+     */
+    public function testMappedAttributeKeyIsRemoved()
+    {
+        $node = new PrototypedArrayNode('root');
+        $node->setKeyAttribute('id', true);
+
+        // each item under the root is an array, with one scalar item
+        $prototype = new ArrayNode(null, $node);
+        $prototype->addChild(new ScalarNode('foo'));
+        $node->setPrototype($prototype);
+
+        $children = array();
+        $children[] = array('id' => 'item_name', 'foo' => 'bar');
+        $normalized = $node->normalize($children);
+
+        $expected = array();
+        $expected['item_name'] = array('foo' => 'bar');
+        $this->assertEquals($expected, $normalized);
+    }
+
+    /**
+     * Tests the opposite of the testMappedAttributeKeyIsRemoved because
+     * the removal can be toggled with an option.
+     */
+    public function testMappedAttributeKeyNotRemoved()
+    {
+        $node = new PrototypedArrayNode('root');
+        $node->setKeyAttribute('id', false);
+
+        // each item under the root is an array, with two scalar items
+        $prototype = new ArrayNode(null, $node);
+        $prototype->addChild(new ScalarNode('foo'));
+        $prototype->addChild(new ScalarNode('id')); // the key attribute will remain
+        $node->setPrototype($prototype);
+
+        $children = array();
+        $children[] = array('id' => 'item_name', 'foo' => 'bar');
+        $normalized = $node->normalize($children);
+
+        $expected = array();
+        $expected['item_name'] = array('id' => 'item_name', 'foo' => 'bar');
+        $this->assertEquals($expected, $normalized);
+    }
+
+    public function testAddDefaultChildren()
+    {
+        $node = $this->getPrototypeNodeWithDefaultChildren();
+        $node->setAddChildrenIfNoneSet();
+        $this->assertTrue($node->hasDefaultValue());
+        $this->assertEquals(array(array('foo' => 'bar')), $node->getDefaultValue());
+
+        $node = $this->getPrototypeNodeWithDefaultChildren();
+        $node->setKeyAttribute('foobar');
+        $node->setAddChildrenIfNoneSet();
+        $this->assertTrue($node->hasDefaultValue());
+        $this->assertEquals(array('defaults' => array('foo' => 'bar')), $node->getDefaultValue());
+
+        $node = $this->getPrototypeNodeWithDefaultChildren();
+        $node->setKeyAttribute('foobar');
+        $node->setAddChildrenIfNoneSet('defaultkey');
+        $this->assertTrue($node->hasDefaultValue());
+        $this->assertEquals(array('defaultkey' => array('foo' => 'bar')), $node->getDefaultValue());
+
+        $node = $this->getPrototypeNodeWithDefaultChildren();
+        $node->setKeyAttribute('foobar');
+        $node->setAddChildrenIfNoneSet(array('defaultkey'));
+        $this->assertTrue($node->hasDefaultValue());
+        $this->assertEquals(array('defaultkey' => array('foo' => 'bar')), $node->getDefaultValue());
+
+        $node = $this->getPrototypeNodeWithDefaultChildren();
+        $node->setKeyAttribute('foobar');
+        $node->setAddChildrenIfNoneSet(array('dk1', 'dk2'));
+        $this->assertTrue($node->hasDefaultValue());
+        $this->assertEquals(array('dk1' => array('foo' => 'bar'), 'dk2' => array('foo' => 'bar')), $node->getDefaultValue());
+
+        $node = $this->getPrototypeNodeWithDefaultChildren();
+        $node->setAddChildrenIfNoneSet(array(5, 6));
+        $this->assertTrue($node->hasDefaultValue());
+        $this->assertEquals(array(0 => array('foo' => 'bar'), 1 => array('foo' => 'bar')), $node->getDefaultValue());
+
+        $node = $this->getPrototypeNodeWithDefaultChildren();
+        $node->setAddChildrenIfNoneSet(2);
+        $this->assertTrue($node->hasDefaultValue());
+        $this->assertEquals(array(array('foo' => 'bar'), array('foo' => 'bar')), $node->getDefaultValue());
+    }
+
+    public function testDefaultChildrenWinsOverDefaultValue()
+    {
+        $node = $this->getPrototypeNodeWithDefaultChildren();
+        $node->setAddChildrenIfNoneSet();
+        $node->setDefaultValue(array('bar' => 'foo'));
+        $this->assertTrue($node->hasDefaultValue());
+        $this->assertEquals(array(array('foo' => 'bar')), $node->getDefaultValue());
+    }
+
+    protected function getPrototypeNodeWithDefaultChildren()
+    {
+        $node = new PrototypedArrayNode('root');
+        $prototype = new ArrayNode(null, $node);
+        $child = new ScalarNode('foo');
+        $child->setDefaultValue('bar');
+        $prototype->addChild($child);
+        $prototype->setAddIfNotSet(true);
+        $node->setPrototype($prototype);
+
+        return $node;
+    }
+}
diff --git a/core/vendor/Symfony/Component/Config/Tests/Definition/ScalarNodeTest.php b/core/vendor/Symfony/Component/Config/Tests/Definition/ScalarNodeTest.php
new file mode 100644
index 0000000..91e47ef
--- /dev/null
+++ b/core/vendor/Symfony/Component/Config/Tests/Definition/ScalarNodeTest.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\Config\Tests\Definition;
+
+use Symfony\Component\Config\Definition\ScalarNode;
+
+class ScalarNodeTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @dataProvider getValidValues
+     */
+    public function testNormalize($value)
+    {
+        $node = new ScalarNode('test');
+        $this->assertSame($value, $node->normalize($value));
+    }
+
+    public function getValidValues()
+    {
+        return array(
+            array(false),
+            array(true),
+            array(null),
+            array(''),
+            array('foo'),
+            array(0),
+            array(1),
+            array(0.0),
+            array(0.1),
+        );
+    }
+
+    /**
+     * @dataProvider getInvalidValues
+     * @expectedException Symfony\Component\Config\Definition\Exception\InvalidTypeException
+     */
+    public function testNormalizeThrowsExceptionOnInvalidValues($value)
+    {
+        $node = new ScalarNode('test');
+        $node->normalize($value);
+    }
+
+    public function getInvalidValues()
+    {
+        return array(
+            array(array()),
+            array(array('foo' => 'bar')),
+            array(new \stdClass()),
+        );
+    }
+}
diff --git a/core/vendor/Symfony/Component/Config/Tests/FileLocatorTest.php b/core/vendor/Symfony/Component/Config/Tests/FileLocatorTest.php
new file mode 100644
index 0000000..8e8f442
--- /dev/null
+++ b/core/vendor/Symfony/Component/Config/Tests/FileLocatorTest.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\Config\Tests;
+
+use Symfony\Component\Config\FileLocator;
+
+class FileLocatorTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @dataProvider getIsAbsolutePathTests
+     */
+    public function testIsAbsolutePath($path)
+    {
+        $loader = new FileLocator(array());
+        $r = new \ReflectionObject($loader);
+        $m = $r->getMethod('isAbsolutePath');
+        $m->setAccessible(true);
+
+        $this->assertTrue($m->invoke($loader, $path), '->isAbsolutePath() returns true for an absolute path');
+    }
+
+    public function getIsAbsolutePathTests()
+    {
+        return array(
+            array('/foo.xml'),
+            array('c:\\\\foo.xml'),
+            array('c:/foo.xml'),
+            array('\\server\\foo.xml'),
+            array('https://server/foo.xml'),
+            array('phar://server/foo.xml'),
+        );
+    }
+
+    public function testLocate()
+    {
+        $loader = new FileLocator(__DIR__.'/Fixtures');
+
+        $this->assertEquals(
+            __DIR__.DIRECTORY_SEPARATOR.'FileLocatorTest.php',
+            $loader->locate('FileLocatorTest.php', __DIR__),
+            '->locate() returns the absolute filename if the file exists in the given path'
+        );
+
+        $this->assertEquals(
+            __DIR__.'/Fixtures'.DIRECTORY_SEPARATOR.'foo.xml',
+            $loader->locate('foo.xml', __DIR__),
+            '->locate() returns the absolute filename if the file exists in one of the paths given in the constructor'
+        );
+
+        $this->assertEquals(
+            __DIR__.'/Fixtures'.DIRECTORY_SEPARATOR.'foo.xml',
+            $loader->locate(__DIR__.'/Fixtures'.DIRECTORY_SEPARATOR.'foo.xml', __DIR__),
+            '->locate() returns the absolute filename if the file exists in one of the paths given in the constructor'
+        );
+
+        $loader = new FileLocator(array(__DIR__.'/Fixtures', __DIR__.'/Fixtures/Again'));
+
+        $this->assertEquals(
+            array(__DIR__.'/Fixtures'.DIRECTORY_SEPARATOR.'foo.xml', __DIR__.'/Fixtures/Again'.DIRECTORY_SEPARATOR.'foo.xml'),
+            $loader->locate('foo.xml', __DIR__, false),
+            '->locate() returns an array of absolute filenames'
+        );
+
+        $this->assertEquals(
+            array(__DIR__.'/Fixtures'.DIRECTORY_SEPARATOR.'foo.xml', __DIR__.'/Fixtures/Again'.DIRECTORY_SEPARATOR.'foo.xml'),
+            $loader->locate('foo.xml', __DIR__.'/Fixtures', false),
+            '->locate() returns an array of absolute filenames'
+        );
+
+        $loader = new FileLocator(__DIR__.'/Fixtures/Again');
+
+        $this->assertEquals(
+            array(__DIR__.'/Fixtures'.DIRECTORY_SEPARATOR.'foo.xml', __DIR__.'/Fixtures/Again'.DIRECTORY_SEPARATOR.'foo.xml'),
+            $loader->locate('foo.xml', __DIR__.'/Fixtures', false),
+            '->locate() returns an array of absolute filenames'
+        );
+    }
+
+    /**
+     * @expectedException \InvalidArgumentException
+     */
+    public function testLocateThrowsAnExceptionIfTheFileDoesNotExists()
+    {
+        $loader = new FileLocator(array(__DIR__.'/Fixtures'));
+
+        $loader->locate('foobar.xml', __DIR__);
+    }
+
+    /**
+     * @expectedException \InvalidArgumentException
+     */
+    public function testLocateThrowsAnExceptionIfTheFileDoesNotExistsInAbsolutePath()
+    {
+        $loader = new FileLocator(array(__DIR__.'/Fixtures'));
+
+        $loader->locate(__DIR__.'/Fixtures/foobar.xml', __DIR__);
+    }
+}
diff --git a/core/vendor/Symfony/Component/Config/Tests/Fixtures/Again/foo.xml b/core/vendor/Symfony/Component/Config/Tests/Fixtures/Again/foo.xml
new file mode 100644
index 0000000..e69de29
diff --git a/core/vendor/Symfony/Component/Config/Tests/Fixtures/Builder/BarNodeDefinition.php b/core/vendor/Symfony/Component/Config/Tests/Fixtures/Builder/BarNodeDefinition.php
new file mode 100644
index 0000000..47701c1
--- /dev/null
+++ b/core/vendor/Symfony/Component/Config/Tests/Fixtures/Builder/BarNodeDefinition.php
@@ -0,0 +1,21 @@
+<?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\Config\Tests\Definition\Builder;
+
+use Symfony\Component\Config\Definition\Builder\NodeDefinition;
+
+class BarNodeDefinition extends NodeDefinition
+{
+    protected function createNode()
+    {
+    }
+}
diff --git a/core/vendor/Symfony/Component/Config/Tests/Fixtures/Builder/NodeBuilder.php b/core/vendor/Symfony/Component/Config/Tests/Fixtures/Builder/NodeBuilder.php
new file mode 100644
index 0000000..aa59863
--- /dev/null
+++ b/core/vendor/Symfony/Component/Config/Tests/Fixtures/Builder/NodeBuilder.php
@@ -0,0 +1,34 @@
+<?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\Config\Tests\Definition\Builder;
+
+use Symfony\Component\Config\Definition\Builder\NodeBuilder as BaseNodeBuilder;
+
+class NodeBuilder extends BaseNodeBuilder
+{
+    public function barNode($name)
+    {
+        return $this->node($name, 'bar');
+    }
+
+    protected function getNodeClass($type)
+    {
+        switch ($type) {
+            case 'variable':
+                return __NAMESPACE__.'\\'.ucfirst($type).'NodeDefinition';
+            case 'bar':
+                return __NAMESPACE__.'\\'.ucfirst($type).'NodeDefinition';
+            default:
+                return parent::getNodeClass($type);
+        }
+    }
+}
diff --git a/core/vendor/Symfony/Component/Config/Tests/Fixtures/Builder/VariableNodeDefinition.php b/core/vendor/Symfony/Component/Config/Tests/Fixtures/Builder/VariableNodeDefinition.php
new file mode 100644
index 0000000..1017880
--- /dev/null
+++ b/core/vendor/Symfony/Component/Config/Tests/Fixtures/Builder/VariableNodeDefinition.php
@@ -0,0 +1,18 @@
+<?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\Config\Tests\Definition\Builder;
+
+use Symfony\Component\Config\Definition\Builder\VariableNodeDefinition as BaseVariableNodeDefinition;
+
+class VariableNodeDefinition extends BaseVariableNodeDefinition
+{
+}
diff --git a/core/vendor/Symfony/Component/Config/Tests/Fixtures/foo.xml b/core/vendor/Symfony/Component/Config/Tests/Fixtures/foo.xml
new file mode 100644
index 0000000..e69de29
diff --git a/core/vendor/Symfony/Component/Config/Tests/Loader/DelegatingLoaderTest.php b/core/vendor/Symfony/Component/Config/Tests/Loader/DelegatingLoaderTest.php
new file mode 100644
index 0000000..3b04a01
--- /dev/null
+++ b/core/vendor/Symfony/Component/Config/Tests/Loader/DelegatingLoaderTest.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\Config\Tests\Loader;
+
+use Symfony\Component\Config\Loader\LoaderResolver;
+use Symfony\Component\Config\Loader\DelegatingLoader;
+
+class DelegatingLoaderTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @covers Symfony\Component\Config\Loader\DelegatingLoader::__construct
+     */
+    public function testConstructor()
+    {
+        $loader = new DelegatingLoader($resolver = new LoaderResolver());
+        $this->assertTrue(true, '__construct() takes a loader resolver as its first argument');
+    }
+
+    /**
+     * @covers Symfony\Component\Config\Loader\DelegatingLoader::getResolver
+     * @covers Symfony\Component\Config\Loader\DelegatingLoader::setResolver
+     */
+    public function testGetSetResolver()
+    {
+        $resolver = new LoaderResolver();
+        $loader = new DelegatingLoader($resolver);
+        $this->assertSame($resolver, $loader->getResolver(), '->getResolver() gets the resolver loader');
+        $loader->setResolver($resolver = new LoaderResolver());
+        $this->assertSame($resolver, $loader->getResolver(), '->setResolver() sets the resolver loader');
+    }
+
+    /**
+     * @covers Symfony\Component\Config\Loader\DelegatingLoader::supports
+     */
+    public function testSupports()
+    {
+        $loader1 = $this->getMock('Symfony\Component\Config\Loader\LoaderInterface');
+        $loader1->expects($this->once())->method('supports')->will($this->returnValue(true));
+        $loader = new DelegatingLoader(new LoaderResolver(array($loader1)));
+        $this->assertTrue($loader->supports('foo.xml'), '->supports() returns true if the resource is loadable');
+
+        $loader1 = $this->getMock('Symfony\Component\Config\Loader\LoaderInterface');
+        $loader1->expects($this->once())->method('supports')->will($this->returnValue(false));
+        $loader = new DelegatingLoader(new LoaderResolver(array($loader1)));
+        $this->assertFalse($loader->supports('foo.foo'), '->supports() returns false if the resource is not loadable');
+    }
+
+    /**
+     * @covers Symfony\Component\Config\Loader\DelegatingLoader::load
+     */
+    public function testLoad()
+    {
+        $loader = $this->getMock('Symfony\Component\Config\Loader\LoaderInterface');
+        $loader->expects($this->once())->method('supports')->will($this->returnValue(true));
+        $loader->expects($this->once())->method('load');
+        $resolver = new LoaderResolver(array($loader));
+        $loader = new DelegatingLoader($resolver);
+
+        $loader->load('foo');
+    }
+
+    /**
+     * @expectedException Symfony\Component\Config\Exception\FileLoaderLoadException
+     */
+    public function testLoadThrowsAnExceptionIfTheResourceCannotBeLoaded()
+    {
+        $loader = $this->getMock('Symfony\Component\Config\Loader\LoaderInterface');
+        $loader->expects($this->once())->method('supports')->will($this->returnValue(false));
+        $resolver = new LoaderResolver(array($loader));
+        $loader = new DelegatingLoader($resolver);
+
+        $loader->load('foo');
+    }
+}
diff --git a/core/vendor/Symfony/Component/Config/Tests/Loader/LoaderResolverTest.php b/core/vendor/Symfony/Component/Config/Tests/Loader/LoaderResolverTest.php
new file mode 100644
index 0000000..8ee276b
--- /dev/null
+++ b/core/vendor/Symfony/Component/Config/Tests/Loader/LoaderResolverTest.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\Config\Tests\Loader;
+
+use Symfony\Component\Config\Loader\LoaderResolver;
+
+class LoaderResolverTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @covers Symfony\Component\Config\Loader\LoaderResolver::__construct
+     */
+    public function testConstructor()
+    {
+        $resolver = new LoaderResolver(array(
+            $loader = $this->getMock('Symfony\Component\Config\Loader\LoaderInterface'),
+        ));
+
+        $this->assertEquals(array($loader), $resolver->getLoaders(), '__construct() takes an array of loaders as its first argument');
+    }
+
+    /**
+     * @covers Symfony\Component\Config\Loader\LoaderResolver::resolve
+     */
+    public function testResolve()
+    {
+        $loader = $this->getMock('Symfony\Component\Config\Loader\LoaderInterface');
+        $resolver = new LoaderResolver(array($loader));
+        $this->assertFalse($resolver->resolve('foo.foo'), '->resolve() returns false if no loader is able to load the resource');
+
+        $loader = $this->getMock('Symfony\Component\Config\Loader\LoaderInterface');
+        $loader->expects($this->once())->method('supports')->will($this->returnValue(true));
+        $resolver = new LoaderResolver(array($loader));
+        $this->assertEquals($loader, $resolver->resolve(function () {}), '->resolve() returns the loader for the given resource');
+    }
+
+    /**
+     * @covers Symfony\Component\Config\Loader\LoaderResolver::getLoaders
+     * @covers Symfony\Component\Config\Loader\LoaderResolver::addLoader
+     */
+    public function testLoaders()
+    {
+        $resolver = new LoaderResolver();
+        $resolver->addLoader($loader = $this->getMock('Symfony\Component\Config\Loader\LoaderInterface'));
+
+        $this->assertEquals(array($loader), $resolver->getLoaders(), 'addLoader() adds a loader');
+    }
+}
diff --git a/core/vendor/Symfony/Component/Config/Tests/Loader/LoaderTest.php b/core/vendor/Symfony/Component/Config/Tests/Loader/LoaderTest.php
new file mode 100644
index 0000000..5b14e19
--- /dev/null
+++ b/core/vendor/Symfony/Component/Config/Tests/Loader/LoaderTest.php
@@ -0,0 +1,74 @@
+<?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\Config\Tests\Loader;
+
+use Symfony\Component\Config\Loader\LoaderResolver;
+use Symfony\Component\Config\Loader\Loader;
+use Symfony\Component\Config\Exception\FileLoaderLoadException;
+
+class LoaderTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @covers Symfony\Component\Config\Loader\Loader::getResolver
+     * @covers Symfony\Component\Config\Loader\Loader::setResolver
+     */
+    public function testGetSetResolver()
+    {
+        $resolver = new LoaderResolver();
+        $loader = new ProjectLoader1();
+        $loader->setResolver($resolver);
+        $this->assertSame($resolver, $loader->getResolver(), '->setResolver() sets the resolver loader');
+    }
+
+    /**
+     * @covers Symfony\Component\Config\Loader\Loader::resolve
+     */
+    public function testResolve()
+    {
+        $loader1 = $this->getMock('Symfony\Component\Config\Loader\LoaderInterface');
+        $loader1->expects($this->once())->method('supports')->will($this->returnValue(true));
+        $resolver = new LoaderResolver(array($loader1));
+        $loader = new ProjectLoader1();
+        $loader->setResolver($resolver);
+
+        $this->assertSame($loader, $loader->resolve('foo.foo'), '->resolve() finds a loader');
+        $this->assertSame($loader1, $loader->resolve('foo.xml'), '->resolve() finds a loader');
+
+        $loader1 = $this->getMock('Symfony\Component\Config\Loader\LoaderInterface');
+        $loader1->expects($this->once())->method('supports')->will($this->returnValue(false));
+        $resolver = new LoaderResolver(array($loader1));
+        $loader = new ProjectLoader1();
+        $loader->setResolver($resolver);
+        try {
+            $loader->resolve('FOOBAR');
+            $this->fail('->resolve() throws a FileLoaderLoadException if the resource cannot be loaded');
+        } catch (FileLoaderLoadException $e) {
+            $this->assertInstanceOf('Symfony\Component\Config\Exception\FileLoaderLoadException', $e, '->resolve() throws a FileLoaderLoadException if the resource cannot be loaded');
+        }
+    }
+}
+
+class ProjectLoader1 extends Loader
+{
+    public function load($resource, $type = null)
+    {
+    }
+
+    public function supports($resource, $type = null)
+    {
+        return is_string($resource) && 'foo' === pathinfo($resource, PATHINFO_EXTENSION);
+    }
+
+    public function getType()
+    {
+    }
+}
diff --git a/core/vendor/Symfony/Component/Config/Tests/Resource/DirectoryResourceTest.php b/core/vendor/Symfony/Component/Config/Tests/Resource/DirectoryResourceTest.php
new file mode 100644
index 0000000..5b1dd47
--- /dev/null
+++ b/core/vendor/Symfony/Component/Config/Tests/Resource/DirectoryResourceTest.php
@@ -0,0 +1,170 @@
+<?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\Config\Tests\Resource;
+
+use Symfony\Component\Config\Resource\DirectoryResource;
+
+class DirectoryResourceTest extends \PHPUnit_Framework_TestCase
+{
+    protected $directory;
+
+    protected function setUp()
+    {
+        $this->directory = sys_get_temp_dir().'/symfonyDirectoryIterator';
+        if (!file_exists($this->directory)) {
+            mkdir($this->directory);
+        }
+        touch($this->directory.'/tmp.xml');
+    }
+
+    protected function tearDown()
+    {
+        if (!is_dir($this->directory)) {
+            return;
+        }
+        $this->removeDirectory($this->directory);
+    }
+
+    protected function removeDirectory($directory) {
+        $iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($directory), \RecursiveIteratorIterator::CHILD_FIRST);
+        foreach ($iterator as $path) {
+            if (preg_match('#/\.\.?$#', $path->__toString())) {
+                continue;
+            }
+            if ($path->isDir()) {
+               rmdir($path->__toString());
+            } else {
+               unlink($path->__toString());
+            }
+        }
+        rmdir($directory);
+    }
+
+    /**
+     * @covers Symfony\Component\Config\Resource\DirectoryResource::getResource
+     */
+    public function testGetResource()
+    {
+        $resource = new DirectoryResource($this->directory);
+        $this->assertEquals($this->directory, $resource->getResource(), '->getResource() returns the path to the resource');
+    }
+
+    public function testGetPattern()
+    {
+        $resource = new DirectoryResource('foo', 'bar');
+        $this->assertEquals('bar', $resource->getPattern());
+    }
+
+    /**
+     * @covers Symfony\Component\Config\Resource\DirectoryResource::isFresh
+     */
+    public function testIsFresh()
+    {
+        $resource = new DirectoryResource($this->directory);
+        $this->assertTrue($resource->isFresh(time() + 10), '->isFresh() returns true if the resource has not changed');
+        $this->assertFalse($resource->isFresh(time() - 86400), '->isFresh() returns false if the resource has been updated');
+
+        $resource = new DirectoryResource('/____foo/foobar'.rand(1, 999999));
+        $this->assertFalse($resource->isFresh(time()), '->isFresh() returns false if the resource does not exist');
+    }
+
+    /**
+     * @covers Symfony\Component\Config\Resource\DirectoryResource::isFresh
+     */
+    public function testIsFreshUpdateFile()
+    {
+        $resource = new DirectoryResource($this->directory);
+        touch($this->directory.'/tmp.xml', time() + 20);
+        $this->assertFalse($resource->isFresh(time() + 10), '->isFresh() returns false if an existing file is modified');
+    }
+
+    /**
+     * @covers Symfony\Component\Config\Resource\DirectoryResource::isFresh
+     */
+    public function testIsFreshNewFile()
+    {
+        $resource = new DirectoryResource($this->directory);
+        touch($this->directory.'/new.xml', time() + 20);
+        $this->assertFalse($resource->isFresh(time() + 10), '->isFresh() returns false if a new file is added');
+    }
+
+    /**
+     * @covers Symfony\Component\Config\Resource\DirectoryResource::isFresh
+     */
+    public function testIsFreshDeleteFile()
+    {
+        $resource = new DirectoryResource($this->directory);
+        unlink($this->directory.'/tmp.xml');
+        $this->assertFalse($resource->isFresh(time()), '->isFresh() returns false if an existing file is removed');
+    }
+
+    /**
+     * @covers Symfony\Component\Config\Resource\DirectoryResource::isFresh
+     */
+    public function testIsFreshDeleteDirectory()
+    {
+        $resource = new DirectoryResource($this->directory);
+        $this->removeDirectory($this->directory);
+        $this->assertFalse($resource->isFresh(time()), '->isFresh() returns false if the whole resource is removed');
+    }
+
+    /**
+     * @covers Symfony\Component\Config\Resource\DirectoryResource::isFresh
+     */
+    public function testIsFreshCreateFileInSubdirectory()
+    {
+        $subdirectory = $this->directory.'/subdirectory';
+        mkdir($subdirectory);
+
+        $resource = new DirectoryResource($this->directory);
+        $this->assertTrue($resource->isFresh(time() + 10), '->isFresh() returns true if an unmodified subdirectory exists');
+
+        touch($subdirectory.'/newfile.xml', time() + 20);
+        $this->assertFalse($resource->isFresh(time() + 10), '->isFresh() returns false if a new file in a subdirectory is added');
+    }
+
+    /**
+     * @covers Symfony\Component\Config\Resource\DirectoryResource::isFresh
+     */
+    public function testIsFreshModifySubdirectory()
+    {
+        $resource = new DirectoryResource($this->directory);
+
+        $subdirectory = $this->directory.'/subdirectory';
+        mkdir($subdirectory);
+        touch($subdirectory, time() + 20);
+
+        $this->assertFalse($resource->isFresh(time() + 10), '->isFresh() returns false if a subdirectory is modified (e.g. a file gets deleted)');
+    }
+
+    /**
+     * @covers Symfony\Component\Config\Resource\DirectoryResource::isFresh
+     */
+    public function testFilterRegexListNoMatch()
+    {
+        $resource = new DirectoryResource($this->directory, '/\.(foo|xml)$/');
+
+        touch($this->directory.'/new.bar', time() + 20);
+        $this->assertTrue($resource->isFresh(time() + 10), '->isFresh() returns true if a new file not matching the filter regex is created');
+    }
+
+    /**
+     * @covers Symfony\Component\Config\Resource\DirectoryResource::isFresh
+     */
+    public function testFilterRegexListMatch()
+    {
+        $resource = new DirectoryResource($this->directory, '/\.(foo|xml)$/');
+
+        touch($this->directory.'/new.xml', time() + 20);
+        $this->assertFalse($resource->isFresh(time() + 10), '->isFresh() returns false if an new file matching the filter regex is created ');
+    }
+}
diff --git a/core/vendor/Symfony/Component/Config/Tests/Resource/FileResourceTest.php b/core/vendor/Symfony/Component/Config/Tests/Resource/FileResourceTest.php
new file mode 100644
index 0000000..83c403b
--- /dev/null
+++ b/core/vendor/Symfony/Component/Config/Tests/Resource/FileResourceTest.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\Config\Tests\Resource;
+
+use Symfony\Component\Config\Resource\FileResource;
+
+class FileResourceTest extends \PHPUnit_Framework_TestCase
+{
+    protected $resource;
+    protected $file;
+
+    protected function setUp()
+    {
+        $this->file = sys_get_temp_dir().'/tmp.xml';
+        touch($this->file);
+        $this->resource = new FileResource($this->file);
+    }
+
+    protected function tearDown()
+    {
+        unlink($this->file);
+    }
+
+    /**
+     * @covers Symfony\Component\Config\Resource\FileResource::getResource
+     */
+    public function testGetResource()
+    {
+        $this->assertEquals(realpath($this->file), $this->resource->getResource(), '->getResource() returns the path to the resource');
+    }
+
+    /**
+     * @covers Symfony\Component\Config\Resource\FileResource::isFresh
+     */
+    public function testIsFresh()
+    {
+        $this->assertTrue($this->resource->isFresh(time() + 10), '->isFresh() returns true if the resource has not changed');
+        $this->assertFalse($this->resource->isFresh(time() - 86400), '->isFresh() returns false if the resource has been updated');
+
+        $resource = new FileResource('/____foo/foobar'.rand(1, 999999));
+        $this->assertFalse($resource->isFresh(time()), '->isFresh() returns false if the resource does not exist');
+    }
+}
diff --git a/core/vendor/Symfony/Component/Config/Tests/bootstrap.php b/core/vendor/Symfony/Component/Config/Tests/bootstrap.php
new file mode 100644
index 0000000..3a61b6d
--- /dev/null
+++ b/core/vendor/Symfony/Component/Config/Tests/bootstrap.php
@@ -0,0 +1,18 @@
+<?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.
+ */
+
+spl_autoload_register(function ($class) {
+    if (0 === strpos(ltrim($class, '/'), 'Symfony\Component\Config')) {
+        if (file_exists($file = __DIR__.'/../'.substr(str_replace('\\', '/', $class), strlen('Symfony\Component\Config')).'.php')) {
+            require_once $file;
+        }
+    }
+});
diff --git a/core/vendor/Symfony/Component/Config/composer.json b/core/vendor/Symfony/Component/Config/composer.json
new file mode 100644
index 0000000..41f08cb
--- /dev/null
+++ b/core/vendor/Symfony/Component/Config/composer.json
@@ -0,0 +1,30 @@
+{
+    "name": "symfony/config",
+    "type": "library",
+    "description": "Symfony Config Component",
+    "keywords": [],
+    "homepage": "http://symfony.com",
+    "license": "MIT",
+    "authors": [
+        {
+            "name": "Fabien Potencier",
+            "email": "fabien@symfony.com"
+        },
+        {
+            "name": "Symfony Community",
+            "homepage": "http://symfony.com/contributors"
+        }
+    ],
+    "require": {
+        "php": ">=5.3.3"
+    },
+    "autoload": {
+        "psr-0": { "Symfony\\Component\\Config": "" }
+    },
+    "target-dir": "Symfony/Component/Config",
+    "extra": {
+        "branch-alias": {
+            "dev-master": "2.1-dev"
+        }
+    }
+}
diff --git a/core/vendor/Symfony/Component/Config/phpunit.xml.dist b/core/vendor/Symfony/Component/Config/phpunit.xml.dist
new file mode 100644
index 0000000..e019519
--- /dev/null
+++ b/core/vendor/Symfony/Component/Config/phpunit.xml.dist
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<phpunit backupGlobals="false"
+         backupStaticAttributes="false"
+         colors="true"
+         convertErrorsToExceptions="true"
+         convertNoticesToExceptions="true"
+         convertWarningsToExceptions="true"
+         processIsolation="false"
+         stopOnFailure="false"
+         syntaxCheck="false"
+         bootstrap="Tests/bootstrap.php"
+>
+    <testsuites>
+        <testsuite name="Symfony Config Component Test Suite">
+            <directory>./Tests/</directory>
+        </testsuite>
+    </testsuites>
+
+    <filter>
+        <whitelist>
+            <directory>./</directory>
+            <exclude>
+                <directory>./Resources</directory>
+                <directory>./Tests</directory>
+                <directory>./vendor</directory>
+            </exclude>
+        </whitelist>
+    </filter>
+</phpunit>
diff --git a/core/vendor/Symfony/Component/Translation/.gitignore b/core/vendor/Symfony/Component/Translation/.gitignore
new file mode 100644
index 0000000..d1502b0
--- /dev/null
+++ b/core/vendor/Symfony/Component/Translation/.gitignore
@@ -0,0 +1,2 @@
+vendor/
+composer.lock
diff --git a/core/vendor/Symfony/Component/Translation/CHANGELOG.md b/core/vendor/Symfony/Component/Translation/CHANGELOG.md
new file mode 100644
index 0000000..72affba
--- /dev/null
+++ b/core/vendor/Symfony/Component/Translation/CHANGELOG.md
@@ -0,0 +1,10 @@
+CHANGELOG
+=========
+
+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/Component/Translation/Dumper/CsvFileDumper.php b/core/vendor/Symfony/Component/Translation/Dumper/CsvFileDumper.php
new file mode 100644
index 0000000..0b41190
--- /dev/null
+++ b/core/vendor/Symfony/Component/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/Component/Translation/Dumper/DumperInterface.php b/core/vendor/Symfony/Component/Translation/Dumper/DumperInterface.php
new file mode 100644
index 0000000..148b082
--- /dev/null
+++ b/core/vendor/Symfony/Component/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
+     */
+    function dump(MessageCatalogue $messages, $options = array());
+}
diff --git a/core/vendor/Symfony/Component/Translation/Dumper/FileDumper.php b/core/vendor/Symfony/Component/Translation/Dumper/FileDumper.php
new file mode 100644
index 0000000..4494812
--- /dev/null
+++ b/core/vendor/Symfony/Component/Translation/Dumper/FileDumper.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;
+
+/**
+ * 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
+{
+    /**
+     * {@inheritDoc}
+     */
+    public function dump(MessageCatalogue $messages, $options = array())
+    {
+        if (!array_key_exists('path', $options)) {
+            throw new \InvalidArgumentException('The file dumper need a path options.');
+        }
+
+        // save a file for each domain
+        foreach ($messages->getDomains() as $domain) {
+            $file = $domain.'.'.$messages->getLocale().'.'.$this->getExtension();
+            // backup
+            if (file_exists($options['path'].$file)) {
+                copy($options['path'].$file, $options['path'].'/'.$file.'~');
+            }
+            // save file
+            file_put_contents($options['path'].'/'.$file, $this->format($messages, $domain));
+        }
+    }
+
+    /**
+     * Transforms a domain of a message catalogue to its string representation.
+     *
+     * @return The string representation
+     */
+    abstract protected function format(MessageCatalogue $messages, $domain);
+
+    /**
+     * Gets the file extension of the dumper.
+     *
+     * @return The file extension
+     */
+    abstract protected function getExtension();
+}
diff --git a/core/vendor/Symfony/Component/Translation/Dumper/IcuResFileDumper.php b/core/vendor/Symfony/Component/Translation/Dumper/IcuResFileDumper.php
new file mode 100644
index 0000000..d0a20ed
--- /dev/null
+++ b/core/vendor/Symfony/Component/Translation/Dumper/IcuResFileDumper.php
@@ -0,0 +1,135 @@
+<?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 implements DumperInterface
+{
+    /**
+     * {@inheritDoc}
+     */
+    public function dump(MessageCatalogue $messages, $options = array())
+    {
+        if (!array_key_exists('path', $options)) {
+            throw new \InvalidArgumentException('The file dumper need a path options.');
+        }
+
+        // save a file for each domain
+        foreach ($messages->getDomains() as $domain) {
+            $file = $messages->getLocale().'.'.$this->getExtension();
+            $path = $options['path'].'/'.$domain.'/';
+
+            if (!file_exists($path)) {
+                mkdir($path);
+            }
+
+            // backup
+            if (file_exists($path.$file)) {
+                copy($path.$file, $path.$file.'~');
+            }
+
+            // save file
+            file_put_contents($path.$file, $this->format($messages, $domain));
+        }
+    }
+
+    /**
+     * {@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/Component/Translation/Dumper/IniFileDumper.php b/core/vendor/Symfony/Component/Translation/Dumper/IniFileDumper.php
new file mode 100644
index 0000000..d808bdb
--- /dev/null
+++ b/core/vendor/Symfony/Component/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 a 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/Component/Translation/Dumper/MoFileDumper.php b/core/vendor/Symfony/Component/Translation/Dumper/MoFileDumper.php
new file mode 100644
index 0000000..448e3cd
--- /dev/null
+++ b/core/vendor/Symfony/Component/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/Component/Translation/Dumper/PhpFileDumper.php b/core/vendor/Symfony/Component/Translation/Dumper/PhpFileDumper.php
new file mode 100644
index 0000000..8de4a5b
--- /dev/null
+++ b/core/vendor/Symfony/Component/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/Component/Translation/Dumper/PoFileDumper.php b/core/vendor/Symfony/Component/Translation/Dumper/PoFileDumper.php
new file mode 100644
index 0000000..cc523ce
--- /dev/null
+++ b/core/vendor/Symfony/Component/Translation/Dumper/PoFileDumper.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;
+
+/**
+ * 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 = '';
+
+        foreach ($messages->all($domain) as $source => $target) {
+            $output .= sprintf("msgid \"%s\"\n", $this->escape($source));
+            $output .= sprintf("msgstr \"%s\"\n\n", $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/Component/Translation/Dumper/QtFileDumper.php b/core/vendor/Symfony/Component/Translation/Dumper/QtFileDumper.php
new file mode 100644
index 0000000..a1a8480
--- /dev/null
+++ b/core/vendor/Symfony/Component/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/Component/Translation/Dumper/XliffFileDumper.php b/core/vendor/Symfony/Component/Translation/Dumper/XliffFileDumper.php
new file mode 100644
index 0000000..ab93959
--- /dev/null
+++ b/core/vendor/Symfony/Component/Translation/Dumper/XliffFileDumper.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\Dumper;
+
+use Symfony\Component\Translation\MessageCatalogue;
+
+/**
+ * XliffFileDumper generates xliff files from a message catalogue.
+ *
+ * @author Michel Salib <michelsalib@hotmail.com>
+ */
+class XliffFileDumper extends FileDumper
+{
+    /**
+     * {@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', $messages->getLocale());
+        $xliffFile->setAttribute('datatype', 'plaintext');
+        $xliffFile->setAttribute('original', 'file.ext');
+        $xliffBody = $xliffFile->appendChild($dom->createElement('body'));
+        $id = 1;
+        foreach ($messages->all($domain) as $source => $target) {
+            $trans = $dom->createElement('trans-unit');
+            $trans->setAttribute('id', $id);
+            $s = $trans->appendChild($dom->createElement('source'));
+            $s->appendChild($dom->createTextNode($source));
+            $t = $trans->appendChild($dom->createElement('target'));
+            $t->appendChild($dom->createTextNode($target));
+            $xliffBody->appendChild($trans);
+            $id++;
+        }
+
+        return $dom->saveXML();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected function getExtension()
+    {
+        return 'xlf';
+    }
+}
diff --git a/core/vendor/Symfony/Component/Translation/Dumper/YamlFileDumper.php b/core/vendor/Symfony/Component/Translation/Dumper/YamlFileDumper.php
new file mode 100644
index 0000000..d8072fb
--- /dev/null
+++ b/core/vendor/Symfony/Component/Translation/Dumper/YamlFileDumper.php
@@ -0,0 +1,39 @@
+<?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)
+    {
+         return Yaml::dump($messages->all($domain));
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected function getExtension()
+    {
+        return 'yml';
+    }
+}
diff --git a/core/vendor/Symfony/Component/Translation/Extractor/ChainExtractor.php b/core/vendor/Symfony/Component/Translation/Extractor/ChainExtractor.php
new file mode 100644
index 0000000..632295f
--- /dev/null
+++ b/core/vendor/Symfony/Component/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 array
+     */
+    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/Component/Translation/Extractor/ExtractorInterface.php b/core/vendor/Symfony/Component/Translation/Extractor/ExtractorInterface.php
new file mode 100644
index 0000000..5378a66
--- /dev/null
+++ b/core/vendor/Symfony/Component/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 template directory 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 a template directory to the catalogue.
+     *
+     * @param string           $directory The path to look into
+     * @param MessageCatalogue $catalogue The catalogue
+     */
+    function extract($directory, MessageCatalogue $catalogue);
+
+    /**
+     * Sets the prefix that should be used for new found messages.
+     *
+     * @param string $prefix The prefix
+     */
+    function setPrefix($prefix);
+}
diff --git a/core/vendor/Symfony/Component/Translation/Gettext.php b/core/vendor/Symfony/Component/Translation/Gettext.php
new file mode 100644
index 0000000..a28fe31
--- /dev/null
+++ b/core/vendor/Symfony/Component/Translation/Gettext.php
@@ -0,0 +1,153 @@
+<?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;
+
+/**
+ * Provide for specific Gettext related helper functionality.
+ *
+ * @see http://www.gnu.org/software/gettext/manual/gettext.html#PO-Files
+ * @author Clemens Tolboom
+ * @copyright Clemens Tolboom clemens@build2be.com
+ */
+class Gettext
+{
+    /**
+     * Defines a key for managing a PO Header in our messages.
+     *
+     * PO and MO files can have a header which needs to be managed.
+     * Currently we choose to let this be done by PoFileLoader static function. 
+     */
+    const HEADER_KEY = "__HEADER__";
+
+    /**
+     * Parses a Gettext header string into a key/value pairs.
+     *
+     * @param $header
+     *   The Gettext header.
+     * @return array
+     *   Array with the key/value pair
+     */
+    static function explodeHeader($header)
+    {
+        $clean_extra = FALSE;
+        $result = array();
+        $lines = explode("\n", $header);
+        foreach ($lines as $line) {
+            $cleaned = trim($line);
+            if ($cleaned == 'msgid ""') {
+                $clean_extra = TRUE;
+            }
+            if (strpos($cleaned, ':') > 0) {
+                list($key, $value) = explode(':', $cleaned, 2);
+                $key = trim($key);
+                if ($clean_extra) {
+                    // Delete prefix: "
+                    $key = substr($key, 1);
+                    // Delete postfix \n"
+                   $value = substr($value, 0, -3);
+                }
+                $result[$key] = trim($value);
+            }
+        }
+        return $result;
+    }
+
+    /**
+     * Merge key/value pair into Gettext compatible item.
+     *
+     * Each combination is into substring: "key: value \n".
+     *
+     * If any key found the values are preceded by empty msgid and msgstr
+     *
+     * @param array $header
+     * @return array or NULL
+     *   A Gettext compatible item.
+     */
+    static function implodeHeader(array $header)
+    {
+       $lines = array();
+       foreach ($header as $key => $value) {
+           $lines[] = '"' . $key . ": " . $value . '\n"';
+       }
+       if (count($lines)) {
+         $result = array(
+           'msgid ""',
+           'msgstr ""',
+         );
+         $result = array_merge($result, $lines);
+         return implode("\n", $result);
+       }
+    }
+
+    /**
+     * Ordered list of Gettext header keys
+     *
+     * TODO: this list is probably incomplete
+     *
+     * @return array
+     *   Ordered list of Gettext keys
+     */
+    static function headerKeys() {
+        return array(
+            'Project-Id-Version',
+            'POT-Creation-Date',
+            'PO-Revision-Date',
+            'Last-Translator',
+            'Language-Team',
+            'MIME-Version',
+            'Content-Type',
+            'Content-Transfer-Encoding',
+            'Plural-Forms'
+        );
+    }
+
+    static function emptyHeader() {
+        return array_fill_keys(Gettext::headerKeys(), "");
+    }
+
+    /**
+     * Retrieve PO Header from messages.
+     *
+     * @param array $messages
+     * @return the found message or NULL
+     */
+    static function getHeader(array &$messages)
+    {
+        if (isset($messages[Gettext::HEADER_KEY])) {
+          return $messages[Gettext::HEADER_KEY];
+        }
+        return NULL;
+    }
+
+    /**
+     * Adds or overwrite a header to the messages.
+     *
+     * @param array $messages
+     * @param type $header 
+     */
+    static function addHeader(array &$messages, $header)
+    {
+        $messages[Gettext::HEADER_KEY] = $header;
+    }
+
+    /**
+     * Deletes a header from the messages if exists.
+     *
+     * @param array $messages 
+     */
+    static function delHeader(array &$messages) {
+        if (isset($messages[Gettext::HEADER_KEY])) {
+          unset($messages[Gettext::HEADER_KEY]);
+        }
+    }
+
+}
diff --git a/core/vendor/Symfony/Component/Translation/IdentityTranslator.php b/core/vendor/Symfony/Component/Translation/IdentityTranslator.php
new file mode 100644
index 0000000..35fe6f0
--- /dev/null
+++ b/core/vendor/Symfony/Component/Translation/IdentityTranslator.php
@@ -0,0 +1,74 @@
+<?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;
+
+    /**
+     * Constructor.
+     *
+     * @param MessageSelector $selector The message selector for pluralization
+     *
+     * @api
+     */
+    public function __construct(MessageSelector $selector)
+    {
+        $this->selector = $selector;
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @api
+     */
+    public function setLocale($locale)
+    {
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @api
+     */
+    public function getLocale()
+    {
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @api
+     */
+    public function trans($id, array $parameters = array(), $domain = 'messages', $locale = null)
+    {
+        return strtr($id, $parameters);
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @api
+     */
+    public function transChoice($id, $number, array $parameters = array(), $domain = 'messages', $locale = null)
+    {
+        return strtr($this->selector->choose($id, (int) $number, $locale), $parameters);
+    }
+}
diff --git a/core/vendor/Symfony/Component/Translation/Interval.php b/core/vendor/Symfony/Component/Translation/Interval.php
new file mode 100644
index 0000000..078e1a4
--- /dev/null
+++ b/core/vendor/Symfony/Component/Translation/Interval.php
@@ -0,0 +1,103 @@
+<?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 integer $number   A number
+     * @param string  $interval An interval
+     */
+    static public 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)
+     */
+    static public function getIntervalRegexp()
+    {
+        return <<<EOF
+        ({\s*
+            (\-?\d+[\s*,\s*\-?\d+]*)
+        \s*})
+
+            |
+
+        (?P<left_delimiter>[\[\]])
+            \s*
+            (?P<left>-Inf|\-?\d+)
+            \s*,\s*
+            (?P<right>\+?Inf|\-?\d+)
+            \s*
+        (?P<right_delimiter>[\[\]])
+EOF;
+    }
+
+    static private function convertNumber($number)
+    {
+        if ('-Inf' === $number) {
+            return log(0);
+        } elseif ('+Inf' === $number || 'Inf' === $number) {
+            return -log(0);
+        }
+
+        return (int) $number;
+    }
+}
diff --git a/core/vendor/Symfony/Component/Translation/LICENSE b/core/vendor/Symfony/Component/Translation/LICENSE
new file mode 100644
index 0000000..cdffe7a
--- /dev/null
+++ b/core/vendor/Symfony/Component/Translation/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2004-2012 Fabien Potencier
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/core/vendor/Symfony/Component/Translation/Loader/ArrayLoader.php b/core/vendor/Symfony/Component/Translation/Loader/ArrayLoader.php
new file mode 100644
index 0000000..cecb2b6
--- /dev/null
+++ b/core/vendor/Symfony/Component/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/Component/Translation/Loader/CsvFileLoader.php b/core/vendor/Symfony/Component/Translation/Loader/CsvFileLoader.php
new file mode 100644
index 0000000..ce8930f
--- /dev/null
+++ b/core/vendor/Symfony/Component/Translation/Loader/CsvFileLoader.php
@@ -0,0 +1,86 @@
+<?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\Resource\FileResource;
+
+/**
+ * CsvFileLoader loads translations from CSV files.
+ *
+ * @author Saša Stamenković <umpirsky@gmail.com>
+ *
+ * @api
+ */
+class CsvFileLoader extends ArrayLoader implements LoaderInterface
+{
+    private $delimiter = ';';
+    private $enclosure = '"';
+    private $escape    = '\\';
+
+    /**
+     * {@inheritdoc}
+     *
+     * @api
+     */
+    public function load($resource, $locale, $domain = 'messages')
+    {
+        $messages = array();
+
+        if (!stream_is_local($resource)) {
+            throw new \InvalidArgumentException(sprintf('This is not a local file "%s".', $resource));
+        }
+
+        try {
+            $file = new \SplFileObject($resource, 'rb');
+        } catch (\RuntimeException $e) {
+            throw new \InvalidArgumentException(sprintf('Error opening file "%s".', $resource));
+        }
+
+        $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);
+        $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/Component/Translation/Loader/IcuDatFileLoader.php b/core/vendor/Symfony/Component/Translation/Loader/IcuDatFileLoader.php
new file mode 100644
index 0000000..83c8aba
--- /dev/null
+++ b/core/vendor/Symfony/Component/Translation/Loader/IcuDatFileLoader.php
@@ -0,0 +1,44 @@
+<?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\Config\Resource\FileResource;
+
+/**
+ * IcuResFileLoader loads translations from a resource bundle.
+ *
+ * @author stealth35
+ */
+class IcuDatFileLoader extends IcuResFileLoader
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function load($resource, $locale, $domain = 'messages')
+    {
+        $rb = new \ResourceBundle($locale, $resource);
+
+        if (!$rb) {
+            throw new \RuntimeException("cannot load this resource : $resource");
+        } elseif (intl_is_failure($rb->getErrorCode())) {
+            throw new \RuntimeException($rb->getErrorMessage(), $rb->getErrorCode());
+        }
+
+        $messages = $this->flatten($rb);
+        $catalogue = new MessageCatalogue($locale);
+        $catalogue->add($messages, $domain);
+        $catalogue->addResource(new FileResource($resource.'.dat'));
+
+        return $catalogue;
+    }
+}
diff --git a/core/vendor/Symfony/Component/Translation/Loader/IcuResFileLoader.php b/core/vendor/Symfony/Component/Translation/Loader/IcuResFileLoader.php
new file mode 100644
index 0000000..9387596
--- /dev/null
+++ b/core/vendor/Symfony/Component/Translation/Loader/IcuResFileLoader.php
@@ -0,0 +1,74 @@
+<?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\Config\Resource\DirectoryResource;
+
+/**
+ * IcuResFileLoader loads translations from a resource bundle.
+ *
+ * @author stealth35
+ */
+class IcuResFileLoader implements LoaderInterface
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function load($resource, $locale, $domain = 'messages')
+    {
+        $rb = new \ResourceBundle($locale, $resource);
+
+        if (!$rb) {
+            throw new \RuntimeException("cannot load this resource : $resource");
+        } elseif (intl_is_failure($rb->getErrorCode())) {
+            throw new \RuntimeException($rb->getErrorMessage(), $rb->getErrorCode());
+        }
+
+        $messages = $this->flatten($rb);
+        $catalogue = new MessageCatalogue($locale);
+        $catalogue->add($messages, $domain);
+        $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/Component/Translation/Loader/IniFileLoader.php b/core/vendor/Symfony/Component/Translation/Loader/IniFileLoader.php
new file mode 100644
index 0000000..cd18170
--- /dev/null
+++ b/core/vendor/Symfony/Component/Translation/Loader/IniFileLoader.php
@@ -0,0 +1,39 @@
+<?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\Resource\FileResource;
+
+/**
+ * IniFileLoader loads translations from an ini file.
+ *
+ * @author stealth35
+ */
+class IniFileLoader extends ArrayLoader implements LoaderInterface
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function load($resource, $locale, $domain = 'messages')
+    {
+        if (!is_file($resource)) {
+            throw new \InvalidArgumentException(sprintf('Error opening file "%s".', $resource));
+        }
+
+        $messages = parse_ini_file($resource, true);
+
+        $catalogue = parent::load($messages, $locale, $domain);
+        $catalogue->addResource(new FileResource($resource));
+
+        return $catalogue;
+    }
+}
diff --git a/core/vendor/Symfony/Component/Translation/Loader/LoaderInterface.php b/core/vendor/Symfony/Component/Translation/Loader/LoaderInterface.php
new file mode 100644
index 0000000..8602390
--- /dev/null
+++ b/core/vendor/Symfony/Component/Translation/Loader/LoaderInterface.php
@@ -0,0 +1,37 @@
+<?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;
+
+/**
+ * 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
+     */
+    function load($resource, $locale, $domain = 'messages');
+}
diff --git a/core/vendor/Symfony/Component/Translation/Loader/MoFileLoader.php b/core/vendor/Symfony/Component/Translation/Loader/MoFileLoader.php
new file mode 100644
index 0000000..104dedc
--- /dev/null
+++ b/core/vendor/Symfony/Component/Translation/Loader/MoFileLoader.php
@@ -0,0 +1,174 @@
+<?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\Resource\FileResource;
+
+/**
+ * @copyright Copyright (c) 2010, Union of RAD http://union-of-rad.org (http://lithify.me/)
+ */
+class MoFileLoader extends ArrayLoader implements LoaderInterface
+{
+    /**
+     * 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 integer Number of bytes.
+     */
+    const MO_HEADER_SIZE = 28;
+
+    public function load($resource, $locale, $domain = 'messages')
+    {
+        $messages = $this->parse($resource);
+
+        // empty file
+        if (null === $messages) {
+            $messages = array();
+        }
+
+        // not an array
+        if (!is_array($messages)) {
+            throw new \InvalidArgumentException(sprintf('The file "%s" must contain a valid mo file.', $resource));
+        }
+
+        $catalogue = parent::load($messages, $locale, $domain);
+        $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 InvalidArgumentException 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 \InvalidArgumentException("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 \InvalidArgumentException("MO stream content has an invalid format.");
+        }
+
+        $header = array(
+            'formatRevision' => null,
+            'count' => null,
+            'offsetId' => null,
+            'offsetTranslated' => null,
+            'sizeHashes' => null,
+            'offsetHashes' => null,
+        );
+        foreach ($header as &$value) {
+            $value = $this->readLong($stream, $isBigEndian);
+        }
+        extract($header);
+        $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);
+
+            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 boolean $isBigEndian
+     * @return integer
+     */
+    private function readLong($stream, $isBigEndian)
+    {
+        $result = unpack($isBigEndian ? 'N1' : 'V1', fread($stream, 4));
+        $result = current($result);
+
+        return (integer) substr($result, -8);
+    }
+}
diff --git a/core/vendor/Symfony/Component/Translation/Loader/PhpFileLoader.php b/core/vendor/Symfony/Component/Translation/Loader/PhpFileLoader.php
new file mode 100644
index 0000000..c80d938
--- /dev/null
+++ b/core/vendor/Symfony/Component/Translation/Loader/PhpFileLoader.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\Loader;
+
+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 implements LoaderInterface
+{
+    /**
+     * {@inheritdoc}
+     *
+     * @api
+     */
+    public function load($resource, $locale, $domain = 'messages')
+    {
+        if (!stream_is_local($resource)) {
+            throw new \InvalidArgumentException(sprintf('This is not a local file "%s".', $resource));
+        }
+
+        $messages = require($resource);
+
+        $catalogue = parent::load($messages, $locale, $domain);
+        $catalogue->addResource(new FileResource($resource));
+
+        return $catalogue;
+    }
+}
diff --git a/core/vendor/Symfony/Component/Translation/Loader/PoFileLoader.php b/core/vendor/Symfony/Component/Translation/Loader/PoFileLoader.php
new file mode 100644
index 0000000..d5de88a
--- /dev/null
+++ b/core/vendor/Symfony/Component/Translation/Loader/PoFileLoader.php
@@ -0,0 +1,157 @@
+<?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\Resource\FileResource;
+use Symfony\Component\Translation\Gettext;
+
+/**
+ * @copyright Copyright (c) 2010, Union of RAD http://union-of-rad.org (http://lithify.me/)
+ */
+class PoFileLoader extends ArrayLoader implements LoaderInterface
+{
+
+  public function load($resource, $locale, $domain = 'messages')
+    {
+        $messages = $this->parse($resource);
+
+        // empty file
+        if (null === $messages) {
+            $messages = array();
+        }
+
+        // not an array
+        if (!is_array($messages)) {
+            throw new \InvalidArgumentException(sprintf('The file "%s" must contain a valid po file.', $resource));
+        }
+
+        $catalogue = parent::load($messages, $locale, $domain);
+        $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
+                // NOTE: this fails when context and comments 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'][(integer) substr($line, 7, 1)] = substr($line, $size + 3, -1);
+            }
+
+        }
+        // save last item
+        $this->addMessage($messages, $item);
+        fclose($stream);
+
+        return array_filter($messages);
+    }
+
+    private function addMessage(&$messages, $item)
+    {
+        if (is_array($item['translated'])) {
+            $messages[$item['ids']['singular']] = stripslashes($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']] = stripslashes($item['translated']);
+        } elseif(!empty($item['translated'])) {
+          // This is a header
+          $messages[Gettext::HEADER_KEY] = $item['translated'];
+        }
+    }
+}
diff --git a/core/vendor/Symfony/Component/Translation/Loader/QtTranslationsLoader.php b/core/vendor/Symfony/Component/Translation/Loader/QtTranslationsLoader.php
new file mode 100644
index 0000000..b31169d
--- /dev/null
+++ b/core/vendor/Symfony/Component/Translation/Loader/QtTranslationsLoader.php
@@ -0,0 +1,85 @@
+<?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\Resource\FileResource;
+use Symfony\Component\Translation\MessageCatalogue;
+
+/**
+ * QtTranslationsLoader loads translations from QT Translations XML files.
+ *
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ *
+ * @api
+ */
+class QtTranslationsLoader implements LoaderInterface
+{
+    /**
+     * {@inheritdoc}
+     *
+     * @api
+     */
+    public function load($resource, $locale, $domain = 'messages')
+    {
+        $dom = new \DOMDocument();
+        $current = libxml_use_internal_errors(true);
+        if (!@$dom->load($resource, defined('LIBXML_COMPACT') ? LIBXML_COMPACT : 0)) {
+            throw new \RuntimeException(implode("\n", $this->getXmlErrors()));
+        }
+
+        $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) {
+                $catalogue->set(
+                    (string) $translation->getElementsByTagName('source')->item(0)->nodeValue,
+                    (string) $translation->getElementsByTagName('translation')->item(0)->nodeValue,
+                    $domain
+                );
+                $translation = $translation->nextSibling;
+            }
+            $catalogue->addResource(new FileResource($resource));
+        }
+
+        libxml_use_internal_errors($current);
+
+        return $catalogue;
+    }
+
+    /**
+     * Returns the XML errors of the internal XML parser
+     *
+     * @return array  An array of errors
+     */
+    private function getXmlErrors()
+    {
+        $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 ? $error->file : 'n/a',
+                $error->line,
+                $error->column
+            );
+        }
+
+        libxml_clear_errors();
+        libxml_use_internal_errors(false);
+
+        return $errors;
+    }
+}
diff --git a/core/vendor/Symfony/Component/Translation/Loader/XliffFileLoader.php b/core/vendor/Symfony/Component/Translation/Loader/XliffFileLoader.php
new file mode 100644
index 0000000..b01ac72
--- /dev/null
+++ b/core/vendor/Symfony/Component/Translation/Loader/XliffFileLoader.php
@@ -0,0 +1,116 @@
+<?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\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 \InvalidArgumentException(sprintf('This is not a local file "%s".', $resource));
+        }
+
+        $xml = $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) {
+            if (2 !== count($translation)) {
+                continue;
+            }
+            $catalogue->set((string) $translation->source, (string) $translation->target, $domain);
+        }
+        $catalogue->addResource(new FileResource($resource));
+
+        return $catalogue;
+    }
+
+    /**
+     * Validates and parses the given file into a SimpleXMLElement
+     *
+     * @param  string $file
+     *
+     * @return SimpleXMLElement
+     */
+    private function parseFile($file)
+    {
+        $dom = new \DOMDocument();
+        $current = libxml_use_internal_errors(true);
+        if (!@$dom->load($file, defined('LIBXML_COMPACT') ? LIBXML_COMPACT : 0)) {
+            throw new \RuntimeException(implode("\n", $this->getXmlErrors()));
+        }
+
+        $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 \RuntimeException(implode("\n", $this->getXmlErrors()));
+        }
+        $dom->validateOnParse = true;
+        $dom->normalizeDocument();
+        libxml_use_internal_errors($current);
+
+        return simplexml_import_dom($dom);
+    }
+
+    /**
+     * Returns the XML errors of the internal XML parser
+     *
+     * @return array  An array of errors
+     */
+    private function getXmlErrors()
+    {
+        $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 ? $error->file : 'n/a',
+                $error->line,
+                $error->column
+            );
+        }
+
+        libxml_clear_errors();
+        libxml_use_internal_errors(false);
+
+        return $errors;
+    }
+}
diff --git a/core/vendor/Symfony/Component/Translation/Loader/YamlFileLoader.php b/core/vendor/Symfony/Component/Translation/Loader/YamlFileLoader.php
new file mode 100644
index 0000000..4ac885b
--- /dev/null
+++ b/core/vendor/Symfony/Component/Translation/Loader/YamlFileLoader.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\Loader;
+
+use Symfony\Component\Config\Resource\FileResource;
+use Symfony\Component\Yaml\Yaml;
+
+/**
+ * YamlFileLoader loads translations from Yaml files.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ *
+ * @api
+ */
+class YamlFileLoader extends ArrayLoader implements LoaderInterface
+{
+    /**
+     * {@inheritdoc}
+     *
+     * @api
+     */
+    public function load($resource, $locale, $domain = 'messages')
+    {
+        $messages = Yaml::parse($resource);
+
+        // empty file
+        if (null === $messages) {
+            $messages = array();
+        }
+
+        // not an array
+        if (!is_array($messages)) {
+            throw new \InvalidArgumentException(sprintf('The file "%s" must contain a YAML array.', $resource));
+        }
+
+        $catalogue = parent::load($messages, $locale, $domain);
+        $catalogue->addResource(new FileResource($resource));
+
+        return $catalogue;
+    }
+}
diff --git a/core/vendor/Symfony/Component/Translation/Loader/schema/dic/xliff-core/xliff-core-1.2-strict.xsd b/core/vendor/Symfony/Component/Translation/Loader/schema/dic/xliff-core/xliff-core-1.2-strict.xsd
new file mode 100644
index 0000000..3ce2a8e
--- /dev/null
+++ b/core/vendor/Symfony/Component/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/Component/Translation/Loader/schema/dic/xliff-core/xml.xsd b/core/vendor/Symfony/Component/Translation/Loader/schema/dic/xliff-core/xml.xsd
new file mode 100644
index 0000000..282cb5b
--- /dev/null
+++ b/core/vendor/Symfony/Component/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/Component/Translation/MessageCatalogue.php b/core/vendor/Symfony/Component/Translation/MessageCatalogue.php
new file mode 100644
index 0000000..49ce9fd
--- /dev/null
+++ b/core/vendor/Symfony/Component/Translation/MessageCatalogue.php
@@ -0,0 +1,234 @@
+<?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
+{
+    private $messages = array();
+    private $locale;
+    private $resources;
+    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;
+        $this->resources = array();
+    }
+
+    /**
+     * {@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);
+        }
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @api
+     */
+    public function addFallbackCatalogue(MessageCatalogueInterface $catalogue)
+    {
+        // detect circular references
+        $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);
+        }
+    }
+
+    /**
+     * Gets the fallback catalogue.
+     *
+     * @return MessageCatalogueInterface A MessageCatalogueInterface instance
+     *
+     * @api
+     */
+    public function getFallbackCatalogue()
+    {
+        return $this->fallbackCatalogue;
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @api
+     */
+    public function getResources()
+    {
+        return array_values(array_unique($this->resources));
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @api
+     */
+    public function addResource(ResourceInterface $resource)
+    {
+        $this->resources[] = $resource;
+    }
+}
diff --git a/core/vendor/Symfony/Component/Translation/MessageCatalogueInterface.php b/core/vendor/Symfony/Component/Translation/MessageCatalogueInterface.php
new file mode 100644
index 0000000..ef1feec
--- /dev/null
+++ b/core/vendor/Symfony/Component/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
+     */
+    function getLocale();
+
+    /**
+     * Gets the domains.
+     *
+     * @return array An array of domains
+     *
+     * @api
+     */
+    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
+     */
+    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
+     */
+    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 Boolean true if the message has a translation, false otherwise
+     *
+     * @api
+     */
+    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 Boolean true if the message has a translation, false otherwise
+     *
+     * @api
+     */
+    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
+     */
+    function get($id, $domain = 'messages');
+
+    /**
+     * Sets translations for a given domain.
+     *
+     * @param string $messages An array of translations
+     * @param string $domain   The domain name
+     *
+     * @api
+     */
+    function replace($messages, $domain = 'messages');
+
+    /**
+     * Adds translations for a given domain.
+     *
+     * @param string $messages An array of translations
+     * @param string $domain   The domain name
+     *
+     * @api
+     */
+    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
+     */
+    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
+     */
+    function addFallbackCatalogue(MessageCatalogueInterface $catalogue);
+
+    /**
+     * Gets the fallback catalogue.
+     *
+     * @return MessageCatalogueInterface A MessageCatalogueInterface instance
+     *
+     * @api
+     */
+    function getFallbackCatalogue();
+
+    /**
+     * Returns an array of resources loaded to build this collection.
+     *
+     * @return ResourceInterface[] An array of resources
+     *
+     * @api
+     */
+    function getResources();
+
+    /**
+     * Adds a resource for this collection.
+     *
+     * @param ResourceInterface $resource A resource instance
+     *
+     * @api
+     */
+    function addResource(ResourceInterface $resource);
+}
diff --git a/core/vendor/Symfony/Component/Translation/MessageSelector.php b/core/vendor/Symfony/Component/Translation/MessageSelector.php
new file mode 100644
index 0000000..0c8ff66
--- /dev/null
+++ b/core/vendor/Symfony/Component/Translation/MessageSelector.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;
+
+/**
+ * MessageSelector.
+ *
+ * @author Fabien Potencier <fabien@symfony.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 is %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  integer $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>.*?)$/x', $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])) {
+            throw new \InvalidArgumentException(sprintf('Unable to choose a translation for "%s" with locale "%s".', $message, $locale));
+        }
+
+        return $standardRules[$position];
+    }
+}
diff --git a/core/vendor/Symfony/Component/Translation/PluralizationRules.php b/core/vendor/Symfony/Component/Translation/PluralizationRules.php
new file mode 100644
index 0000000..a981f76
--- /dev/null
+++ b/core/vendor/Symfony/Component/Translation/PluralizationRules.php
@@ -0,0 +1,217 @@
+<?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
+{
+    // @codeCoverageIgnoreStart
+    static private $rules = array();
+
+    /**
+     * Returns the plural position to use for the given locale and number.
+     *
+     * @param  integer $number The number
+     * @param  string  $locale The locale
+     *
+     * @return integer The plural position
+     */
+    static public 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 '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 'az':
+            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 >= 3) && ($number <= 10)) ? 3 : ((($number >= 11) && ($number <= 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
+     *
+     * @return null
+     */
+    static public 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;
+    }
+
+    // @codeCoverageIgnoreEnd
+}
diff --git a/core/vendor/Symfony/Component/Translation/README.md b/core/vendor/Symfony/Component/Translation/README.md
new file mode 100644
index 0000000..c5dd052
--- /dev/null
+++ b/core/vendor/Symfony/Component/Translation/README.md
@@ -0,0 +1,38 @@
+Translation Component
+=====================
+
+Translation provides tools for loading translation files and generating
+translated strings from these including support for pluralization.
+
+    use Symfony\Component\Translation\Translator;
+    use Symfony\Component\Translation\MessageSelector;
+    use Symfony\Component\Translation\Loader\ArrayLoader;
+
+    $translator = new Translator('fr_FR', new MessageSelector());
+    $translator->setFallbackLocale('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/fabpot/Silex/blob/master/src/Silex/Provider/TranslationServiceProvider.php
+
+Documentation:
+
+http://symfony.com/doc/2.0/book/translation.html
+
+You can run the unit tests with the following command:
+
+    phpunit
+
+If you also want to run the unit tests that depend on other Symfony
+Components, install dev dependencies before running PHPUnit:
+
+    php composer.phar install --dev
diff --git a/core/vendor/Symfony/Component/Translation/Tests/Dumper/CsvFileDumperTest.php b/core/vendor/Symfony/Component/Translation/Tests/Dumper/CsvFileDumperTest.php
new file mode 100644
index 0000000..f3f1fb8
--- /dev/null
+++ b/core/vendor/Symfony/Component/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();
+        $dumperString = $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/Component/Translation/Tests/Dumper/IcuResFileDumperTest.php b/core/vendor/Symfony/Component/Translation/Tests/Dumper/IcuResFileDumperTest.php
new file mode 100644
index 0000000..ce1da5a
--- /dev/null
+++ b/core/vendor/Symfony/Component/Translation/Tests/Dumper/IcuResFileDumperTest.php
@@ -0,0 +1,37 @@
+<?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 (!extension_loaded('mbstring')) {
+            $this->markTestSkipped('This test requires mbstring to work.');
+        }
+
+        $catalogue = new MessageCatalogue('en');
+        $catalogue->add(array('foo' => 'bar'));
+
+        $tempDir = sys_get_temp_dir();
+        $dumper = new IcuResFileDumper();
+        $dumperString = $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');
+    }
+}
diff --git a/core/vendor/Symfony/Component/Translation/Tests/Dumper/IniFileDumperTest.php b/core/vendor/Symfony/Component/Translation/Tests/Dumper/IniFileDumperTest.php
new file mode 100644
index 0000000..be5895a
--- /dev/null
+++ b/core/vendor/Symfony/Component/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();
+        $dumperString = $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/Component/Translation/Tests/Dumper/MoFileDumperTest.php b/core/vendor/Symfony/Component/Translation/Tests/Dumper/MoFileDumperTest.php
new file mode 100644
index 0000000..5b35d81
--- /dev/null
+++ b/core/vendor/Symfony/Component/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();
+        $dumperString = $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/Component/Translation/Tests/Dumper/PhpFileDumperTest.php b/core/vendor/Symfony/Component/Translation/Tests/Dumper/PhpFileDumperTest.php
new file mode 100644
index 0000000..ef37d18
--- /dev/null
+++ b/core/vendor/Symfony/Component/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();
+        $dumperString = $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/Component/Translation/Tests/Dumper/PoFileDumperTest.php b/core/vendor/Symfony/Component/Translation/Tests/Dumper/PoFileDumperTest.php
new file mode 100644
index 0000000..9c434f9
--- /dev/null
+++ b/core/vendor/Symfony/Component/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();
+        $dumperString = $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/Component/Translation/Tests/Dumper/QtFileDumperTest.php b/core/vendor/Symfony/Component/Translation/Tests/Dumper/QtFileDumperTest.php
new file mode 100644
index 0000000..8e63ee9
--- /dev/null
+++ b/core/vendor/Symfony/Component/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();
+        $dumperString = $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/Component/Translation/Tests/Dumper/XliffFileDumperTest.php b/core/vendor/Symfony/Component/Translation/Tests/Dumper/XliffFileDumperTest.php
new file mode 100644
index 0000000..5514221
--- /dev/null
+++ b/core/vendor/Symfony/Component/Translation/Tests/Dumper/XliffFileDumperTest.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\XliffFileDumper;
+
+class XliffFileDumperTest extends \PHPUnit_Framework_TestCase
+{
+    public function testDump()
+    {
+        $catalogue = new MessageCatalogue('en');
+        $catalogue->add(array('foo' => 'bar', 'key' => ''));
+
+        $tempDir = sys_get_temp_dir();
+        $dumper = new XliffFileDumper();
+        $dumperString = $dumper->dump($catalogue, array('path' => $tempDir));
+
+        $this->assertEquals(file_get_contents(__DIR__.'/../fixtures/resources-clean.xlf'), file_get_contents($tempDir.'/messages.en.xlf'));
+
+        unlink($tempDir.'/messages.en.xlf');
+    }
+}
diff --git a/core/vendor/Symfony/Component/Translation/Tests/Dumper/YamlFileDumperTest.php b/core/vendor/Symfony/Component/Translation/Tests/Dumper/YamlFileDumperTest.php
new file mode 100644
index 0000000..324f375
--- /dev/null
+++ b/core/vendor/Symfony/Component/Translation/Tests/Dumper/YamlFileDumperTest.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\YamlFileDumper;
+
+class YamlFileDumperTest extends \PHPUnit_Framework_TestCase
+{
+    protected function setUp() {
+        if (!class_exists('Symfony\Component\Yaml\Yaml')) {
+            $this->markTestSkipped('The "Yaml" component is not available');
+        }
+    }
+
+    public function testDump()
+    {
+        $catalogue = new MessageCatalogue('en');
+        $catalogue->add(array('foo' => 'bar'));
+
+        $tempDir = sys_get_temp_dir();
+        $dumper = new YamlFileDumper();
+        $dumperString = $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/Component/Translation/Tests/GettextTest.php b/core/vendor/Symfony/Component/Translation/Tests/GettextTest.php
new file mode 100644
index 0000000..f5457bd
--- /dev/null
+++ b/core/vendor/Symfony/Component/Translation/Tests/GettextTest.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\Gettext;
+
+/**
+ * Description of GettextText
+ *
+ * @author clemens
+ */
+class GettextTest extends \PHPUnit_Framework_TestCase
+{
+    function testHeaderExplode() {
+        $header = "";
+        $actual = Gettext::explodeHeader($header);
+        $this->assertEquals($actual, array(), 'Empty header.');
+        $header = "A:B\nC:D";
+        $actual = Gettext::explodeHeader($header);
+        $this->assertArrayHasKey('C', $actual, 'Header key A found');
+        $this->assertEquals('D', $actual['C'], 'Header value D for C');
+    }
+
+    function testHeaderImplode() {
+        $header = array();
+        $actual = Gettext::implodeHeader($header);
+        $this->assertEquals($actual, NULL, 'Empty header.');
+        $header = array("A" => "B", "C" => "D");
+        $actual = Gettext::implodeHeader($header);
+        $expected = implode("\n", array('msgid ""', 'msgstr ""', '"A: B\n"','"C: D\n"'));
+        $this->assertEquals($expected, $actual, 'Header string ok');
+    }
+
+    function testValidHeader() {
+        $header = Gettext::emptyHeader();
+        $this->assertEquals(Gettext::headerKeys(), array_keys($header));
+        $this->assertEquals("", implode('', $header));
+        $implode = Gettext::implodeHeader($header);
+        $this->assertEquals($header, Gettext::explodeHeader($implode));
+    }
+    
+    function testIdentityHeader() {
+        $resource = __DIR__.'/fixtures/header.po';
+        $header = file_get_contents($resource);
+        // Make sure header keeps the same
+        $exploded = Gettext::explodeHeader($header);
+        $imploded = Gettext::implodeHeader($exploded);
+        $this->assertEquals($header, $imploded, 'Header from file maps to internal version');
+    }
+
+}
diff --git a/core/vendor/Symfony/Component/Translation/Tests/IdentityTranslatorTest.php b/core/vendor/Symfony/Component/Translation/Tests/IdentityTranslatorTest.php
new file mode 100644
index 0000000..435f0c2
--- /dev/null
+++ b/core/vendor/Symfony/Component/Translation/Tests/IdentityTranslatorTest.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\Tests;
+
+use Symfony\Component\Translation\IdentityTranslator;
+use Symfony\Component\Translation\MessageSelector;
+
+class IdentityTranslatorTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @dataProvider getTransTests
+     */
+    public function testTrans($expected, $id, $parameters)
+    {
+        $translator = new IdentityTranslator(new MessageSelector());
+
+        $this->assertEquals($expected, $translator->trans($id, $parameters));
+    }
+
+    /**
+     * @dataProvider getTransChoiceTests
+     */
+    public function testTransChoice($expected, $id, $number, $parameters)
+    {
+        $translator = new IdentityTranslator(new MessageSelector());
+
+        $this->assertEquals($expected, $translator->transChoice($id, $number, $parameters));
+    }
+
+    // noop
+    public function testGetSetLocale()
+    {
+        $translator = new IdentityTranslator(new MessageSelector());
+        $translator->setLocale('en');
+        $translator->getLocale();
+    }
+
+    public function getTransTests()
+    {
+        return array(
+            array('Symfony2 is great!', 'Symfony2 is great!', array()),
+            array('Symfony2 is awesome!', 'Symfony2 is %what%!', array('%what%' => 'awesome')),
+        );
+    }
+
+    public function getTransChoiceTests()
+    {
+        return array(
+            array('There is 10 apples', '{0} There is no apples|{1} There is one apple|]1,Inf] There is %count% apples', 10, array('%count%' => 10)),
+        );
+    }
+}
diff --git a/core/vendor/Symfony/Component/Translation/Tests/IntervalTest.php b/core/vendor/Symfony/Component/Translation/Tests/IntervalTest.php
new file mode 100644
index 0000000..075c98b
--- /dev/null
+++ b/core/vendor/Symfony/Component/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/Component/Translation/Tests/Loader/CsvFileLoaderTest.php b/core/vendor/Symfony/Component/Translation/Tests/Loader/CsvFileLoaderTest.php
new file mode 100644
index 0000000..b5a80d3
--- /dev/null
+++ b/core/vendor/Symfony/Component/Translation/Tests/Loader/CsvFileLoaderTest.php
@@ -0,0 +1,66 @@
+<?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
+{
+    protected function setUp() {
+        if (!class_exists('Symfony\Component\Config\Loader\Loader')) {
+            $this->markTestSkipped('The "Config" component is not available');
+        }
+    }
+
+    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 \InvalidArgumentException
+     */
+    public function testLoadThrowsAnExceptionIfFileNotExists()
+    {
+        $loader = new CsvFileLoader();
+        $resource = __DIR__.'/../fixtures/not-exists.csv';
+        $loader->load($resource, 'en', 'domain1');
+    }
+
+    /**
+     * @expectedException \InvalidArgumentException
+     */
+    public function testLoadThrowsAnExceptionIfFileNotLocal()
+    {
+        $loader = new CsvFileLoader();
+        $resource = 'http://example.com/resources.csv';
+        $loader->load($resource, 'en', 'domain1');
+    }
+}
diff --git a/core/vendor/Symfony/Component/Translation/Tests/Loader/IcuDatFileLoaderTest.php b/core/vendor/Symfony/Component/Translation/Tests/Loader/IcuDatFileLoaderTest.php
new file mode 100644
index 0000000..9214675
--- /dev/null
+++ b/core/vendor/Symfony/Component/Translation/Tests/Loader/IcuDatFileLoaderTest.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\Tests\Loader;
+
+use Symfony\Component\Translation\Loader\IcuDatFileLoader;
+use Symfony\Component\Config\Resource\FileResource;
+
+class IcuDatFileLoaderTest extends LocalizedTestCase
+{
+    protected function setUp() {
+        if (!class_exists('Symfony\Component\Config\Loader\Loader')) {
+            $this->markTestSkipped('The "Config" component is not available');
+        }
+
+        if (!extension_loaded('intl')) {
+            $this->markTestSkipped('This test requires intl extension to work.');
+        }
+
+    }
+
+    public function testDatEnglishLoad()
+    {
+        // bundled resource is build using pkgdata command which at leas 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 \RuntimeException
+     */
+    public function testLoadInvalidResource()
+    {
+        $loader = new IcuDatFileLoader();
+        $catalogue = $loader->load(__DIR__.'/../fixtures/resourcebundle/res/en.txt', 'en', 'domain1');
+    }
+}
diff --git a/core/vendor/Symfony/Component/Translation/Tests/Loader/IcuResFileLoaderTest.php b/core/vendor/Symfony/Component/Translation/Tests/Loader/IcuResFileLoaderTest.php
new file mode 100644
index 0000000..4c7960e
--- /dev/null
+++ b/core/vendor/Symfony/Component/Translation/Tests/Loader/IcuResFileLoaderTest.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\IcuResFileLoader;
+use Symfony\Component\Config\Resource\DirectoryResource;
+
+class IcuResFileLoaderTest extends LocalizedTestCase
+{
+    protected function setUp() {
+        if (!class_exists('Symfony\Component\Config\Loader\Loader')) {
+            $this->markTestSkipped('The "Config" component is not available');
+        }
+
+        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 \RuntimeException
+     */
+    public function testLoadInvalidResource()
+    {
+        $loader = new IcuResFileLoader();
+        $catalogue = $loader->load(__DIR__.'/../fixtures/resourcebundle/res/en.txt', 'en', 'domain1');
+    }
+}
diff --git a/core/vendor/Symfony/Component/Translation/Tests/Loader/IniFileLoaderTest.php b/core/vendor/Symfony/Component/Translation/Tests/Loader/IniFileLoaderTest.php
new file mode 100644
index 0000000..8e73d5c
--- /dev/null
+++ b/core/vendor/Symfony/Component/Translation/Tests/Loader/IniFileLoaderTest.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\Loader;
+
+use Symfony\Component\Translation\Loader\IniFileLoader;
+use Symfony\Component\Config\Resource\FileResource;
+
+class IniFileLoaderTest 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 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 \InvalidArgumentException
+     */
+    public function testLoadThrowsAnExceptionIfFileNotExists()
+    {
+        $loader = new IniFileLoader();
+        $resource = __DIR__.'/../fixtures/not-exists.ini';
+        $loader->load($resource, 'en', 'domain1');
+    }
+}
diff --git a/core/vendor/Symfony/Component/Translation/Tests/Loader/LocalizedTestCase.php b/core/vendor/Symfony/Component/Translation/Tests/Loader/LocalizedTestCase.php
new file mode 100644
index 0000000..9d7c5d7
--- /dev/null
+++ b/core/vendor/Symfony/Component/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/Component/Translation/Tests/Loader/MoFileLoaderTest.php b/core/vendor/Symfony/Component/Translation/Tests/Loader/MoFileLoaderTest.php
new file mode 100644
index 0000000..00870e7
--- /dev/null
+++ b/core/vendor/Symfony/Component/Translation/Tests/Loader/MoFileLoaderTest.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\Loader;
+
+use Symfony\Component\Translation\Loader\MoFileLoader;
+use Symfony\Component\Config\Resource\FileResource;
+
+class MoFileLoaderTest 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 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 \InvalidArgumentException
+     */
+    public function testLoadInvalidResource()
+    {
+        $loader = new MoFileLoader();
+        $resource = __DIR__.'/../fixtures/empty.mo';
+        $catalogue = $loader->load($resource, 'en', 'domain1');
+    }
+}
diff --git a/core/vendor/Symfony/Component/Translation/Tests/Loader/PhpFileLoaderTest.php b/core/vendor/Symfony/Component/Translation/Tests/Loader/PhpFileLoaderTest.php
new file mode 100644
index 0000000..dc5dda3
--- /dev/null
+++ b/core/vendor/Symfony/Component/Translation/Tests/Loader/PhpFileLoaderTest.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\Tests\Loader;
+
+use Symfony\Component\Translation\Loader\PhpFileLoader;
+use Symfony\Component\Config\Resource\FileResource;
+
+class PhpFileLoaderTest 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 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 \InvalidArgumentException
+     */
+    public function testLoadThrowsAnExceptionIfFileNotLocal()
+    {
+        $loader = new PhpFileLoader();
+        $resource = 'http://example.com/resources.php';
+        $loader->load($resource, 'en', 'domain1');
+    }
+}
diff --git a/core/vendor/Symfony/Component/Translation/Tests/Loader/PoFileLoaderTest.php b/core/vendor/Symfony/Component/Translation/Tests/Loader/PoFileLoaderTest.php
new file mode 100644
index 0000000..58cd5ed
--- /dev/null
+++ b/core/vendor/Symfony/Component/Translation/Tests/Loader/PoFileLoaderTest.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\Tests\Loader;
+
+use Symfony\Component\Translation\Loader\PoFileLoader;
+use Symfony\Component\Config\Resource\FileResource;
+use Symfony\Component\Translation\Gettext;
+
+class PoFileLoaderTest 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 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' => '{0} bar|{1} 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());
+    }
+
+    public function testLoadMultiline()
+    {
+        $loader = new PoFileLoader();
+        $resource = __DIR__.'/../fixtures/multiline.po';
+        $catalogue = $loader->load($resource, 'en', 'domain1');
+
+        $this->assertEquals(3, count($catalogue->all('domain1')));
+
+        $messages = $catalogue->all('domain1');
+        $this->assertEquals('trans single line', $messages['both single line']);
+        $this->assertEquals('trans multi line', $messages['source single line']);
+        $this->assertEquals('trans single line', $messages['source multi line']);
+
+    }
+
+    /**
+     * Read file with one item without whitespaces before and after.
+     */
+    public function testLoadMinimalFile()
+    {
+        $loader = new PoFileLoader();
+        $resource = __DIR__.'/../fixtures/minimal.po';
+        $catalogue = $loader->load($resource, 'en', 'domain1');
+        // TODO: This fails on 'source multi line'
+        $this->assertEquals(1, count($catalogue->all('domain1')));
+    }
+
+    /**
+     * Read the PO header and check it's available.
+     */
+    public function testLoadHeader()
+    {
+        $loader = new PoFileLoader();
+        $resource = __DIR__.'/../fixtures/header.po';
+        $catalogue = $loader->load($resource, 'en', 'domain1');
+        $messages = $catalogue->all('domain1');
+        $this->assertEquals(1, count($catalogue->all('domain1')));
+        // Header exists
+        $header = Gettext::getHeader($messages);
+        $this->assertNotNull($header, 'PoFileLoader has a header.');
+        // Is header removed
+        $header = Gettext::delHeader($messages);
+        $header = Gettext::getHeader($messages);
+        $this->assertNull($header, 'PoFileLoader has no header.');
+        // Add header
+        $header = Gettext::addHeader($messages, 'foo');
+        $header = Gettext::getHeader($messages);
+        $this->assertEquals($header, 'foo', 'PoFileLoader has a header.');
+    }
+
+}
diff --git a/core/vendor/Symfony/Component/Translation/Tests/Loader/QtTranslationsLoaderTest.php b/core/vendor/Symfony/Component/Translation/Tests/Loader/QtTranslationsLoaderTest.php
new file mode 100644
index 0000000..34edc45
--- /dev/null
+++ b/core/vendor/Symfony/Component/Translation/Tests/Loader/QtTranslationsLoaderTest.php
@@ -0,0 +1,35 @@
+<?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\QtTranslationsLoader;
+use Symfony\Component\Config\Resource\FileResource;
+
+class QtTranslationsLoaderTest 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 QtTranslationsLoader();
+        $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());
+    }
+}
diff --git a/core/vendor/Symfony/Component/Translation/Tests/Loader/XliffFileLoaderTest.php b/core/vendor/Symfony/Component/Translation/Tests/Loader/XliffFileLoaderTest.php
new file mode 100644
index 0000000..1afeabb
--- /dev/null
+++ b/core/vendor/Symfony/Component/Translation/Tests/Loader/XliffFileLoaderTest.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\XliffFileLoader;
+use Symfony\Component\Config\Resource\FileResource;
+
+class XliffFileLoaderTest 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 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());
+    }
+
+    public function testIncompleteResource()
+    {
+        $loader = new XliffFileLoader();
+        $catalogue = $loader->load(__DIR__.'/../fixtures/resources.xlf', 'en', 'domain1');
+
+        $this->assertEquals(array('foo' => 'bar', 'key' => ''), $catalogue->all('domain1'));
+        $this->assertFalse($catalogue->has('extra', 'domain1'));
+    }
+
+    /**
+     * @expectedException \RuntimeException
+     */
+    public function testLoadInvalidResource()
+    {
+        $loader = new XliffFileLoader();
+        $catalogue = $loader->load(__DIR__.'/../fixtures/resources.php', 'en', 'domain1');
+    }
+
+    /**
+     * @expectedException \RuntimeException
+     */
+    public function testLoadResourceDoesNotValidate()
+    {
+        $loader = new XliffFileLoader();
+        $catalogue = $loader->load(__DIR__.'/../fixtures/non-valid.xlf', 'en', 'domain1');
+    }
+
+    /**
+     * @expectedException \InvalidArgumentException
+     */
+    public function testLoadThrowsAnExceptionIfFileNotLocal()
+    {
+        $loader = new XliffFileLoader();
+        $resource = 'http://example.com/resources.xlf';
+        $loader->load($resource, 'en', 'domain1');
+    }
+}
diff --git a/core/vendor/Symfony/Component/Translation/Tests/Loader/YamlFileLoaderTest.php b/core/vendor/Symfony/Component/Translation/Tests/Loader/YamlFileLoaderTest.php
new file mode 100644
index 0000000..30ab24d
--- /dev/null
+++ b/core/vendor/Symfony/Component/Translation/Tests/Loader/YamlFileLoaderTest.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\YamlFileLoader;
+use Symfony\Component\Config\Resource\FileResource;
+
+class YamlFileLoaderTest extends \PHPUnit_Framework_TestCase
+{
+    protected function setUp() {
+        if (!class_exists('Symfony\Component\Config\Loader\Loader')) {
+            $this->markTestSkipped('The "Config" component is not available');
+        }
+
+        if (!class_exists('Symfony\Component\Yaml\Yaml')) {
+            $this->markTestSkipped('The "Yaml" component is not available');
+        }
+    }
+
+    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 \InvalidArgumentException
+     */
+    public function testLoadThrowsAnExceptionIfNotAnArray()
+    {
+        $loader = new YamlFileLoader();
+        $resource = __DIR__.'/../fixtures/non-valid.yml';
+        $loader->load($resource, 'en', 'domain1');
+    }
+}
diff --git a/core/vendor/Symfony/Component/Translation/Tests/MessageCatalogueTest.php b/core/vendor/Symfony/Component/Translation/Tests/MessageCatalogueTest.php
new file mode 100644
index 0000000..0448e3c
--- /dev/null
+++ b/core/vendor/Symfony/Component/Translation/Tests/MessageCatalogueTest.php
@@ -0,0 +1,173 @@
+<?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()
+    {
+        if (!class_exists('Symfony\Component\Config\Loader\Loader')) {
+            $this->markTestSkipped('The "Config" component is not available');
+        }
+
+        $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()
+    {
+        if (!class_exists('Symfony\Component\Config\Loader\Loader')) {
+            $this->markTestSkipped('The "Config" component is not available');
+        }
+
+        $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 testAddFallbackCatalogueWithCircularReference()
+    {
+        $main = new MessageCatalogue('en_US');
+        $fallback = new MessageCatalogue('fr_FR');
+
+        $fallback->addFallbackCatalogue($main);
+        $main->addFallbackCatalogue($fallback);
+    }
+
+    /**
+     * @expectedException LogicException
+     */
+    public function testAddCatalogueWhenLocaleIsNotTheSameAsTheCurrentOne()
+    {
+        $catalogue = new MessageCatalogue('en');
+        $catalogue->addCatalogue(new MessageCatalogue('fr', array()));
+    }
+
+    public function testGetAddResource()
+    {
+        if (!class_exists('Symfony\Component\Config\Loader\Loader')) {
+            $this->markTestSkipped('The "Config" component is not available');
+        }
+
+        $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());
+    }
+}
diff --git a/core/vendor/Symfony/Component/Translation/Tests/MessageSelectorTest.php b/core/vendor/Symfony/Component/Translation/Tests/MessageSelectorTest.php
new file mode 100644
index 0000000..5624d73
--- /dev/null
+++ b/core/vendor/Symfony/Component/Translation/Tests/MessageSelectorTest.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;
+
+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'));
+    }
+
+    /**
+     * @expectedException InvalidArgumentException
+     */
+    public function testChooseWhenNoEnoughChoices()
+    {
+        $selector = new MessageSelector();
+
+        $selector->choose('foo', 10, 'en');
+    }
+
+    public function getChooseTests()
+    {
+        return array(
+            array('There is no apples', '{0} There is no apples|{1} There is one apple|]1,Inf] There is %count% apples', 0),
+            array('There is no apples', '{0}     There is no apples|{1} There is one apple|]1,Inf] There is %count% apples', 0),
+            array('There is no apples', '{0}There is no apples|{1} There is one apple|]1,Inf] There is %count% apples', 0),
+
+            array('There is one apple', '{0} There is no apples|{1} There is one apple|]1,Inf] There is %count% apples', 1),
+
+            array('There is %count% apples', '{0} There is no apples|{1} There is one apple|]1,Inf] There is %count% apples', 10),
+            array('There is %count% apples', '{0} There is no apples|{1} There is one apple|]1,Inf]There is %count% apples', 10),
+            array('There is %count% apples', '{0} There is no apples|{1} There is one apple|]1,Inf]     There is %count% apples', 10),
+
+            array('There is %count% apples', 'There is one apple|There is %count% apples', 0),
+            array('There is one apple', 'There is one apple|There is %count% apples', 1),
+            array('There is %count% apples', 'There is one apple|There is %count% apples', 10),
+
+            array('There is %count% apples', 'one: There is one apple|more: There is %count% apples', 0),
+            array('There is one apple', 'one: There is one apple|more: There is %count% apples', 1),
+            array('There is %count% apples', 'one: There is one apple|more: There is %count% apples', 10),
+
+            array('There is no apples', '{0} There is no apples|one: There is one apple|more: There is %count% apples', 0),
+            array('There is one apple', '{0} There is no apples|one: There is one apple|more: There is %count% apples', 1),
+            array('There is %count% apples', '{0} There is no apples|one: There is one apple|more: There is %count% apples', 10),
+
+            array('', '{0}|{1} There is one apple|]1,Inf] There is %count% apples', 0),
+            array('', '{0} There is no apples|{1}|]1,Inf] There is %count% apples', 1),
+        );
+    }
+}
diff --git a/core/vendor/Symfony/Component/Translation/Tests/TranslatorTest.php b/core/vendor/Symfony/Component/Translation/Tests/TranslatorTest.php
new file mode 100644
index 0000000..82aedfe
--- /dev/null
+++ b/core/vendor/Symfony/Component/Translation/Tests/TranslatorTest.php
@@ -0,0 +1,248 @@
+<?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;
+
+class TranslatorTest extends \PHPUnit_Framework_TestCase
+{
+    public function testSetGetLocale()
+    {
+        $translator = new Translator('en', new MessageSelector());
+
+        $this->assertEquals('en', $translator->getLocale());
+
+        $translator->setLocale('fr');
+        $this->assertEquals('fr', $translator->getLocale());
+    }
+
+    public function testSetFallbackLocale()
+    {
+        $translator = new Translator('en', new MessageSelector());
+        $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->setFallbackLocale('fr');
+        $this->assertEquals('foobar', $translator->trans('bar'));
+    }
+
+    public function testSetFallbackLocaleMultiple()
+    {
+        $translator = new Translator('en', new MessageSelector());
+        $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->setFallbackLocale(array('fr_FR', 'fr'));
+        $this->assertEquals('bar (fr)', $translator->trans('bar'));
+    }
+
+    public function testTransWithFallbackLocale()
+    {
+        $translator = new Translator('fr_FR', new MessageSelector());
+        $translator->addLoader('array', new ArrayLoader());
+        $translator->addResource('array', array('foo' => 'foofoo'), 'en_US');
+        $translator->addResource('array', array('bar' => 'foobar'), 'en');
+
+        $translator->setFallbackLocale('en');
+
+        $this->assertEquals('foobar', $translator->trans('bar'));
+    }
+
+    public function testTransWithFallbackLocaleBis()
+    {
+        $translator = new Translator('en_US', new MessageSelector());
+        $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', new MessageSelector());
+        $translator->addLoader('array', new ArrayLoader());
+        $translator->addResource('array', array('foo' => 'foo (en_US)'), 'en_US');
+        $translator->addResource('array', array('bar' => 'bar (en)'), 'en');
+
+        $translator->setFallbackLocale(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', new MessageSelector());
+        $translator->setFallbackLocale('en');
+        $translator->addLoader('array', new ArrayLoader());
+        $this->assertEquals('non-existent', $translator->trans('non-existent'));
+    }
+
+    /**
+     * @expectedException RuntimeException
+     */
+    public function testWhenAResourceHasNoRegisteredLoader()
+    {
+        $translator = new Translator('en', new MessageSelector());
+        $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', new MessageSelector());
+        $translator->addLoader('array', new ArrayLoader());
+        $translator->addResource('array', array((string) $id => $translation), $locale, $domain);
+
+        $this->assertEquals($expected, $translator->trans($id, $parameters, $domain, $locale));
+    }
+
+    /**
+     * @dataProvider getFlattenedTransTests
+     */
+    public function testFlattenedTrans($expected, $messages, $id)
+    {
+        $translator = new Translator('en', new MessageSelector());
+        $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', new MessageSelector());
+        $translator->addLoader('array', new ArrayLoader());
+        $translator->addResource('array', array((string) $id => $translation), $locale, $domain);
+
+        $this->assertEquals($expected, $translator->transChoice($id, $number, $parameters, $domain, $locale));
+    }
+
+    public function getTransTests()
+    {
+        return array(
+            array('Symfony2 est super !', 'Symfony2 is great!', 'Symfony2 est super !', array(), 'fr', ''),
+            array('Symfony2 est awesome !', 'Symfony2 is %what%!', 'Symfony2 est %what% !', array('%what%' => 'awesome'), 'fr', ''),
+            array('Symfony2 est super !', new String('Symfony2 is great!'), 'Symfony2 est super !', array(), 'fr', ''),
+        );
+    }
+
+    public function getFlattenedTransTests()
+    {
+        $messages = array(
+            'symfony2' => array(
+                'is' => array(
+                    'great' => 'Symfony2 est super!'
+                )
+            ),
+            'foo' => array(
+                'bar' => array(
+                    'baz' => 'Foo Bar Baz'
+                ),
+                'baz' => 'Foo Baz',
+            ),
+        );
+
+        return array(
+            array('Symfony2 est super!', $messages, 'symfony2.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 is no apples|{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 is no apples|{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 is no apples|{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 is no apple|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 is no apple|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 is no apple|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 String('{0} There is no apples|{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 testTransChoiceFallback()
+    {
+        $translator = new Translator('ru', new MessageSelector());
+        $translator->setFallbackLocale('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', new MessageSelector());
+        $translator->setFallbackLocale(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)));
+    }
+
+    /**
+     * @expectedException \InvalidArgumentException
+     */
+    public function testTransChoiceFallbackWithNoTranslation()
+    {
+        $translator = new Translator('ru', new MessageSelector());
+        $translator->setFallbackLocale('en');
+        $translator->addLoader('array', new ArrayLoader());
+
+        $this->assertEquals('10 things', $translator->transChoice('some_message2', 10, array('%count%' => 10)));
+    }
+}
+
+class String
+{
+    protected $str;
+
+    public function __construct($str)
+    {
+        $this->str = $str;
+    }
+
+    public function __toString()
+    {
+        return $this->str;
+    }
+}
diff --git a/core/vendor/Symfony/Component/Translation/Tests/bootstrap.php b/core/vendor/Symfony/Component/Translation/Tests/bootstrap.php
new file mode 100644
index 0000000..c203e99
--- /dev/null
+++ b/core/vendor/Symfony/Component/Translation/Tests/bootstrap.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.
+ */
+
+spl_autoload_register(function ($class) {
+    if (0 === strpos(ltrim($class, '/'), 'Symfony\Component\Translation')) {
+        if (file_exists($file = __DIR__.'/../'.substr(str_replace('\\', '/', $class), strlen('Symfony\Component\Translation')).'.php')) {
+            require_once $file;
+        }
+    }
+});
+
+if (file_exists($loader = __DIR__.'/../vendor/autoload.php')) {
+    require_once $loader;
+}
diff --git a/core/vendor/Symfony/Component/Translation/Tests/fixtures/empty.csv b/core/vendor/Symfony/Component/Translation/Tests/fixtures/empty.csv
new file mode 100644
index 0000000..e69de29
diff --git a/core/vendor/Symfony/Component/Translation/Tests/fixtures/empty.ini b/core/vendor/Symfony/Component/Translation/Tests/fixtures/empty.ini
new file mode 100644
index 0000000..e69de29
diff --git a/core/vendor/Symfony/Component/Translation/Tests/fixtures/empty.mo b/core/vendor/Symfony/Component/Translation/Tests/fixtures/empty.mo
new file mode 100644
index 0000000..e69de29
diff --git a/core/vendor/Symfony/Component/Translation/Tests/fixtures/empty.po b/core/vendor/Symfony/Component/Translation/Tests/fixtures/empty.po
new file mode 100644
index 0000000..e69de29
diff --git a/core/vendor/Symfony/Component/Translation/Tests/fixtures/empty.yml b/core/vendor/Symfony/Component/Translation/Tests/fixtures/empty.yml
new file mode 100644
index 0000000..e69de29
diff --git a/core/vendor/Symfony/Component/Translation/Tests/fixtures/header.po b/core/vendor/Symfony/Component/Translation/Tests/fixtures/header.po
new file mode 100644
index 0000000..5650159
--- /dev/null
+++ b/core/vendor/Symfony/Component/Translation/Tests/fixtures/header.po
@@ -0,0 +1,11 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: PROJECT VERSION\n"
+"POT-Creation-Date: \n"
+"PO-Revision-Date: \n"
+"Last-Translator: NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <EMAIL@ADDRESS>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=6; plural=((n==1)?(0):((n==0)?(1):((n==2)?(2):((((n%100)>=3)&&((n%100)<=10))?(3):((((n%100)>=11)&&((n%100)<=99))?(4):5)))));\n"
\ No newline at end of file
diff --git a/core/vendor/Symfony/Component/Translation/Tests/fixtures/minimal.po b/core/vendor/Symfony/Component/Translation/Tests/fixtures/minimal.po
new file mode 100644
index 0000000..b255c1f
--- /dev/null
+++ b/core/vendor/Symfony/Component/Translation/Tests/fixtures/minimal.po
@@ -0,0 +1,2 @@
+msgid "source no whitespace before"
+msgstr "trans no whitespace after"
\ No newline at end of file
diff --git a/core/vendor/Symfony/Component/Translation/Tests/fixtures/multiline.po b/core/vendor/Symfony/Component/Translation/Tests/fixtures/multiline.po
new file mode 100644
index 0000000..1326ccd
--- /dev/null
+++ b/core/vendor/Symfony/Component/Translation/Tests/fixtures/multiline.po
@@ -0,0 +1,13 @@
+
+msgid "both single line"
+msgstr "trans single line"
+
+msgid "source single line"
+msgstr ""
+"trans "
+"multi line"
+
+msgid ""
+"source multi "
+"line"
+msgstr "trans single line"
diff --git a/core/vendor/Symfony/Component/Translation/Tests/fixtures/non-valid.xlf b/core/vendor/Symfony/Component/Translation/Tests/fixtures/non-valid.xlf
new file mode 100644
index 0000000..734fc97
--- /dev/null
+++ b/core/vendor/Symfony/Component/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/Component/Translation/Tests/fixtures/non-valid.yml b/core/vendor/Symfony/Component/Translation/Tests/fixtures/non-valid.yml
new file mode 100644
index 0000000..257cc56
--- /dev/null
+++ b/core/vendor/Symfony/Component/Translation/Tests/fixtures/non-valid.yml
@@ -0,0 +1 @@
+foo
diff --git a/core/vendor/Symfony/Component/Translation/Tests/fixtures/plurals.mo b/core/vendor/Symfony/Component/Translation/Tests/fixtures/plurals.mo
new file mode 100644
index 0000000000000000000000000000000000000000..6445e77beab595289cd154ea253c4e49dfd6af47
GIT binary patch
literal 74
zcmca7#4?ou2pEA_28dOFm>Gz5fS3b_Eugd`kOrxNfwcU51|TkGNJ=aM;bH~=*B}U7

literal 0
HcmV?d00001

diff --git a/core/vendor/Symfony/Component/Translation/Tests/fixtures/plurals.po b/core/vendor/Symfony/Component/Translation/Tests/fixtures/plurals.po
new file mode 100644
index 0000000..439c41a
--- /dev/null
+++ b/core/vendor/Symfony/Component/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/Component/Translation/Tests/fixtures/resourcebundle/dat/en.res b/core/vendor/Symfony/Component/Translation/Tests/fixtures/resourcebundle/dat/en.res
new file mode 100644
index 0000000000000000000000000000000000000000..1fc1436d6641b7290ad5d9f4d331111e4a0419dd
GIT binary patch
literal 120
zcmY#jxTP+_00K-5L8-+~j7$s+j4WUQFaeZPU<0x^fmjTR8No6P48@hXY594T3_?JD
sFheCnE<+kaK0_XmrNCeW#F-4mKr)@7h#{3Bk)Z^rYSk)61{ttf0N1AuGXMYp

literal 0
HcmV?d00001

diff --git a/core/vendor/Symfony/Component/Translation/Tests/fixtures/resourcebundle/dat/en.txt b/core/vendor/Symfony/Component/Translation/Tests/fixtures/resourcebundle/dat/en.txt
new file mode 100644
index 0000000..c04a4e8
--- /dev/null
+++ b/core/vendor/Symfony/Component/Translation/Tests/fixtures/resourcebundle/dat/en.txt
@@ -0,0 +1,3 @@
+en{
+    symfony{"Symfony 2 is great"}
+}
\ No newline at end of file
diff --git a/core/vendor/Symfony/Component/Translation/Tests/fixtures/resourcebundle/dat/fr.res b/core/vendor/Symfony/Component/Translation/Tests/fixtures/resourcebundle/dat/fr.res
new file mode 100644
index 0000000000000000000000000000000000000000..f58416094be89f5fb64f78f6c3b873c6458696d0
GIT binary patch
literal 124
zcmY#jxTP+_00K-5L8-+~j7$s+j4WUQFd@popuh%XaRRY86f=Tl7#NBxbJOzkDj7if
wgBdCrav9PX@)`1gECmK5AWmf{W+(yD=?pJ{qL~bd3^_oRt5z{G$biiQ03-qri2wiq

literal 0
HcmV?d00001

diff --git a/core/vendor/Symfony/Component/Translation/Tests/fixtures/resourcebundle/dat/fr.txt b/core/vendor/Symfony/Component/Translation/Tests/fixtures/resourcebundle/dat/fr.txt
new file mode 100644
index 0000000..7e84f67
--- /dev/null
+++ b/core/vendor/Symfony/Component/Translation/Tests/fixtures/resourcebundle/dat/fr.txt
@@ -0,0 +1,3 @@
+fr{
+    symfony{"Symfony 2 est génial"}
+}
\ No newline at end of file
diff --git a/core/vendor/Symfony/Component/Translation/Tests/fixtures/resourcebundle/dat/packagelist.txt b/core/vendor/Symfony/Component/Translation/Tests/fixtures/resourcebundle/dat/packagelist.txt
new file mode 100644
index 0000000..c5783ed
--- /dev/null
+++ b/core/vendor/Symfony/Component/Translation/Tests/fixtures/resourcebundle/dat/packagelist.txt
@@ -0,0 +1,2 @@
+en.res
+fr.res
diff --git a/core/vendor/Symfony/Component/Translation/Tests/fixtures/resourcebundle/dat/resources.dat b/core/vendor/Symfony/Component/Translation/Tests/fixtures/resourcebundle/dat/resources.dat
new file mode 100644
index 0000000000000000000000000000000000000000..563b0eaef2e5a0a6e9623bf7b93b44beb0a7dc27
GIT binary patch
literal 352
zcmY#jxTP+_00K-5&bfImj6fDMm=7VCfD}mH0f<$B_y7<Wr55Lx7A2<^>!;@F0Xawl
zX+>axRdAqyWPVU;u@fWEKt>jzAy5D`TY(M8<^*CfC<eI!1d1zj)AI8w8H9lBV1`PD
zT!u7;e1<$AOM$@%h%*_Afn+*E5ko3NB0~vK)v8sD3^HJ|U=AQ;zbKOZ;y@EX7~Ou5
Y|FPMh3belj?1Gm-S7id-kb~g{0B1ft-T(jq

literal 0
HcmV?d00001

diff --git a/core/vendor/Symfony/Component/Translation/Tests/fixtures/resourcebundle/res/en.res b/core/vendor/Symfony/Component/Translation/Tests/fixtures/resourcebundle/res/en.res
new file mode 100644
index 0000000000000000000000000000000000000000..ad894a92be2d5392136de413bc2cb5ea8a94bfb1
GIT binary patch
literal 84
zcmY#jxTP+_00K-5L8-+~j7$s+j4WUQFu~2hpuh%XaR4zd6f=Tl7#Py>^BI_d>?DRn
Nh9V%%$RGn&2LK231)%@{

literal 0
HcmV?d00001

diff --git a/core/vendor/Symfony/Component/Translation/Tests/fixtures/resourcebundle/res/en.txt b/core/vendor/Symfony/Component/Translation/Tests/fixtures/resourcebundle/res/en.txt
new file mode 100644
index 0000000..a8a87e5
--- /dev/null
+++ b/core/vendor/Symfony/Component/Translation/Tests/fixtures/resourcebundle/res/en.txt
@@ -0,0 +1,3 @@
+en {
+    foo { "bar" }
+}
\ No newline at end of file
diff --git a/core/vendor/Symfony/Component/Translation/Tests/fixtures/resources-clean.xlf b/core/vendor/Symfony/Component/Translation/Tests/fixtures/resources-clean.xlf
new file mode 100644
index 0000000..231e8a6
--- /dev/null
+++ b/core/vendor/Symfony/Component/Translation/Tests/fixtures/resources-clean.xlf
@@ -0,0 +1,15 @@
+<?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>key</source>
+        <target></target>
+      </trans-unit>
+    </body>
+  </file>
+</xliff>
diff --git a/core/vendor/Symfony/Component/Translation/Tests/fixtures/resources.csv b/core/vendor/Symfony/Component/Translation/Tests/fixtures/resources.csv
new file mode 100644
index 0000000..374b9eb
--- /dev/null
+++ b/core/vendor/Symfony/Component/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/Component/Translation/Tests/fixtures/resources.ini b/core/vendor/Symfony/Component/Translation/Tests/fixtures/resources.ini
new file mode 100644
index 0000000..4953062
--- /dev/null
+++ b/core/vendor/Symfony/Component/Translation/Tests/fixtures/resources.ini
@@ -0,0 +1 @@
+foo="bar"
diff --git a/core/vendor/Symfony/Component/Translation/Tests/fixtures/resources.mo b/core/vendor/Symfony/Component/Translation/Tests/fixtures/resources.mo
new file mode 100644
index 0000000000000000000000000000000000000000..0a9660257c07afef243a011d9806d6217e4f1379
GIT binary patch
literal 52
pcmca7#4?ou2pEA_28dNa93apEVrC%Lh0=yVnjtMepCKu+2mox%1k?Zk

literal 0
HcmV?d00001

diff --git a/core/vendor/Symfony/Component/Translation/Tests/fixtures/resources.php b/core/vendor/Symfony/Component/Translation/Tests/fixtures/resources.php
new file mode 100644
index 0000000..c291398
--- /dev/null
+++ b/core/vendor/Symfony/Component/Translation/Tests/fixtures/resources.php
@@ -0,0 +1,5 @@
+<?php
+
+return array (
+  'foo' => 'bar',
+);
diff --git a/core/vendor/Symfony/Component/Translation/Tests/fixtures/resources.po b/core/vendor/Symfony/Component/Translation/Tests/fixtures/resources.po
new file mode 100644
index 0000000..59ecd39
--- /dev/null
+++ b/core/vendor/Symfony/Component/Translation/Tests/fixtures/resources.po
@@ -0,0 +1,3 @@
+msgid "foo"
+msgstr "bar"
+
diff --git a/core/vendor/Symfony/Component/Translation/Tests/fixtures/resources.ts b/core/vendor/Symfony/Component/Translation/Tests/fixtures/resources.ts
new file mode 100644
index 0000000..40e1852
--- /dev/null
+++ b/core/vendor/Symfony/Component/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/Component/Translation/Tests/fixtures/resources.xlf b/core/vendor/Symfony/Component/Translation/Tests/fixtures/resources.xlf
new file mode 100644
index 0000000..3f43d0b
--- /dev/null
+++ b/core/vendor/Symfony/Component/Translation/Tests/fixtures/resources.xlf
@@ -0,0 +1,18 @@
+<?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>
+    </body>
+  </file>
+</xliff>
diff --git a/core/vendor/Symfony/Component/Translation/Tests/fixtures/resources.yml b/core/vendor/Symfony/Component/Translation/Tests/fixtures/resources.yml
new file mode 100644
index 0000000..20e9ff3
--- /dev/null
+++ b/core/vendor/Symfony/Component/Translation/Tests/fixtures/resources.yml
@@ -0,0 +1 @@
+foo: bar
diff --git a/core/vendor/Symfony/Component/Translation/Tests/fixtures/valid.csv b/core/vendor/Symfony/Component/Translation/Tests/fixtures/valid.csv
new file mode 100644
index 0000000..59882e5
--- /dev/null
+++ b/core/vendor/Symfony/Component/Translation/Tests/fixtures/valid.csv
@@ -0,0 +1,4 @@
+foo;bar
+bar;"foo
+foo"
+"foo;foo";bar
diff --git a/core/vendor/Symfony/Component/Translation/Translator.php b/core/vendor/Symfony/Component/Translation/Translator.php
new file mode 100644
index 0000000..4db0be2
--- /dev/null
+++ b/core/vendor/Symfony/Component/Translation/Translator.php
@@ -0,0 +1,212 @@
+<?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;
+
+/**
+ * Translator.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ *
+ * @api
+ */
+class Translator implements TranslatorInterface
+{
+    protected $catalogues;
+    protected $locale;
+    private $fallbackLocales;
+    private $loaders;
+    private $resources;
+    private $selector;
+
+    /**
+     * Constructor.
+     *
+     * @param string          $locale   The locale
+     * @param MessageSelector $selector The message selector for pluralization
+     *
+     * @api
+     */
+    public function __construct($locale, MessageSelector $selector = null)
+    {
+        $this->locale = $locale;
+        $this->selector = null === $selector ? new MessageSelector() : $selector;
+        $this->loaders = array();
+        $this->resources = array();
+        $this->catalogues = array();
+        $this->fallbackLocales = array();
+    }
+
+    /**
+     * 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
+     *
+     * @api
+     */
+    public function addResource($format, $resource, $locale, $domain = 'messages')
+    {
+        $this->resources[$locale][] = array($format, $resource, $domain);
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @api
+     */
+    public function setLocale($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)
+     *
+     * @api
+     */
+    public function setFallbackLocale($locales)
+    {
+        // needed as the fallback locales are linked to the already loaded catalogues
+        $this->catalogues = array();
+
+        $this->fallbackLocales = is_array($locales) ? $locales : array($locales);
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @api
+     */
+    public function trans($id, array $parameters = array(), $domain = 'messages', $locale = null)
+    {
+        if (!isset($locale)) {
+            $locale = $this->getLocale();
+        }
+
+        if (!isset($this->catalogues[$locale])) {
+            $this->loadCatalogue($locale);
+        }
+
+        return strtr($this->catalogues[$locale]->get((string) $id, $domain), $parameters);
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @api
+     */
+    public function transChoice($id, $number, array $parameters = array(), $domain = 'messages', $locale = null)
+    {
+        if (!isset($locale)) {
+            $locale = $this->getLocale();
+        }
+
+        if (!isset($this->catalogues[$locale])) {
+            $this->loadCatalogue($locale);
+        }
+
+        $id = (string) $id;
+
+        $catalogue = $this->catalogues[$locale];
+        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);
+    }
+
+    protected function loadCatalogue($locale)
+    {
+        $this->doLoadCatalogue($locale);
+        $this->loadFallbackCatalogues($locale);
+    }
+
+    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);
+            }
+
+            $current->addFallbackCatalogue($this->catalogues[$fallback]);
+            $current = $this->catalogues[$fallback];
+        }
+    }
+
+    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);
+    }
+}
diff --git a/core/vendor/Symfony/Component/Translation/TranslatorInterface.php b/core/vendor/Symfony/Component/Translation/TranslatorInterface.php
new file mode 100644
index 0000000..5c53d0d
--- /dev/null
+++ b/core/vendor/Symfony/Component/Translation/TranslatorInterface.php
@@ -0,0 +1,69 @@
+<?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;
+
+/**
+ * TranslatorInterface.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ *
+ * @api
+ */
+interface TranslatorInterface
+{
+    /**
+     * Translates the given message.
+     *
+     * @param string $id         The message id
+     * @param array  $parameters An array of parameters for the message
+     * @param string $domain     The domain for the message
+     * @param string $locale     The locale
+     *
+     * @return string The translated string
+     *
+     * @api
+     */
+    function trans($id, array $parameters = array(), $domain = null, $locale = null);
+
+    /**
+     * Translates the given choice message by choosing a translation according to a number.
+     *
+     * @param string  $id         The message id
+     * @param integer $number     The number to use to find the indice of the message
+     * @param array   $parameters An array of parameters for the message
+     * @param string  $domain     The domain for the message
+     * @param string  $locale     The locale
+     *
+     * @return string The translated string
+     *
+     * @api
+     */
+    function transChoice($id, $number, array $parameters = array(), $domain = null, $locale = null);
+
+    /**
+     * Sets the current locale.
+     *
+     * @param string $locale The locale
+     *
+     * @api
+     */
+    function setLocale($locale);
+
+    /**
+     * Returns the current locale.
+     *
+     * @return string The locale
+     *
+     * @api
+     */
+    function getLocale();
+}
diff --git a/core/vendor/Symfony/Component/Translation/Writer/TranslationWriter.php b/core/vendor/Symfony/Component/Translation/Writer/TranslationWriter.php
new file mode 100644
index 0000000..4d68ce5
--- /dev/null
+++ b/core/vendor/Symfony/Component/Translation/Writer/TranslationWriter.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\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;
+    }
+
+    /**
+     * 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 type             $format    The format to use to dump the messages
+     * @param array            $options   Options that are passed to the dumper
+     */
+    public function writeTranslations(MessageCatalogue $catalogue, $format, $options = array())
+    {
+        if (!isset($this->dumpers[$format])) {
+            throw new \InvalidArgumentException('There is no dumper associated with this format.');
+        }
+
+        // get the right dumper
+        $dumper = $this->dumpers[$format];
+
+        // save
+        $dumper->dump($catalogue, $options);
+    }
+}
diff --git a/core/vendor/Symfony/Component/Translation/composer.json b/core/vendor/Symfony/Component/Translation/composer.json
new file mode 100644
index 0000000..3c20fe3
--- /dev/null
+++ b/core/vendor/Symfony/Component/Translation/composer.json
@@ -0,0 +1,38 @@
+{
+    "name": "symfony/translation",
+    "type": "library",
+    "description": "Symfony Translation Component",
+    "keywords": [],
+    "homepage": "http://symfony.com",
+    "license": "MIT",
+    "authors": [
+        {
+            "name": "Fabien Potencier",
+            "email": "fabien@symfony.com"
+        },
+        {
+            "name": "Symfony Community",
+            "homepage": "http://symfony.com/contributors"
+        }
+    ],
+    "require": {
+        "php": ">=5.3.3"
+    },
+    "require-dev": {
+        "symfony/config": "2.1.*",
+        "symfony/yaml": "2.1.*"
+    },
+    "suggest": {
+        "symfony/config": "self.version",
+        "symfony/yaml": "self.version"
+    },
+    "autoload": {
+        "psr-0": { "Symfony\\Component\\Translation": "" }
+    },
+    "target-dir": "Symfony/Component/Translation",
+    "extra": {
+        "branch-alias": {
+            "dev-master": "2.1-dev"
+        }
+    }
+}
diff --git a/core/vendor/Symfony/Component/Translation/phpunit.xml.dist b/core/vendor/Symfony/Component/Translation/phpunit.xml.dist
new file mode 100644
index 0000000..65542f6
--- /dev/null
+++ b/core/vendor/Symfony/Component/Translation/phpunit.xml.dist
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<phpunit backupGlobals="false"
+         backupStaticAttributes="false"
+         colors="true"
+         convertErrorsToExceptions="true"
+         convertNoticesToExceptions="true"
+         convertWarningsToExceptions="true"
+         processIsolation="false"
+         stopOnFailure="false"
+         syntaxCheck="false"
+         bootstrap="Tests/bootstrap.php"
+>
+    <testsuites>
+        <testsuite name="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>
