From 969407ec016c6487895877d53dc5a4327cbcc2c5 Mon Sep 17 00:00:00 2001
From: sun <sun@unleashedmind.com>
Date: Wed, 2 May 2012 03:16:14 +0200
Subject: [PATCH 1/3] - #1470824 by sun: Added Symfony YAML component.

---
 core/vendor/Symfony/Component/Yaml/Dumper.php      |   54 ++
 core/vendor/Symfony/Component/Yaml/Escaper.php     |   88 +++
 .../Component/Yaml/Exception/DumpException.php     |   23 +
 .../Yaml/Exception/ExceptionInterface.php          |   23 +
 .../Component/Yaml/Exception/ParseException.php    |  143 +++++
 core/vendor/Symfony/Component/Yaml/Inline.php      |  406 ++++++++++++++
 core/vendor/Symfony/Component/Yaml/LICENSE         |   19 +
 core/vendor/Symfony/Component/Yaml/Parser.php      |  556 ++++++++++++++++++++
 core/vendor/Symfony/Component/Yaml/README.md       |   17 +
 core/vendor/Symfony/Component/Yaml/Unescaper.php   |  145 +++++
 core/vendor/Symfony/Component/Yaml/Yaml.php        |  111 ++++
 core/vendor/Symfony/Component/Yaml/composer.json   |   30 +
 12 files changed, 1615 insertions(+), 0 deletions(-)
 create mode 100644 core/vendor/Symfony/Component/Yaml/Dumper.php
 create mode 100644 core/vendor/Symfony/Component/Yaml/Escaper.php
 create mode 100644 core/vendor/Symfony/Component/Yaml/Exception/DumpException.php
 create mode 100644 core/vendor/Symfony/Component/Yaml/Exception/ExceptionInterface.php
 create mode 100644 core/vendor/Symfony/Component/Yaml/Exception/ParseException.php
 create mode 100644 core/vendor/Symfony/Component/Yaml/Inline.php
 create mode 100644 core/vendor/Symfony/Component/Yaml/LICENSE
 create mode 100644 core/vendor/Symfony/Component/Yaml/Parser.php
 create mode 100644 core/vendor/Symfony/Component/Yaml/README.md
 create mode 100644 core/vendor/Symfony/Component/Yaml/Unescaper.php
 create mode 100644 core/vendor/Symfony/Component/Yaml/Yaml.php
 create mode 100644 core/vendor/Symfony/Component/Yaml/composer.json

diff --git a/core/vendor/Symfony/Component/Yaml/Dumper.php b/core/vendor/Symfony/Component/Yaml/Dumper.php
new file mode 100644
index 0000000..97ec9d2
--- /dev/null
+++ b/core/vendor/Symfony/Component/Yaml/Dumper.php
@@ -0,0 +1,54 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Yaml;
+
+/**
+ * Dumper dumps PHP variables to YAML strings.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class Dumper
+{
+    /**
+     * Dumps a PHP value to YAML.
+     *
+     * @param  mixed   $input  The PHP value
+     * @param  integer $inline The level where you switch to inline YAML
+     * @param  integer $indent The level of indentation (used internally)
+     *
+     * @return string  The YAML representation of the PHP value
+     */
+    public function dump($input, $inline = 0, $indent = 0)
+    {
+        $output = '';
+        $prefix = $indent ? str_repeat(' ', $indent) : '';
+
+        if ($inline <= 0 || !is_array($input) || empty($input)) {
+            $output .= $prefix.Inline::dump($input);
+        } else {
+            $isAHash = array_keys($input) !== range(0, count($input) - 1);
+
+            foreach ($input as $key => $value) {
+                $willBeInlined = $inline - 1 <= 0 || !is_array($value) || empty($value);
+
+                $output .= sprintf('%s%s%s%s',
+                    $prefix,
+                    $isAHash ? Inline::dump($key).':' : '-',
+                    $willBeInlined ? ' ' : "\n",
+                    $this->dump($value, $inline - 1, $willBeInlined ? 0 : $indent + 4)
+                ).($willBeInlined ? "\n" : '');
+            }
+        }
+
+        return $output;
+    }
+}
diff --git a/core/vendor/Symfony/Component/Yaml/Escaper.php b/core/vendor/Symfony/Component/Yaml/Escaper.php
new file mode 100644
index 0000000..81a7d5f
--- /dev/null
+++ b/core/vendor/Symfony/Component/Yaml/Escaper.php
@@ -0,0 +1,88 @@
+<?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\Yaml;
+
+/**
+ * Escaper encapsulates escaping rules for single and double-quoted
+ * YAML strings.
+ *
+ * @author Matthew Lewinski <matthew@lewinski.org>
+ */
+class Escaper
+{
+    // Characters that would cause a dumped string to require double quoting.
+    const REGEX_CHARACTER_TO_ESCAPE = "[\\x00-\\x1f]|\xc2\x85|\xc2\xa0|\xe2\x80\xa8|\xe2\x80\xa9";
+
+    // Mapping arrays for escaping a double quoted string. The backslash is
+    // first to ensure proper escaping because str_replace operates iteratively
+    // on the input arrays. This ordering of the characters avoids the use of strtr,
+    // which performs more slowly.
+    static private $escapees = array('\\\\', '\\"',
+                                     "\x00",  "\x01",  "\x02",  "\x03",  "\x04",  "\x05",  "\x06",  "\x07",
+                                     "\x08",  "\x09",  "\x0a",  "\x0b",  "\x0c",  "\x0d",  "\x0e",  "\x0f",
+                                     "\x10",  "\x11",  "\x12",  "\x13",  "\x14",  "\x15",  "\x16",  "\x17",
+                                     "\x18",  "\x19",  "\x1a",  "\x1b",  "\x1c",  "\x1d",  "\x1e",  "\x1f",
+                                     "\xc2\x85", "\xc2\xa0", "\xe2\x80\xa8", "\xe2\x80\xa9");
+    static private $escaped  = array('\\"', '\\\\',
+                                     "\\0",   "\\x01", "\\x02", "\\x03", "\\x04", "\\x05", "\\x06", "\\a",
+                                     "\\b",   "\\t",   "\\n",   "\\v",   "\\f",   "\\r",   "\\x0e", "\\x0f",
+                                     "\\x10", "\\x11", "\\x12", "\\x13", "\\x14", "\\x15", "\\x16", "\\x17",
+                                     "\\x18", "\\x19", "\\x1a", "\\e",   "\\x1c", "\\x1d", "\\x1e", "\\x1f",
+                                     "\\N", "\\_", "\\L", "\\P");
+
+    /**
+     * Determines if a PHP value would require double quoting in YAML.
+     *
+     * @param string $value A PHP value
+     *
+     * @return Boolean True if the value would require double quotes.
+     */
+    static public function requiresDoubleQuoting($value)
+    {
+        return preg_match('/'.self::REGEX_CHARACTER_TO_ESCAPE.'/u', $value);
+    }
+
+    /**
+     * Escapes and surrounds a PHP value with double quotes.
+     *
+     * @param string $value A PHP value
+     *
+     * @return string The quoted, escaped string
+     */
+    static public function escapeWithDoubleQuotes($value)
+    {
+        return sprintf('"%s"', str_replace(self::$escapees, self::$escaped, $value));
+    }
+
+    /**
+     * Determines if a PHP value would require single quoting in YAML.
+     *
+     * @param string $value A PHP value
+     *
+     * @return Boolean True if the value would require single quotes.
+     */
+    static public function requiresSingleQuoting($value)
+    {
+        return preg_match('/[ \s \' " \: \{ \} \[ \] , & \* \# \?] | \A[ - ? | < > = ! % @ ` ]/x', $value);
+    }
+
+    /**
+     * Escapes and surrounds a PHP value with single quotes.
+     *
+     * @param string $value A PHP value
+     *
+     * @return string The quoted, escaped string
+     */
+    static public function escapeWithSingleQuotes($value)
+    {
+        return sprintf("'%s'", str_replace('\'', '\'\'', $value));
+    }
+}
diff --git a/core/vendor/Symfony/Component/Yaml/Exception/DumpException.php b/core/vendor/Symfony/Component/Yaml/Exception/DumpException.php
new file mode 100644
index 0000000..53952ce
--- /dev/null
+++ b/core/vendor/Symfony/Component/Yaml/Exception/DumpException.php
@@ -0,0 +1,23 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Yaml\Exception;
+
+/**
+ * Exception class thrown when an error occurs during dumping.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ *
+ * @api
+ */
+class DumpException extends \RuntimeException implements ExceptionInterface
+{
+}
diff --git a/core/vendor/Symfony/Component/Yaml/Exception/ExceptionInterface.php b/core/vendor/Symfony/Component/Yaml/Exception/ExceptionInterface.php
new file mode 100644
index 0000000..92e5c2e
--- /dev/null
+++ b/core/vendor/Symfony/Component/Yaml/Exception/ExceptionInterface.php
@@ -0,0 +1,23 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Yaml\Exception;
+
+/**
+ * Exception interface for all exceptions thrown by the component.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ *
+ * @api
+ */
+interface ExceptionInterface
+{
+}
diff --git a/core/vendor/Symfony/Component/Yaml/Exception/ParseException.php b/core/vendor/Symfony/Component/Yaml/Exception/ParseException.php
new file mode 100644
index 0000000..975fe6d
--- /dev/null
+++ b/core/vendor/Symfony/Component/Yaml/Exception/ParseException.php
@@ -0,0 +1,143 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Yaml\Exception;
+
+/**
+ * Exception class thrown when an error occurs during parsing.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ *
+ * @api
+ */
+class ParseException extends \RuntimeException implements ExceptionInterface
+{
+    private $parsedFile;
+    private $parsedLine;
+    private $snippet;
+    private $rawMessage;
+
+    /**
+     * Constructor.
+     *
+     * @param string    $message    The error message
+     * @param integer   $parsedLine The line where the error occurred
+     * @param integer   $snippet    The snippet of code near the problem
+     * @param string    $parsedFile The file name where the error occurred
+     * @param Exception $previous   The previous exception
+     */
+    public function __construct($message, $parsedLine = -1, $snippet = null, $parsedFile = null, Exception $previous = null)
+    {
+        $this->parsedFile = $parsedFile;
+        $this->parsedLine = $parsedLine;
+        $this->snippet = $snippet;
+        $this->rawMessage = $message;
+
+        $this->updateRepr();
+
+        parent::__construct($this->message, 0, $previous);
+    }
+
+    /**
+     * Gets the snippet of code near the error.
+     *
+     * @return string The snippet of code
+     */
+    public function getSnippet()
+    {
+        return $this->snippet;
+    }
+
+    /**
+     * Sets the snippet of code near the error.
+     *
+     * @param string $snippet The code snippet
+     */
+    public function setSnippet($snippet)
+    {
+        $this->snippet = $snippet;
+
+        $this->updateRepr();
+    }
+
+    /**
+     * Gets the filename where the error occurred.
+     *
+     * This method returns null if a string is parsed.
+     *
+     * @return string The filename
+     */
+    public function getParsedFile()
+    {
+        return $this->parsedFile;
+    }
+
+    /**
+     * Sets the filename where the error occurred.
+     *
+     * @param string $parsedFile The filename
+     */
+    public function setParsedFile($parsedFile)
+    {
+        $this->parsedFile = $parsedFile;
+
+        $this->updateRepr();
+    }
+
+    /**
+     * Gets the line where the error occurred.
+     *
+     * @return integer The file line
+     */
+    public function getParsedLine()
+    {
+        return $this->parsedLine;
+    }
+
+    /**
+     * Sets the line where the error occurred.
+     *
+     * @param integer $parsedLine The file line
+     */
+    public function setParsedLine($parsedLine)
+    {
+        $this->parsedLine = $parsedLine;
+
+        $this->updateRepr();
+    }
+
+    private function updateRepr()
+    {
+        $this->message = $this->rawMessage;
+
+        $dot = false;
+        if ('.' === substr($this->message, -1)) {
+            $this->message = substr($this->message, 0, -1);
+            $dot = true;
+        }
+
+        if (null !== $this->parsedFile) {
+            $this->message .= sprintf(' in %s', json_encode($this->parsedFile));
+        }
+
+        if ($this->parsedLine >= 0) {
+            $this->message .= sprintf(' at line %d', $this->parsedLine);
+        }
+
+        if ($this->snippet) {
+            $this->message .= sprintf(' (near "%s")', $this->snippet);
+        }
+
+        if ($dot) {
+            $this->message .= '.';
+        }
+    }
+}
diff --git a/core/vendor/Symfony/Component/Yaml/Inline.php b/core/vendor/Symfony/Component/Yaml/Inline.php
new file mode 100644
index 0000000..5933ac7
--- /dev/null
+++ b/core/vendor/Symfony/Component/Yaml/Inline.php
@@ -0,0 +1,406 @@
+<?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\Yaml;
+
+use Symfony\Component\Yaml\Exception\ParseException;
+use Symfony\Component\Yaml\Exception\DumpException;
+
+/**
+ * Inline implements a YAML parser/dumper for the YAML inline syntax.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class Inline
+{
+    const REGEX_QUOTED_STRING = '(?:"([^"\\\\]*(?:\\\\.[^"\\\\]*)*)"|\'([^\']*(?:\'\'[^\']*)*)\')';
+
+    /**
+     * Converts a YAML string to a PHP array.
+     *
+     * @param string $value A YAML string
+     *
+     * @return array A PHP array representing the YAML string
+     */
+    static public function parse($value)
+    {
+        $value = trim($value);
+
+        if (0 == strlen($value)) {
+            return '';
+        }
+
+        if (function_exists('mb_internal_encoding') && ((int) ini_get('mbstring.func_overload')) & 2) {
+            $mbEncoding = mb_internal_encoding();
+            mb_internal_encoding('ASCII');
+        }
+
+        switch ($value[0]) {
+            case '[':
+                $result = self::parseSequence($value);
+                break;
+            case '{':
+                $result = self::parseMapping($value);
+                break;
+            default:
+                $result = self::parseScalar($value);
+        }
+
+        if (isset($mbEncoding)) {
+            mb_internal_encoding($mbEncoding);
+        }
+
+        return $result;
+    }
+
+    /**
+     * Dumps a given PHP variable to a YAML string.
+     *
+     * @param mixed $value The PHP variable to convert
+     *
+     * @return string The YAML string representing the PHP array
+     *
+     * @throws DumpException When trying to dump PHP resource
+     */
+    static public function dump($value)
+    {
+        switch (true) {
+            case is_resource($value):
+                throw new DumpException(sprintf('Unable to dump PHP resources in a YAML file ("%s").', get_resource_type($value)));
+            case is_object($value):
+                return '!!php/object:'.serialize($value);
+            case is_array($value):
+                return self::dumpArray($value);
+            case null === $value:
+                return 'null';
+            case true === $value:
+                return 'true';
+            case false === $value:
+                return 'false';
+            case ctype_digit($value):
+                return is_string($value) ? "'$value'" : (int) $value;
+            case is_numeric($value):
+                $locale = setlocale(LC_NUMERIC, 0);
+                if (false !== $locale) {
+                    setlocale(LC_NUMERIC, 'C');
+                }
+                $repr = is_string($value) ? "'$value'" : (is_infinite($value) ? str_ireplace('INF', '.Inf', strval($value)) : strval($value));
+
+                if (false !== $locale) {
+                    setlocale(LC_NUMERIC, $locale);
+                }
+
+                return $repr;
+            case Escaper::requiresDoubleQuoting($value):
+                return Escaper::escapeWithDoubleQuotes($value);
+            case Escaper::requiresSingleQuoting($value):
+                return Escaper::escapeWithSingleQuotes($value);
+            case '' == $value:
+                return "''";
+            case preg_match(self::getTimestampRegex(), $value):
+            case in_array(strtolower($value), array('null', '~', 'true', 'false')):
+                return "'$value'";
+            default:
+                return $value;
+        }
+    }
+
+    /**
+     * Dumps a PHP array to a YAML string.
+     *
+     * @param array $value The PHP array to dump
+     *
+     * @return string The YAML string representing the PHP array
+     */
+    static private function dumpArray($value)
+    {
+        // array
+        $keys = array_keys($value);
+        if ((1 == count($keys) && '0' == $keys[0])
+            || (count($keys) > 1 && array_reduce($keys, function ($v, $w) { return (integer) $v + $w; }, 0) == count($keys) * (count($keys) - 1) / 2)
+        ) {
+            $output = array();
+            foreach ($value as $val) {
+                $output[] = self::dump($val);
+            }
+
+            return sprintf('[%s]', implode(', ', $output));
+        }
+
+        // mapping
+        $output = array();
+        foreach ($value as $key => $val) {
+            $output[] = sprintf('%s: %s', self::dump($key), self::dump($val));
+        }
+
+        return sprintf('{ %s }', implode(', ', $output));
+    }
+
+    /**
+     * Parses a scalar to a YAML string.
+     *
+     * @param scalar  $scalar
+     * @param string  $delimiters
+     * @param array   $stringDelimiters
+     * @param integer &$i
+     * @param Boolean $evaluate
+     *
+     * @return string A YAML string
+     *
+     * @throws ParseException When malformed inline YAML string is parsed
+     */
+    static public function parseScalar($scalar, $delimiters = null, $stringDelimiters = array('"', "'"), &$i = 0, $evaluate = true)
+    {
+        if (in_array($scalar[$i], $stringDelimiters)) {
+            // quoted scalar
+            $output = self::parseQuotedScalar($scalar, $i);
+        } else {
+            // "normal" string
+            if (!$delimiters) {
+                $output = substr($scalar, $i);
+                $i += strlen($output);
+
+                // remove comments
+                if (false !== $strpos = strpos($output, ' #')) {
+                    $output = rtrim(substr($output, 0, $strpos));
+                }
+            } elseif (preg_match('/^(.+?)('.implode('|', $delimiters).')/', substr($scalar, $i), $match)) {
+                $output = $match[1];
+                $i += strlen($output);
+            } else {
+                throw new ParseException(sprintf('Malformed inline YAML string (%s).', $scalar));
+            }
+
+            $output = $evaluate ? self::evaluateScalar($output) : $output;
+        }
+
+        return $output;
+    }
+
+    /**
+     * Parses a quoted scalar to YAML.
+     *
+     * @param string  $scalar
+     * @param integer &$i
+     *
+     * @return string A YAML string
+     *
+     * @throws ParseException When malformed inline YAML string is parsed
+     */
+    static private function parseQuotedScalar($scalar, &$i)
+    {
+        if (!preg_match('/'.self::REGEX_QUOTED_STRING.'/Au', substr($scalar, $i), $match)) {
+            throw new ParseException(sprintf('Malformed inline YAML string (%s).', substr($scalar, $i)));
+        }
+
+        $output = substr($match[0], 1, strlen($match[0]) - 2);
+
+        $unescaper = new Unescaper();
+        if ('"' == $scalar[$i]) {
+            $output = $unescaper->unescapeDoubleQuotedString($output);
+        } else {
+            $output = $unescaper->unescapeSingleQuotedString($output);
+        }
+
+        $i += strlen($match[0]);
+
+        return $output;
+    }
+
+    /**
+     * Parses a sequence to a YAML string.
+     *
+     * @param string  $sequence
+     * @param integer &$i
+     *
+     * @return string A YAML string
+     *
+     * @throws ParseException When malformed inline YAML string is parsed
+     */
+    static private function parseSequence($sequence, &$i = 0)
+    {
+        $output = array();
+        $len = strlen($sequence);
+        $i += 1;
+
+        // [foo, bar, ...]
+        while ($i < $len) {
+            switch ($sequence[$i]) {
+                case '[':
+                    // nested sequence
+                    $output[] = self::parseSequence($sequence, $i);
+                    break;
+                case '{':
+                    // nested mapping
+                    $output[] = self::parseMapping($sequence, $i);
+                    break;
+                case ']':
+                    return $output;
+                case ',':
+                case ' ':
+                    break;
+                default:
+                    $isQuoted = in_array($sequence[$i], array('"', "'"));
+                    $value = self::parseScalar($sequence, array(',', ']'), array('"', "'"), $i);
+
+                    if (!$isQuoted && false !== strpos($value, ': ')) {
+                        // embedded mapping?
+                        try {
+                            $value = self::parseMapping('{'.$value.'}');
+                        } catch (\InvalidArgumentException $e) {
+                            // no, it's not
+                        }
+                    }
+
+                    $output[] = $value;
+
+                    --$i;
+            }
+
+            ++$i;
+        }
+
+        throw new ParseException(sprintf('Malformed inline YAML string %s', $sequence));
+    }
+
+    /**
+     * Parses a mapping to a YAML string.
+     *
+     * @param string  $mapping
+     * @param integer &$i
+     *
+     * @return string A YAML string
+     *
+     * @throws ParseException When malformed inline YAML string is parsed
+     */
+    static private function parseMapping($mapping, &$i = 0)
+    {
+        $output = array();
+        $len = strlen($mapping);
+        $i += 1;
+
+        // {foo: bar, bar:foo, ...}
+        while ($i < $len) {
+            switch ($mapping[$i]) {
+                case ' ':
+                case ',':
+                    ++$i;
+                    continue 2;
+                case '}':
+                    return $output;
+            }
+
+            // key
+            $key = self::parseScalar($mapping, array(':', ' '), array('"', "'"), $i, false);
+
+            // value
+            $done = false;
+            while ($i < $len) {
+                switch ($mapping[$i]) {
+                    case '[':
+                        // nested sequence
+                        $output[$key] = self::parseSequence($mapping, $i);
+                        $done = true;
+                        break;
+                    case '{':
+                        // nested mapping
+                        $output[$key] = self::parseMapping($mapping, $i);
+                        $done = true;
+                        break;
+                    case ':':
+                    case ' ':
+                        break;
+                    default:
+                        $output[$key] = self::parseScalar($mapping, array(',', '}'), array('"', "'"), $i);
+                        $done = true;
+                        --$i;
+                }
+
+                ++$i;
+
+                if ($done) {
+                    continue 2;
+                }
+            }
+        }
+
+        throw new ParseException(sprintf('Malformed inline YAML string %s', $mapping));
+    }
+
+    /**
+     * Evaluates scalars and replaces magic values.
+     *
+     * @param string $scalar
+     *
+     * @return string A YAML string
+     */
+    static private function evaluateScalar($scalar)
+    {
+        $scalar = trim($scalar);
+
+        switch (true) {
+            case 'null' == strtolower($scalar):
+            case '' == $scalar:
+            case '~' == $scalar:
+                return null;
+            case 0 === strpos($scalar, '!str'):
+                return (string) substr($scalar, 5);
+            case 0 === strpos($scalar, '! '):
+                return intval(self::parseScalar(substr($scalar, 2)));
+            case 0 === strpos($scalar, '!!php/object:'):
+                return unserialize(substr($scalar, 13));
+            case ctype_digit($scalar):
+                $raw = $scalar;
+                $cast = intval($scalar);
+
+                return '0' == $scalar[0] ? octdec($scalar) : (((string) $raw == (string) $cast) ? $cast : $raw);
+            case 'true' === strtolower($scalar):
+                return true;
+            case 'false' === strtolower($scalar):
+                return false;
+            case is_numeric($scalar):
+                return '0x' == $scalar[0].$scalar[1] ? hexdec($scalar) : floatval($scalar);
+            case 0 == strcasecmp($scalar, '.inf'):
+            case 0 == strcasecmp($scalar, '.NaN'):
+                return -log(0);
+            case 0 == strcasecmp($scalar, '-.inf'):
+                return log(0);
+            case preg_match('/^(-|\+)?[0-9,]+(\.[0-9]+)?$/', $scalar):
+                return floatval(str_replace(',', '', $scalar));
+            case preg_match(self::getTimestampRegex(), $scalar):
+                return strtotime($scalar);
+            default:
+                return (string) $scalar;
+        }
+    }
+
+    /**
+     * Gets a regex that matches an unix timestamp
+     *
+     * @return string The regular expression
+     */
+    static private function getTimestampRegex()
+    {
+        return <<<EOF
+        ~^
+        (?P<year>[0-9][0-9][0-9][0-9])
+        -(?P<month>[0-9][0-9]?)
+        -(?P<day>[0-9][0-9]?)
+        (?:(?:[Tt]|[ \t]+)
+        (?P<hour>[0-9][0-9]?)
+        :(?P<minute>[0-9][0-9])
+        :(?P<second>[0-9][0-9])
+        (?:\.(?P<fraction>[0-9]*))?
+        (?:[ \t]*(?P<tz>Z|(?P<tz_sign>[-+])(?P<tz_hour>[0-9][0-9]?)
+        (?::(?P<tz_minute>[0-9][0-9]))?))?)?
+        $~x
+EOF;
+    }
+}
diff --git a/core/vendor/Symfony/Component/Yaml/LICENSE b/core/vendor/Symfony/Component/Yaml/LICENSE
new file mode 100644
index 0000000..cdffe7a
--- /dev/null
+++ b/core/vendor/Symfony/Component/Yaml/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/Yaml/Parser.php b/core/vendor/Symfony/Component/Yaml/Parser.php
new file mode 100644
index 0000000..0743069
--- /dev/null
+++ b/core/vendor/Symfony/Component/Yaml/Parser.php
@@ -0,0 +1,556 @@
+<?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\Yaml;
+
+use Symfony\Component\Yaml\Exception\ParseException;
+
+/**
+ * Parser parses YAML strings to convert them to PHP arrays.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class Parser
+{
+    private $offset         = 0;
+    private $lines          = array();
+    private $currentLineNb  = -1;
+    private $currentLine    = '';
+    private $refs           = array();
+
+    /**
+     * Constructor
+     *
+     * @param integer $offset The offset of YAML document (used for line numbers in error messages)
+     */
+    public function __construct($offset = 0)
+    {
+        $this->offset = $offset;
+    }
+
+    /**
+     * Parses a YAML string to a PHP value.
+     *
+     * @param  string $value A YAML string
+     *
+     * @return mixed  A PHP value
+     *
+     * @throws ParseException If the YAML is not valid
+     */
+    public function parse($value)
+    {
+        $this->currentLineNb = -1;
+        $this->currentLine = '';
+        $this->lines = explode("\n", $this->cleanup($value));
+
+        if (function_exists('mb_detect_encoding') && false === mb_detect_encoding($value, 'UTF-8', true)) {
+            throw new ParseException('The YAML value does not appear to be valid UTF-8.');
+        }
+
+        if (function_exists('mb_internal_encoding') && ((int) ini_get('mbstring.func_overload')) & 2) {
+            $mbEncoding = mb_internal_encoding();
+            mb_internal_encoding('UTF-8');
+        }
+
+        $data = array();
+        while ($this->moveToNextLine()) {
+            if ($this->isCurrentLineEmpty()) {
+                continue;
+            }
+
+            // tab?
+            if ("\t" === $this->currentLine[0]) {
+                throw new ParseException('A YAML file cannot contain tabs as indentation.', $this->getRealCurrentLineNb() + 1, $this->currentLine);
+            }
+
+            $isRef = $isInPlace = $isProcessed = false;
+            if (preg_match('#^\-((?P<leadspaces>\s+)(?P<value>.+?))?\s*$#u', $this->currentLine, $values)) {
+                if (isset($values['value']) && preg_match('#^&(?P<ref>[^ ]+) *(?P<value>.*)#u', $values['value'], $matches)) {
+                    $isRef = $matches['ref'];
+                    $values['value'] = $matches['value'];
+                }
+
+                // array
+                if (!isset($values['value']) || '' == trim($values['value'], ' ') || 0 === strpos(ltrim($values['value'], ' '), '#')) {
+                    $c = $this->getRealCurrentLineNb() + 1;
+                    $parser = new Parser($c);
+                    $parser->refs =& $this->refs;
+                    $data[] = $parser->parse($this->getNextEmbedBlock());
+                } else {
+                    if (isset($values['leadspaces'])
+                        && ' ' == $values['leadspaces']
+                        && preg_match('#^(?P<key>'.Inline::REGEX_QUOTED_STRING.'|[^ \'"\{\[].*?) *\:(\s+(?P<value>.+?))?\s*$#u', $values['value'], $matches)
+                    ) {
+                        // this is a compact notation element, add to next block and parse
+                        $c = $this->getRealCurrentLineNb();
+                        $parser = new Parser($c);
+                        $parser->refs =& $this->refs;
+
+                        $block = $values['value'];
+                        if (!$this->isNextLineIndented()) {
+                            $block .= "\n".$this->getNextEmbedBlock($this->getCurrentLineIndentation() + 2);
+                        }
+
+                        $data[] = $parser->parse($block);
+                    } else {
+                        $data[] = $this->parseValue($values['value']);
+                    }
+                }
+            } elseif (preg_match('#^(?P<key>'.Inline::REGEX_QUOTED_STRING.'|[^ \'"\[\{].*?) *\:(\s+(?P<value>.+?))?\s*$#u', $this->currentLine, $values)) {
+                try {
+                    $key = Inline::parseScalar($values['key']);
+                } catch (ParseException $e) {
+                    $e->setParsedLine($this->getRealCurrentLineNb() + 1);
+                    $e->setSnippet($this->currentLine);
+
+                    throw $e;
+                }
+
+                if ('<<' === $key) {
+                    if (isset($values['value']) && 0 === strpos($values['value'], '*')) {
+                        $isInPlace = substr($values['value'], 1);
+                        if (!array_key_exists($isInPlace, $this->refs)) {
+                            throw new ParseException(sprintf('Reference "%s" does not exist.', $isInPlace), $this->getRealCurrentLineNb() + 1, $this->currentLine);
+                        }
+                    } else {
+                        if (isset($values['value']) && $values['value'] !== '') {
+                            $value = $values['value'];
+                        } else {
+                            $value = $this->getNextEmbedBlock();
+                        }
+                        $c = $this->getRealCurrentLineNb() + 1;
+                        $parser = new Parser($c);
+                        $parser->refs =& $this->refs;
+                        $parsed = $parser->parse($value);
+
+                        $merged = array();
+                        if (!is_array($parsed)) {
+                            throw new ParseException('YAML merge keys used with a scalar value instead of an array.', $this->getRealCurrentLineNb() + 1, $this->currentLine);
+                        } elseif (isset($parsed[0])) {
+                            // Numeric array, merge individual elements
+                            foreach (array_reverse($parsed) as $parsedItem) {
+                                if (!is_array($parsedItem)) {
+                                    throw new ParseException('Merge items must be arrays.', $this->getRealCurrentLineNb() + 1, $parsedItem);
+                                }
+                                $merged = array_merge($parsedItem, $merged);
+                            }
+                        } else {
+                            // Associative array, merge
+                            $merged = array_merge($merged, $parsed);
+                        }
+
+                        $isProcessed = $merged;
+                    }
+                } elseif (isset($values['value']) && preg_match('#^&(?P<ref>[^ ]+) *(?P<value>.*)#u', $values['value'], $matches)) {
+                    $isRef = $matches['ref'];
+                    $values['value'] = $matches['value'];
+                }
+
+                if ($isProcessed) {
+                    // Merge keys
+                    $data = $isProcessed;
+                // hash
+                } elseif (!isset($values['value']) || '' == trim($values['value'], ' ') || 0 === strpos(ltrim($values['value'], ' '), '#')) {
+                    // if next line is less indented or equal, then it means that the current value is null
+                    if ($this->isNextLineIndented()) {
+                        $data[$key] = null;
+                    } else {
+                        $c = $this->getRealCurrentLineNb() + 1;
+                        $parser = new Parser($c);
+                        $parser->refs =& $this->refs;
+                        $data[$key] = $parser->parse($this->getNextEmbedBlock());
+                    }
+                } else {
+                    if ($isInPlace) {
+                        $data = $this->refs[$isInPlace];
+                    } else {
+                        $data[$key] = $this->parseValue($values['value']);
+                    }
+                }
+            } else {
+                // 1-liner followed by newline
+                if (2 == count($this->lines) && empty($this->lines[1])) {
+                    try {
+                        $value = Inline::parse($this->lines[0]);
+                    } catch (ParseException $e) {
+                        $e->setParsedLine($this->getRealCurrentLineNb() + 1);
+                        $e->setSnippet($this->currentLine);
+
+                        throw $e;
+                    }
+
+                    if (is_array($value)) {
+                        $first = reset($value);
+                        if (is_string($first) && 0 === strpos($first, '*')) {
+                            $data = array();
+                            foreach ($value as $alias) {
+                                $data[] = $this->refs[substr($alias, 1)];
+                            }
+                            $value = $data;
+                        }
+                    }
+
+                    if (isset($mbEncoding)) {
+                        mb_internal_encoding($mbEncoding);
+                    }
+
+                    return $value;
+                }
+
+                switch (preg_last_error()) {
+                    case PREG_INTERNAL_ERROR:
+                        $error = 'Internal PCRE error.';
+                        break;
+                    case PREG_BACKTRACK_LIMIT_ERROR:
+                        $error = 'pcre.backtrack_limit reached.';
+                        break;
+                    case PREG_RECURSION_LIMIT_ERROR:
+                        $error = 'pcre.recursion_limit reached.';
+                        break;
+                    case PREG_BAD_UTF8_ERROR:
+                        $error = 'Malformed UTF-8 data.';
+                        break;
+                    case PREG_BAD_UTF8_OFFSET_ERROR:
+                        $error = 'Offset doesn\'t correspond to the begin of a valid UTF-8 code point.';
+                        break;
+                    default:
+                        $error = 'Unable to parse.';
+                }
+
+                throw new ParseException($error, $this->getRealCurrentLineNb() + 1, $this->currentLine);
+            }
+
+            if ($isRef) {
+                $this->refs[$isRef] = end($data);
+            }
+        }
+
+        if (isset($mbEncoding)) {
+            mb_internal_encoding($mbEncoding);
+        }
+
+        return empty($data) ? null : $data;
+    }
+
+    /**
+     * Returns the current line number (takes the offset into account).
+     *
+     * @return integer The current line number
+     */
+    private function getRealCurrentLineNb()
+    {
+        return $this->currentLineNb + $this->offset;
+    }
+
+    /**
+     * Returns the current line indentation.
+     *
+     * @return integer The current line indentation
+     */
+    private function getCurrentLineIndentation()
+    {
+        return strlen($this->currentLine) - strlen(ltrim($this->currentLine, ' '));
+    }
+
+    /**
+     * Returns the next embed block of YAML.
+     *
+     * @param integer $indentation The indent level at which the block is to be read, or null for default
+     *
+     * @return string A YAML string
+     *
+     * @throws ParseException When indentation problem are detected
+     */
+    private function getNextEmbedBlock($indentation = null)
+    {
+        $this->moveToNextLine();
+
+        if (null === $indentation) {
+            $newIndent = $this->getCurrentLineIndentation();
+
+            if (!$this->isCurrentLineEmpty() && 0 == $newIndent) {
+                throw new ParseException('Indentation problem.', $this->getRealCurrentLineNb() + 1, $this->currentLine);
+            }
+        } else {
+            $newIndent = $indentation;
+        }
+
+        $data = array(substr($this->currentLine, $newIndent));
+
+        while ($this->moveToNextLine()) {
+            if ($this->isCurrentLineEmpty()) {
+                if ($this->isCurrentLineBlank()) {
+                    $data[] = substr($this->currentLine, $newIndent);
+                }
+
+                continue;
+            }
+
+            $indent = $this->getCurrentLineIndentation();
+
+            if (preg_match('#^(?P<text> *)$#', $this->currentLine, $match)) {
+                // empty line
+                $data[] = $match['text'];
+            } elseif ($indent >= $newIndent) {
+                $data[] = substr($this->currentLine, $newIndent);
+            } elseif (0 == $indent) {
+                $this->moveToPreviousLine();
+
+                break;
+            } else {
+                throw new ParseException('Indentation problem.', $this->getRealCurrentLineNb() + 1, $this->currentLine);
+            }
+        }
+
+        return implode("\n", $data);
+    }
+
+    /**
+     * Moves the parser to the next line.
+     *
+     * @return Boolean
+     */
+    private function moveToNextLine()
+    {
+        if ($this->currentLineNb >= count($this->lines) - 1) {
+            return false;
+        }
+
+        $this->currentLine = $this->lines[++$this->currentLineNb];
+
+        return true;
+    }
+
+    /**
+     * Moves the parser to the previous line.
+     */
+    private function moveToPreviousLine()
+    {
+        $this->currentLine = $this->lines[--$this->currentLineNb];
+    }
+
+    /**
+     * Parses a YAML value.
+     *
+     * @param  string $value A YAML value
+     *
+     * @return mixed  A PHP value
+     *
+     * @throws ParseException When reference does not exist
+     */
+    private function parseValue($value)
+    {
+        if (0 === strpos($value, '*')) {
+            if (false !== $pos = strpos($value, '#')) {
+                $value = substr($value, 1, $pos - 2);
+            } else {
+                $value = substr($value, 1);
+            }
+
+            if (!array_key_exists($value, $this->refs)) {
+                throw new ParseException(sprintf('Reference "%s" does not exist.', $value), $this->currentLine);
+            }
+
+            return $this->refs[$value];
+        }
+
+        if (preg_match('/^(?P<separator>\||>)(?P<modifiers>\+|\-|\d+|\+\d+|\-\d+|\d+\+|\d+\-)?(?P<comments> +#.*)?$/', $value, $matches)) {
+            $modifiers = isset($matches['modifiers']) ? $matches['modifiers'] : '';
+
+            return $this->parseFoldedScalar($matches['separator'], preg_replace('#\d+#', '', $modifiers), intval(abs($modifiers)));
+        }
+
+        try {
+            return Inline::parse($value);
+        } catch (ParseException $e) {
+            $e->setParsedLine($this->getRealCurrentLineNb() + 1);
+            $e->setSnippet($this->currentLine);
+
+            throw $e;
+        }
+    }
+
+    /**
+     * Parses a folded scalar.
+     *
+     * @param  string  $separator   The separator that was used to begin this folded scalar (| or >)
+     * @param  string  $indicator   The indicator that was used to begin this folded scalar (+ or -)
+     * @param  integer $indentation The indentation that was used to begin this folded scalar
+     *
+     * @return string  The text value
+     */
+    private function parseFoldedScalar($separator, $indicator = '', $indentation = 0)
+    {
+        $separator = '|' == $separator ? "\n" : ' ';
+        $text = '';
+
+        $notEOF = $this->moveToNextLine();
+
+        while ($notEOF && $this->isCurrentLineBlank()) {
+            $text .= "\n";
+
+            $notEOF = $this->moveToNextLine();
+        }
+
+        if (!$notEOF) {
+            return '';
+        }
+
+        if (!preg_match('#^(?P<indent>'.($indentation ? str_repeat(' ', $indentation) : ' +').')(?P<text>.*)$#u', $this->currentLine, $matches)) {
+            $this->moveToPreviousLine();
+
+            return '';
+        }
+
+        $textIndent = $matches['indent'];
+        $previousIndent = 0;
+
+        $text .= $matches['text'].$separator;
+        while ($this->currentLineNb + 1 < count($this->lines)) {
+            $this->moveToNextLine();
+
+            if (preg_match('#^(?P<indent> {'.strlen($textIndent).',})(?P<text>.+)$#u', $this->currentLine, $matches)) {
+                if (' ' == $separator && $previousIndent != $matches['indent']) {
+                    $text = substr($text, 0, -1)."\n";
+                }
+                $previousIndent = $matches['indent'];
+
+                $text .= str_repeat(' ', $diff = strlen($matches['indent']) - strlen($textIndent)).$matches['text'].($diff ? "\n" : $separator);
+            } elseif (preg_match('#^(?P<text> *)$#', $this->currentLine, $matches)) {
+                $text .= preg_replace('#^ {1,'.strlen($textIndent).'}#', '', $matches['text'])."\n";
+            } else {
+                $this->moveToPreviousLine();
+
+                break;
+            }
+        }
+
+        if (' ' == $separator) {
+            // replace last separator by a newline
+            $text = preg_replace('/ (\n*)$/', "\n$1", $text);
+        }
+
+        switch ($indicator) {
+            case '':
+                $text = preg_replace('#\n+$#s', "\n", $text);
+                break;
+            case '+':
+                break;
+            case '-':
+                $text = preg_replace('#\n+$#s', '', $text);
+                break;
+        }
+
+        return $text;
+    }
+
+    /**
+     * Returns true if the next line is indented.
+     *
+     * @return Boolean Returns true if the next line is indented, false otherwise
+     */
+    private function isNextLineIndented()
+    {
+        $currentIndentation = $this->getCurrentLineIndentation();
+        $notEOF = $this->moveToNextLine();
+
+        while ($notEOF && $this->isCurrentLineEmpty()) {
+            $notEOF = $this->moveToNextLine();
+        }
+
+        if (false === $notEOF) {
+            return false;
+        }
+
+        $ret = false;
+        if ($this->getCurrentLineIndentation() <= $currentIndentation) {
+            $ret = true;
+        }
+
+        $this->moveToPreviousLine();
+
+        return $ret;
+    }
+
+    /**
+     * Returns true if the current line is blank or if it is a comment line.
+     *
+     * @return Boolean Returns true if the current line is empty or if it is a comment line, false otherwise
+     */
+    private function isCurrentLineEmpty()
+    {
+        return $this->isCurrentLineBlank() || $this->isCurrentLineComment();
+    }
+
+    /**
+     * Returns true if the current line is blank.
+     *
+     * @return Boolean Returns true if the current line is blank, false otherwise
+     */
+    private function isCurrentLineBlank()
+    {
+        return '' == trim($this->currentLine, ' ');
+    }
+
+    /**
+     * Returns true if the current line is a comment line.
+     *
+     * @return Boolean Returns true if the current line is a comment line, false otherwise
+     */
+    private function isCurrentLineComment()
+    {
+        //checking explicitly the first char of the trim is faster than loops or strpos
+        $ltrimmedLine = ltrim($this->currentLine, ' ');
+
+        return $ltrimmedLine[0] === '#';
+    }
+
+    /**
+     * Cleanups a YAML string to be parsed.
+     *
+     * @param  string $value The input YAML string
+     *
+     * @return string A cleaned up YAML string
+     */
+    private function cleanup($value)
+    {
+        $value = str_replace(array("\r\n", "\r"), "\n", $value);
+
+        if (!preg_match("#\n$#", $value)) {
+            $value .= "\n";
+        }
+
+        // strip YAML header
+        $count = 0;
+        $value = preg_replace('#^\%YAML[: ][\d\.]+.*\n#su', '', $value, -1, $count);
+        $this->offset += $count;
+
+        // remove leading comments
+        $trimmedValue = preg_replace('#^(\#.*?\n)+#s', '', $value, -1, $count);
+        if ($count == 1) {
+            // items have been removed, update the offset
+            $this->offset += substr_count($value, "\n") - substr_count($trimmedValue, "\n");
+            $value = $trimmedValue;
+        }
+
+        // remove start of the document marker (---)
+        $trimmedValue = preg_replace('#^\-\-\-.*?\n#s', '', $value, -1, $count);
+        if ($count == 1) {
+            // items have been removed, update the offset
+            $this->offset += substr_count($value, "\n") - substr_count($trimmedValue, "\n");
+            $value = $trimmedValue;
+
+            // remove end of the document marker (...)
+            $value = preg_replace('#\.\.\.\s*$#s', '', $value);
+        }
+
+        return $value;
+    }
+}
diff --git a/core/vendor/Symfony/Component/Yaml/README.md b/core/vendor/Symfony/Component/Yaml/README.md
new file mode 100644
index 0000000..f1c5129
--- /dev/null
+++ b/core/vendor/Symfony/Component/Yaml/README.md
@@ -0,0 +1,17 @@
+Yaml Component
+==============
+
+YAML implements most of the YAML 1.2 specification.
+
+    use Symfony\Component\Yaml\Yaml;
+
+    $array = Yaml::parse($file);
+
+    print Yaml::dump($array);
+
+Resources
+---------
+
+Unit tests:
+
+https://github.com/symfony/symfony/tree/master/tests/Symfony/Tests/Component/Yaml
diff --git a/core/vendor/Symfony/Component/Yaml/Unescaper.php b/core/vendor/Symfony/Component/Yaml/Unescaper.php
new file mode 100644
index 0000000..807a35e
--- /dev/null
+++ b/core/vendor/Symfony/Component/Yaml/Unescaper.php
@@ -0,0 +1,145 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Yaml;
+
+/**
+ * Unescaper encapsulates unescaping rules for single and double-quoted
+ * YAML strings.
+ *
+ * @author Matthew Lewinski <matthew@lewinski.org>
+ */
+class Unescaper
+{
+    // Parser and Inline assume UTF-8 encoding, so escaped Unicode characters
+    // must be converted to that encoding.
+    const ENCODING = 'UTF-8';
+
+    // Regex fragment that matches an escaped character in a double quoted
+    // string.
+    const REGEX_ESCAPED_CHARACTER = "\\\\([0abt\tnvfre \\\"\\/\\\\N_LP]|x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|U[0-9a-fA-F]{8})";
+
+    /**
+     * Unescapes a single quoted string.
+     *
+     * @param string $value A single quoted string.
+     *
+     * @return string The unescaped string.
+     */
+    public function unescapeSingleQuotedString($value)
+    {
+        return str_replace('\'\'', '\'', $value);
+    }
+
+    /**
+     * Unescapes a double quoted string.
+     *
+     * @param string $value A double quoted string.
+     *
+     * @return string The unescaped string.
+     */
+    public function unescapeDoubleQuotedString($value)
+    {
+        $self = $this;
+        $callback = function($match) use($self) {
+            return $self->unescapeCharacter($match[0]);
+        };
+
+        // evaluate the string
+        return preg_replace_callback('/'.self::REGEX_ESCAPED_CHARACTER.'/u', $callback, $value);
+    }
+
+    /**
+     * Unescapes a character that was found in a double-quoted string
+     *
+     * @param string $value An escaped character
+     *
+     * @return string The unescaped character
+     */
+    public function unescapeCharacter($value)
+    {
+        switch ($value{1}) {
+            case '0':
+                return "\x0";
+            case 'a':
+                return "\x7";
+            case 'b':
+                return "\x8";
+            case 't':
+                return "\t";
+            case "\t":
+                return "\t";
+            case 'n':
+                return "\n";
+            case 'v':
+                return "\xb";
+            case 'f':
+                return "\xc";
+            case 'r':
+                return "\xd";
+            case 'e':
+                return "\x1b";
+            case ' ':
+                return ' ';
+            case '"':
+                return '"';
+            case '/':
+                return '/';
+            case '\\':
+                return '\\';
+            case 'N':
+                // U+0085 NEXT LINE
+                return $this->convertEncoding("\x00\x85", self::ENCODING, 'UCS-2BE');
+            case '_':
+                // U+00A0 NO-BREAK SPACE
+                return $this->convertEncoding("\x00\xA0", self::ENCODING, 'UCS-2BE');
+            case 'L':
+                // U+2028 LINE SEPARATOR
+                return $this->convertEncoding("\x20\x28", self::ENCODING, 'UCS-2BE');
+            case 'P':
+                // U+2029 PARAGRAPH SEPARATOR
+                return $this->convertEncoding("\x20\x29", self::ENCODING, 'UCS-2BE');
+            case 'x':
+                $char = pack('n', hexdec(substr($value, 2, 2)));
+
+                return $this->convertEncoding($char, self::ENCODING, 'UCS-2BE');
+            case 'u':
+                $char = pack('n', hexdec(substr($value, 2, 4)));
+
+                return $this->convertEncoding($char, self::ENCODING, 'UCS-2BE');
+            case 'U':
+                $char = pack('N', hexdec(substr($value, 2, 8)));
+
+                return $this->convertEncoding($char, self::ENCODING, 'UCS-4BE');
+        }
+    }
+
+    /**
+     * Convert a string from one encoding to another.
+     *
+     * @param string $value The string to convert
+     * @param string $to    The input encoding
+     * @param string $from  The output encoding
+     *
+     * @return string The string with the new encoding
+     *
+     * @throws \RuntimeException if no suitable encoding function is found (iconv or mbstring)
+     */
+    private function convertEncoding($value, $to, $from)
+    {
+        if (function_exists('iconv')) {
+            return iconv($from, $to, $value);
+        } elseif (function_exists('mb_convert_encoding')) {
+            return mb_convert_encoding($value, $to, $from);
+        }
+
+        throw new \RuntimeException('No suitable convert encoding function (install the iconv or mbstring extension).');
+    }
+}
diff --git a/core/vendor/Symfony/Component/Yaml/Yaml.php b/core/vendor/Symfony/Component/Yaml/Yaml.php
new file mode 100644
index 0000000..c2f6c97
--- /dev/null
+++ b/core/vendor/Symfony/Component/Yaml/Yaml.php
@@ -0,0 +1,111 @@
+<?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\Yaml;
+
+use Symfony\Component\Yaml\Exception\ParseException;
+
+/**
+ * Yaml offers convenience methods to load and dump YAML.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ *
+ * @api
+ */
+class Yaml
+{
+    static public $enablePhpParsing = false;
+
+    static public function enablePhpParsing()
+    {
+        self::$enablePhpParsing = true;
+    }
+
+    /**
+     * Parses YAML into a PHP array.
+     *
+     * The parse method, when supplied with a YAML stream (string or file),
+     * will do its best to convert YAML in a file into a PHP array.
+     *
+     *  Usage:
+     *  <code>
+     *   $array = Yaml::parse('config.yml');
+     *   print_r($array);
+     *  </code>
+     *
+     * @param string $input Path to a YAML file or a string containing YAML
+     *
+     * @return array The YAML converted to a PHP array
+     *
+     * @throws \InvalidArgumentException If the YAML is not valid
+     *
+     * @api
+     */
+    static public function parse($input)
+    {
+        // if input is a file, process it
+        $file = '';
+        if (strpos($input, "\n") === false && is_file($input)) {
+            if (false === is_readable($input)) {
+                throw new ParseException(sprintf('Unable to parse "%s" as the file is not readable.', $input));
+            }
+
+            $file = $input;
+            if (self::$enablePhpParsing) {
+                ob_start();
+                $retval = include($file);
+                $content = ob_get_clean();
+
+                // if an array is returned by the config file assume it's in plain php form else in YAML
+                $input = is_array($retval) ? $retval : $content;
+
+                // if an array is returned by the config file assume it's in plain php form else in YAML
+                if (is_array($input)) {
+                    return $input;
+                }
+            } else {
+                $input = file_get_contents($file);
+            }
+        }
+
+        $yaml = new Parser();
+
+        try {
+            return $yaml->parse($input);
+        } catch (ParseException $e) {
+            if ($file) {
+                $e->setParsedFile($file);
+            }
+
+            throw $e;
+        }
+    }
+
+    /**
+     * Dumps a PHP array to a YAML string.
+     *
+     * The dump method, when supplied with an array, will do its best
+     * to convert the array into friendly YAML.
+     *
+     * @param array   $array PHP array
+     * @param integer $inline The level where you switch to inline YAML
+     *
+     * @return string A YAML string representing the original PHP array
+     *
+     * @api
+     */
+    static public function dump($array, $inline = 2)
+    {
+        $yaml = new Dumper();
+
+        return $yaml->dump($array, $inline);
+    }
+}
diff --git a/core/vendor/Symfony/Component/Yaml/composer.json b/core/vendor/Symfony/Component/Yaml/composer.json
new file mode 100644
index 0000000..dc87721
--- /dev/null
+++ b/core/vendor/Symfony/Component/Yaml/composer.json
@@ -0,0 +1,30 @@
+{
+    "name": "symfony/yaml",
+    "type": "library",
+    "description": "Symfony Yaml 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.2"
+    },
+    "autoload": {
+        "psr-0": { "Symfony\\Component\\Yaml": "" }
+    },
+    "target-dir": "Symfony/Component/Yaml",
+    "extra": {
+        "branch-alias": {
+            "dev-master": "2.1-dev"
+        }
+    }
+}
-- 
1.7.6.msysgit.0


From 8dbbc973f7db5e3ade18c4a529228bed88a71547 Mon Sep 17 00:00:00 2001
From: sun <sun@unleashedmind.com>
Date: Wed, 2 May 2012 03:20:02 +0200
Subject: [PATCH 2/3] - #1470824 by sun: Changed configuration format from XML
 to YAML.

Temporarily hacks in public access to file storage.
---
 core/includes/config.inc                           |   84 +++++++++++++++-----
 core/lib/Drupal/Core/Config/DrupalConfig.php       |    9 ++-
 .../Core/Config/DrupalConfigVerifiedStorage.php    |    4 +-
 core/lib/Drupal/Core/Config/SignedFileStorage.php  |   35 +++++++-
 4 files changed, 104 insertions(+), 28 deletions(-)

diff --git a/core/includes/config.inc b/core/includes/config.inc
index cb81acc..f933efc 100644
--- a/core/includes/config.inc
+++ b/core/includes/config.inc
@@ -1,6 +1,7 @@
 <?php
 
 use Drupal\Core\Config\DrupalVerifiedStorageSQL;
+use Symfony\Component\Yaml\Yaml;
 
 /**
  * @file
@@ -148,13 +149,20 @@ function config_decode($data) {
     return array();
   }
 
-  // This is the fastest and easiest way to get from a string of XML to a PHP
-  // array since SimpleXML and json_decode()/encode() are native to PHP. Our
-  // only other choice would be a custom userspace implementation which would
-  // be a lot less performant and more complex.
-  $xml = new SimpleXMLElement($data);
-  $json = json_encode($xml);
-  return json_decode($json, TRUE);
+  // Check for XML.
+  if ($data[0] === '<') {
+    // This is the fastest and easiest way to get from a string of XML to a PHP
+    // array since SimpleXML and json_decode()/encode() are native to PHP. Our
+    // only other choice would be a custom userspace implementation which would
+    // be a lot less performant and more complex.
+    $xml = new SimpleXMLElement($data);
+    $json = json_encode($xml);
+    return json_decode($json, TRUE);
+  }
+  // Assume YAML.
+  else {
+    return Yaml::parse($data);
+  }
 }
 
 /**
@@ -201,18 +209,9 @@ function config_xml_to_array($data) {
  * @todo The loaded XML can be invalid; throwing plenty of PHP warnings but no
  *   catchable error.
  */
-function config_encode($data) {
-  // Convert the supplied array into a SimpleXMLElement.
-  $xml_object = new SimpleXMLElement("<?xml version=\"1.0\"?><config></config>");
-  config_array_to_xml($data, $xml_object);
-
-  // Pretty print the result.
-  $dom = new DOMDocument('1.0');
-  $dom->preserveWhiteSpace = false;
-  $dom->formatOutput = true;
-  $dom->loadXML($xml_object->asXML());
-
-  return $dom->saveXML();
+function config_encode(array $data) {
+  // Create YAML.
+  return Yaml::dump($data, 5);
 }
 
 /**
@@ -241,3 +240,50 @@ function config_array_to_xml($array, &$xml_object) {
     }
   }
 }
+
+/**
+ * @todo Remove after conversion.
+ * @todo The Config API and its premature optimizations are nuts to work with.
+ *
+ * @param $name
+ *   The config object/file base name.
+ * @param $path
+ *   (optional) The path where $name.xml is located and $name.yaml to write.
+ */
+function config_xml2yaml($name, $path = NULL) {
+  // Initialize.
+  $config = config($name);
+
+  // Read from XML.
+  $config->_verifiedStorage->signedFileStorage()->setFileExtension('xml');
+  if (isset($path)) {
+    $config->_verifiedStorage->signedFileStorage()->setFilePath($path);
+  }
+  $string = $config->_verifiedStorage->readFromFile();
+  $config->parseString($string);
+
+  // Write to YAML.
+  $config->_verifiedStorage->signedFileStorage()->setFileExtension('yaml');
+  $config->_verifiedStorage->signedFileStorage()->write(config_encode($config->get()));
+
+  return $config->get();
+}
+
+function config_xml2yaml_all() {
+  $modules = system_rebuild_module_data();
+  $files = array();
+  foreach ($modules as $name => $module) {
+    $path = dirname($module->uri) . '/config';
+    if (is_dir(DRUPAL_ROOT . '/' . $path)) {
+      foreach (glob($path . '/*.xml') as $file) {
+        $files[$path][] = basename($file, '.xml');
+      }
+    }
+  }
+  // debug($files);
+  foreach ($files as $path => $names) {
+    foreach ($names as $name) {
+      config_xml2yaml($name, $path);
+    }
+  }
+}
diff --git a/core/lib/Drupal/Core/Config/DrupalConfig.php b/core/lib/Drupal/Core/Config/DrupalConfig.php
index 9fc33aa..d890401 100644
--- a/core/lib/Drupal/Core/Config/DrupalConfig.php
+++ b/core/lib/Drupal/Core/Config/DrupalConfig.php
@@ -15,7 +15,7 @@ class DrupalConfig {
    *
    * @var DrupalConfigVerifiedStorageInterface
    */
-  protected $_verifiedStorage;
+  public $_verifiedStorage;
 
   protected $data = array();
 
@@ -36,7 +36,12 @@ class DrupalConfig {
    * Reads config data from the active store into our object.
    */
   public function read() {
-    $active = (array) config_decode($this->_verifiedStorage->read());
+    $active = $this->_verifiedStorage->read();
+    $this->parseString($active);
+  }
+
+  public function parseString($string) {
+    $active = (array) config_decode($string);
     foreach ($active as $key => $value) {
       // If the setting is empty, return an empty string rather than an array.
       // This is necessary because SimpleXML's default behavior is to return
diff --git a/core/lib/Drupal/Core/Config/DrupalConfigVerifiedStorage.php b/core/lib/Drupal/Core/Config/DrupalConfigVerifiedStorage.php
index 267c834..56ccf0e 100644
--- a/core/lib/Drupal/Core/Config/DrupalConfigVerifiedStorage.php
+++ b/core/lib/Drupal/Core/Config/DrupalConfigVerifiedStorage.php
@@ -32,7 +32,7 @@ abstract class DrupalConfigVerifiedStorage implements DrupalConfigVerifiedStorag
    * @return SignedFileStorage
    *   The signed file object for this configuration object.
    */
-  protected function signedFileStorage() {
+  public function signedFileStorage() {
     if (!isset($this->signedFile)) {
       $this->signedFile = new SignedFileStorage($this->name);
     }
@@ -67,7 +67,7 @@ abstract class DrupalConfigVerifiedStorage implements DrupalConfigVerifiedStorag
    *   @todo
    */
   public function readFromFile() {
-    return $this->signedFileStorage()->read($this->name);
+    return $this->signedFileStorage()->read();
   }
 
   /**
diff --git a/core/lib/Drupal/Core/Config/SignedFileStorage.php b/core/lib/Drupal/Core/Config/SignedFileStorage.php
index c669029..c3dbc26 100644
--- a/core/lib/Drupal/Core/Config/SignedFileStorage.php
+++ b/core/lib/Drupal/Core/Config/SignedFileStorage.php
@@ -12,6 +12,22 @@ namespace Drupal\Core\Config;
 class SignedFileStorage {
 
   /**
+   * The configuration object name.
+   *
+   * @var string
+   */
+  protected $name;
+
+  protected $path;
+
+  /**
+   * The configuration file format extension (e.g., 'yaml' or 'xml').
+   *
+   * @var string
+   */
+  protected $extension = 'yaml';
+
+  /**
    * Constructs a SignedFileStorage object.
    *
    * @param string $name
@@ -19,6 +35,7 @@ class SignedFileStorage {
    */
   public function __construct($name) {
     $this->name = $name;
+    $this->path = config_get_config_directory();
   }
 
   /**
@@ -35,6 +52,7 @@ class SignedFileStorage {
     if ($content === FALSE) {
       throw new \Exception('Read file is invalid.');
     }
+    return array('data' => $content);
     $signature = file_get_contents($this->getFilePath() . '.sig');
     if ($signature === FALSE) {
       throw new \Exception('Signature file is invalid.');
@@ -59,7 +77,17 @@ class SignedFileStorage {
    *   @todo
    */
   public function getFilePath() {
-    return config_get_config_directory() . '/' . $this->name  . '.xml';
+    return $this->path . '/' . $this->name  . '.' . $this->extension;
+  }
+
+  public function setFilePath($path) {
+    $this->path = $path;
+    return $this;
+  }
+
+  public function setFileExtension($extension) {
+    $this->extension = $extension;
+    return $this;
   }
 
   /**
@@ -86,6 +114,7 @@ class SignedFileStorage {
   public function verify($contentOnSuccess = FALSE) {
     if ($this->exists()) {
       $split = $this->readWithSignature();
+      return $contentOnSuccess ? $split['data'] : TRUE; // Fuck this.
       $expected_signature = config_sign_data($split['data']);
       if ($expected_signature === $split['signature']) {
         if ($contentOnSuccess) {
@@ -107,13 +136,9 @@ class SignedFileStorage {
    *   Exception
    */
   public function write($data) {
-    $signature = config_sign_data($data);
     if (!file_put_contents($this->getFilePath(), $data)) {
       throw new \Exception('Failed to write configuration file: ' . $this->getFilePath());
     }
-    if (!file_put_contents($this->getFilePath() . '.sig', $signature)) {
-      throw new \Exception('Failed to write signature file: ' . $this->getFilePath());
-    }
   }
 
   /**
-- 
1.7.6.msysgit.0


From 3da3a4776630696f2f9b432f4291c6af85fae4fc Mon Sep 17 00:00:00 2001
From: sun <sun@unleashedmind.com>
Date: Wed, 2 May 2012 03:21:02 +0200
Subject: [PATCH 3/3] - #1470824 by sun: Converted default configuration files
 to YAML.

---
 core/modules/block/config/block.performance.xml    |    4 ----
 core/modules/block/config/block.performance.yaml   |    1 +
 core/modules/image/config/image.style.large.xml    |   16 ----------------
 core/modules/image/config/image.style.large.yaml   |   10 ++++++++++
 core/modules/image/config/image.style.medium.xml   |   16 ----------------
 core/modules/image/config/image.style.medium.yaml  |   10 ++++++++++
 .../modules/image/config/image.style.thumbnail.xml |   16 ----------------
 .../image/config/image.style.thumbnail.yaml        |   10 ++++++++++
 core/modules/system/config/system.performance.xml  |    9 ---------
 core/modules/system/config/system.performance.yaml |    6 ++++++
 .../modules/config_upgrade/config/config.test.xml  |    5 -----
 .../modules/config_upgrade/config/config.test.yaml |    2 ++
 12 files changed, 39 insertions(+), 66 deletions(-)
 delete mode 100644 core/modules/block/config/block.performance.xml
 create mode 100644 core/modules/block/config/block.performance.yaml
 delete mode 100644 core/modules/image/config/image.style.large.xml
 create mode 100644 core/modules/image/config/image.style.large.yaml
 delete mode 100644 core/modules/image/config/image.style.medium.xml
 create mode 100644 core/modules/image/config/image.style.medium.yaml
 delete mode 100644 core/modules/image/config/image.style.thumbnail.xml
 create mode 100644 core/modules/image/config/image.style.thumbnail.yaml
 delete mode 100644 core/modules/system/config/system.performance.xml
 create mode 100644 core/modules/system/config/system.performance.yaml
 delete mode 100644 core/modules/system/tests/modules/config_upgrade/config/config.test.xml
 create mode 100644 core/modules/system/tests/modules/config_upgrade/config/config.test.yaml

diff --git a/core/modules/block/config/block.performance.xml b/core/modules/block/config/block.performance.xml
deleted file mode 100644
index ff3f7e1..0000000
--- a/core/modules/block/config/block.performance.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0"?>
-<config>
-  <block_cache>0</block_cache>
-</config>
diff --git a/core/modules/block/config/block.performance.yaml b/core/modules/block/config/block.performance.yaml
new file mode 100644
index 0000000..d8fa4d7
--- /dev/null
+++ b/core/modules/block/config/block.performance.yaml
@@ -0,0 +1 @@
+block_cache: '0'
diff --git a/core/modules/image/config/image.style.large.xml b/core/modules/image/config/image.style.large.xml
deleted file mode 100644
index 62448c1..0000000
--- a/core/modules/image/config/image.style.large.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0"?>
-<config>
-  <name>large</name>
-  <effects>
-    <image_scale_480_480_1>
-      <name>image_scale</name>
-      <ieid>image_scale_480_480_1</ieid>
-      <data>
-        <width>480</width>
-        <height>480</height>
-        <upscale>1</upscale>
-      </data>
-      <weight>0</weight>
-    </image_scale_480_480_1>
-  </effects>
-</config>
diff --git a/core/modules/image/config/image.style.large.yaml b/core/modules/image/config/image.style.large.yaml
new file mode 100644
index 0000000..4ad7cef
--- /dev/null
+++ b/core/modules/image/config/image.style.large.yaml
@@ -0,0 +1,10 @@
+name: large
+effects:
+    image_scale_480_480_1:
+        name: image_scale
+        ieid: image_scale_480_480_1
+        data:
+            width: '480'
+            height: '480'
+            upscale: '1'
+        weight: '0'
diff --git a/core/modules/image/config/image.style.medium.xml b/core/modules/image/config/image.style.medium.xml
deleted file mode 100644
index d301877..0000000
--- a/core/modules/image/config/image.style.medium.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0"?>
-<config>
-  <name>medium</name>
-  <effects>
-    <image_scale_220_220_1>
-      <name>image_scale</name>
-      <ieid>image_scale_220_220_1</ieid>
-      <data>
-        <width>220</width>
-        <height>220</height>
-        <upscale>1</upscale>
-      </data>
-      <weight>0</weight>
-    </image_scale_220_220_1>
-  </effects>
-</config>
diff --git a/core/modules/image/config/image.style.medium.yaml b/core/modules/image/config/image.style.medium.yaml
new file mode 100644
index 0000000..55f216e
--- /dev/null
+++ b/core/modules/image/config/image.style.medium.yaml
@@ -0,0 +1,10 @@
+name: medium
+effects:
+    image_scale_220_220_1:
+        name: image_scale
+        ieid: image_scale_220_220_1
+        data:
+            width: '220'
+            height: '220'
+            upscale: '1'
+        weight: '0'
diff --git a/core/modules/image/config/image.style.thumbnail.xml b/core/modules/image/config/image.style.thumbnail.xml
deleted file mode 100644
index 385abe6..0000000
--- a/core/modules/image/config/image.style.thumbnail.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0"?>
-<config>
-  <name>thumbnail</name>
-  <effects>
-    <image_scale_100_100_1>
-      <name>image_scale</name>
-      <ieid>image_scale_100_100_1</ieid>
-      <data>
-        <width>100</width>
-        <height>100</height>
-        <upscale>1</upscale>
-      </data>
-      <weight>0</weight>
-    </image_scale_100_100_1>
-  </effects>
-</config>
diff --git a/core/modules/image/config/image.style.thumbnail.yaml b/core/modules/image/config/image.style.thumbnail.yaml
new file mode 100644
index 0000000..682c6ec
--- /dev/null
+++ b/core/modules/image/config/image.style.thumbnail.yaml
@@ -0,0 +1,10 @@
+name: thumbnail
+effects:
+    image_scale_100_100_1:
+        name: image_scale
+        ieid: image_scale_100_100_1
+        data:
+            width: '100'
+            height: '100'
+            upscale: '1'
+        weight: '0'
diff --git a/core/modules/system/config/system.performance.xml b/core/modules/system/config/system.performance.xml
deleted file mode 100644
index 8edf1eb..0000000
--- a/core/modules/system/config/system.performance.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<?xml version="1.0"?>
-<config>
-  <cache>0</cache>
-  <cache_lifetime>0</cache_lifetime>
-  <page_cache_maximum_age>0</page_cache_maximum_age>
-  <page_compression>0</page_compression>
-  <preprocess_css>0</preprocess_css>
-  <preprocess_js>0</preprocess_js>
-</config>
diff --git a/core/modules/system/config/system.performance.yaml b/core/modules/system/config/system.performance.yaml
new file mode 100644
index 0000000..0313ef8
--- /dev/null
+++ b/core/modules/system/config/system.performance.yaml
@@ -0,0 +1,6 @@
+cache: '0'
+cache_lifetime: '0'
+page_cache_maximum_age: '0'
+page_compression: '0'
+preprocess_css: '0'
+preprocess_js: '0'
diff --git a/core/modules/system/tests/modules/config_upgrade/config/config.test.xml b/core/modules/system/tests/modules/config_upgrade/config/config.test.xml
deleted file mode 100644
index bb3e791..0000000
--- a/core/modules/system/tests/modules/config_upgrade/config/config.test.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<?xml version="1.0"?>
-<config>
-  <config_test_foo>bar</config_test_foo>
-  <config_test_bar>foo</config_test_bar>
-</config>
diff --git a/core/modules/system/tests/modules/config_upgrade/config/config.test.yaml b/core/modules/system/tests/modules/config_upgrade/config/config.test.yaml
new file mode 100644
index 0000000..4e5eb16
--- /dev/null
+++ b/core/modules/system/tests/modules/config_upgrade/config/config.test.yaml
@@ -0,0 +1,2 @@
+config_test_foo: bar
+config_test_bar: foo
-- 
1.7.6.msysgit.0

