diff --git a/core/composer.json b/core/composer.json
index fd0e942..715cecd 100644
--- a/core/composer.json
+++ b/core/composer.json
@@ -10,6 +10,7 @@
     "symfony/http-kernel": "2.1.*",
     "symfony/routing": "2.1.*",
     "symfony/serializer": "2.1.*",
+    "symfony/validator": "2.2.x-dev",
     "symfony/yaml": "2.1.*",
     "twig/twig": "1.8.*",
     "doctrine/common": "2.3.*",
diff --git a/core/composer.lock b/core/composer.lock
index fa87f0e..2be7e7b 100644
--- a/core/composer.lock
+++ b/core/composer.lock
@@ -1,5 +1,5 @@
 {
-    "hash": "90e0986bd0957088356cb234e33f6332",
+    "hash": "7d3ea90a5c44f754e4f3b95d168abf8a",
     "packages": [
         {
             "name": "doctrine/common",
@@ -760,6 +760,63 @@
             "homepage": "http://symfony.com"
         },
         {
+            "name": "symfony/validator",
+            "version": "dev-master",
+            "target-dir": "Symfony/Component/Validator",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/Validator",
+                "reference": "256bc3a6cb2beae375f07217035ddef7bacbda34"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://github.com/symfony/Validator/archive/256bc3a6cb2beae375f07217035ddef7bacbda34.zip",
+                "reference": "256bc3a6cb2beae375f07217035ddef7bacbda34",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.3.3"
+            },
+            "require-dev": {
+                "symfony/http-foundation": "2.2.*",
+                "symfony/locale": "2.2.*",
+                "symfony/yaml": "2.2.*"
+            },
+            "suggest": {
+                "doctrine/common": ">=2.1,<2.4-dev",
+                "symfony/http-foundation": "2.2.*",
+                "symfony/yaml": "2.2.*"
+            },
+            "time": "2012-11-29 10:32:45",
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "2.2-dev"
+                }
+            },
+            "installation-source": "source",
+            "autoload": {
+                "psr-0": {
+                    "Symfony\\Component\\Validator\\": ""
+                }
+            },
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Fabien Potencier",
+                    "email": "fabien@symfony.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "http://symfony.com/contributors"
+                }
+            ],
+            "description": "Symfony Validator Component",
+            "homepage": "http://symfony.com"
+        },
+        {
             "name": "symfony/yaml",
             "version": "v2.1.0-RC2",
             "target-dir": "Symfony/Component/Yaml",
@@ -869,7 +926,7 @@
 
     ],
     "minimum-stability": "alpha",
-    "stability-flags": [
-
-    ]
+    "stability-flags": {
+        "symfony/validator": 20
+    }
 }
diff --git a/core/vendor/.gitignore b/core/vendor/.gitignore
index 1475637..a4ff0b2 100644
--- a/core/vendor/.gitignore
+++ b/core/vendor/.gitignore
@@ -2,3 +2,6 @@
 symfony/dependency-injection/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services1-1.php
 symfony/class-loader/Symfony/Component/ClassLoader/Tests/Fixtures/php5.4/traits.php
 symfony/dependency-injection/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services11.php
+
+# The resources for the Validator component are not required.
+symfony/validator/Symfony/Component/Validator/Resources
diff --git a/core/vendor/autoload.php b/core/vendor/autoload.php
index 004ba3a..5173263 100644
--- a/core/vendor/autoload.php
+++ b/core/vendor/autoload.php
@@ -4,4 +4,4 @@
 
 require_once __DIR__ . '/composer' . '/autoload_real.php';
 
-return ComposerAutoloaderInit::getLoader();
+return ComposerAutoloaderInit83564e32cf6191bf1e368d3f88550c21::getLoader();
diff --git a/core/vendor/composer/autoload_namespaces.php b/core/vendor/composer/autoload_namespaces.php
index e21abde..789aca0 100644
--- a/core/vendor/composer/autoload_namespaces.php
+++ b/core/vendor/composer/autoload_namespaces.php
@@ -8,6 +8,7 @@
 return array(
     'Twig_' => $vendorDir . '/twig/twig/lib/',
     'Symfony\\Component\\Yaml' => $vendorDir . '/symfony/yaml/',
+    'Symfony\\Component\\Validator' => $vendorDir . '/symfony/validator/',
     'Symfony\\Component\\Serializer' => $vendorDir . '/symfony/serializer/',
     'Symfony\\Component\\Routing' => $vendorDir . '/symfony/routing/',
     'Symfony\\Component\\Process' => $vendorDir . '/symfony/process/',
diff --git a/core/vendor/composer/autoload_real.php b/core/vendor/composer/autoload_real.php
index 9028b73..1e2164d 100644
--- a/core/vendor/composer/autoload_real.php
+++ b/core/vendor/composer/autoload_real.php
@@ -2,19 +2,27 @@
 
 // autoload_real.php generated by Composer
 
-require __DIR__ . '/ClassLoader.php';
-
-class ComposerAutoloaderInit
+class ComposerAutoloaderInit83564e32cf6191bf1e368d3f88550c21
 {
     private static $loader;
 
+    public static function loadClassLoader($class)
+    {
+        if ('Composer\Autoload\ClassLoader' === $class) {
+            require __DIR__ . '/ClassLoader.php';
+        }
+    }
+
     public static function getLoader()
     {
         if (null !== static::$loader) {
             return static::$loader;
         }
 
+        spl_autoload_register(array('ComposerAutoloaderInit83564e32cf6191bf1e368d3f88550c21', 'loadClassLoader'));
         static::$loader = $loader = new \Composer\Autoload\ClassLoader();
+        spl_autoload_unregister(array('ComposerAutoloaderInit83564e32cf6191bf1e368d3f88550c21', 'loadClassLoader'));
+
         $vendorDir = dirname(__DIR__);
         $baseDir = dirname($vendorDir);
 
diff --git a/core/vendor/composer/installed.json b/core/vendor/composer/installed.json
index fc7a619..bd79e6f 100644
--- a/core/vendor/composer/installed.json
+++ b/core/vendor/composer/installed.json
@@ -876,5 +876,63 @@
             "client",
             "Guzzle"
         ]
+    },
+    {
+        "name": "symfony/validator",
+        "version": "dev-master",
+        "version_normalized": "9999999-dev",
+        "target-dir": "Symfony/Component/Validator",
+        "source": {
+            "type": "git",
+            "url": "https://github.com/symfony/Validator",
+            "reference": "256bc3a6cb2beae375f07217035ddef7bacbda34"
+        },
+        "dist": {
+            "type": "zip",
+            "url": "https://github.com/symfony/Validator/archive/256bc3a6cb2beae375f07217035ddef7bacbda34.zip",
+            "reference": "256bc3a6cb2beae375f07217035ddef7bacbda34",
+            "shasum": ""
+        },
+        "require": {
+            "php": ">=5.3.3"
+        },
+        "require-dev": {
+            "symfony/http-foundation": "2.2.*",
+            "symfony/locale": "2.2.*",
+            "symfony/yaml": "2.2.*"
+        },
+        "suggest": {
+            "doctrine/common": ">=2.1,<2.4-dev",
+            "symfony/http-foundation": "2.2.*",
+            "symfony/yaml": "2.2.*"
+        },
+        "time": "2012-11-29 10:32:45",
+        "type": "library",
+        "extra": {
+            "branch-alias": {
+                "dev-master": "2.2-dev"
+            }
+        },
+        "installation-source": "source",
+        "autoload": {
+            "psr-0": {
+                "Symfony\\Component\\Validator\\": ""
+            }
+        },
+        "license": [
+            "MIT"
+        ],
+        "authors": [
+            {
+                "name": "Fabien Potencier",
+                "email": "fabien@symfony.com"
+            },
+            {
+                "name": "Symfony Community",
+                "homepage": "http://symfony.com/contributors"
+            }
+        ],
+        "description": "Symfony Validator Component",
+        "homepage": "http://symfony.com"
     }
 ]
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/.gitignore b/core/vendor/symfony/validator/Symfony/Component/Validator/.gitignore
new file mode 100644
index 0000000..44de97a
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/.gitignore
@@ -0,0 +1,4 @@
+vendor/
+composer.lock
+phpunit.xml
+
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/CHANGELOG.md b/core/vendor/symfony/validator/Symfony/Component/Validator/CHANGELOG.md
new file mode 100644
index 0000000..c56f7ba
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/CHANGELOG.md
@@ -0,0 +1,56 @@
+CHANGELOG
+=========
+
+2.2.0
+-----
+
+ * added a CardScheme validator
+ * added a Luhn validator
+ * moved @api-tags from `Validator` to `ValidatorInterface`
+ * moved @api-tags from `ConstraintViolation` to the new `ConstraintViolationInterface`
+ * moved @api-tags from `ConstraintViolationList` to the new `ConstraintViolationListInterface`
+ * moved @api-tags from `ExecutionContext` to the new `ExecutionContextInterface`
+ * [BC BREAK] `ConstraintValidatorInterface::initialize` is now type hinted against `ExecutionContextInterface` instead of `ExecutionContext`
+ * [BC BREAK] changed the visibility of the properties in `Validator` from protected to private
+ * deprecated `ClassMetadataFactoryInterface` in favor of the new `MetadataFactoryInterface`
+ * deprecated `ClassMetadataFactory::getClassMetadata` in favor of `getMetadataFor`
+ * created `MetadataInterface`, `PropertyMetadataInterface`, `ClassBasedInterface` and `PropertyMetadataContainerInterface`
+ * deprecated `GraphWalker` in favor of the new `ValidationVisitorInterface`
+ * deprecated `ExecutionContext::addViolationAtPath`
+ * deprecated `ExecutionContext::addViolationAtSubPath` in favor of `ExecutionContextInterface::addViolationAt`
+ * deprecated `ExecutionContext::getCurrentClass` in favor of `ExecutionContextInterface::getClassName`
+ * deprecated `ExecutionContext::getCurrentProperty` in favor of `ExecutionContextInterface::getPropertyName`
+ * deprecated `ExecutionContext::getCurrentValue` in favor of `ExecutionContextInterface::getValue`
+ * deprecated `ExecutionContext::getGraphWalker` in favor of `ExecutionContextInterface::validate` and `ExecutionContextInterface::validateValue`
+ * improved `ValidatorInterface::validateValue` to accept arrays of constraints
+ * changed `ValidatorInterface::getMetadataFactory` to return a `MetadataFactoryInterface` instead of a `ClassMetadataFactoryInterface`
+ * removed `ClassMetadataFactoryInterface` type hint from `ValidatorBuilderInterface::setMetadataFactory`.
+   As of Symfony 2.3, this method will be typed against `MetadataFactoryInterface` instead.
+
+2.1.0
+-----
+
+ * added support for `ctype_*` assertions in `TypeValidator`
+ * improved the ImageValidator with min width, max width, min height, and max height constraints
+ * added support for MIME with wildcard in FileValidator
+ * changed Collection validator to add "missing" and "extra" errors to
+   individual fields
+ * changed default value for `extraFieldsMessage` and `missingFieldsMessage`
+   in Collection constraint
+ * made ExecutionContext immutable
+ * deprecated Constraint methods `setMessage`, `getMessageTemplate` and
+   `getMessageParameters`
+ * added support for dynamic group sequences with the GroupSequenceProvider pattern
+ * [BC BREAK] ConstraintValidatorInterface method `isValid` has been renamed to
+   `validate`, its return value was dropped. ConstraintValidator still contains
+   `isValid` for BC
+ * [BC BREAK] collections in fields annotated with `Valid` are not traversed
+   recursively anymore by default. `Valid` contains a new property `deep`
+   which enables the BC behavior.
+ * added Count constraint
+ * added Length constraint
+ * added Range constraint
+ * deprecated the Min and Max constraints
+ * deprecated the MinLength and MaxLength constraints
+ * added Validation and ValidatorBuilderInterface
+ * deprecated ValidatorContext, ValidatorContextInterface and ValidatorFactory
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/ClassBasedInterface.php b/core/vendor/symfony/validator/Symfony/Component/Validator/ClassBasedInterface.php
new file mode 100644
index 0000000..c8fa25d
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/ClassBasedInterface.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\Validator;
+
+/**
+ * An object backed by a PHP class.
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+interface ClassBasedInterface
+{
+    /**
+     * Returns the name of the backing PHP class.
+     *
+     * @return string The name of the backing class.
+     */
+    public function getClassName();
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Constraint.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraint.php
new file mode 100644
index 0000000..6c568aa
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraint.php
@@ -0,0 +1,220 @@
+<?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\Validator;
+
+use Symfony\Component\Validator\Exception\InvalidOptionsException;
+use Symfony\Component\Validator\Exception\MissingOptionsException;
+use Symfony\Component\Validator\Exception\ConstraintDefinitionException;
+
+/**
+ * Contains the properties of a constraint definition.
+ *
+ * A constraint can be defined on a class, an option or a getter method.
+ * The Constraint class encapsulates all the configuration required for
+ * validating this class, option or getter result successfully.
+ *
+ * Constraint instances are immutable and serializable.
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @api
+ */
+abstract class Constraint
+{
+    /**
+     * The name of the group given to all constraints with no explicit group
+     * @var string
+     */
+    const DEFAULT_GROUP = 'Default';
+
+    /**
+     * Marks a constraint that can be put onto classes
+     * @var string
+     */
+    const CLASS_CONSTRAINT = 'class';
+
+    /**
+     * Marks a constraint that can be put onto properties
+     * @var string
+     */
+    const PROPERTY_CONSTRAINT = 'property';
+
+    /**
+     * @var array
+     */
+    public $groups = array(self::DEFAULT_GROUP);
+
+    /**
+     * Initializes the constraint with options.
+     *
+     * You should pass an associative array. The keys should be the names of
+     * existing properties in this class. The values should be the value for these
+     * properties.
+     *
+     * Alternatively you can override the method getDefaultOption() to return the
+     * name of an existing property. If no associative array is passed, this
+     * property is set instead.
+     *
+     * You can force that certain options are set by overriding
+     * getRequiredOptions() to return the names of these options. If any
+     * option is not set here, an exception is thrown.
+     *
+     * @param mixed $options The options (as associative array)
+     *                       or the value for the default
+     *                       option (any other type)
+     *
+     * @throws InvalidOptionsException       When you pass the names of non-existing
+     *                                       options
+     * @throws MissingOptionsException       When you don't pass any of the options
+     *                                       returned by getRequiredOptions()
+     * @throws ConstraintDefinitionException When you don't pass an associative
+     *                                       array, but getDefaultOption() returns
+     *                                       NULL
+     *
+     * @api
+     */
+    public function __construct($options = null)
+    {
+        $invalidOptions = array();
+        $missingOptions = array_flip((array) $this->getRequiredOptions());
+
+        if (is_array($options) && count($options) == 1 && isset($options['value'])) {
+            $options = $options['value'];
+        }
+
+        if (is_array($options) && count($options) > 0 && is_string(key($options))) {
+            foreach ($options as $option => $value) {
+                if (property_exists($this, $option)) {
+                    $this->$option = $value;
+                    unset($missingOptions[$option]);
+                } else {
+                    $invalidOptions[] = $option;
+                }
+            }
+        } elseif (null !== $options && ! (is_array($options) && count($options) === 0)) {
+            $option = $this->getDefaultOption();
+
+            if (null === $option) {
+                throw new ConstraintDefinitionException(
+                    sprintf('No default option is configured for constraint %s', get_class($this))
+                );
+            }
+
+            if (property_exists($this, $option)) {
+                $this->$option = $options;
+                unset($missingOptions[$option]);
+            } else {
+                $invalidOptions[] = $option;
+            }
+        }
+
+        if (count($invalidOptions) > 0) {
+            throw new InvalidOptionsException(
+                sprintf('The options "%s" do not exist in constraint %s', implode('", "', $invalidOptions), get_class($this)),
+                $invalidOptions
+            );
+        }
+
+        if (count($missingOptions) > 0) {
+            throw new MissingOptionsException(
+                sprintf('The options "%s" must be set for constraint %s', implode('", "', array_keys($missingOptions)), get_class($this)),
+                array_keys($missingOptions)
+            );
+        }
+
+        $this->groups = (array) $this->groups;
+    }
+
+    /**
+     * Unsupported operation.
+     */
+    public function __set($option, $value)
+    {
+        throw new InvalidOptionsException(sprintf('The option "%s" does not exist in constraint %s', $option, get_class($this)), array($option));
+    }
+
+    /**
+     * Adds the given group if this constraint is in the Default group
+     *
+     * @param string $group
+     *
+     * @api
+     */
+    public function addImplicitGroupName($group)
+    {
+        if (in_array(Constraint::DEFAULT_GROUP, $this->groups) && !in_array($group, $this->groups)) {
+            $this->groups[] = $group;
+        }
+    }
+
+    /**
+     * Returns the name of the default option
+     *
+     * Override this method to define a default option.
+     *
+     * @return string
+     * @see __construct()
+     *
+     * @api
+     */
+    public function getDefaultOption()
+    {
+        return null;
+    }
+
+    /**
+     * Returns the name of the required options
+     *
+     * Override this method if you want to define required options.
+     *
+     * @return array
+     * @see __construct()
+     *
+     * @api
+     */
+    public function getRequiredOptions()
+    {
+        return array();
+    }
+
+    /**
+     * Returns the name of the class that validates this constraint
+     *
+     * By default, this is the fully qualified name of the constraint class
+     * suffixed with "Validator". You can override this method to change that
+     * behaviour.
+     *
+     * @return string
+     *
+     * @api
+     */
+    public function validatedBy()
+    {
+        return get_class($this).'Validator';
+    }
+
+    /**
+     * Returns whether the constraint can be put onto classes, properties or
+     * both
+     *
+     * This method should return one or more of the constants
+     * Constraint::CLASS_CONSTRAINT and Constraint::PROPERTY_CONSTRAINT.
+     *
+     * @return string|array  One or more constant values
+     *
+     * @api
+     */
+    public function getTargets()
+    {
+        return self::PROPERTY_CONSTRAINT;
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/ConstraintValidator.php b/core/vendor/symfony/validator/Symfony/Component/Validator/ConstraintValidator.php
new file mode 100644
index 0000000..cf58c70
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/ConstraintValidator.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\Validator;
+
+use Symfony\Component\Validator\Exception\ValidatorException;
+
+/**
+ * Base class for constraint validators
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @api
+ */
+abstract class ConstraintValidator implements ConstraintValidatorInterface
+{
+    /**
+     * @var ExecutionContextInterface
+     */
+    protected $context;
+
+    /**
+     * @var string
+     *
+     * @deprecated
+     */
+    private $messageTemplate;
+
+    /**
+     * @var array
+     *
+     * @deprecated
+     */
+    private $messageParameters;
+
+    /**
+     * {@inheritDoc}
+     */
+    public function initialize(ExecutionContextInterface $context)
+    {
+        $this->context = $context;
+        $this->messageTemplate = '';
+        $this->messageParameters = array();
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @deprecated Deprecated since version 2.1, to be removed in 2.3.
+     */
+    public function getMessageTemplate()
+    {
+        return $this->messageTemplate;
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @deprecated Deprecated since version 2.1, to be removed in 2.3.
+     */
+    public function getMessageParameters()
+    {
+        return $this->messageParameters;
+    }
+
+    /**
+     * Wrapper for $this->context->addViolation()
+     *
+     * @deprecated Deprecated since version 2.1, to be removed in 2.3.
+     */
+    protected function setMessage($template, array $parameters = array())
+    {
+        $this->messageTemplate = $template;
+        $this->messageParameters = $parameters;
+
+        if (!$this->context instanceof ExecutionContext) {
+            throw new ValidatorException('ConstraintValidator::initialize() must be called before setting violation messages');
+        }
+
+        $this->context->addViolation($template, $parameters);
+    }
+
+    /**
+     * Stub implementation delegating to the deprecated isValid method.
+     *
+     * This stub exists for BC and will be dropped in Symfony 2.3.
+     *
+     * @see ConstraintValidatorInterface::validate
+     */
+    public function validate($value, Constraint $constraint)
+    {
+        return $this->isValid($value, $constraint);
+    }
+
+    /**
+     * BC variant of validate.
+     *
+     * @deprecated Deprecated since version 2.1, to be removed in 2.3.
+     */
+    protected function isValid($value, Constraint $constraint)
+    {
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/ConstraintValidatorFactory.php b/core/vendor/symfony/validator/Symfony/Component/Validator/ConstraintValidatorFactory.php
new file mode 100644
index 0000000..f297cc8
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/ConstraintValidatorFactory.php
@@ -0,0 +1,41 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator;
+
+use Symfony\Component\Validator\ConstraintValidatorFactoryInterface;
+use Symfony\Component\Validator\Constraint;
+
+/**
+ * Default implementation of the ConstraintValidatorFactoryInterface.
+ *
+ * This enforces the convention that the validatedBy() method on any
+ * Constrain will return the class name of the ConstraintValidator that
+ * should validate the Constraint.
+ */
+class ConstraintValidatorFactory implements ConstraintValidatorFactoryInterface
+{
+    protected $validators = array();
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getInstance(Constraint $constraint)
+    {
+        $className = $constraint->validatedBy();
+
+        if (!isset($this->validators[$className])) {
+            $this->validators[$className] = new $className();
+        }
+
+        return $this->validators[$className];
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/ConstraintValidatorFactoryInterface.php b/core/vendor/symfony/validator/Symfony/Component/Validator/ConstraintValidatorFactoryInterface.php
new file mode 100644
index 0000000..584f980
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/ConstraintValidatorFactoryInterface.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\Validator;
+
+use Symfony\Component\Validator\Constraint;
+
+/**
+ * Specifies an object able to return the correct ConstraintValidatorInterface
+ * instance given a Constrain object.
+ */
+interface ConstraintValidatorFactoryInterface
+{
+    /**
+     * Given a Constraint, this returns the ConstraintValidatorInterface
+     * object that should be used to verify its validity.
+     *
+     * @param Constraint $constraint The source constraint
+     *
+     * @return ConstraintValidatorInterface
+     */
+    public function getInstance(Constraint $constraint);
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/ConstraintValidatorInterface.php b/core/vendor/symfony/validator/Symfony/Component/Validator/ConstraintValidatorInterface.php
new file mode 100644
index 0000000..f7538a1
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/ConstraintValidatorInterface.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\Validator;
+
+/**
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @api
+ */
+interface ConstraintValidatorInterface
+{
+    /**
+     * Initializes the constraint validator.
+     *
+     * @param ExecutionContextInterface $context The current validation context
+     */
+    public function initialize(ExecutionContextInterface $context);
+
+    /**
+     * Checks if the passed value is valid.
+     *
+     * @param mixed      $value      The value that should be validated
+     * @param Constraint $constraint The constraint for the validation
+     *
+     * @api
+     */
+    public function validate($value, Constraint $constraint);
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/ConstraintViolation.php b/core/vendor/symfony/validator/Symfony/Component/Validator/ConstraintViolation.php
new file mode 100644
index 0000000..7b6f1e1
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/ConstraintViolation.php
@@ -0,0 +1,177 @@
+<?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\Validator;
+
+/**
+ * Default implementation of {@ConstraintViolationInterface}.
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+class ConstraintViolation implements ConstraintViolationInterface
+{
+    /**
+     * @var string
+     */
+    private $messageTemplate;
+
+    /**
+     * @var array
+     */
+    private $messageParameters;
+
+    /**
+     * @var integer|null
+     */
+    private $messagePluralization;
+
+    /**
+     * @var mixed
+     */
+    private $root;
+
+    /**
+     * @var string
+     */
+    private $propertyPath;
+
+    /**
+     * @var mixed
+     */
+    private $invalidValue;
+
+    /**
+     * @var mixed
+     */
+    private $code;
+
+    /**
+     * Creates a new constraint violation.
+     *
+     * @param string       $messageTemplate       The raw violation message.
+     * @param array        $messageParameters     The parameters to substitute
+     *                                            in the raw message.
+     * @param mixed        $root                  The value originally passed
+     *                                            to the validator.
+     * @param string       $propertyPath          The property path from the
+     *                                            root value to the invalid
+     *                                            value.
+     * @param mixed        $invalidValue          The invalid value causing the
+     *                                            violation.
+     * @param integer|null $messagePluralization  The pluralization parameter.
+     * @param mixed        $code                  The error code of the
+     *                                            violation, if any.
+     */
+    public function __construct($messageTemplate, array $messageParameters, $root, $propertyPath, $invalidValue, $messagePluralization = null, $code = null)
+    {
+        $this->messageTemplate = $messageTemplate;
+        $this->messageParameters = $messageParameters;
+        $this->messagePluralization = $messagePluralization;
+        $this->root = $root;
+        $this->propertyPath = $propertyPath;
+        $this->invalidValue = $invalidValue;
+        $this->code = $code;
+    }
+
+    /**
+     * Converts the violation into a string for debugging purposes.
+     *
+     * @return string The violation as string.
+     */
+    public function __toString()
+    {
+        $class = (string) (is_object($this->root) ? get_class($this->root) : $this->root);
+        $propertyPath = (string) $this->propertyPath;
+        $code = $this->code;
+
+        if ('' !== $propertyPath && '[' !== $propertyPath[0] && '' !== $class) {
+            $class .= '.';
+        }
+
+        if (!empty($code)) {
+            $code = ' (code ' . $code . ')';
+        }
+
+        return $class . $propertyPath . ":\n    " . $this->getMessage() . $code;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getMessageTemplate()
+    {
+        return $this->messageTemplate;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getMessageParameters()
+    {
+        return $this->messageParameters;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getMessagePluralization()
+    {
+        return $this->messagePluralization;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getMessage()
+    {
+        $parameters = $this->messageParameters;
+
+        foreach ($parameters as $i => $parameter) {
+            if (is_array($parameter)) {
+                $parameters[$i] = 'Array';
+            }
+        }
+
+        return strtr($this->messageTemplate, $parameters);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getRoot()
+    {
+        return $this->root;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getPropertyPath()
+    {
+        return $this->propertyPath;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getInvalidValue()
+    {
+        return $this->invalidValue;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getCode()
+    {
+        return $this->code;
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/ConstraintViolationInterface.php b/core/vendor/symfony/validator/Symfony/Component/Validator/ConstraintViolationInterface.php
new file mode 100644
index 0000000..cf1d5b9
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/ConstraintViolationInterface.php
@@ -0,0 +1,136 @@
+<?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\Validator;
+
+/**
+ * A violation of a constraint that happened during validation.
+ *
+ * For each constraint that fails during validation one or more violations are
+ * created. The violations store the violation message, the path to the failing
+ * element in the validation graph and the root element that was originally
+ * passed to the validator. For example, take the following graph:
+ *
+ * <pre>
+ * (Person)---(firstName: string)
+ *      \
+ *   (address: Address)---(street: string)
+ * </pre>
+ *
+ * If the <tt>Person</tt> object is validated and validation fails for the
+ * "firstName" property, the generated violation has the <tt>Person</tt>
+ * instance as root and the property path "firstName". If validation fails
+ * for the "street" property of the related <tt>Address</tt> instance, the root
+ * element is still the person, but the property path is "address.street".
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @api
+ */
+interface ConstraintViolationInterface
+{
+    /**
+     * Returns the violation message.
+     *
+     * @return string The violation message.
+     *
+     * @api
+     */
+    public function getMessage();
+
+    /**
+     * Returns the raw violation message.
+     *
+     * The raw violation message contains placeholders for the parameters
+     * returned by {@link getMessageParameters}. Typically you'll pass the
+     * message template and parameters to a translation engine.
+     *
+     * @return string The raw violation message.
+     *
+     * @api
+     */
+    public function getMessageTemplate();
+
+    /**
+     * Returns the parameters to be inserted into the raw violation message.
+     *
+     * @return array A possibly empty list of parameters indexed by the names
+     *               that appear in the message template.
+     *
+     * @see getMessageTemplate
+     *
+     * @api
+     */
+    public function getMessageParameters();
+
+    /**
+     * Returns a number for pluralizing the violation message.
+     *
+     * For example, the message template could have different translation based
+     * on a parameter "choices":
+     *
+     * <ul>
+     * <li>Please select exactly one entry. (choices=1)</li>
+     * <li>Please select two entries. (choices=2)</li>
+     * </ul>
+     *
+     * This method returns the value of the parameter for choosing the right
+     * pluralization form (in this case "choices").
+     *
+     * @return integer|null The number to use to pluralize of the message.
+     */
+    public function getMessagePluralization();
+
+    /**
+     * Returns the root element of the validation.
+     *
+     * @return mixed The value that was passed originally to the validator when
+     *               the validation was started. Because the validator traverses
+     *               the object graph, the value at which the violation occurs
+     *               is not necessarily the value that was originally validated.
+     *
+     * @api
+     */
+    public function getRoot();
+
+    /**
+     * Returns the property path from the root element to the violation.
+     *
+     * @return string The property path indicates how the validator reached
+     *                the invalid value from the root element. If the root
+     *                element is a <tt>Person</tt> instance with a property
+     *                "address" that contains an <tt>Address</tt> instance
+     *                with an invalid property "street", the generated property
+     *                path is "address.street". Property access is denoted by
+     *                dots, while array access is denoted by square brackets,
+     *                for example "addresses[1].street".
+     *
+     * @api
+     */
+    public function getPropertyPath();
+
+    /**
+     * Returns the value that caused the violation.
+     *
+     * @return mixed The invalid value that caused the validated constraint to
+     *               fail.
+     *
+     * @api
+     */
+    public function getInvalidValue();
+
+    /**
+     * Returns a machine-digestible error code for the violation.
+     *
+     * @return mixed The error code.
+     */
+    public function getCode();
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/ConstraintViolationList.php b/core/vendor/symfony/validator/Symfony/Component/Validator/ConstraintViolationList.php
new file mode 100644
index 0000000..ef5a196
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/ConstraintViolationList.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\Validator;
+
+/**
+ * Default implementation of {@ConstraintViolationListInterface}.
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+class ConstraintViolationList implements \IteratorAggregate, ConstraintViolationListInterface
+{
+    /**
+     * @var ConstraintViolationInterface[]
+     */
+    private $violations = array();
+
+    /**
+     * Creates a new constraint violation list.
+     *
+     * @param ConstraintViolationInterface[] $violations The constraint violations to add to the list
+     */
+    public function __construct(array $violations = array())
+    {
+        foreach ($violations as $violation) {
+            $this->add($violation);
+        }
+    }
+
+    /**
+     * Converts the violation into a string for debugging purposes.
+     *
+     * @return string The violation as string.
+     */
+    public function __toString()
+    {
+        $string = '';
+
+        foreach ($this->violations as $violation) {
+            $string .= $violation . "\n";
+        }
+
+        return $string;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function add(ConstraintViolationInterface $violation)
+    {
+        $this->violations[] = $violation;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function addAll(ConstraintViolationListInterface $otherList)
+    {
+        foreach ($otherList as $violation) {
+            $this->violations[] = $violation;
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function get($offset)
+    {
+        if (!isset($this->violations[$offset])) {
+            throw new \OutOfBoundsException(sprintf('The offset "%s" does not exist.', $offset));
+        }
+
+        return $this->violations[$offset];
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function has($offset)
+    {
+        return isset($this->violations[$offset]);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function set($offset, ConstraintViolationInterface $violation)
+    {
+        $this->violations[$offset] = $violation;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function remove($offset)
+    {
+        unset($this->violations[$offset]);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getIterator()
+    {
+        return new \ArrayIterator($this->violations);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function count()
+    {
+        return count($this->violations);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function offsetExists($offset)
+    {
+        return $this->has($offset);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function offsetGet($offset)
+    {
+        return $this->get($offset);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function offsetSet($offset, $violation)
+    {
+        if (null === $offset) {
+            $this->add($violation);
+        } else {
+            $this->set($offset, $violation);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function offsetUnset($offset)
+    {
+        $this->remove($offset);
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/ConstraintViolationListInterface.php b/core/vendor/symfony/validator/Symfony/Component/Validator/ConstraintViolationListInterface.php
new file mode 100644
index 0000000..21b857e
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/ConstraintViolationListInterface.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\Validator;
+
+/**
+ * A list of constraint violations.
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @api
+ */
+interface ConstraintViolationListInterface extends \Traversable, \Countable, \ArrayAccess
+{
+    /**
+     * Adds a constraint violation to this list.
+     *
+     * @param ConstraintViolationInterface $violation The violation to add.
+     *
+     * @api
+     */
+    public function add(ConstraintViolationInterface $violation);
+
+    /**
+     * Merges an existing violation list into this list.
+     *
+     * @param ConstraintViolationListInterface $otherList The list to merge.
+     *
+     * @api
+     */
+    public function addAll(ConstraintViolationListInterface $otherList);
+
+    /**
+     * Returns the violation at a given offset.
+     *
+     * @param  integer $offset The offset of the violation.
+     *
+     * @return ConstraintViolationInterface The violation.
+     *
+     * @throws \OutOfBoundsException If the offset does not exist.
+     *
+     * @api
+     */
+    public function get($offset);
+
+    /**
+     * Returns whether the given offset exists.
+     *
+     * @param  integer $offset The violation offset.
+     *
+     * @return Boolean Whether the offset exists.
+     *
+     * @api
+     */
+    public function has($offset);
+
+    /**
+     * Sets a violation at a given offset.
+     *
+     * @param integer                      $offset    The violation offset.
+     * @param ConstraintViolationInterface $violation The violation.
+     *
+     * @api
+     */
+    public function set($offset, ConstraintViolationInterface $violation);
+
+    /**
+     * Removes a violation at a given offset.
+     *
+     * @param integer $offset The offset to remove.
+     *
+     * @api
+     */
+    public function remove($offset);
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/All.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/All.php
new file mode 100644
index 0000000..612aaf2
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/All.php
@@ -0,0 +1,57 @@
+<?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\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\Exception\ConstraintDefinitionException;
+
+/**
+ * @Annotation
+ *
+ * @api
+ */
+class All extends Constraint
+{
+    public $constraints = array();
+
+    /**
+     * {@inheritDoc}
+     */
+    public function __construct($options = null)
+    {
+        parent::__construct($options);
+
+        if (!is_array($this->constraints)) {
+            $this->constraints = array($this->constraints);
+        }
+
+        foreach ($this->constraints as $constraint) {
+            if (!$constraint instanceof Constraint) {
+                throw new ConstraintDefinitionException('The value ' . $constraint . ' is not an instance of Constraint in constraint ' . __CLASS__);
+            }
+
+            if ($constraint instanceof Valid) {
+                throw new ConstraintDefinitionException('The constraint Valid cannot be nested inside constraint ' . __CLASS__ . '. You can only declare the Valid constraint directly on a field or method.');
+            }
+        }
+    }
+
+    public function getDefaultOption()
+    {
+        return 'constraints';
+    }
+
+    public function getRequiredOptions()
+    {
+        return array('constraints');
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/AllValidator.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/AllValidator.php
new file mode 100644
index 0000000..622a90b
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/AllValidator.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\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\ConstraintValidator;
+use Symfony\Component\Validator\Exception\UnexpectedTypeException;
+
+/**
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @api
+ */
+class AllValidator extends ConstraintValidator
+{
+    /**
+     * {@inheritDoc}
+     */
+    public function validate($value, Constraint $constraint)
+    {
+        if (null === $value) {
+            return;
+        }
+
+        if (!is_array($value) && !$value instanceof \Traversable) {
+            throw new UnexpectedTypeException($value, 'array or Traversable');
+        }
+
+        $walker = $this->context->getGraphWalker();
+        $group = $this->context->getGroup();
+        $propertyPath = $this->context->getPropertyPath();
+
+        foreach ($value as $key => $element) {
+            foreach ($constraint->constraints as $constr) {
+                $walker->walkConstraint($constr, $element, $group, $propertyPath.'['.$key.']');
+            }
+        }
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Blank.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Blank.php
new file mode 100644
index 0000000..b6db62a
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Blank.php
@@ -0,0 +1,24 @@
+<?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\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+
+/**
+ * @Annotation
+ *
+ * @api
+ */
+class Blank extends Constraint
+{
+    public $message = 'This value should be blank.';
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/BlankValidator.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/BlankValidator.php
new file mode 100644
index 0000000..0a67358
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/BlankValidator.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\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\ConstraintValidator;
+
+/**
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @api
+ */
+class BlankValidator extends ConstraintValidator
+{
+    /**
+     * {@inheritDoc}
+     */
+    public function validate($value, Constraint $constraint)
+    {
+        if ('' !== $value && null !== $value) {
+            $this->context->addViolation($constraint->message, array('{{ value }}' => $value));
+        }
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Callback.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Callback.php
new file mode 100644
index 0000000..4470b70
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Callback.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\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+
+/**
+ * @Annotation
+ *
+ * @api
+ */
+class Callback extends Constraint
+{
+    public $methods;
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getRequiredOptions()
+    {
+        return array('methods');
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getDefaultOption()
+    {
+        return 'methods';
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getTargets()
+    {
+        return self::CLASS_CONSTRAINT;
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/CallbackValidator.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/CallbackValidator.php
new file mode 100644
index 0000000..ab3c56f
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/CallbackValidator.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\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\ConstraintValidator;
+use Symfony\Component\Validator\Exception\UnexpectedTypeException;
+use Symfony\Component\Validator\Exception\ConstraintDefinitionException;
+
+/**
+ * Validator for Callback constraint
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @api
+ */
+class CallbackValidator extends ConstraintValidator
+{
+    /**
+     * {@inheritDoc}
+     */
+    public function validate($object, Constraint $constraint)
+    {
+        if (null === $object) {
+            return;
+        }
+
+        // has to be an array so that we can differentiate between callables
+        // and method names
+        if (!is_array($constraint->methods)) {
+            throw new UnexpectedTypeException($constraint->methods, 'array');
+        }
+
+        $methods = $constraint->methods;
+
+        foreach ($methods as $method) {
+            if (is_array($method) || $method instanceof \Closure) {
+                if (!is_callable($method)) {
+                    throw new ConstraintDefinitionException(sprintf('"%s::%s" targeted by Callback constraint is not a valid callable', $method[0], $method[1]));
+                }
+
+                call_user_func($method, $object, $this->context);
+            } else {
+                if (!method_exists($object, $method)) {
+                    throw new ConstraintDefinitionException(sprintf('Method "%s" targeted by Callback constraint does not exist', $method));
+                }
+
+                $object->$method($this->context);
+            }
+        }
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/CardScheme.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/CardScheme.php
new file mode 100644
index 0000000..356cad9
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/CardScheme.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\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+
+/**
+ * Metadata for the CardSchemeValidator.
+ *
+ * @Annotation
+ */
+class CardScheme extends Constraint
+{
+    public $message = 'Unsupported card type or invalid card number';
+    public $schemes;
+
+    public function getDefaultOption()
+    {
+        return 'schemes';
+    }
+
+    public function getRequiredOptions()
+    {
+        return array('schemes');
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/CardSchemeValidator.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/CardSchemeValidator.php
new file mode 100644
index 0000000..97b4567
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/CardSchemeValidator.php
@@ -0,0 +1,92 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\ConstraintValidator;
+
+/**
+ * Validates that a card number belongs to a specified scheme.
+ *
+ * @see http://en.wikipedia.org/wiki/Bank_card_number
+ * @author Tim Nagel <t.nagel@infinite.net.au>
+ */
+class CardSchemeValidator extends ConstraintValidator
+{
+    protected $schemes = array(
+        'AMEX' => array(
+            '/^(3[47])([0-9]{13})/'
+        ),
+        'CHINA_UNIONPAY' => array(
+            '/^(62)([0-9]{16,19}/'
+        ),
+        'DINERS' => array(
+            '/^(36)([0-9]{12})/',
+            '/^(30[0-5])([0-9]{11})/',
+            '/^(5[45])([0-9]{14})/'
+        ),
+        'DISCOVER' => array(
+            '/^(6011)([0-9]{12})/',
+            '/^(64[4-9])([0-9]{13})/',
+            '/^(65)([0-9]{14})/',
+            '/^(622)(12[6-9]|1[3-9][0-9]|[2-8][0-9][0-9]|91[0-9]|92[0-5])([0-9]{10})/'
+        ),
+        'INSTAPAYMENT' => array(
+            '/^(63[7-9])([0-9]{13})/'
+        ),
+        'JCB' => array(
+            '/^(352[8-9]|35[3-8][0-9])([0-9]{12})/'
+        ),
+        'LASER' => array(
+            '/^(6304|670[69]|6771)([0-9]{12, 15})/'
+        ),
+        'MAESTRO' => array(
+            '/^(5018|5020|5038|6304|6759|6761|676[23]|0604)([0-9]{8, 15})/'
+        ),
+        'MASTERCARD' => array(
+            '/^(5[1-5])([0-9]{14})/'
+        ),
+        'VISA' => array(
+            '/^(4)([0-9]{12})/'
+        ),
+    );
+
+    /**
+     * Validates a creditcard belongs to a specified scheme.
+     *
+     * @param mixed $value
+     * @param Constraint $constraint
+     */
+    public function validate($value, Constraint $constraint)
+    {
+        if (null === $value || '' === $value) {
+            return;
+        }
+
+        if (!is_numeric($value)) {
+            $this->context->addViolation($constraint->message);
+        }
+
+        $schemes = array_flip($constraint->schemes);
+        $schemeRegexes = array_intersect_key($this->schemes, $schemes);
+
+        foreach ($schemeRegexes as $regexes) {
+            foreach ($regexes as $regex) {
+                if (preg_match($regex, $value)) {
+                    return;
+                }
+            }
+        }
+
+        $this->context->addViolation($constraint->message);
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Choice.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Choice.php
new file mode 100644
index 0000000..b73bd77
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Choice.php
@@ -0,0 +1,41 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+
+/**
+ * @Annotation
+ *
+ * @api
+ */
+class Choice extends Constraint
+{
+    public $choices;
+    public $callback;
+    public $multiple = false;
+    public $strict = false;
+    public $min = null;
+    public $max = null;
+    public $message = 'The value you selected is not a valid choice.';
+    public $multipleMessage = 'One or more of the given values is invalid.';
+    public $minMessage = 'You must select at least {{ limit }} choices.';
+    public $maxMessage = 'You must select at most {{ limit }} choices.';
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getDefaultOption()
+    {
+        return 'choices';
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/ChoiceValidator.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/ChoiceValidator.php
new file mode 100644
index 0000000..96e2833
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/ChoiceValidator.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\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\ConstraintValidator;
+use Symfony\Component\Validator\Exception\ConstraintDefinitionException;
+use Symfony\Component\Validator\Exception\UnexpectedTypeException;
+
+/**
+ * ChoiceValidator validates that the value is one of the expected values.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ * @author Florian Eckerstorfer <florian@eckerstorfer.org>
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @api
+ */
+class ChoiceValidator extends ConstraintValidator
+{
+    /**
+     * {@inheritDoc}
+     */
+    public function validate($value, Constraint $constraint)
+    {
+        if (!$constraint->choices && !$constraint->callback) {
+            throw new ConstraintDefinitionException('Either "choices" or "callback" must be specified on constraint Choice');
+        }
+
+        if (null === $value) {
+            return;
+        }
+
+        if ($constraint->multiple && !is_array($value)) {
+            throw new UnexpectedTypeException($value, 'array');
+        }
+
+        if ($constraint->callback) {
+            if (is_callable(array($this->context->getCurrentClass(), $constraint->callback))) {
+                $choices = call_user_func(array($this->context->getCurrentClass(), $constraint->callback));
+            } elseif (is_callable($constraint->callback)) {
+                $choices = call_user_func($constraint->callback);
+            } else {
+                throw new ConstraintDefinitionException('The Choice constraint expects a valid callback');
+            }
+        } else {
+            $choices = $constraint->choices;
+        }
+
+        if ($constraint->multiple) {
+            foreach ($value as $_value) {
+                if (!in_array($_value, $choices, $constraint->strict)) {
+                    $this->context->addViolation($constraint->multipleMessage, array('{{ value }}' => $_value));
+                }
+            }
+
+            $count = count($value);
+
+            if ($constraint->min !== null && $count < $constraint->min) {
+                $this->context->addViolation($constraint->minMessage, array('{{ limit }}' => $constraint->min), null, (int) $constraint->min);
+
+                return;
+            }
+
+            if ($constraint->max !== null && $count > $constraint->max) {
+                $this->context->addViolation($constraint->maxMessage, array('{{ limit }}' => $constraint->max), null, (int) $constraint->max);
+
+                return;
+            }
+        } elseif (!in_array($value, $choices, $constraint->strict)) {
+            $this->context->addViolation($constraint->message, array('{{ value }}' => $value));
+        }
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Collection.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Collection.php
new file mode 100644
index 0000000..b618b41
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Collection.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\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\Constraints\Collection\Required;
+use Symfony\Component\Validator\Constraints\Collection\Optional;
+use Symfony\Component\Validator\Exception\ConstraintDefinitionException;
+
+/**
+ * @Annotation
+ *
+ * @api
+ */
+class Collection extends Constraint
+{
+    public $fields;
+    public $allowExtraFields = false;
+    public $allowMissingFields = false;
+    public $extraFieldsMessage = 'This field was not expected.';
+    public $missingFieldsMessage = 'This field is missing.';
+
+    /**
+     * {@inheritDoc}
+     */
+    public function __construct($options = null)
+    {
+        // no known options set? $options is the fields array
+        if (is_array($options)
+            && !array_intersect(array_keys($options), array('groups', 'fields', 'allowExtraFields', 'allowMissingFields', 'extraFieldsMessage', 'missingFieldsMessage'))) {
+            $options = array('fields' => $options);
+        }
+
+        parent::__construct($options);
+
+        if (!is_array($this->fields)) {
+            throw new ConstraintDefinitionException('The option "fields" is expected to be an array in constraint ' . __CLASS__);
+        }
+
+        foreach ($this->fields as $fieldName => $field) {
+            if (!$field instanceof Optional && !$field instanceof Required) {
+                $this->fields[$fieldName] = $field = new Required($field);
+            }
+
+            if (!is_array($field->constraints)) {
+                $field->constraints = array($field->constraints);
+            }
+
+            foreach ($field->constraints as $constraint) {
+                if (!$constraint instanceof Constraint) {
+                    throw new ConstraintDefinitionException('The value ' . $constraint . ' of the field ' . $fieldName . ' is not an instance of Constraint in constraint ' . __CLASS__);
+                }
+
+                if ($constraint instanceof Valid) {
+                    throw new ConstraintDefinitionException('The constraint Valid cannot be nested inside constraint ' . __CLASS__ . '. You can only declare the Valid constraint directly on a field or method.');
+                }
+            }
+        }
+    }
+
+    public function getRequiredOptions()
+    {
+        return array('fields');
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Collection/Optional.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Collection/Optional.php
new file mode 100644
index 0000000..8d4c774
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Collection/Optional.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\Validator\Constraints\Collection;
+
+use Symfony\Component\Validator\Constraint;
+
+/**
+ * @Annotation
+ */
+class Optional extends Constraint
+{
+    public $constraints = array();
+
+    public function getDefaultOption()
+    {
+        return 'constraints';
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Collection/Required.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Collection/Required.php
new file mode 100644
index 0000000..5dda743
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Collection/Required.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\Validator\Constraints\Collection;
+
+use Symfony\Component\Validator\Constraint;
+
+/**
+ * @Annotation
+ */
+class Required extends Constraint
+{
+    public $constraints = array();
+
+    public function getDefaultOption()
+    {
+        return 'constraints';
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/CollectionValidator.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/CollectionValidator.php
new file mode 100644
index 0000000..13551f4
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/CollectionValidator.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\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\ConstraintValidator;
+use Symfony\Component\Validator\Exception\UnexpectedTypeException;
+use Symfony\Component\Validator\Constraints\Collection\Optional;
+
+/**
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @api
+ */
+class CollectionValidator extends ConstraintValidator
+{
+    /**
+     * {@inheritDoc}
+     */
+    public function validate($value, Constraint $constraint)
+    {
+        if (null === $value) {
+            return;
+        }
+
+        if (!is_array($value) && !($value instanceof \Traversable && $value instanceof \ArrayAccess)) {
+            throw new UnexpectedTypeException($value, 'array or Traversable and ArrayAccess');
+        }
+
+        $walker = $this->context->getGraphWalker();
+        $group = $this->context->getGroup();
+        $propertyPath = $this->context->getPropertyPath();
+
+        foreach ($constraint->fields as $field => $fieldConstraint) {
+            if (
+                // bug fix issue #2779
+                (is_array($value) && array_key_exists($field, $value)) ||
+                ($value instanceof \ArrayAccess && $value->offsetExists($field))
+            ) {
+                foreach ($fieldConstraint->constraints as $constr) {
+                    $walker->walkConstraint($constr, $value[$field], $group, $propertyPath.'['.$field.']');
+                }
+            } elseif (!$fieldConstraint instanceof Optional && !$constraint->allowMissingFields) {
+                $this->context->addViolationAtSubPath('['.$field.']', $constraint->missingFieldsMessage, array(
+                    '{{ field }}' => $field
+                ), null);
+            }
+        }
+
+        if (!$constraint->allowExtraFields) {
+            foreach ($value as $field => $fieldValue) {
+                if (!isset($constraint->fields[$field])) {
+                    $this->context->addViolationAtSubPath('['.$field.']', $constraint->extraFieldsMessage, array(
+                        '{{ field }}' => $field
+                    ), $fieldValue);
+                }
+            }
+        }
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Count.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Count.php
new file mode 100644
index 0000000..db0661d
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Count.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\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\Exception\MissingOptionsException;
+
+/**
+ * @Annotation
+ *
+ * @api
+ */
+class Count extends Constraint
+{
+    public $minMessage = 'This collection should contain {{ limit }} elements or more.';
+    public $maxMessage = 'This collection should contain {{ limit }} elements or less.';
+    public $exactMessage = 'This collection should contain exactly {{ limit }} elements.';
+    public $min;
+    public $max;
+
+    public function __construct($options = null)
+    {
+        if (null !== $options && !is_array($options)) {
+            $options = array(
+                'min' => $options,
+                'max' => $options,
+            );
+        }
+
+        parent::__construct($options);
+
+        if (null === $this->min && null === $this->max) {
+            throw new MissingOptionsException('Either option "min" or "max" must be given for constraint ' . __CLASS__, array('min', 'max'));
+        }
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/CountValidator.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/CountValidator.php
new file mode 100644
index 0000000..0a3be12
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/CountValidator.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\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\ConstraintValidator;
+use Symfony\Component\Validator\Exception\UnexpectedTypeException;
+
+/**
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+class CountValidator extends ConstraintValidator
+{
+    /**
+     * {@inheritDoc}
+     */
+    public function validate($value, Constraint $constraint)
+    {
+        if (null === $value) {
+            return;
+        }
+
+        if (!is_array($value) && !$value instanceof \Countable) {
+            throw new UnexpectedTypeException($value, 'array or \Countable');
+        }
+
+        $count = count($value);
+
+        if ($constraint->min == $constraint->max && $count != $constraint->min) {
+            $this->context->addViolation($constraint->exactMessage, array(
+                '{{ count }}' => $count,
+                '{{ limit }}' => $constraint->min,
+            ), $value, (int) $constraint->min);
+
+            return;
+        }
+
+        if (null !== $constraint->max && $count > $constraint->max) {
+            $this->context->addViolation($constraint->maxMessage, array(
+                '{{ count }}' => $count,
+                '{{ limit }}' => $constraint->max,
+            ), $value, (int) $constraint->max);
+
+            return;
+        }
+
+        if (null !== $constraint->min && $count < $constraint->min) {
+            $this->context->addViolation($constraint->minMessage, array(
+                '{{ count }}' => $count,
+                '{{ limit }}' => $constraint->min,
+            ), $value, (int) $constraint->min);
+        }
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Country.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Country.php
new file mode 100644
index 0000000..5e81df4
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Country.php
@@ -0,0 +1,24 @@
+<?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\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+
+/**
+ * @Annotation
+ *
+ * @api
+ */
+class Country extends Constraint
+{
+    public $message = 'This value is not a valid country.';
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/CountryValidator.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/CountryValidator.php
new file mode 100644
index 0000000..1d49954
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/CountryValidator.php
@@ -0,0 +1,46 @@
+<?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\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\ConstraintValidator;
+use Symfony\Component\Validator\Exception\UnexpectedTypeException;
+
+/**
+ * Validates whether a value is a valid country code
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @api
+ */
+class CountryValidator extends ConstraintValidator
+{
+    /**
+     * {@inheritDoc}
+     */
+    public function validate($value, Constraint $constraint)
+    {
+        if (null === $value || '' === $value) {
+            return;
+        }
+
+        if (!is_scalar($value) && !(is_object($value) && method_exists($value, '__toString'))) {
+            throw new UnexpectedTypeException($value, 'string');
+        }
+
+        $value = (string) $value;
+
+        if (!in_array($value, \Symfony\Component\Locale\Locale::getCountries())) {
+            $this->context->addViolation($constraint->message, array('{{ value }}' => $value));
+        }
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Date.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Date.php
new file mode 100644
index 0000000..c34851e
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Date.php
@@ -0,0 +1,24 @@
+<?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\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+
+/**
+ * @Annotation
+ *
+ * @api
+ */
+class Date extends Constraint
+{
+    public $message = 'This value is not a valid date.';
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/DateTime.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/DateTime.php
new file mode 100644
index 0000000..a2059b0
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/DateTime.php
@@ -0,0 +1,24 @@
+<?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\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+
+/**
+ * @Annotation
+ *
+ * @api
+ */
+class DateTime extends Constraint
+{
+    public $message = 'This value is not a valid datetime.';
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/DateTimeValidator.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/DateTimeValidator.php
new file mode 100644
index 0000000..49e04b9
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/DateTimeValidator.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\Validator\Constraints;
+
+/**
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @api
+ */
+class DateTimeValidator extends DateValidator
+{
+    const PATTERN = '/^(\d{4})-(\d{2})-(\d{2}) (0[0-9]|1[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$/';
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/DateValidator.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/DateValidator.php
new file mode 100644
index 0000000..f891f9d
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/DateValidator.php
@@ -0,0 +1,46 @@
+<?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\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\ConstraintValidator;
+use Symfony\Component\Validator\Exception\UnexpectedTypeException;
+
+/**
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @api
+ */
+class DateValidator extends ConstraintValidator
+{
+    const PATTERN = '/^(\d{4})-(\d{2})-(\d{2})$/';
+
+    /**
+     * {@inheritDoc}
+     */
+    public function validate($value, Constraint $constraint)
+    {
+        if (null === $value || '' === $value || $value instanceof \DateTime) {
+            return;
+        }
+
+        if (!is_scalar($value) && !(is_object($value) && method_exists($value, '__toString'))) {
+            throw new UnexpectedTypeException($value, 'string');
+        }
+
+        $value = (string) $value;
+
+        if (!preg_match(static::PATTERN, $value, $matches) || !checkdate($matches[2], $matches[3], $matches[1])) {
+            $this->context->addViolation($constraint->message, array('{{ value }}' => $value));
+        }
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Email.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Email.php
new file mode 100644
index 0000000..db250df
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Email.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\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+
+/**
+ * @Annotation
+ *
+ * @api
+ */
+class Email extends Constraint
+{
+    public $message = 'This value is not a valid email address.';
+    public $checkMX = false;
+    public $checkHost = false;
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/EmailValidator.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/EmailValidator.php
new file mode 100644
index 0000000..bfdad09
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/EmailValidator.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\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\ConstraintValidator;
+use Symfony\Component\Validator\Exception\UnexpectedTypeException;
+
+/**
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @api
+ */
+class EmailValidator extends ConstraintValidator
+{
+    /**
+     * {@inheritDoc}
+     */
+    public function validate($value, Constraint $constraint)
+    {
+        if (null === $value || '' === $value) {
+            return;
+        }
+
+        if (!is_scalar($value) && !(is_object($value) && method_exists($value, '__toString'))) {
+            throw new UnexpectedTypeException($value, 'string');
+        }
+
+        $value = (string) $value;
+        $valid = filter_var($value, FILTER_VALIDATE_EMAIL);
+
+        if ($valid) {
+            $host = substr($value, strpos($value, '@') + 1);
+
+            if (version_compare(PHP_VERSION, '5.3.3', '<') && strpos($host, '.') === false) {
+                // Likely not a FQDN, bug in PHP FILTER_VALIDATE_EMAIL prior to PHP 5.3.3
+                $valid = false;
+            }
+
+            // Check for host DNS resource records
+            if ($valid && $constraint->checkMX) {
+                $valid = $this->checkMX($host);
+            } elseif ($valid && $constraint->checkHost) {
+                $valid = $this->checkHost($host);
+            }
+        }
+
+        if (!$valid) {
+            $this->context->addViolation($constraint->message, array('{{ value }}' => $value));
+        }
+    }
+
+    /**
+     * Check DNS Records for MX type.
+     *
+     * @param string $host Hostname
+     *
+     * @return Boolean
+     */
+    private function checkMX($host)
+    {
+        return checkdnsrr($host, 'MX');
+    }
+
+    /**
+     * Check if one of MX, A or AAAA DNS RR exists.
+     *
+     * @param string $host Hostname
+     *
+     * @return Boolean
+     */
+    private function checkHost($host)
+    {
+        return $this->checkMX($host) || (checkdnsrr($host, "A") || checkdnsrr($host, "AAAA"));
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/False.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/False.php
new file mode 100644
index 0000000..1a1f163
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/False.php
@@ -0,0 +1,24 @@
+<?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\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+
+/**
+ * @Annotation
+ *
+ * @api
+ */
+class False extends Constraint
+{
+    public $message = 'This value should be false.';
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/FalseValidator.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/FalseValidator.php
new file mode 100644
index 0000000..7cead61
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/FalseValidator.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\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\ConstraintValidator;
+
+/**
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @api
+ */
+class FalseValidator extends ConstraintValidator
+{
+    /**
+     * {@inheritDoc}
+     */
+    public function validate($value, Constraint $constraint)
+    {
+        if (null === $value || false === $value || 0 === $value || '0' === $value) {
+            return;
+        }
+
+        $this->context->addViolation($constraint->message);
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/File.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/File.php
new file mode 100644
index 0000000..49880ad
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/File.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\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+
+/**
+ * @Annotation
+ *
+ * @api
+ */
+class File extends Constraint
+{
+    public $maxSize = null;
+    public $mimeTypes = array();
+    public $notFoundMessage = 'The file could not be found.';
+    public $notReadableMessage = 'The file is not readable.';
+    public $maxSizeMessage = 'The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}.';
+    public $mimeTypesMessage = 'The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}.';
+
+    public $uploadIniSizeErrorMessage   = 'The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}.';
+    public $uploadFormSizeErrorMessage  = 'The file is too large.';
+    public $uploadPartialErrorMessage   = 'The file was only partially uploaded.';
+    public $uploadNoFileErrorMessage    = 'No file was uploaded.';
+    public $uploadNoTmpDirErrorMessage  = 'No temporary folder was configured in php.ini.';
+    public $uploadCantWriteErrorMessage = 'Cannot write temporary file to disk.';
+    public $uploadExtensionErrorMessage = 'A PHP extension caused the upload to fail.';
+    public $uploadErrorMessage          = 'The file could not be uploaded.';
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/FileValidator.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/FileValidator.php
new file mode 100644
index 0000000..7d68882
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/FileValidator.php
@@ -0,0 +1,158 @@
+<?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\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\ConstraintValidator;
+use Symfony\Component\Validator\Exception\ConstraintDefinitionException;
+use Symfony\Component\Validator\Exception\UnexpectedTypeException;
+use Symfony\Component\HttpFoundation\File\File as FileObject;
+use Symfony\Component\HttpFoundation\File\UploadedFile;
+
+/**
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @api
+ */
+class FileValidator extends ConstraintValidator
+{
+    /**
+     * {@inheritDoc}
+     */
+    public function validate($value, Constraint $constraint)
+    {
+        if (null === $value || '' === $value) {
+            return;
+        }
+
+        if ($value instanceof UploadedFile && !$value->isValid()) {
+            switch ($value->getError()) {
+                case UPLOAD_ERR_INI_SIZE:
+                    $maxSize = UploadedFile::getMaxFilesize();
+                    $maxSize = $constraint->maxSize ? min($maxSize, $constraint->maxSize) : $maxSize;
+                    $this->context->addViolation($constraint->uploadIniSizeErrorMessage, array(
+                        '{{ limit }}' => $maxSize,
+                        '{{ suffix }}' => 'bytes',
+                    ));
+
+                    return;
+                case UPLOAD_ERR_FORM_SIZE:
+                    $this->context->addViolation($constraint->uploadFormSizeErrorMessage);
+
+                    return;
+                case UPLOAD_ERR_PARTIAL:
+                    $this->context->addViolation($constraint->uploadPartialErrorMessage);
+
+                    return;
+                case UPLOAD_ERR_NO_FILE:
+                    $this->context->addViolation($constraint->uploadNoFileErrorMessage);
+
+                    return;
+                case UPLOAD_ERR_NO_TMP_DIR:
+                    $this->context->addViolation($constraint->uploadNoTmpDirErrorMessage);
+
+                    return;
+                case UPLOAD_ERR_CANT_WRITE:
+                    $this->context->addViolation($constraint->uploadCantWriteErrorMessage);
+
+                    return;
+                case UPLOAD_ERR_EXTENSION:
+                    $this->context->addViolation($constraint->uploadExtensionErrorMessage);
+
+                    return;
+                default:
+                    $this->context->addViolation($constraint->uploadErrorMessage);
+
+                    return;
+            }
+        }
+
+        if (!is_scalar($value) && !$value instanceof FileObject && !(is_object($value) && method_exists($value, '__toString'))) {
+            throw new UnexpectedTypeException($value, 'string');
+        }
+
+        $path = $value instanceof FileObject ? $value->getPathname() : (string) $value;
+
+        if (!is_file($path)) {
+            $this->context->addViolation($constraint->notFoundMessage, array('{{ file }}' => $path));
+
+            return;
+        }
+
+        if (!is_readable($path)) {
+            $this->context->addViolation($constraint->notReadableMessage, array('{{ file }}' => $path));
+
+            return;
+        }
+
+        if ($constraint->maxSize) {
+            if (ctype_digit((string) $constraint->maxSize)) {
+                $size = filesize($path);
+                $limit = $constraint->maxSize;
+                $suffix = 'bytes';
+            } elseif (preg_match('/^(\d+)k$/', $constraint->maxSize, $matches)) {
+                $size = round(filesize($path) / 1000, 2);
+                $limit = $matches[1];
+                $suffix = 'kB';
+            } elseif (preg_match('/^(\d+)M$/', $constraint->maxSize, $matches)) {
+                $size = round(filesize($path) / 1000000, 2);
+                $limit = $matches[1];
+                $suffix = 'MB';
+            } else {
+                throw new ConstraintDefinitionException(sprintf('"%s" is not a valid maximum size', $constraint->maxSize));
+            }
+
+            if ($size > $limit) {
+                $this->context->addViolation($constraint->maxSizeMessage, array(
+                    '{{ size }}'    => $size,
+                    '{{ limit }}'   => $limit,
+                    '{{ suffix }}'  => $suffix,
+                    '{{ file }}'    => $path,
+                ));
+
+                return;
+            }
+        }
+
+        if ($constraint->mimeTypes) {
+            if (!$value instanceof FileObject) {
+                $value = new FileObject($value);
+            }
+
+            $mimeTypes = (array) $constraint->mimeTypes;
+            $mime = $value->getMimeType();
+            $valid = false;
+
+            foreach ($mimeTypes as $mimeType) {
+                if ($mimeType === $mime) {
+                    $valid = true;
+                    break;
+                }
+
+                if ($discrete = strstr($mimeType, '/*', true)) {
+                    if (strstr($mime, '/', true) === $discrete) {
+                        $valid = true;
+                        break;
+                    }
+                }
+            }
+
+            if (false === $valid) {
+                $this->context->addViolation($constraint->mimeTypesMessage, array(
+                    '{{ type }}'    => '"'.$mime.'"',
+                    '{{ types }}'   => '"'.implode('", "', $mimeTypes) .'"',
+                    '{{ file }}'    => $path,
+                ));
+            }
+        }
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/GroupSequence.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/GroupSequence.php
new file mode 100644
index 0000000..c19f5f8
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/GroupSequence.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\Validator\Constraints;
+
+/**
+ * Annotation for group sequences
+ *
+ * @Annotation
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @api
+ */
+class GroupSequence
+{
+    /**
+     * The members of the sequence
+     * @var array
+     */
+    public $groups;
+
+    public function __construct(array $groups)
+    {
+        $this->groups = $groups['value'];
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/GroupSequenceProvider.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/GroupSequenceProvider.php
new file mode 100644
index 0000000..4571559
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/GroupSequenceProvider.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\Validator\Constraints;
+
+/**
+ * Annotation to define a group sequence provider
+ *
+ * @Annotation
+ */
+class GroupSequenceProvider
+{
+
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Image.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Image.php
new file mode 100644
index 0000000..a231064
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Image.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\Validator\Constraints;
+
+/**
+ * @Annotation
+ *
+ * @api
+ */
+class Image extends File
+{
+    public $mimeTypes = 'image/*';
+    public $minWidth = null;
+    public $maxWidth = null;
+    public $maxHeight = null;
+    public $minHeight = null;
+
+    public $mimeTypesMessage = 'This file is not a valid image.';
+    public $sizeNotDetectedMessage = 'The size of the image could not be detected.';
+    public $maxWidthMessage = 'The image width is too big ({{ width }}px). Allowed maximum width is {{ max_width }}px.';
+    public $minWidthMessage = 'The image width is too small ({{ width }}px). Minimum width expected is {{ min_width }}px.';
+    public $maxHeightMessage = 'The image height is too big ({{ height }}px). Allowed maximum height is {{ max_height }}px.';
+    public $minHeightMessage = 'The image height is too small ({{ height }}px). Minimum height expected is {{ min_height }}px.';
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/ImageValidator.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/ImageValidator.php
new file mode 100644
index 0000000..79e6bdc
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/ImageValidator.php
@@ -0,0 +1,113 @@
+<?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\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\Exception\ConstraintDefinitionException;
+
+/**
+ * Validates whether a value is a valid image file and is valid
+ * against minWidth, maxWidth, minHeight and maxHeight constraints
+ *
+ * @author Benjamin Dulau <benjamin.dulau@gmail.com>
+ */
+class ImageValidator extends FileValidator
+{
+    /**
+     * {@inheritDoc}
+     */
+    public function validate($value, Constraint $constraint)
+    {
+        $violations = count($this->context->getViolations());
+
+        parent::validate($value, $constraint);
+
+        $failed = count($this->context->getViolations()) !== $violations;
+
+        if ($failed || null === $value || '' === $value) {
+            return;
+        }
+
+        if (null === $constraint->minWidth && null === $constraint->maxWidth
+            && null === $constraint->minHeight && null === $constraint->maxHeight) {
+            return;
+        }
+
+        $size = @getimagesize($value);
+        if (empty($size) || ($size[0] === 0) || ($size[1] === 0)) {
+            $this->context->addViolation($constraint->sizeNotDetectedMessage);
+
+            return;
+        }
+
+        $width  = $size[0];
+        $height = $size[1];
+
+        if ($constraint->minWidth) {
+            if (!ctype_digit((string) $constraint->minWidth)) {
+                throw new ConstraintDefinitionException(sprintf('"%s" is not a valid minimum width', $constraint->minWidth));
+            }
+
+            if ($width < $constraint->minWidth) {
+                $this->context->addViolation($constraint->minWidthMessage, array(
+                    '{{ width }}'    => $width,
+                    '{{ min_width }}' => $constraint->minWidth
+                ));
+
+                return;
+            }
+        }
+
+        if ($constraint->maxWidth) {
+            if (!ctype_digit((string) $constraint->maxWidth)) {
+                throw new ConstraintDefinitionException(sprintf('"%s" is not a valid maximum width', $constraint->maxWidth));
+            }
+
+            if ($width > $constraint->maxWidth) {
+                $this->context->addViolation($constraint->maxWidthMessage, array(
+                    '{{ width }}'    => $width,
+                    '{{ max_width }}' => $constraint->maxWidth
+                ));
+
+                return;
+            }
+        }
+
+        if ($constraint->minHeight) {
+            if (!ctype_digit((string) $constraint->minHeight)) {
+                throw new ConstraintDefinitionException(sprintf('"%s" is not a valid minimum height', $constraint->minHeight));
+            }
+
+            if ($height < $constraint->minHeight) {
+                $this->context->addViolation($constraint->minHeightMessage, array(
+                    '{{ height }}'    => $height,
+                    '{{ min_height }}' => $constraint->minHeight
+                ));
+
+                return;
+            }
+        }
+
+        if ($constraint->maxHeight) {
+            if (!ctype_digit((string) $constraint->maxHeight)) {
+                throw new ConstraintDefinitionException(sprintf('"%s" is not a valid maximum height', $constraint->maxHeight));
+            }
+
+            if ($height > $constraint->maxHeight) {
+                $this->context->addViolation($constraint->maxHeightMessage, array(
+                    '{{ height }}'    => $height,
+                    '{{ max_height }}' => $constraint->maxHeight
+                ));
+            }
+        }
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Ip.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Ip.php
new file mode 100644
index 0000000..1698d11
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Ip.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\Validator\Constraints;
+
+use Symfony\Component\Validator\Exception\ConstraintDefinitionException;
+use Symfony\Component\Validator\Constraint;
+
+/**
+ * Validates that a value is a valid IP address
+ *
+ * @Annotation
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @author Joseph Bielawski <stloyd@gmail.com>
+ *
+ * @api
+ */
+class Ip extends Constraint
+{
+    const V4 = '4';
+    const V6 = '6';
+    const ALL = 'all';
+
+    // adds FILTER_FLAG_NO_PRIV_RANGE flag (skip private ranges)
+    const V4_NO_PRIV = '4_no_priv';
+    const V6_NO_PRIV = '6_no_priv';
+    const ALL_NO_PRIV = 'all_no_priv';
+
+    // adds FILTER_FLAG_NO_RES_RANGE flag (skip reserved ranges)
+    const V4_NO_RES = '4_no_res';
+    const V6_NO_RES = '6_no_res';
+    const ALL_NO_RES = 'all_no_res';
+
+    // adds FILTER_FLAG_NO_PRIV_RANGE and FILTER_FLAG_NO_RES_RANGE flags (skip both)
+    const V4_ONLY_PUBLIC = '4_public';
+    const V6_ONLY_PUBLIC = '6_public';
+    const ALL_ONLY_PUBLIC = 'all_public';
+
+    protected static $versions = array(
+        self::V4,
+        self::V6,
+        self::ALL,
+
+        self::V4_NO_PRIV,
+        self::V6_NO_PRIV,
+        self::ALL_NO_PRIV,
+
+        self::V4_NO_RES,
+        self::V6_NO_RES,
+        self::ALL_NO_RES,
+
+        self::V4_ONLY_PUBLIC,
+        self::V6_ONLY_PUBLIC,
+        self::ALL_ONLY_PUBLIC,
+    );
+
+    public $version = self::V4;
+
+    public $message = 'This is not a valid IP address.';
+
+    /**
+     * {@inheritDoc}
+     */
+    public function __construct($options = null)
+    {
+        parent::__construct($options);
+
+        if (!in_array($this->version, self::$versions)) {
+            throw new ConstraintDefinitionException(sprintf('The option "version" must be one of "%s"', implode('", "', self::$versions)));
+        }
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/IpValidator.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/IpValidator.php
new file mode 100644
index 0000000..3358ec2
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/IpValidator.php
@@ -0,0 +1,97 @@
+<?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\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\ConstraintValidator;
+use Symfony\Component\Validator\Exception\UnexpectedTypeException;
+
+/**
+ * Validates whether a value is a valid IP address
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @author Joseph Bielawski <stloyd@gmail.com>
+ *
+ * @api
+ */
+class IpValidator extends ConstraintValidator
+{
+    /**
+     * {@inheritDoc}
+     */
+    public function validate($value, Constraint $constraint)
+    {
+        if (null === $value || '' === $value) {
+            return;
+        }
+
+        if (!is_scalar($value) && !(is_object($value) && method_exists($value, '__toString'))) {
+            throw new UnexpectedTypeException($value, 'string');
+        }
+
+        $value = (string) $value;
+
+        switch ($constraint->version) {
+            case Ip::V4:
+               $flag = FILTER_FLAG_IPV4;
+               break;
+
+            case Ip::V6:
+               $flag = FILTER_FLAG_IPV6;
+               break;
+
+            case Ip::V4_NO_PRIV:
+               $flag = FILTER_FLAG_IPV4 | FILTER_FLAG_NO_PRIV_RANGE;
+               break;
+
+            case Ip::V6_NO_PRIV:
+               $flag = FILTER_FLAG_IPV6 | FILTER_FLAG_NO_PRIV_RANGE;
+               break;
+
+            case Ip::ALL_NO_PRIV:
+               $flag = FILTER_FLAG_NO_PRIV_RANGE;
+               break;
+
+            case Ip::V4_NO_RES:
+               $flag = FILTER_FLAG_IPV4 | FILTER_FLAG_NO_RES_RANGE;
+               break;
+
+            case Ip::V6_NO_RES:
+               $flag = FILTER_FLAG_IPV6 | FILTER_FLAG_NO_RES_RANGE;
+               break;
+
+            case Ip::ALL_NO_RES:
+               $flag = FILTER_FLAG_NO_RES_RANGE;
+               break;
+
+            case Ip::V4_ONLY_PUBLIC:
+               $flag = FILTER_FLAG_IPV4 | FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE;
+               break;
+
+            case Ip::V6_ONLY_PUBLIC:
+               $flag = FILTER_FLAG_IPV6 | FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE;
+               break;
+
+            case Ip::ALL_ONLY_PUBLIC:
+               $flag = FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE;
+               break;
+
+            default:
+                $flag = null;
+                break;
+        }
+
+        if (!filter_var($value, FILTER_VALIDATE_IP, $flag)) {
+            $this->context->addViolation($constraint->message, array('{{ value }}' => $value));
+        }
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Language.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Language.php
new file mode 100644
index 0000000..a0a099b
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Language.php
@@ -0,0 +1,24 @@
+<?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\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+
+/**
+ * @Annotation
+ *
+ * @api
+ */
+class Language extends Constraint
+{
+    public $message = 'This value is not a valid language.';
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/LanguageValidator.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/LanguageValidator.php
new file mode 100644
index 0000000..5aed18a
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/LanguageValidator.php
@@ -0,0 +1,46 @@
+<?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\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\ConstraintValidator;
+use Symfony\Component\Validator\Exception\UnexpectedTypeException;
+
+/**
+ * Validates whether a value is a valid language code
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @api
+ */
+class LanguageValidator extends ConstraintValidator
+{
+    /**
+     * {@inheritDoc}
+     */
+    public function validate($value, Constraint $constraint)
+    {
+        if (null === $value || '' === $value) {
+            return;
+        }
+
+        if (!is_scalar($value) && !(is_object($value) && method_exists($value, '__toString'))) {
+            throw new UnexpectedTypeException($value, 'string');
+        }
+
+        $value = (string) $value;
+
+        if (!in_array($value, \Symfony\Component\Locale\Locale::getLanguages())) {
+            $this->context->addViolation($constraint->message, array('{{ value }}' => $value));
+        }
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Length.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Length.php
new file mode 100644
index 0000000..70554c0
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Length.php
@@ -0,0 +1,46 @@
+<?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\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\Exception\MissingOptionsException;
+
+/**
+ * @Annotation
+ *
+ * @api
+ */
+class Length extends Constraint
+{
+    public $maxMessage = 'This value is too long. It should have {{ limit }} characters or less.';
+    public $minMessage = 'This value is too short. It should have {{ limit }} characters or more.';
+    public $exactMessage = 'This value should have exactly {{ limit }} characters.';
+    public $max;
+    public $min;
+    public $charset = 'UTF-8';
+
+    public function __construct($options = null)
+    {
+        if (null !== $options && !is_array($options)) {
+            $options = array(
+                'min' => $options,
+                'max' => $options,
+            );
+        }
+
+        parent::__construct($options);
+
+        if (null === $this->min && null === $this->max) {
+            throw new MissingOptionsException('Either option "min" or "max" must be given for constraint ' . __CLASS__, array('min', 'max'));
+        }
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/LengthValidator.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/LengthValidator.php
new file mode 100644
index 0000000..8090a2c
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/LengthValidator.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\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\ConstraintValidator;
+use Symfony\Component\Validator\Exception\UnexpectedTypeException;
+
+/**
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+class LengthValidator extends ConstraintValidator
+{
+    /**
+     * {@inheritDoc}
+     */
+    public function validate($value, Constraint $constraint)
+    {
+        if (null === $value || '' === $value) {
+            return;
+        }
+
+        if (!is_scalar($value) && !(is_object($value) && method_exists($value, '__toString'))) {
+            throw new UnexpectedTypeException($value, 'string');
+        }
+
+        $stringValue = (string) $value;
+
+        if (function_exists('grapheme_strlen') && 'UTF-8' === $constraint->charset) {
+            $length = grapheme_strlen($stringValue);
+        } elseif (function_exists('mb_strlen')) {
+            $length = mb_strlen($stringValue, $constraint->charset);
+        } else {
+            $length = strlen($stringValue);
+        }
+
+        if ($constraint->min == $constraint->max && $length != $constraint->min) {
+            $this->context->addViolation($constraint->exactMessage, array(
+                '{{ value }}' => $stringValue,
+                '{{ limit }}' => $constraint->min,
+            ), $value, (int) $constraint->min);
+
+            return;
+        }
+
+        if (null !== $constraint->max && $length > $constraint->max) {
+            $this->context->addViolation($constraint->maxMessage, array(
+                '{{ value }}' => $stringValue,
+                '{{ limit }}' => $constraint->max,
+            ), $value, (int) $constraint->max);
+
+            return;
+        }
+
+        if (null !== $constraint->min && $length < $constraint->min) {
+            $this->context->addViolation($constraint->minMessage, array(
+                '{{ value }}' => $stringValue,
+                '{{ limit }}' => $constraint->min,
+            ), $value, (int) $constraint->min);
+        }
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Locale.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Locale.php
new file mode 100644
index 0000000..9a9025e
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Locale.php
@@ -0,0 +1,24 @@
+<?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\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+
+/**
+ * @Annotation
+ *
+ * @api
+ */
+class Locale extends Constraint
+{
+    public $message = 'This value is not a valid locale.';
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/LocaleValidator.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/LocaleValidator.php
new file mode 100644
index 0000000..5cacdb4
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/LocaleValidator.php
@@ -0,0 +1,46 @@
+<?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\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\ConstraintValidator;
+use Symfony\Component\Validator\Exception\UnexpectedTypeException;
+
+/**
+ * Validates whether a value is a valid locale code
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @api
+ */
+class LocaleValidator extends ConstraintValidator
+{
+    /**
+     * {@inheritDoc}
+     */
+    public function validate($value, Constraint $constraint)
+    {
+        if (null === $value || '' === $value) {
+            return;
+        }
+
+        if (!is_scalar($value) && !(is_object($value) && method_exists($value, '__toString'))) {
+            throw new UnexpectedTypeException($value, 'string');
+        }
+
+        $value = (string) $value;
+
+        if (!in_array($value, \Symfony\Component\Locale\Locale::getLocales())) {
+            $this->context->addViolation($constraint->message, array('{{ value }}' => $value));
+        }
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Luhn.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Luhn.php
new file mode 100644
index 0000000..f376045
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Luhn.php
@@ -0,0 +1,24 @@
+<?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\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+
+/**
+ * Metadata for the LuhnValidator.
+ *
+ * @Annotation
+ */
+class Luhn extends Constraint
+{
+    public $message = 'Invalid card number';
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/LuhnValidator.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/LuhnValidator.php
new file mode 100644
index 0000000..1ae8b39
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/LuhnValidator.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\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\ConstraintValidator;
+
+/**
+ * Validates a PAN using the LUHN Algorithm
+ *
+ * For a list of example card numbers that are used to test this
+ * class, please see the LuhnValidatorTest class.
+ *
+ * @see    http://en.wikipedia.org/wiki/Luhn_algorithm
+ * @author Tim Nagel <t.nagel@infinite.net.au>
+ * @author Greg Knapp http://gregk.me/2011/php-implementation-of-bank-card-luhn-algorithm/
+ */
+class LuhnValidator extends ConstraintValidator
+{
+    /**
+     * Validates a creditcard number with the Luhn algorithm.
+     *
+     * @param mixed      $value
+     * @param Constraint $constraint
+     */
+    public function validate($value, Constraint $constraint)
+    {
+        if (null === $value || '' === $value) {
+            return;
+        }
+
+        if (!is_numeric($value)) {
+            $this->context->addViolation($constraint->message);
+
+            return;
+        }
+
+        $length = strlen($value);
+        $oddLength = $length % 2;
+        for ($sum = 0, $i = $length - 1; $i >= 0; $i--) {
+            $digit = (int) $value[$i];
+            $sum += (($i % 2) === $oddLength) ? array_sum(str_split($digit * 2)) : $digit;
+        }
+
+        if (($sum % 10) !== 0) {
+            $this->context->addViolation($constraint->message);
+        }
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Max.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Max.php
new file mode 100644
index 0000000..814fc1f
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Max.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\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+
+/**
+ * @Annotation
+ *
+ * @api
+ *
+ * @deprecated Deprecated since version 2.1, to be removed in 2.3.
+ */
+class Max extends Constraint
+{
+    public $message = 'This value should be {{ limit }} or less.';
+    public $invalidMessage = 'This value should be a valid number.';
+    public $limit;
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getDefaultOption()
+    {
+        return 'limit';
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getRequiredOptions()
+    {
+        return array('limit');
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/MaxLength.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/MaxLength.php
new file mode 100644
index 0000000..765d548
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/MaxLength.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\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+
+/**
+ * @Annotation
+ *
+ * @api
+ *
+ * @deprecated Deprecated since version 2.1, to be removed in 2.3.
+ */
+class MaxLength extends Constraint
+{
+    public $message = 'This value is too long. It should have {{ limit }} characters or less.';
+    public $limit;
+    public $charset = 'UTF-8';
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getDefaultOption()
+    {
+        return 'limit';
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getRequiredOptions()
+    {
+        return array('limit');
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/MaxLengthValidator.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/MaxLengthValidator.php
new file mode 100644
index 0000000..9b9e9b9
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/MaxLengthValidator.php
@@ -0,0 +1,57 @@
+<?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\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\ConstraintValidator;
+use Symfony\Component\Validator\Exception\UnexpectedTypeException;
+
+/**
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @api
+ *
+ * @deprecated Deprecated since version 2.1, to be removed in 2.3.
+ */
+class MaxLengthValidator extends ConstraintValidator
+{
+    /**
+     * {@inheritDoc}
+     */
+    public function validate($value, Constraint $constraint)
+    {
+        if (null === $value || '' === $value) {
+            return;
+        }
+
+        if (!is_scalar($value) && !(is_object($value) && method_exists($value, '__toString'))) {
+            throw new UnexpectedTypeException($value, 'string');
+        }
+
+        $stringValue = (string) $value;
+
+        if (function_exists('grapheme_strlen') && 'UTF-8' === $constraint->charset) {
+            $length = grapheme_strlen($stringValue);
+        } elseif (function_exists('mb_strlen')) {
+            $length = mb_strlen($stringValue, $constraint->charset);
+        } else {
+            $length = strlen($stringValue);
+        }
+
+        if ($length > $constraint->limit) {
+            $this->context->addViolation($constraint->message, array(
+                '{{ value }}' => $stringValue,
+                '{{ limit }}' => $constraint->limit,
+            ), $value, (int) $constraint->limit);
+        }
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/MaxValidator.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/MaxValidator.php
new file mode 100644
index 0000000..2019d69
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/MaxValidator.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\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\ConstraintValidator;
+
+/**
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @api
+ *
+ * @deprecated Deprecated since version 2.1, to be removed in 2.3.
+ */
+class MaxValidator extends ConstraintValidator
+{
+    /**
+     * {@inheritDoc}
+     */
+    public function validate($value, Constraint $constraint)
+    {
+        if (null === $value || '' === $value) {
+            return;
+        }
+
+        if (!is_numeric($value)) {
+            $this->context->addViolation($constraint->invalidMessage, array(
+                '{{ value }}' => $value,
+                '{{ limit }}' => $constraint->limit,
+            ));
+
+            return;
+        }
+
+        if ($value > $constraint->limit) {
+            $this->context->addViolation($constraint->message, array(
+                '{{ value }}' => $value,
+                '{{ limit }}' => $constraint->limit,
+            ));
+        }
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Min.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Min.php
new file mode 100644
index 0000000..6e8b364
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Min.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\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+
+/**
+ * @Annotation
+ *
+ * @api
+ *
+ * @deprecated Deprecated since version 2.1, to be removed in 2.3.
+ */
+class Min extends Constraint
+{
+    public $message = 'This value should be {{ limit }} or more.';
+    public $invalidMessage = 'This value should be a valid number.';
+    public $limit;
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getDefaultOption()
+    {
+        return 'limit';
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getRequiredOptions()
+    {
+        return array('limit');
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/MinLength.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/MinLength.php
new file mode 100644
index 0000000..4457f6c
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/MinLength.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\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+
+/**
+ * @Annotation
+ *
+ * @api
+ *
+ * @deprecated Deprecated since version 2.1, to be removed in 2.3.
+ */
+class MinLength extends Constraint
+{
+    public $message = 'This value is too short. It should have {{ limit }} characters or more.';
+    public $limit;
+    public $charset = 'UTF-8';
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getDefaultOption()
+    {
+        return 'limit';
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getRequiredOptions()
+    {
+        return array('limit');
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/MinLengthValidator.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/MinLengthValidator.php
new file mode 100644
index 0000000..80fcac4
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/MinLengthValidator.php
@@ -0,0 +1,57 @@
+<?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\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\ConstraintValidator;
+use Symfony\Component\Validator\Exception\UnexpectedTypeException;
+
+/**
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @api
+ *
+ * @deprecated Deprecated since version 2.1, to be removed in 2.3.
+ */
+class MinLengthValidator extends ConstraintValidator
+{
+    /**
+     * {@inheritDoc}
+     */
+    public function validate($value, Constraint $constraint)
+    {
+        if (null === $value || '' === $value) {
+            return;
+        }
+
+        if (!is_scalar($value) && !(is_object($value) && method_exists($value, '__toString'))) {
+            throw new UnexpectedTypeException($value, 'string');
+        }
+
+        $stringValue = (string) $value;
+
+        if (function_exists('grapheme_strlen') && 'UTF-8' === $constraint->charset) {
+            $length = grapheme_strlen($stringValue);
+        } elseif (function_exists('mb_strlen')) {
+            $length = mb_strlen($stringValue, $constraint->charset);
+        } else {
+            $length = strlen($stringValue);
+        }
+
+        if ($length < $constraint->limit) {
+            $this->context->addViolation($constraint->message, array(
+                '{{ value }}' => $stringValue,
+                '{{ limit }}' => $constraint->limit,
+            ), $value, (int) $constraint->limit);
+        }
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/MinValidator.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/MinValidator.php
new file mode 100644
index 0000000..c907793
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/MinValidator.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\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\ConstraintValidator;
+
+/**
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @api
+ *
+ * @deprecated Deprecated since version 2.1, to be removed in 2.3.
+ */
+class MinValidator extends ConstraintValidator
+{
+    /**
+     * Checks if the passed value is valid.
+     *
+     * @param mixed      $value      The value that should be validated
+     * @param Constraint $constraint The constraint for the validation
+     *
+     * @api
+     */
+    public function validate($value, Constraint $constraint)
+    {
+        if (null === $value || '' === $value) {
+            return;
+        }
+
+        if (!is_numeric($value)) {
+            $this->context->addViolation($constraint->invalidMessage, array(
+                '{{ value }}' => $value,
+                '{{ limit }}' => $constraint->limit,
+            ));
+
+            return;
+        }
+
+        if ($value < $constraint->limit) {
+            $this->context->addViolation($constraint->message, array(
+                '{{ value }}' => $value,
+                '{{ limit }}' => $constraint->limit,
+            ));
+        }
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/NotBlank.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/NotBlank.php
new file mode 100644
index 0000000..c3281ad
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/NotBlank.php
@@ -0,0 +1,24 @@
+<?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\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+
+/**
+ * @Annotation
+ *
+ * @api
+ */
+class NotBlank extends Constraint
+{
+    public $message = 'This value should not be blank.';
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/NotBlankValidator.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/NotBlankValidator.php
new file mode 100644
index 0000000..dd3dbdd
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/NotBlankValidator.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\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\ConstraintValidator;
+
+/**
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @api
+ */
+class NotBlankValidator extends ConstraintValidator
+{
+    /**
+     * {@inheritDoc}
+     */
+    public function validate($value, Constraint $constraint)
+    {
+        if (false === $value || (empty($value) && '0' != $value)) {
+            $this->context->addViolation($constraint->message);
+        }
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/NotNull.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/NotNull.php
new file mode 100644
index 0000000..2608ab3
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/NotNull.php
@@ -0,0 +1,24 @@
+<?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\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+
+/**
+ * @Annotation
+ *
+ * @api
+ */
+class NotNull extends Constraint
+{
+    public $message = 'This value should not be null.';
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/NotNullValidator.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/NotNullValidator.php
new file mode 100644
index 0000000..4ee6592
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/NotNullValidator.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\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\ConstraintValidator;
+
+/**
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @api
+ */
+class NotNullValidator extends ConstraintValidator
+{
+    /**
+     * {@inheritDoc}
+     */
+    public function validate($value, Constraint $constraint)
+    {
+        if (null === $value) {
+            $this->context->addViolation($constraint->message);
+        }
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Null.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Null.php
new file mode 100644
index 0000000..e110bf8
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Null.php
@@ -0,0 +1,24 @@
+<?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\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+
+/**
+ * @Annotation
+ *
+ * @api
+ */
+class Null extends Constraint
+{
+    public $message = 'This value should be null.';
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/NullValidator.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/NullValidator.php
new file mode 100644
index 0000000..e8fa24e
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/NullValidator.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\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\ConstraintValidator;
+
+/**
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @api
+ */
+class NullValidator extends ConstraintValidator
+{
+    /**
+     * {@inheritDoc}
+     */
+    public function validate($value, Constraint $constraint)
+    {
+        if (null !== $value) {
+            $this->context->addViolation($constraint->message, array('{{ value }}' => $value));
+        }
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Range.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Range.php
new file mode 100644
index 0000000..a94825e
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Range.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\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\Exception\MissingOptionsException;
+
+/**
+ * @Annotation
+ *
+ * @api
+ */
+class Range extends Constraint
+{
+    public $minMessage = 'This value should be {{ limit }} or more.';
+    public $maxMessage = 'This value should be {{ limit }} or less.';
+    public $invalidMessage = 'This value should be a valid number.';
+    public $min;
+    public $max;
+
+    public function __construct($options = null)
+    {
+        parent::__construct($options);
+
+        if (null === $this->min && null === $this->max) {
+            throw new MissingOptionsException('Either option "min" or "max" must be given for constraint ' . __CLASS__, array('min', 'max'));
+        }
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/RangeValidator.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/RangeValidator.php
new file mode 100644
index 0000000..1a8ba15
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/RangeValidator.php
@@ -0,0 +1,55 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\ConstraintValidator;
+
+/**
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+class RangeValidator extends ConstraintValidator
+{
+    /**
+     * {@inheritDoc}
+     */
+    public function validate($value, Constraint $constraint)
+    {
+        if (null === $value) {
+            return;
+        }
+
+        if (!is_numeric($value)) {
+            $this->context->addViolation($constraint->invalidMessage, array(
+                '{{ value }}' => $value,
+            ));
+
+            return;
+        }
+
+        if (null !== $constraint->max && $value > $constraint->max) {
+            $this->context->addViolation($constraint->maxMessage, array(
+                '{{ value }}' => $value,
+                '{{ limit }}' => $constraint->max,
+            ));
+
+            return;
+        }
+
+        if (null !== $constraint->min && $value < $constraint->min) {
+            $this->context->addViolation($constraint->minMessage, array(
+                '{{ value }}' => $value,
+                '{{ limit }}' => $constraint->min,
+            ));
+        }
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Regex.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Regex.php
new file mode 100644
index 0000000..f26186c
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Regex.php
@@ -0,0 +1,96 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+
+/**
+ * @Annotation
+ *
+ * @api
+ */
+class Regex extends Constraint
+{
+    public $message = 'This value is not valid.';
+    public $pattern;
+    public $htmlPattern = null;
+    public $match = true;
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getDefaultOption()
+    {
+        return 'pattern';
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getRequiredOptions()
+    {
+        return array('pattern');
+    }
+
+    /**
+     * Returns htmlPattern if exists or pattern is convertible.
+     *
+     * @return string|null
+     */
+    public function getHtmlPattern()
+    {
+        // If htmlPattern is specified, use it
+        if (null !== $this->htmlPattern) {
+            return empty($this->htmlPattern)
+                ? null
+                : $this->htmlPattern;
+        }
+
+        return $this->getNonDelimitedPattern();
+    }
+
+    /**
+     * Convert the htmlPattern to a suitable format for HTML5 pattern.
+     * Example: /^[a-z]+$/ would be converted to [a-z]+
+     * However, if options are specified, it cannot be converted
+     * 
+     * Pattern is also ignored if match=false since the pattern should
+     * then be reversed before application.
+     *
+     * @todo reverse pattern in case match=false as per issue #5307
+     *
+     * @link http://dev.w3.org/html5/spec/single-page.html#the-pattern-attribute
+     *
+     * @return string|null
+     */
+    private function getNonDelimitedPattern()
+    {
+        // If match = false, pattern should not be added to HTML5 validation
+        if (!$this->match) {
+            return null;
+        }
+        
+        if (preg_match('/^(.)(\^?)(.*?)(\$?)\1$/', $this->pattern, $matches)) {
+            $delimiter = $matches[1];
+            $start     = empty($matches[2]) ? '.*' : '';
+            $pattern   = $matches[3];
+            $end       = empty($matches[4]) ? '.*' : '';
+
+            // Unescape the delimiter in pattern
+            $pattern = str_replace('\\' . $delimiter, $delimiter, $pattern);
+
+            return $start . $pattern . $end;
+        }
+
+        return null;
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/RegexValidator.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/RegexValidator.php
new file mode 100644
index 0000000..c39869d
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/RegexValidator.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\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\ConstraintValidator;
+use Symfony\Component\Validator\Exception\UnexpectedTypeException;
+
+/**
+ * Validates whether a value match or not given regexp pattern
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @author Joseph Bielawski <stloyd@gmail.com>
+ *
+ * @api
+ */
+class RegexValidator extends ConstraintValidator
+{
+    /**
+     * {@inheritDoc}
+     */
+    public function validate($value, Constraint $constraint)
+    {
+        if (null === $value || '' === $value) {
+            return;
+        }
+
+        if (!is_scalar($value) && !(is_object($value) && method_exists($value, '__toString'))) {
+            throw new UnexpectedTypeException($value, 'string');
+        }
+
+        $value = (string) $value;
+
+        if ($constraint->match xor preg_match($constraint->pattern, $value)) {
+            $this->context->addViolation($constraint->message, array('{{ value }}' => $value));
+        }
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Time.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Time.php
new file mode 100644
index 0000000..3ff8a50
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Time.php
@@ -0,0 +1,24 @@
+<?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\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+
+/**
+ * @Annotation
+ *
+ * @api
+ */
+class Time extends Constraint
+{
+    public $message = 'This value is not a valid time.';
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/TimeValidator.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/TimeValidator.php
new file mode 100644
index 0000000..31259cc
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/TimeValidator.php
@@ -0,0 +1,46 @@
+<?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\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\ConstraintValidator;
+use Symfony\Component\Validator\Exception\UnexpectedTypeException;
+
+/**
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @api
+ */
+class TimeValidator extends ConstraintValidator
+{
+    const PATTERN = '/^(0[0-9]|1[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$/';
+
+    /**
+     * {@inheritDoc}
+     */
+    public function validate($value, Constraint $constraint)
+    {
+        if (null === $value || '' === $value || $value instanceof \DateTime) {
+            return;
+        }
+
+        if (!is_scalar($value) && !(is_object($value) && method_exists($value, '__toString'))) {
+            throw new UnexpectedTypeException($value, 'string');
+        }
+
+        $value = (string) $value;
+
+        if (!preg_match(static::PATTERN, $value)) {
+            $this->context->addViolation($constraint->message, array('{{ value }}' => $value));
+        }
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/True.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/True.php
new file mode 100644
index 0000000..a5bfc85
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/True.php
@@ -0,0 +1,24 @@
+<?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\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+
+/**
+ * @Annotation
+ *
+ * @api
+ */
+class True extends Constraint
+{
+    public $message = 'This value should be true.';
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/TrueValidator.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/TrueValidator.php
new file mode 100644
index 0000000..2fbe047
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/TrueValidator.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\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\ConstraintValidator;
+
+/**
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @api
+ */
+class TrueValidator extends ConstraintValidator
+{
+    /**
+     * {@inheritDoc}
+     */
+    public function validate($value, Constraint $constraint)
+    {
+        if (null === $value) {
+            return;
+        }
+
+        if (true !== $value && 1 !== $value && '1' !== $value) {
+            $this->context->addViolation($constraint->message);
+        }
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Type.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Type.php
new file mode 100644
index 0000000..11dec3c
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Type.php
@@ -0,0 +1,41 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+
+/**
+ * @Annotation
+ *
+ * @api
+ */
+class Type extends Constraint
+{
+    public $message = 'This value should be of type {{ type }}.';
+    public $type;
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getDefaultOption()
+    {
+        return 'type';
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getRequiredOptions()
+    {
+        return array('type');
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/TypeValidator.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/TypeValidator.php
new file mode 100644
index 0000000..ecc88df
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/TypeValidator.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\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\ConstraintValidator;
+
+/**
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @api
+ */
+class TypeValidator extends ConstraintValidator
+{
+    /**
+     * {@inheritDoc}
+     */
+    public function validate($value, Constraint $constraint)
+    {
+        if (null === $value) {
+            return;
+        }
+
+        $type = strtolower($constraint->type);
+        $type = $type == 'boolean' ? 'bool' : $constraint->type;
+        $isFunction = 'is_'.$type;
+        $ctypeFunction = 'ctype_'.$type;
+
+        if (function_exists($isFunction) && call_user_func($isFunction, $value)) {
+            return;
+        } elseif (function_exists($ctypeFunction) && call_user_func($ctypeFunction, $value)) {
+            return;
+        } elseif ($value instanceof $constraint->type) {
+            return;
+        }
+
+        $this->context->addViolation($constraint->message, array(
+            '{{ value }}' => is_object($value) ? get_class($value) : (is_array($value) ? 'Array' : (string) $value),
+            '{{ type }}'  => $constraint->type,
+        ));
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Url.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Url.php
new file mode 100644
index 0000000..4b4e96c
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Url.php
@@ -0,0 +1,25 @@
+<?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\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+
+/**
+ * @Annotation
+ *
+ * @api
+ */
+class Url extends Constraint
+{
+    public $message = 'This value is not a valid URL.';
+    public $protocols = array('http', 'https');
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/UrlValidator.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/UrlValidator.php
new file mode 100644
index 0000000..1fc380e
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/UrlValidator.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\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\ConstraintValidator;
+use Symfony\Component\Validator\Exception\UnexpectedTypeException;
+
+/**
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @api
+ */
+class UrlValidator extends ConstraintValidator
+{
+    const PATTERN = '~^
+            (%s)://                                 # protocol
+            (
+                ([\pL\pN\pS-]+\.)+[\pL]+                   # a domain name
+                    |                                     #  or
+                \d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}      # a IP address
+                    |                                     #  or
+                \[
+                    (?:(?:(?:(?:(?:(?:(?:[0-9a-f]{1,4})):){6})(?:(?:(?:(?:(?:[0-9a-f]{1,4})):(?:(?:[0-9a-f]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:::(?:(?:(?:[0-9a-f]{1,4})):){5})(?:(?:(?:(?:(?:[0-9a-f]{1,4})):(?:(?:[0-9a-f]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:[0-9a-f]{1,4})))?::(?:(?:(?:[0-9a-f]{1,4})):){4})(?:(?:(?:(?:(?:[0-9a-f]{1,4})):(?:(?:[0-9a-f]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-f]{1,4})):){0,1}(?:(?:[0-9a-f]{1,4})))?::(?:(?:(?:[0-9a-f]{1,4})):){3})(?:(?:(?:(?:(?:[0-9a-f]{1,4})):(?:(?:[0-9a-f]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-f]{1,4})):){0,2}(?:(?:[0-9a-f]{1,4})))?::(?:(?:(?:[0-9a-f]{1,4})):){2})(?:(?:(?:(?:(?:[0-9a-f]{1,4})):(?:(?:[0-9a-f]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-f]{1,4})):){0,3}(?:(?:[0-9a-f]{1,4})))?::(?:(?:[0-9a-f]{1,4})):)(?:(?:(?:(?:(?:[0-9a-f]{1,4})):(?:(?:[0-9a-f]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-f]{1,4})):){0,4}(?:(?:[0-9a-f]{1,4})))?::)(?:(?:(?:(?:(?:[0-9a-f]{1,4})):(?:(?:[0-9a-f]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-f]{1,4})):){0,5}(?:(?:[0-9a-f]{1,4})))?::)(?:(?:[0-9a-f]{1,4})))|(?:(?:(?:(?:(?:(?:[0-9a-f]{1,4})):){0,6}(?:(?:[0-9a-f]{1,4})))?::))))
+                \]  # a IPv6 address
+            )
+            (:[0-9]+)?                              # a port (optional)
+            (/?|/\S+)                               # a /, nothing or a / with something
+        $~ixu';
+
+    /**
+     * {@inheritDoc}
+     */
+    public function validate($value, Constraint $constraint)
+    {
+        if (null === $value || '' === $value) {
+            return;
+        }
+
+        if (!is_scalar($value) && !(is_object($value) && method_exists($value, '__toString'))) {
+            throw new UnexpectedTypeException($value, 'string');
+        }
+
+        $value = (string) $value;
+
+        $pattern = sprintf(static::PATTERN, implode('|', $constraint->protocols));
+
+        if (!preg_match($pattern, $value)) {
+            $this->context->addViolation($constraint->message, array('{{ value }}' => $value));
+        }
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Valid.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Valid.php
new file mode 100644
index 0000000..42b413e
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Constraints/Valid.php
@@ -0,0 +1,36 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\Exception\ConstraintDefinitionException;
+
+/**
+ * @Annotation
+ *
+ * @api
+ */
+class Valid extends Constraint
+{
+    public $traverse = true;
+
+    public $deep = false;
+
+    public function __construct($options = null)
+    {
+        if (is_array($options) && array_key_exists('groups', $options)) {
+            throw new ConstraintDefinitionException('The option "groups" is not supported by the constraint ' . __CLASS__);
+        }
+
+        parent::__construct($options);
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Exception/ConstraintDefinitionException.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Exception/ConstraintDefinitionException.php
new file mode 100644
index 0000000..b24fdd6
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Exception/ConstraintDefinitionException.php
@@ -0,0 +1,16 @@
+<?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\Validator\Exception;
+
+class ConstraintDefinitionException extends ValidatorException
+{
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Exception/GroupDefinitionException.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Exception/GroupDefinitionException.php
new file mode 100644
index 0000000..ab7e91d
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Exception/GroupDefinitionException.php
@@ -0,0 +1,16 @@
+<?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\Validator\Exception;
+
+class GroupDefinitionException extends ValidatorException
+{
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Exception/InvalidOptionsException.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Exception/InvalidOptionsException.php
new file mode 100644
index 0000000..ce87c42
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Exception/InvalidOptionsException.php
@@ -0,0 +1,29 @@
+<?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\Validator\Exception;
+
+class InvalidOptionsException extends ValidatorException
+{
+    private $options;
+
+    public function __construct($message, array $options)
+    {
+        parent::__construct($message);
+
+        $this->options = $options;
+    }
+
+    public function getOptions()
+    {
+        return $this->options;
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Exception/MappingException.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Exception/MappingException.php
new file mode 100644
index 0000000..4c8c057
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Exception/MappingException.php
@@ -0,0 +1,16 @@
+<?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\Validator\Exception;
+
+class MappingException extends ValidatorException
+{
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Exception/MissingOptionsException.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Exception/MissingOptionsException.php
new file mode 100644
index 0000000..07c5d9e
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Exception/MissingOptionsException.php
@@ -0,0 +1,29 @@
+<?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\Validator\Exception;
+
+class MissingOptionsException extends ValidatorException
+{
+    private $options;
+
+    public function __construct($message, array $options)
+    {
+        parent::__construct($message);
+
+        $this->options = $options;
+    }
+
+    public function getOptions()
+    {
+        return $this->options;
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Exception/NoSuchMetadataException.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Exception/NoSuchMetadataException.php
new file mode 100644
index 0000000..4cac74c
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Exception/NoSuchMetadataException.php
@@ -0,0 +1,19 @@
+<?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\Validator\Exception;
+
+/**
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+class NoSuchMetadataException extends ValidatorException
+{
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Exception/UnexpectedTypeException.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Exception/UnexpectedTypeException.php
new file mode 100644
index 0000000..573fecd
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Exception/UnexpectedTypeException.php
@@ -0,0 +1,20 @@
+<?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\Validator\Exception;
+
+class UnexpectedTypeException extends ValidatorException
+{
+    public function __construct($value, $expectedType)
+    {
+        parent::__construct(sprintf('Expected argument of type %s, %s given', $expectedType, gettype($value)));
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Exception/ValidatorException.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Exception/ValidatorException.php
new file mode 100644
index 0000000..6ee2416
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Exception/ValidatorException.php
@@ -0,0 +1,16 @@
+<?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\Validator\Exception;
+
+class ValidatorException extends \RuntimeException
+{
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/ExecutionContext.php b/core/vendor/symfony/validator/Symfony/Component/Validator/ExecutionContext.php
new file mode 100644
index 0000000..af9b2e6
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/ExecutionContext.php
@@ -0,0 +1,375 @@
+<?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\Validator;
+
+/**
+ * Default implementation of {@link ExecutionContextInterface}.
+ *
+ * This class is immutable by design.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+class ExecutionContext implements ExecutionContextInterface
+{
+    /**
+     * @var GlobalExecutionContextInterface
+     */
+    private $globalContext;
+
+    /**
+     * @var MetadataInterface
+     */
+    private $metadata;
+
+    /**
+     * @var mixed
+     */
+    private $value;
+
+    /**
+     * @var string
+     */
+    private $group;
+
+    /**
+     * @var string
+     */
+    private $propertyPath;
+
+    /**
+     * Creates a new execution context.
+     *
+     * @param GlobalExecutionContextInterface $globalContext The global context storing node-independent state.
+     * @param MetadataInterface               $metadata      The metadata of the validated node.
+     * @param mixed                           $value         The value of the validated node.
+     * @param string                          $group         The current validation group.
+     * @param string                          $propertyPath  The property path to the current node.
+     */
+    public function __construct(GlobalExecutionContextInterface $globalContext, MetadataInterface $metadata = null, $value = null, $group = null, $propertyPath = '')
+    {
+        if (null === $group) {
+            $group = Constraint::DEFAULT_GROUP;
+        }
+
+        $this->globalContext = $globalContext;
+        $this->metadata = $metadata;
+        $this->value = $value;
+        $this->propertyPath = $propertyPath;
+        $this->group = $group;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function addViolation($message, array $params = array(), $invalidValue = null, $pluralization = null, $code = null)
+    {
+        $this->globalContext->getViolations()->add(new ConstraintViolation(
+            $message,
+            $params,
+            $this->globalContext->getRoot(),
+            $this->propertyPath,
+            // check using func_num_args() to allow passing null values
+            func_num_args() >= 3 ? $invalidValue : $this->value,
+            $pluralization,
+            $code
+        ));
+    }
+
+    /**
+     * Adds a violation at the validation graph node with the given property
+     * path.
+     *
+     * @param string       $propertyPath  The property path for the violation.
+     * @param string       $message       The error message.
+     * @param array        $params        The parameters parsed into the error message.
+     * @param mixed        $invalidValue  The invalid, validated value.
+     * @param integer|null $pluralization The number to use to pluralize of the message.
+     * @param integer|null $code          The violation code.
+     *
+     * @deprecated Deprecated since version 2.2, to be removed in 2.3.
+     */
+    public function addViolationAtPath($propertyPath, $message, array $params = array(), $invalidValue = null, $pluralization = null, $code = null)
+    {
+        $this->globalContext->getViolations()->add(new ConstraintViolation(
+            $message,
+            $params,
+            $this->globalContext->getRoot(),
+            $propertyPath,
+            // check using func_num_args() to allow passing null values
+            func_num_args() >= 4 ? $invalidValue : $this->value,
+            $pluralization,
+            $code
+        ));
+    }
+
+    /**
+     * Adds a violation at the validation graph node with the given property
+     * path relative to the current property path.
+     *
+     * @param string       $subPath       The relative property path for the violation.
+     * @param string       $message       The error message.
+     * @param array        $params        The parameters parsed into the error message.
+     * @param mixed        $invalidValue  The invalid, validated value.
+     * @param integer|null $pluralization The number to use to pluralize of the message.
+     * @param integer|null $code          The violation code.
+     *
+     * @deprecated Deprecated since version 2.2, to be removed in 2.3. Use the
+     *             method {@link atViolationAt} instead.
+     */
+    public function addViolationAtSubPath($subPath, $message, array $params = array(), $invalidValue = null, $pluralization = null, $code = null)
+    {
+        if (func_num_args() >= 4) {
+            $this->addViolationAt($subPath, $message, $params, $invalidValue, $pluralization, $code);
+        } else {
+            // Needed in order to make the check for func_num_args() inside work
+            $this->addViolationAt($subPath, $message, $params);
+        }
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function addViolationAt($subPath, $message, array $params = array(), $invalidValue = null, $pluralization = null, $code = null)
+    {
+        $this->globalContext->getViolations()->add(new ConstraintViolation(
+            $message,
+            $params,
+            $this->globalContext->getRoot(),
+            $this->getPropertyPath($subPath),
+            // check using func_num_args() to allow passing null values
+            func_num_args() >= 4 ? $invalidValue : $this->value,
+            $pluralization,
+            $code
+        ));
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getViolations()
+    {
+        return $this->globalContext->getViolations();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getRoot()
+    {
+        return $this->globalContext->getRoot();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getPropertyPath($subPath = null)
+    {
+        if (null !== $subPath && '' !== $this->propertyPath && '' !== $subPath && '[' !== $subPath[0]) {
+            return $this->propertyPath . '.' . $subPath;
+        }
+
+        return $this->propertyPath . $subPath;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getClassName()
+    {
+        if ($this->metadata instanceof ClassBasedInterface) {
+            return $this->metadata->getClassName();
+        }
+
+        return null;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getPropertyName()
+    {
+        if ($this->metadata instanceof PropertyMetadataInterface) {
+            return $this->metadata->getPropertyName();
+        }
+
+        return null;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getValue()
+    {
+        return $this->value;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getGroup()
+    {
+        return $this->group;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getMetadata()
+    {
+        return $this->metadata;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getMetadataFor($value)
+    {
+        return $this->globalContext->getMetadataFactory()->getMetadataFor($value);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function validate($value, $groups = null, $subPath = '', $traverse = false, $deep = false)
+    {
+        $propertyPath = $this->getPropertyPath($subPath);
+
+        foreach ($this->resolveGroups($groups) as $group) {
+            $this->globalContext->getVisitor()->validate($value, $group, $propertyPath, $traverse, $deep);
+        }
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function validateValue($value, $constraints, $groups = null, $subPath = '')
+    {
+        $constraints = is_array($constraints) ? $constraints : array($constraints);
+
+        if (null === $groups && '' === $subPath) {
+            $context = clone $this;
+            $context->value = $value;
+            $context->executeConstraintValidators($value, $constraints);
+
+            return;
+        }
+
+        $propertyPath = $this->getPropertyPath($subPath);
+
+        foreach ($this->resolveGroups($groups) as $group) {
+            $context = clone $this;
+            $context->value = $value;
+            $context->group = $group;
+            $context->propertyPath = $propertyPath;
+            $context->executeConstraintValidators($value, $constraints);
+        }
+    }
+
+    /**
+     * Returns the class name of the current node.
+     *
+     * @return string|null The class name or null, if the current node does not
+     *                     hold information about a class.
+     *
+     * @see getClassName
+     *
+     * @deprecated Deprecated since version 2.2, to be removed in 2.3. Use
+     *             {@link getClassName} instead.
+     */
+    public function getCurrentClass()
+    {
+        return $this->getClassName();
+    }
+
+    /**
+     * Returns the property name of the current node.
+     *
+     * @return string|null The property name or null, if the current node does
+     *                     not hold information about a property.
+     *
+     * @see getPropertyName
+     *
+     * @deprecated Deprecated since version 2.2, to be removed in 2.3. Use
+     *             {@link getClassName} instead.
+     */
+    public function getCurrentProperty()
+    {
+        return $this->getPropertyName();
+    }
+
+    /**
+     * Returns the currently validated value.
+     *
+     * @return mixed The current value.
+     *
+     * @see getValue
+     *
+     * @deprecated Deprecated since version 2.2, to be removed in 2.3. Use
+     *             {@link getValue} instead.
+     */
+    public function getCurrentValue()
+    {
+        return $this->value;
+    }
+
+    /**
+     * Returns the graph walker instance.
+     *
+     * @return GraphWalker The graph walker.
+     *
+     * @deprecated Deprecated since version 2.2, to be removed in 2.3. Use
+     *             {@link validate} and {@link validateValue} instead.
+     */
+    public function getGraphWalker()
+    {
+        return $this->globalContext->getVisitor()->getGraphWalker();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getMetadataFactory()
+    {
+        return $this->globalContext->getMetadataFactory();
+    }
+
+    /**
+     * Executes the validators of the given constraints for the given value.
+     *
+     * @param mixed        $value       The value to validate.
+     * @param Constraint[] $constraints The constraints to match against.
+     */
+    private function executeConstraintValidators($value, array $constraints)
+    {
+        foreach ($constraints as $constraint) {
+            $validator = $this->globalContext->getValidatorFactory()->getInstance($constraint);
+            $validator->initialize($this);
+            $validator->validate($value, $constraint);
+        }
+    }
+
+    /**
+     * Returns an array of group names.
+     *
+     * @param null|string|string[] $groups The groups to resolve. If a single string is
+     *                                     passed, it is converted to an array. If null
+     *                                     is passed, an array containing the current
+     *                                     group of the context is returned.
+     *
+     * @return array An array of validation groups.
+     */
+    private function resolveGroups($groups)
+    {
+        return $groups ? (array) $groups : (array) $this->group;
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/ExecutionContextInterface.php b/core/vendor/symfony/validator/Symfony/Component/Validator/ExecutionContextInterface.php
new file mode 100644
index 0000000..cae91a9
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/ExecutionContextInterface.php
@@ -0,0 +1,304 @@
+<?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\Validator;
+
+/**
+ * Stores the validator's state during validation.
+ *
+ * For example, let's validate the following object graph:
+ *
+ * <pre>
+ * (Person)---($firstName: string)
+ *      \
+ *   ($address: Address)---($street: string)
+ * </pre>
+ *
+ * We validate the <tt>Person</tt> instance, which becomes the "root" of the
+ * validation run (see {@link getRoot}). The state of the context after the
+ * first step will be like this:
+ *
+ * <pre>
+ * (Person)---($firstName: string)
+ *    ^ \
+ *   ($address: Address)---($street: string)
+ * </pre>
+ *
+ * The validator is stopped at the <tt>Person</tt> node, both the root and the
+ * value (see {@link getValue}) of the context point to the <tt>Person</tt>
+ * instance. The property path is empty at this point (see {@link getPropertyPath}).
+ * The metadata of the context is the metadata of the <tt>Person</tt> node
+ * (see {@link getMetadata}).
+ *
+ * After advancing to the property <tt>$firstName</tt> of the <tt>Person</tt>
+ * instance, the state of the context looks like this:
+ *
+ * <pre>
+ * (Person)---($firstName: string)
+ *      \              ^
+ *   ($address: Address)---($street: string)
+ * </pre>
+ *
+ * The validator is stopped at the property <tt>$firstName</tt>. The root still
+ * points to the <tt>Person</tt> instance, because this is where the validation
+ * started. The property path is now "firstName" and the current value is the
+ * value of that property.
+ *
+ * After advancing to the <tt>$address</tt> property and then to the
+ * <tt>$street</tt> property of the <tt>Address</tt> instance, the context state
+ * looks like this:
+ *
+ * <pre>
+ * (Person)---($firstName: string)
+ *      \
+ *   ($address: Address)---($street: string)
+ *                               ^
+ * </pre>
+ *
+ * The validator is stopped at the property <tt>$street</tt>. The root still
+ * points to the <tt>Person</tt> instance, but the property path is now
+ * "address.street" and the validated value is the value of that property.
+ *
+ * Apart from the root, the property path and the currently validated value,
+ * the execution context also knows the metadata of the current node (see
+ * {@link getMetadata}) which for example returns a {@link Mapping\PropertyMetadata}
+ * or a {@link Mapping\ClassMetadata} object. he context also contains the
+ * validation group that is currently being validated (see {@link getGroup}) and
+ * the violations that happened up until now (see {@link getViolations}).
+ *
+ * Apart from reading the execution context, you can also use
+ * {@link addViolation} or {@link addViolationAt} to add new violations and
+ * {@link validate} or {@link validateValue} to validate values that the
+ * validator otherwise would not reach.
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @api
+ */
+interface ExecutionContextInterface
+{
+    /**
+     * Adds a violation at the current node of the validation graph.
+     *
+     * @param string       $message       The error message.
+     * @param array        $params        The parameters substituted in the error message.
+     * @param mixed        $invalidValue  The invalid, validated value.
+     * @param integer|null $pluralization The number to use to pluralize of the message.
+     * @param integer|null $code          The violation code.
+     *
+     * @api
+     */
+    public function addViolation($message, array $params = array(), $invalidValue = null, $pluralization = null, $code = null);
+
+    /**
+     * Adds a violation at the validation graph node with the given property
+     * path relative to the current property path.
+     *
+     * @param string       $subPath       The relative property path for the violation.
+     * @param string       $message       The error message.
+     * @param array        $params        The parameters substituted in the error message.
+     * @param mixed        $invalidValue  The invalid, validated value.
+     * @param integer|null $pluralization The number to use to pluralize of the message.
+     * @param integer|null $code          The violation code.
+     *
+     * @api
+     */
+    public function addViolationAt($subPath, $message, array $params = array(), $invalidValue = null, $pluralization = null, $code = null);
+
+    /**
+     * Validates the given value within the scope of the current validation.
+     *
+     * The value may be any value recognized by the used metadata factory
+     * (see {@link MetadataFactoryInterface::getMetadata}), or an array or a
+     * traversable object of such values.
+     *
+     * Usually you validate a value that is not the current node of the
+     * execution context. For this case, you can pass the {@link $subPath}
+     * argument which is appended to the current property path when a violation
+     * is created. For example, take the following object graph:
+     *
+     * <pre>
+     * (Person)---($address: Address)---($phoneNumber: PhoneNumber)
+     *                     ^
+     * </pre>
+     *
+     * When the execution context stops at the <tt>Person</tt> instance, the
+     * property path is "address". When you validate the <tt>PhoneNumber</tt>
+     * instance now, pass "phoneNumber" as sub path to correct the property path
+     * to "address.phoneNumber":
+     *
+     * <pre>
+     * $context->validate($address->phoneNumber, 'phoneNumber');
+     * </pre>
+     *
+     * Any violations generated during the validation will be added to the
+     * violation list that you can access with {@link getViolations}.
+     *
+     * @param mixed  $value    The value to validate.
+     * @param string $subPath  The path to append to the context's property path.
+     * @param null   $groups   The groups to validate in. If you don't pass any
+     *                         groups here, the current group of the context
+     *                         will be used.
+     * @param bool   $traverse Whether to traverse the value if it is an array
+     *                         or an instance of <tt>\Traversable</tt>.
+     * @param bool   $deep     Whether to traverse the value recursively if
+     *                         it is a collection of collections.
+     */
+    public function validate($value, $subPath = '', $groups = null, $traverse = false, $deep = false);
+
+    /**
+     * Validates a value against a constraint.
+     *
+     * Use the parameter <tt>$subPath</tt> to adapt the property path for the
+     * validated value. For example, take the following object graph:
+     *
+     * <pre>
+     * (Person)---($address: Address)---($street: string)
+     *                     ^
+     * </pre>
+     *
+     * When the validator validates the <tt>Address</tt> instance, the
+     * property path stored in the execution context is "address". When you
+     * manually validate the property <tt>$street</tt> now, pass the sub path
+     * "street" to adapt the full property path to "address.street":
+     *
+     * <pre>
+     * $context->validate($address->street, new NotNull(), 'street');
+     * </pre>
+     *
+     * @param mixed                   $value       The value to validate.
+     * @param Constraint|Constraint[] $constraints The constraint(s) to validate against.
+     * @param string                  $subPath     The path to append to the context's property path.
+     * @param null                    $groups      The groups to validate in. If you don't pass any
+     *                                             groups here, the current group of the context
+     *                                             will be used.
+     */
+    public function validateValue($value, $constraints, $subPath = '', $groups = null);
+
+    /**
+     * Returns the violations generated by the validator so far.
+     *
+     * @return ConstraintViolationListInterface The constraint violation list.
+     *
+     * @api
+     */
+    public function getViolations();
+
+    /**
+     * Returns the value at which validation was started in the object graph.
+     *
+     * The validator, when given an object, traverses the properties and
+     * related objects and their properties. The root of the validation is the
+     * object from which the traversal started.
+     *
+     * The current value is returned by {@link getValue}.
+     *
+     * @return mixed The root value of the validation.
+     */
+    public function getRoot();
+
+    /**
+     * Returns the value that the validator is currently validating.
+     *
+     * If you want to retrieve the object that was originally passed to the
+     * validator, use {@link getRoot}.
+     *
+     * @return mixed The currently validated value.
+     */
+    public function getValue();
+
+    /**
+     * Returns the metadata for the currently validated value.
+     *
+     * With the core implementation, this method returns a
+     * {@link Mapping\ClassMetadata} instance if the current value is an object,
+     * a {@link Mapping\PropertyMetadata} instance if the current value is
+     * the value of a property and a {@link Mapping\GetterMetadata} instance if
+     * the validated value is the result of a getter method.
+     *
+     * If the validated value is neither of these, for example if the validator
+     * has been called with a plain value and constraint, this method returns
+     * null.
+     *
+     * @return MetadataInterface|null The metadata of the currently validated
+     *                                value.
+     */
+    public function getMetadata();
+
+    /**
+     * Returns the used metadata factory.
+     *
+     * @return MetadataFactoryInterface The metadata factory.
+     */
+    public function getMetadataFactory();
+
+    /**
+     * Returns the validation group that is currently being validated.
+     *
+     * @return string The current validation group.
+     */
+    public function getGroup();
+
+    /**
+     * Returns the class name of the current node.
+     *
+     * If the metadata of the current node does not implement
+     * {@link ClassBasedInterface} or if no metadata is available for the
+     * current node, this method returns null.
+     *
+     * @return string|null The class name or null, if no class name could be found.
+     */
+    public function getClassName();
+
+    /**
+     * Returns the property name of the current node.
+     *
+     * If the metadata of the current node does not implement
+     * {@link PropertyMetadataInterface} or if no metadata is available for the
+     * current node, this method returns null.
+     *
+     * @return string|null The property name or null, if no property name could be found.
+     */
+    public function getPropertyName();
+
+    /**
+     * Returns the property path to the value that the validator is currently
+     * validating.
+     *
+     * For example, take the following object graph:
+     *
+     * <pre>
+     * (Person)---($address: Address)---($street: string)
+     * </pre>
+     *
+     * When the <tt>Person</tt> instance is passed to the validator, the
+     * property path is initially empty. When the <tt>$address</tt> property
+     * of that person is validated, the property path is "address". When
+     * the <tt>$street</tt> property of the related <tt>Address</tt> instance
+     * is validated, the property path is "address.street".
+     *
+     * Properties of objects are prefixed with a dot in the property path.
+     * Indices of arrays or objects implementing the {@link \ArrayAccess}
+     * interface are enclosed in brackets. For example, if the property in
+     * the previous example is <tt>$addresses</tt> and contains an array
+     * of <tt>Address</tt> instance, the property path generated for the
+     * <tt>$street</tt> property of one of these addresses is for example
+     * "addresses[0].street".
+     *
+     * @param string $subPath Optional. The suffix appended to the current
+     *                        property path.
+     *
+     * @return string The current property path. The result may be an empty
+     *                string if the validator is currently validating the
+     *                root value of the validation graph.
+     */
+    public function getPropertyPath($subPath = null);
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/GlobalExecutionContextInterface.php b/core/vendor/symfony/validator/Symfony/Component/Validator/GlobalExecutionContextInterface.php
new file mode 100644
index 0000000..aff44b3
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/GlobalExecutionContextInterface.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\Validator;
+
+/**
+ * Stores the node-independent state of a validation run.
+ *
+ * When the validator validates a graph of objects, it uses two classes to
+ * store the state during the validation:
+ *
+ * <ul>
+ * <li>For each node in the validation graph (objects, properties, getters) the
+ * validator creates an instance of {@link ExecutionContextInterface} that
+ * stores the information about that node.</li>
+ * <li>One single <tt>GlobalExecutionContextInterface</tt> stores the state
+ * that is independent of the current node.</li>
+ * </ul>
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+interface GlobalExecutionContextInterface
+{
+    /**
+     * Returns the violations generated by the validator so far.
+     *
+     * @return ConstraintViolationListInterface A list of constraint violations.
+     */
+    public function getViolations();
+
+    /**
+     * Returns the value at which validation was started in the object graph.
+     *
+     * @return mixed The root value.
+     *
+     * @see ExecutionContextInterface::getRoot
+     */
+    public function getRoot();
+
+    /**
+     * Returns the visitor instance used to validate the object graph nodes.
+     *
+     * @return ValidationVisitorInterface The validation visitor.
+     */
+    public function getVisitor();
+
+    /**
+     * Returns the factory for constraint validators.
+     *
+     * @return ConstraintValidatorFactoryInterface The constraint validator factory.
+     */
+    public function getValidatorFactory();
+
+    /**
+     * Returns the factory for validation metadata objects.
+     *
+     * @return MetadataFactoryInterface The metadata factory.
+     */
+    public function getMetadataFactory();
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/GraphWalker.php b/core/vendor/symfony/validator/Symfony/Component/Validator/GraphWalker.php
new file mode 100644
index 0000000..26177b0
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/GraphWalker.php
@@ -0,0 +1,205 @@
+<?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\Validator;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\Exception\UnexpectedTypeException;
+use Symfony\Component\Validator\Mapping\ClassMetadata;
+use Symfony\Component\Validator\Mapping\MemberMetadata;
+
+/**
+ * Responsible for walking over and initializing validation on different
+ * types of items.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @deprecated Deprecated since version 2.2, to be removed in 2.3. This class
+ *             has been replaced by {@link ValidationVisitorInterface} and
+ *             {@link MetadataInterface}.
+ */
+class GraphWalker
+{
+    /**
+     * @var ValidationVisitor
+     */
+    private $visitor;
+
+    /**
+     * @var MetadataFactoryInterface
+     */
+    private $metadataFactory;
+
+    /**
+     * @var array
+     */
+    private $validatedObjects;
+
+    /**
+     * Creates a new graph walker.
+     *
+     * @param ValidationVisitor        $visitor
+     * @param MetadataFactoryInterface $metadataFactory
+     * @param array                    $validatedObjects
+     *
+     * @deprecated Deprecated since version 2.2, to be removed in 2.3.
+     */
+    public function __construct(ValidationVisitor $visitor, MetadataFactoryInterface $metadataFactory, array &$validatedObjects = array())
+    {
+        $this->visitor = $visitor;
+        $this->metadataFactory = $metadataFactory;
+        $this->validatedObjects = &$validatedObjects;
+    }
+
+    /**
+     * @return ConstraintViolationList
+     *
+     * @deprecated Deprecated since version 2.2, to be removed in 2.3.
+     */
+    public function getViolations()
+    {
+        return $this->visitor->getViolations();
+    }
+
+    /**
+     * Initialize validation on the given object using the given metadata
+     * instance and validation group.
+     *
+     * @param ClassMetadata $metadata
+     * @param object        $object       The object to validate
+     * @param string        $group        The validator group to use for validation
+     * @param string        $propertyPath
+     *
+     * @deprecated Deprecated since version 2.2, to be removed in 2.3.
+     */
+    public function walkObject(ClassMetadata $metadata, $object, $group, $propertyPath)
+    {
+        $hash = spl_object_hash($object);
+
+        // Exit, if the object is already validated for the current group
+        if (isset($this->validatedObjects[$hash][$group])) {
+            return;
+        }
+
+        // Remember validating this object before starting and possibly
+        // traversing the object graph
+        $this->validatedObjects[$hash][$group] = true;
+
+        $metadata->accept($this->visitor, $object, $group, $propertyPath);
+    }
+
+    protected function walkObjectForGroup(ClassMetadata $metadata, $object, $group, $propertyPath, $propagatedGroup = null)
+    {
+        $metadata->accept($this->visitor, $object, $group, $propertyPath, $propagatedGroup);
+    }
+
+    /**
+     * Validates a property of a class.
+     *
+     * @param Mapping\ClassMetadata $metadata
+     * @param                       $property
+     * @param                       $object
+     * @param                       $group
+     * @param                       $propertyPath
+     * @param null                  $propagatedGroup
+     *
+     * @throws Exception\UnexpectedTypeException
+     *
+     * @deprecated Deprecated since version 2.2, to be removed in 2.3.
+     */
+    public function walkProperty(ClassMetadata $metadata, $property, $object, $group, $propertyPath, $propagatedGroup = null)
+    {
+        if (!is_object($object)) {
+            throw new UnexpectedTypeException($object, 'object');
+        }
+
+        foreach ($metadata->getMemberMetadatas($property) as $member) {
+            $member->accept($this->visitor, $member->getValue($object), $group, $propertyPath, $propagatedGroup);
+        }
+    }
+
+    /**
+     * Validates a property of a class against a potential value.
+     *
+     * @param Mapping\ClassMetadata $metadata
+     * @param                       $property
+     * @param                       $value
+     * @param                       $group
+     * @param                       $propertyPath
+     *
+     * @deprecated Deprecated since version 2.2, to be removed in 2.3.
+     */
+    public function walkPropertyValue(ClassMetadata $metadata, $property, $value, $group, $propertyPath)
+    {
+        foreach ($metadata->getMemberMetadatas($property) as $member) {
+            $member->accept($this->visitor, $value, $group, $propertyPath);
+        }
+    }
+
+    protected function walkMember(MemberMetadata $metadata, $value, $group, $propertyPath, $propagatedGroup = null)
+    {
+        $metadata->accept($this->visitor, $value, $group, $propertyPath, $propagatedGroup);
+    }
+
+    /**
+     * Validates an object or an array.
+     *
+     * @param      $value
+     * @param      $group
+     * @param      $propertyPath
+     * @param      $traverse
+     * @param bool $deep
+     *
+     * @deprecated Deprecated since version 2.2, to be removed in 2.3.
+     */
+    public function walkReference($value, $group, $propertyPath, $traverse, $deep = false)
+    {
+        $this->visitor->validate($value, $group, $propertyPath, $traverse, $deep);
+    }
+
+    /**
+     * Validates a value against a constraint.
+     *
+     * @param Constraint $constraint
+     * @param            $value
+     * @param            $group
+     * @param            $propertyPath
+     * @param null       $currentClass
+     * @param null       $currentProperty
+     *
+     * @deprecated Deprecated since version 2.2, to be removed in 2.3.
+     */
+    public function walkConstraint(Constraint $constraint, $value, $group, $propertyPath, $currentClass = null, $currentProperty = null)
+    {
+        $metadata = null;
+
+        // BC code to make getCurrentClass() and getCurrentProperty() work when
+        // called from within this method
+        if (null !== $currentClass) {
+            $metadata = $this->metadataFactory->getMetadataFor($currentClass);
+
+            if (null !== $currentProperty && $metadata instanceof PropertyMetadataContainerInterface) {
+                $metadata = current($metadata->getPropertyMetadata($currentProperty));
+            }
+        }
+
+        $context = new ExecutionContext(
+            $this->visitor,
+            $metadata,
+            $value,
+            $group,
+            $propertyPath
+        );
+
+        $context->validateValue($value, $constraint);
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/GroupSequenceProviderInterface.php b/core/vendor/symfony/validator/Symfony/Component/Validator/GroupSequenceProviderInterface.php
new file mode 100644
index 0000000..62e8a5e
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/GroupSequenceProviderInterface.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\Validator;
+
+/**
+ * Defines the interface for a group sequence provider.
+ */
+interface GroupSequenceProviderInterface
+{
+    /**
+     * Returns which validation groups should be used for a certain state
+     * of the object.
+     *
+     * @return array An array of validation groups
+     */
+    public function getGroupSequence();
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/LICENSE b/core/vendor/symfony/validator/Symfony/Component/Validator/LICENSE
new file mode 100644
index 0000000..cdffe7a
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/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/validator/Symfony/Component/Validator/Mapping/BlackholeMetadataFactory.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Mapping/BlackholeMetadataFactory.php
new file mode 100644
index 0000000..4cd1175
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Mapping/BlackholeMetadataFactory.php
@@ -0,0 +1,25 @@
+<?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\Validator\Mapping;
+
+/**
+ * Simple implementation of ClassMetadataFactoryInterface that can be used when using ValidatorInterface::validateValue().
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class BlackholeMetadataFactory implements ClassMetadataFactoryInterface
+{
+    public function getClassMetadata($class)
+    {
+        throw new \LogicException('BlackholeClassMetadataFactory only works with ValidatorInterface::validateValue().');
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Cache/ApcCache.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Cache/ApcCache.php
new file mode 100644
index 0000000..226fab3
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Cache/ApcCache.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\Validator\Mapping\Cache;
+
+use Symfony\Component\Validator\Mapping\ClassMetadata;
+
+class ApcCache implements CacheInterface
+{
+    private $prefix;
+
+    public function __construct($prefix)
+    {
+        if (!extension_loaded('apc')) {
+            throw new \RuntimeException('Unable to use ApcCache to cache validator mappings as APC is not enabled.');
+        }
+
+        $this->prefix = $prefix;
+    }
+
+    public function has($class)
+    {
+        if (!function_exists('apc_exists')) {
+            $exists = false;
+
+            apc_fetch($this->prefix.$class, $exists);
+
+            return $exists;
+        }
+
+        return apc_exists($this->prefix.$class);
+    }
+
+    public function read($class)
+    {
+        return apc_fetch($this->prefix.$class);
+    }
+
+    public function write(ClassMetadata $metadata)
+    {
+        apc_store($this->prefix.$metadata->getClassName(), $metadata);
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Cache/CacheInterface.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Cache/CacheInterface.php
new file mode 100644
index 0000000..2f9b031
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Cache/CacheInterface.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\Validator\Mapping\Cache;
+
+use Symfony\Component\Validator\Mapping\ClassMetadata;
+
+/**
+ * Persists ClassMetadata instances in a cache
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+interface CacheInterface
+{
+    /**
+     * Returns whether metadata for the given class exists in the cache
+     *
+     * @param string $class
+     */
+    public function has($class);
+
+    /**
+     * Returns the metadata for the given class from the cache
+     *
+     * @param string $class Class Name
+     *
+     * @return ClassMetadata|false A ClassMetadata instance or false on miss
+     */
+    public function read($class);
+
+    /**
+     * Stores a class metadata in the cache
+     *
+     * @param ClassMetadata $metadata A Class Metadata
+     */
+    public function write(ClassMetadata $metadata);
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Mapping/ClassMetadata.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Mapping/ClassMetadata.php
new file mode 100644
index 0000000..40dc41a
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Mapping/ClassMetadata.php
@@ -0,0 +1,407 @@
+<?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\Validator\Mapping;
+
+use Symfony\Component\Validator\ValidationVisitorInterface;
+use Symfony\Component\Validator\PropertyMetadataContainerInterface;
+use Symfony\Component\Validator\ClassBasedInterface;
+use Symfony\Component\Validator\MetadataInterface;
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\Exception\ConstraintDefinitionException;
+use Symfony\Component\Validator\Exception\GroupDefinitionException;
+
+/**
+ * Represents all the configured constraints on a given class.
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ * @author Fabien Potencier <fabien@symfony.com>
+ */
+class ClassMetadata extends ElementMetadata implements MetadataInterface, ClassBasedInterface, PropertyMetadataContainerInterface
+{
+    /**
+     * @var string
+     */
+    public $name;
+
+    /**
+     * @var string
+     */
+    public $defaultGroup;
+
+    /**
+     * @var MemberMetadata[]
+     */
+    public $members = array();
+
+    /**
+     * @var PropertyMetadata[]
+     */
+    public $properties = array();
+
+    /**
+     * @var GetterMetadata[]
+     */
+    public $getters = array();
+
+    /**
+     * @var array
+     */
+    public $groupSequence = array();
+
+    /**
+     * @var Boolean
+     */
+    public $groupSequenceProvider = false;
+
+    /**
+     * @var \ReflectionClass
+     */
+    private $reflClass;
+
+    /**
+     * Constructs a metadata for the given class
+     *
+     * @param string $class
+     */
+    public function __construct($class)
+    {
+        $this->name = $class;
+        // class name without namespace
+        if (false !== $nsSep = strrpos($class, '\\')) {
+            $this->defaultGroup = substr($class, $nsSep + 1);
+        } else {
+            $this->defaultGroup = $class;
+        }
+    }
+    
+    public function accept(ValidationVisitorInterface $visitor, $value, $group, $propertyPath, $propagatedGroup = null)
+    {
+        if (null === $propagatedGroup && Constraint::DEFAULT_GROUP === $group
+                && ($this->hasGroupSequence() || $this->isGroupSequenceProvider())) {
+            if ($this->hasGroupSequence()) {
+                $groups = $this->getGroupSequence();
+            } else {
+                $groups = $value->getGroupSequence();
+            }
+
+            foreach ($groups as $group) {
+                $this->accept($visitor, $value, $group, $propertyPath, Constraint::DEFAULT_GROUP);
+
+                if (count($visitor->getViolations()) > 0) {
+                    break;
+                }
+            }
+
+            return;
+        }
+
+        $visitor->visit($this, $value, $group, $propertyPath);
+
+        if (null !== $value) {
+            $pathPrefix = empty($propertyPath) ? '' : $propertyPath.'.';
+
+            foreach ($this->getConstrainedProperties() as $property) {
+                foreach ($this->getMemberMetadatas($property) as $member) {
+                    $member->accept($visitor, $member->getValue($value), $group, $pathPrefix.$property, $propagatedGroup);
+                }
+            }
+        }
+    }
+
+    /**
+     * Returns the properties to be serialized
+     *
+     * @return array
+     */
+    public function __sleep()
+    {
+        return array_merge(parent::__sleep(), array(
+            'getters',
+            'groupSequence',
+            'groupSequenceProvider',
+            'members',
+            'name',
+            'properties',
+            'defaultGroup'
+        ));
+    }
+
+    /**
+     * Returns the fully qualified name of the class
+     *
+     * @return string  The fully qualified class name
+     */
+    public function getClassName()
+    {
+        return $this->name;
+    }
+
+    /**
+     * Returns the name of the default group for this class
+     *
+     * For each class, the group "Default" is an alias for the group
+     * "<ClassName>", where <ClassName> is the non-namespaced name of the
+     * class. All constraints implicitly or explicitly assigned to group
+     * "Default" belong to both of these groups, unless the class defines
+     * a group sequence.
+     *
+     * If a class defines a group sequence, validating the class in "Default"
+     * will validate the group sequence. The constraints assigned to "Default"
+     * can still be validated by validating the class in "<ClassName>".
+     *
+     * @return string  The name of the default group
+     */
+    public function getDefaultGroup()
+    {
+        return $this->defaultGroup;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function addConstraint(Constraint $constraint)
+    {
+        if (!in_array(Constraint::CLASS_CONSTRAINT, (array) $constraint->getTargets())) {
+            throw new ConstraintDefinitionException(sprintf(
+                'The constraint %s cannot be put on classes',
+                get_class($constraint)
+            ));
+        }
+
+        $constraint->addImplicitGroupName($this->getDefaultGroup());
+
+        parent::addConstraint($constraint);
+    }
+
+    /**
+     * Adds a constraint to the given property.
+     *
+     * @param string     $property   The name of the property
+     * @param Constraint $constraint The constraint
+     *
+     * @return ClassMetadata This object
+     */
+    public function addPropertyConstraint($property, Constraint $constraint)
+    {
+        if (!isset($this->properties[$property])) {
+            $this->properties[$property] = new PropertyMetadata($this->getClassName(), $property);
+
+            $this->addMemberMetadata($this->properties[$property]);
+        }
+
+        $constraint->addImplicitGroupName($this->getDefaultGroup());
+
+        $this->properties[$property]->addConstraint($constraint);
+
+        return $this;
+    }
+
+    /**
+     * Adds a constraint to the getter of the given property.
+     *
+     * The name of the getter is assumed to be the name of the property with an
+     * uppercased first letter and either the prefix "get" or "is".
+     *
+     * @param string     $property   The name of the property
+     * @param Constraint $constraint The constraint
+     *
+     * @return ClassMetadata This object
+     */
+    public function addGetterConstraint($property, Constraint $constraint)
+    {
+        if (!isset($this->getters[$property])) {
+            $this->getters[$property] = new GetterMetadata($this->getClassName(), $property);
+
+            $this->addMemberMetadata($this->getters[$property]);
+        }
+
+        $constraint->addImplicitGroupName($this->getDefaultGroup());
+
+        $this->getters[$property]->addConstraint($constraint);
+
+        return $this;
+    }
+
+    /**
+     * Merges the constraints of the given metadata into this object.
+     *
+     * @param ClassMetadata $source The source metadata
+     */
+    public function mergeConstraints(ClassMetadata $source)
+    {
+        foreach ($source->getConstraints() as $constraint) {
+            $this->addConstraint(clone $constraint);
+        }
+
+        foreach ($source->getConstrainedProperties() as $property) {
+            foreach ($source->getMemberMetadatas($property) as $member) {
+                $member = clone $member;
+
+                foreach ($member->getConstraints() as $constraint) {
+                    $constraint->addImplicitGroupName($this->getDefaultGroup());
+                }
+
+                $this->addMemberMetadata($member);
+
+                if (!$member->isPrivate()) {
+                    $property = $member->getPropertyName();
+
+                    if ($member instanceof PropertyMetadata && !isset($this->properties[$property])) {
+                        $this->properties[$property] = $member;
+                    } elseif ($member instanceof GetterMetadata && !isset($this->getters[$property])) {
+                        $this->getters[$property] = $member;
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Adds a member metadata.
+     *
+     * @param MemberMetadata $metadata
+     */
+    protected function addMemberMetadata(MemberMetadata $metadata)
+    {
+        $property = $metadata->getPropertyName();
+
+        $this->members[$property][] = $metadata;
+    }
+
+    /**
+     * Returns true if metadatas of members is present for the given property.
+     *
+     * @param string $property The name of the property
+     *
+     * @return Boolean
+     */
+    public function hasMemberMetadatas($property)
+    {
+        return array_key_exists($property, $this->members);
+    }
+
+    /**
+     * Returns all metadatas of members describing the given property.
+     *
+     * @param string $property The name of the property
+     *
+     * @return MemberMetadata[] An array of MemberMetadata
+     */
+    public function getMemberMetadatas($property)
+    {
+        return $this->members[$property];
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getPropertyMetadata($property)
+    {
+        return $this->members[$property];
+    }
+
+    /**
+     * Returns all properties for which constraints are defined.
+     *
+     * @return array An array of property names
+     */
+    public function getConstrainedProperties()
+    {
+        return array_keys($this->members);
+    }
+
+    /**
+     * Sets the default group sequence for this class.
+     *
+     * @param array $groups An array of group names
+     */
+    public function setGroupSequence(array $groups)
+    {
+        if ($this->isGroupSequenceProvider()) {
+            throw new GroupDefinitionException('Defining a static group sequence is not allowed with a group sequence provider');
+        }
+
+        if (in_array(Constraint::DEFAULT_GROUP, $groups, true)) {
+            throw new GroupDefinitionException(sprintf('The group "%s" is not allowed in group sequences', Constraint::DEFAULT_GROUP));
+        }
+
+        if (!in_array($this->getDefaultGroup(), $groups, true)) {
+            throw new GroupDefinitionException(sprintf('The group "%s" is missing in the group sequence', $this->getDefaultGroup()));
+        }
+
+        $this->groupSequence = $groups;
+
+        return $this;
+    }
+
+    /**
+     * Returns whether this class has an overridden default group sequence.
+     *
+     * @return Boolean
+     */
+    public function hasGroupSequence()
+    {
+        return count($this->groupSequence) > 0;
+    }
+
+    /**
+     * Returns the default group sequence for this class.
+     *
+     * @return array An array of group names
+     */
+    public function getGroupSequence()
+    {
+        return $this->groupSequence;
+    }
+
+    /**
+     * Returns a ReflectionClass instance for this class.
+     *
+     * @return \ReflectionClass
+     */
+    public function getReflectionClass()
+    {
+        if (!$this->reflClass) {
+            $this->reflClass = new \ReflectionClass($this->getClassName());
+        }
+
+        return $this->reflClass;
+    }
+
+    /**
+     * Sets whether a group sequence provider should be used.
+     *
+     * @param Boolean $active
+     */
+    public function setGroupSequenceProvider($active)
+    {
+        if ($this->hasGroupSequence()) {
+            throw new GroupDefinitionException('Defining a group sequence provider is not allowed with a static group sequence');
+        }
+
+        if (!$this->getReflectionClass()->implementsInterface('Symfony\Component\Validator\GroupSequenceProviderInterface')) {
+            throw new GroupDefinitionException(sprintf('Class "%s" must implement GroupSequenceProviderInterface', $this->name));
+        }
+
+        $this->groupSequenceProvider = $active;
+    }
+
+    /**
+     * Returns whether the class is a group sequence provider.
+     *
+     * @return Boolean
+     */
+    public function isGroupSequenceProvider()
+    {
+        return $this->groupSequenceProvider;
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Mapping/ClassMetadataFactory.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Mapping/ClassMetadataFactory.php
new file mode 100644
index 0000000..279d833
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Mapping/ClassMetadataFactory.php
@@ -0,0 +1,123 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Mapping;
+
+use Symfony\Component\Validator\MetadataFactoryInterface;
+use Symfony\Component\Validator\Exception\NoSuchMetadataException;
+use Symfony\Component\Validator\Mapping\Loader\LoaderInterface;
+use Symfony\Component\Validator\Mapping\Cache\CacheInterface;
+
+/**
+ * A factory for creating metadata for PHP classes.
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+class ClassMetadataFactory implements ClassMetadataFactoryInterface, MetadataFactoryInterface
+{
+    /**
+     * The loader for loading the class metadata
+     * @var LoaderInterface
+     */
+    protected $loader;
+
+    /**
+     * The cache for caching class metadata
+     * @var CacheInterface
+     */
+    protected $cache;
+
+    protected $loadedClasses = array();
+
+    public function __construct(LoaderInterface $loader = null, CacheInterface $cache = null)
+    {
+        $this->loader = $loader;
+        $this->cache = $cache;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getMetadataFor($value)
+    {
+        if (!is_object($value) && !is_string($value)) {
+            throw new NoSuchMetadataException('Cannot create metadata for non-objects. Got: ' . gettype($value));
+        }
+
+        $class = ltrim(is_object($value) ? get_class($value) : $value, '\\');
+
+        if (isset($this->loadedClasses[$class])) {
+            return $this->loadedClasses[$class];
+        }
+
+        if (null !== $this->cache && false !== ($this->loadedClasses[$class] = $this->cache->read($class))) {
+            return $this->loadedClasses[$class];
+        }
+
+        if (!class_exists($class) && !interface_exists($class)) {
+            throw new NoSuchMetadataException('The class or interface "' . $class . '" does not exist.');
+        }
+
+        $metadata = new ClassMetadata($class);
+
+        // Include constraints from the parent class
+        if ($parent = $metadata->getReflectionClass()->getParentClass()) {
+            $metadata->mergeConstraints($this->getClassMetadata($parent->name));
+        }
+
+        // Include constraints from all implemented interfaces
+        foreach ($metadata->getReflectionClass()->getInterfaces() as $interface) {
+            if ('Symfony\Component\Validator\GroupSequenceProviderInterface' === $interface->name) {
+                continue;
+            }
+            $metadata->mergeConstraints($this->getClassMetadata($interface->name));
+        }
+
+        if (null !== $this->loader) {
+            $this->loader->loadClassMetadata($metadata);
+        }
+
+        if (null !== $this->cache) {
+            $this->cache->write($metadata);
+        }
+
+        return $this->loadedClasses[$class] = $metadata;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function hasMetadataFor($value)
+    {
+        if (!is_object($value) && !is_string($value)) {
+            return false;
+        }
+
+        $class = ltrim(is_object($value) ? get_class($value) : $value, '\\');
+
+        if (class_exists($class) || interface_exists($class)) {
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * {@inheritdoc}
+     *
+     * @deprecated Deprecated since version 2.2, to be removed in 2.3. Use
+     *             {@link getMetadataFor} instead.
+     */
+    public function getClassMetadata($class)
+    {
+        return $this->getMetadataFor($class);
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Mapping/ClassMetadataFactoryAdapter.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Mapping/ClassMetadataFactoryAdapter.php
new file mode 100644
index 0000000..017e4e4
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Mapping/ClassMetadataFactoryAdapter.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\Validator\Mapping;
+
+use Symfony\Component\Validator\MetadataFactoryInterface;
+use Symfony\Component\Validator\Exception\NoSuchMetadataException;
+
+/**
+ * An adapter for exposing {@link ClassMetadataFactoryInterface} implementations
+ * under the new {@link MetadataFactoryInterface}.
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+class ClassMetadataFactoryAdapter implements MetadataFactoryInterface
+{
+    /**
+     * @var ClassMetadataFactoryInterface
+     */
+    private $innerFactory;
+
+    public function __construct(ClassMetadataFactoryInterface $innerFactory)
+    {
+        $this->innerFactory = $innerFactory;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getMetadataFor($value)
+    {
+        $class = is_object($value) ? get_class($value) : $value;
+        $metadata = $this->innerFactory->getClassMetadata($class);
+
+        if (null === $metadata) {
+            throw new NoSuchMetadataException('No metadata exists for class '. $class);
+        }
+
+        return $metadata;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function hasMetadataFor($value)
+    {
+        $class = is_object($value) ? get_class($value) : $value;
+
+        return null !== $this->innerFactory->getClassMetadata($class);
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Mapping/ClassMetadataFactoryInterface.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Mapping/ClassMetadataFactoryInterface.php
new file mode 100644
index 0000000..42fff5c
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Mapping/ClassMetadataFactoryInterface.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\Validator\Mapping;
+
+/**
+ * A factory for {@link ClassMetadata} objects.
+ *
+ * @deprecated Deprecated since version 2.2, to be removed in 2.3. Implement
+ *             {@link \Symfony\Component\Validator\MetadataFactoryInterface} instead.
+ */
+interface ClassMetadataFactoryInterface
+{
+    /**
+     * Returns metadata for a given class.
+     *
+     * @param string $class The class name.
+     *
+     * @return ClassMetadata The class metadata instance.
+     */
+    public function getClassMetadata($class);
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Mapping/ElementMetadata.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Mapping/ElementMetadata.php
new file mode 100644
index 0000000..1504eb7
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Mapping/ElementMetadata.php
@@ -0,0 +1,105 @@
+<?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\Validator\Mapping;
+
+use Symfony\Component\Validator\Constraint;
+
+abstract class ElementMetadata
+{
+    /**
+     * @var Constraint[]
+     */
+    public $constraints = array();
+
+    /**
+     * @var array
+     */
+    public $constraintsByGroup = array();
+
+    /**
+     * Returns the names of the properties that should be serialized.
+     *
+     * @return array
+     */
+    public function __sleep()
+    {
+        return array(
+            'constraints',
+            'constraintsByGroup',
+        );
+    }
+
+    /**
+     * Clones this object.
+     */
+    public function __clone()
+    {
+        $constraints = $this->constraints;
+
+        $this->constraints = array();
+        $this->constraintsByGroup = array();
+
+        foreach ($constraints as $constraint) {
+            $this->addConstraint(clone $constraint);
+        }
+    }
+
+    /**
+     * Adds a constraint to this element.
+     *
+     * @param Constraint $constraint
+     */
+    public function addConstraint(Constraint $constraint)
+    {
+        $this->constraints[] = $constraint;
+
+        foreach ($constraint->groups as $group) {
+            $this->constraintsByGroup[$group][] = $constraint;
+        }
+
+        return $this;
+    }
+
+    /**
+     * Returns all constraints of this element.
+     *
+     * @return Constraint[] An array of Constraint instances
+     */
+    public function getConstraints()
+    {
+        return $this->constraints;
+    }
+
+    /**
+     * Returns whether this element has any constraints.
+     *
+     * @return Boolean
+     */
+    public function hasConstraints()
+    {
+        return count($this->constraints) > 0;
+    }
+
+    /**
+     * Returns the constraints of the given group and global ones (* group).
+     *
+     * @param string $group The group name
+     *
+     * @return array An array with all Constraint instances belonging to the group
+     */
+    public function findConstraints($group)
+    {
+        return isset($this->constraintsByGroup[$group])
+                ? $this->constraintsByGroup[$group]
+                : array();
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Mapping/GetterMetadata.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Mapping/GetterMetadata.php
new file mode 100644
index 0000000..38cc6e4
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Mapping/GetterMetadata.php
@@ -0,0 +1,55 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Mapping;
+
+use Symfony\Component\Validator\Exception\ValidatorException;
+
+class GetterMetadata extends MemberMetadata
+{
+    /**
+     * Constructor.
+     *
+     * @param string $class    The class the getter is defined on
+     * @param string $property The property which the getter returns
+     */
+    public function __construct($class, $property)
+    {
+        $getMethod = 'get'.ucfirst($property);
+        $isMethod = 'is'.ucfirst($property);
+
+        if (method_exists($class, $getMethod)) {
+            $method = $getMethod;
+        } elseif (method_exists($class, $isMethod)) {
+            $method = $isMethod;
+        } else {
+            throw new ValidatorException(sprintf('Neither method %s nor %s exists in class %s', $getMethod, $isMethod, $class));
+        }
+
+        parent::__construct($class, $method, $property);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getPropertyValue($object)
+    {
+        return $this->getReflectionMember()->invoke($object);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected function newReflectionMember()
+    {
+        return new \ReflectionMethod($this->getClassName(), $this->getName());
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/AbstractLoader.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/AbstractLoader.php
new file mode 100644
index 0000000..54c0dbe
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/AbstractLoader.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\Validator\Mapping\Loader;
+
+use Symfony\Component\Validator\Exception\MappingException;
+
+abstract class AbstractLoader implements LoaderInterface
+{
+    /**
+     * Contains all known namespaces indexed by their prefix
+     * @var array
+     */
+    protected $namespaces;
+
+    /**
+     * Adds a namespace alias.
+     *
+     * @param string $alias     The alias
+     * @param string $namespace The PHP namespace
+     */
+    protected function addNamespaceAlias($alias, $namespace)
+    {
+        $this->namespaces[$alias] = $namespace;
+    }
+
+    /**
+     * Creates a new constraint instance for the given constraint name.
+     *
+     * @param string $name The constraint name. Either a constraint relative
+     *                        to the default constraint namespace, or a fully
+     *                        qualified class name
+     * @param array $options The constraint options
+     *
+     * @return Constraint
+     *
+     * @throws MappingException If the namespace prefix is undefined
+     */
+    protected function newConstraint($name, $options)
+    {
+        if (strpos($name, '\\') !== false && class_exists($name)) {
+            $className = (string) $name;
+        } elseif (strpos($name, ':') !== false) {
+            list($prefix, $className) = explode(':', $name, 2);
+
+            if (!isset($this->namespaces[$prefix])) {
+                throw new MappingException(sprintf('Undefined namespace prefix "%s"', $prefix));
+            }
+
+            $className = $this->namespaces[$prefix].$className;
+        } else {
+            $className = 'Symfony\\Component\\Validator\\Constraints\\'.$name;
+        }
+
+        return new $className($options);
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/AnnotationLoader.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/AnnotationLoader.php
new file mode 100644
index 0000000..0e7e89b
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/AnnotationLoader.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\Validator\Mapping\Loader;
+
+use Doctrine\Common\Annotations\Reader;
+use Symfony\Component\Validator\Exception\MappingException;
+use Symfony\Component\Validator\Mapping\ClassMetadata;
+use Symfony\Component\Validator\Constraints\GroupSequence;
+use Symfony\Component\Validator\Constraints\GroupSequenceProvider;
+use Symfony\Component\Validator\Constraint;
+
+class AnnotationLoader implements LoaderInterface
+{
+    protected $reader;
+
+    public function __construct(Reader $reader)
+    {
+        $this->reader = $reader;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function loadClassMetadata(ClassMetadata $metadata)
+    {
+        $reflClass = $metadata->getReflectionClass();
+        $className = $reflClass->name;
+        $loaded = false;
+
+        foreach ($this->reader->getClassAnnotations($reflClass) as $constraint) {
+            if ($constraint instanceof GroupSequence) {
+                $metadata->setGroupSequence($constraint->groups);
+            } elseif ($constraint instanceof GroupSequenceProvider) {
+                $metadata->setGroupSequenceProvider(true);
+            } elseif ($constraint instanceof Constraint) {
+                $metadata->addConstraint($constraint);
+            }
+
+            $loaded = true;
+        }
+
+        foreach ($reflClass->getProperties() as $property) {
+            if ($property->getDeclaringClass()->name == $className) {
+                foreach ($this->reader->getPropertyAnnotations($property) as $constraint) {
+                    if ($constraint instanceof Constraint) {
+                        $metadata->addPropertyConstraint($property->name, $constraint);
+                    }
+
+                    $loaded = true;
+                }
+            }
+        }
+
+        foreach ($reflClass->getMethods() as $method) {
+            if ($method->getDeclaringClass()->name ==  $className) {
+                foreach ($this->reader->getMethodAnnotations($method) as $constraint) {
+                    if ($constraint instanceof Constraint) {
+                        if (preg_match('/^(get|is)(.+)$/i', $method->name, $matches)) {
+                            $metadata->addGetterConstraint(lcfirst($matches[2]), $constraint);
+                        } else {
+                            throw new MappingException(sprintf('The constraint on "%s::%s" cannot be added. Constraints can only be added on methods beginning with "get" or "is".', $className, $method->name));
+                        }
+                    }
+
+                    $loaded = true;
+                }
+            }
+        }
+
+        return $loaded;
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/FileLoader.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/FileLoader.php
new file mode 100644
index 0000000..2b8c6c0
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/FileLoader.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\Validator\Mapping\Loader;
+
+use Symfony\Component\Validator\Exception\MappingException;
+
+abstract class FileLoader extends AbstractLoader
+{
+    protected $file;
+
+    /**
+     * Constructor.
+     *
+     * @param string $file The mapping file to load
+     *
+     * @throws MappingException if the mapping file does not exist
+     * @throws MappingException if the mapping file is not readable
+     */
+    public function __construct($file)
+    {
+        if (!is_file($file)) {
+            throw new MappingException(sprintf('The mapping file %s does not exist', $file));
+        }
+
+        if (!is_readable($file)) {
+            throw new MappingException(sprintf('The mapping file %s is not readable', $file));
+        }
+
+        $this->file = $file;
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/FilesLoader.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/FilesLoader.php
new file mode 100644
index 0000000..a20c797
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/FilesLoader.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\Validator\Mapping\Loader;
+
+/**
+ * Creates mapping loaders for array of files.
+ *
+ * Abstract class, used by
+ *
+ * @author Bulat Shakirzyanov <mallluhuct@gmail.com>
+ *
+ * @see    Symfony\Component\Validator\Mapping\Loader\YamlFileLoader
+ * @see    Symfony\Component\Validator\Mapping\Loader\XmlFileLoader
+ */
+abstract class FilesLoader extends LoaderChain
+{
+    /**
+     * Array of mapping files.
+     *
+     * @param array $paths Array of file paths
+     */
+    public function __construct(array $paths)
+    {
+        parent::__construct($this->getFileLoaders($paths));
+    }
+
+    /**
+     * Array of mapping files.
+     *
+     * @param array $paths Array of file paths
+     *
+     * @return LoaderInterface[] Array of metadata loaders
+     */
+    protected function getFileLoaders($paths)
+    {
+        $loaders = array();
+        foreach ($paths as $path) {
+            $loaders[] = $this->getFileLoaderInstance($path);
+        }
+
+        return $loaders;
+    }
+
+    /**
+     * Takes mapping file path.
+     *
+     * @param string $file
+     *
+     * @return LoaderInterface
+     */
+    abstract protected function getFileLoaderInstance($file);
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/LoaderChain.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/LoaderChain.php
new file mode 100644
index 0000000..a0c9ef1
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/LoaderChain.php
@@ -0,0 +1,62 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Mapping\Loader;
+
+use Symfony\Component\Validator\Exception\MappingException;
+use Symfony\Component\Validator\Mapping\ClassMetadata;
+
+/**
+ * Calls multiple LoaderInterface instances in a chain
+ *
+ * This class accepts multiple instances of LoaderInterface to be passed to the
+ * constructor. When loadClassMetadata() is called, the same method is called
+ * in <em>all</em> of these loaders, regardless of whether any of them was
+ * successful or not.
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+class LoaderChain implements LoaderInterface
+{
+    protected $loaders;
+
+    /**
+     * Accepts a list of LoaderInterface instances
+     *
+     * @param LoaderInterface[] $loaders An array of LoaderInterface instances
+     *
+     * @throws MappingException If any of the loaders does not implement LoaderInterface
+     */
+    public function __construct(array $loaders)
+    {
+        foreach ($loaders as $loader) {
+            if (!$loader instanceof LoaderInterface) {
+                throw new MappingException(sprintf('Class %s is expected to implement LoaderInterface', get_class($loader)));
+            }
+        }
+
+        $this->loaders = $loaders;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function loadClassMetadata(ClassMetadata $metadata)
+    {
+        $success = false;
+
+        foreach ($this->loaders as $loader) {
+            $success = $loader->loadClassMetadata($metadata) || $success;
+        }
+
+        return $success;
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/LoaderInterface.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/LoaderInterface.php
new file mode 100644
index 0000000..bd679b0
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/LoaderInterface.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\Validator\Mapping\Loader;
+
+use Symfony\Component\Validator\Mapping\ClassMetadata;
+
+interface LoaderInterface
+{
+    /**
+     * Load a Class Metadata.
+     *
+     * @param ClassMetadata $metadata A metadata
+     *
+     * @return Boolean
+     */
+    public function loadClassMetadata(ClassMetadata $metadata);
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/StaticMethodLoader.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/StaticMethodLoader.php
new file mode 100644
index 0000000..64d3df7
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/StaticMethodLoader.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\Validator\Mapping\Loader;
+
+use Symfony\Component\Validator\Exception\MappingException;
+use Symfony\Component\Validator\Mapping\ClassMetadata;
+
+class StaticMethodLoader implements LoaderInterface
+{
+    protected $methodName;
+
+    public function __construct($methodName = 'loadValidatorMetadata')
+    {
+        $this->methodName = $methodName;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function loadClassMetadata(ClassMetadata $metadata)
+    {
+        /** @var \ReflectionClass $reflClass */
+        $reflClass = $metadata->getReflectionClass();
+
+        if (!$reflClass->isInterface() && $reflClass->hasMethod($this->methodName)) {
+            $reflMethod = $reflClass->getMethod($this->methodName);
+
+            if (!$reflMethod->isStatic()) {
+                throw new MappingException(sprintf('The method %s::%s should be static', $reflClass->name, $this->methodName));
+            }
+
+            if ($reflMethod->getDeclaringClass()->name != $reflClass->name) {
+                return false;
+            }
+
+            $reflMethod->invoke(null, $metadata);
+
+            return true;
+        }
+
+        return false;
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/XmlFileLoader.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/XmlFileLoader.php
new file mode 100644
index 0000000..4925abb
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/XmlFileLoader.php
@@ -0,0 +1,238 @@
+<?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\Validator\Mapping\Loader;
+
+use Symfony\Component\Validator\Exception\MappingException;
+use Symfony\Component\Validator\Mapping\ClassMetadata;
+
+class XmlFileLoader extends FileLoader
+{
+    /**
+     * An array of SimpleXMLElement instances.
+     *
+     * @var \SimpleXMLElement[]
+     */
+    protected $classes = null;
+
+    /**
+     * {@inheritDoc}
+     */
+    public function loadClassMetadata(ClassMetadata $metadata)
+    {
+        if (null === $this->classes) {
+            $this->classes = array();
+            $xml = $this->parseFile($this->file);
+
+            foreach ($xml->namespace as $namespace) {
+                $this->addNamespaceAlias((string) $namespace['prefix'], trim((string) $namespace));
+            }
+
+            foreach ($xml->class as $class) {
+                $this->classes[(string) $class['name']] = $class;
+            }
+        }
+
+        if (isset($this->classes[$metadata->getClassName()])) {
+            $xml = $this->classes[$metadata->getClassName()];
+
+            foreach ($xml->{'group-sequence-provider'} as $provider) {
+                $metadata->setGroupSequenceProvider(true);
+            }
+
+            foreach ($xml->{'group-sequence'} as $groupSequence) {
+                if (count($groupSequence->value) > 0) {
+                    $metadata->setGroupSequence($this->parseValues($groupSequence[0]->value));
+                }
+            }
+
+            foreach ($this->parseConstraints($xml->constraint) as $constraint) {
+                $metadata->addConstraint($constraint);
+            }
+
+            foreach ($xml->property as $property) {
+                foreach ($this->parseConstraints($property->constraint) as $constraint) {
+                    $metadata->addPropertyConstraint((string) $property['name'], $constraint);
+                }
+            }
+
+            foreach ($xml->getter as $getter) {
+                foreach ($this->parseConstraints($getter->constraint) as $constraint) {
+                    $metadata->addGetterConstraint((string) $getter['property'], $constraint);
+                }
+            }
+
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Parses a collection of "constraint" XML nodes.
+     *
+     * @param \SimpleXMLElement $nodes The XML nodes
+     *
+     * @return array The Constraint instances
+     */
+    protected function parseConstraints(\SimpleXMLElement $nodes)
+    {
+        $constraints = array();
+
+        foreach ($nodes as $node) {
+            if (count($node) > 0) {
+                if (count($node->value) > 0) {
+                    $options = $this->parseValues($node->value);
+                } elseif (count($node->constraint) > 0) {
+                    $options = $this->parseConstraints($node->constraint);
+                } elseif (count($node->option) > 0) {
+                    $options = $this->parseOptions($node->option);
+                } else {
+                    $options = array();
+                }
+            } elseif (strlen((string) $node) > 0) {
+                $options = trim($node);
+            } else {
+                $options = null;
+            }
+
+            $constraints[] = $this->newConstraint($node['name'], $options);
+        }
+
+        return $constraints;
+    }
+
+    /**
+     * Parses a collection of "value" XML nodes.
+     *
+     * @param \SimpleXMLElement $nodes The XML nodes
+     *
+     * @return array The values
+     */
+    protected function parseValues(\SimpleXMLElement $nodes)
+    {
+        $values = array();
+
+        foreach ($nodes as $node) {
+            if (count($node) > 0) {
+                if (count($node->value) > 0) {
+                    $value = $this->parseValues($node->value);
+                } elseif (count($node->constraint) > 0) {
+                    $value = $this->parseConstraints($node->constraint);
+                } else {
+                    $value = array();
+                }
+            } else {
+                $value = trim($node);
+            }
+
+            if (isset($node['key'])) {
+                $values[(string) $node['key']] = $value;
+            } else {
+                $values[] = $value;
+            }
+        }
+
+        return $values;
+    }
+
+    /**
+     * Parses a collection of "option" XML nodes.
+     *
+     * @param \SimpleXMLElement $nodes The XML nodes
+     *
+     * @return array The options
+     */
+    protected function parseOptions(\SimpleXMLElement $nodes)
+    {
+        $options = array();
+
+        foreach ($nodes as $node) {
+            if (count($node) > 0) {
+                if (count($node->value) > 0) {
+                    $value = $this->parseValues($node->value);
+                } elseif (count($node->constraint) > 0) {
+                    $value = $this->parseConstraints($node->constraint);
+                } else {
+                    $value = array();
+                }
+            } else {
+                $value = trim($node);
+            }
+
+            $options[(string) $node['name']] = $value;
+        }
+
+        return $options;
+    }
+
+    /**
+     * Parse a XML File.
+     *
+     * @param string $file Path of file
+     *
+     * @return SimpleXMLElement
+     *
+     * @throws MappingException
+     */
+    protected function parseFile($file)
+    {
+        $internalErrors = libxml_use_internal_errors(true);
+        $disableEntities = libxml_disable_entity_loader(true);
+        libxml_clear_errors();
+
+        $dom = new \DOMDocument();
+        $dom->validateOnParse = true;
+        if (!$dom->loadXML(file_get_contents($file), LIBXML_NONET | (defined('LIBXML_COMPACT') ? LIBXML_COMPACT : 0))) {
+            libxml_disable_entity_loader($disableEntities);
+
+            throw new MappingException(implode("\n", $this->getXmlErrors($internalErrors)));
+        }
+
+        libxml_disable_entity_loader($disableEntities);
+
+        if (!$dom->schemaValidate(__DIR__.'/schema/dic/constraint-mapping/constraint-mapping-1.0.xsd')) {
+            throw new MappingException(implode("\n", $this->getXmlErrors($internalErrors)));
+        }
+
+        $dom->normalizeDocument();
+
+        libxml_use_internal_errors($internalErrors);
+
+        foreach ($dom->childNodes as $child) {
+            if ($child->nodeType === XML_DOCUMENT_TYPE_NODE) {
+                throw new MappingException('Document types are not allowed.');
+            }
+        }
+
+        return simplexml_import_dom($dom);
+    }
+
+    protected function getXmlErrors($internalErrors)
+    {
+        $errors = array();
+        foreach (libxml_get_errors() as $error) {
+            $errors[] = sprintf('[%s %s] %s (in %s - line %d, column %d)',
+                LIBXML_ERR_WARNING == $error->level ? 'WARNING' : 'ERROR',
+                $error->code,
+                trim($error->message),
+                $error->file ? $error->file : 'n/a',
+                $error->line,
+                $error->column
+            );
+        }
+
+        libxml_clear_errors();
+        libxml_use_internal_errors($internalErrors);
+
+        return $errors;
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/XmlFilesLoader.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/XmlFilesLoader.php
new file mode 100644
index 0000000..a4628cf
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/XmlFilesLoader.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\Validator\Mapping\Loader;
+
+/**
+ * Loads multiple xml mapping files
+ *
+ * @author Bulat Shakirzyanov <mallluhuct@gmail.com>
+ *
+ * @see    Symfony\Component\Validator\Mapping\Loader\FilesLoader
+ */
+class XmlFilesLoader extends FilesLoader
+{
+    /**
+     * {@inheritDoc}
+     */
+    public function getFileLoaderInstance($file)
+    {
+        return new XmlFileLoader($file);
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/YamlFileLoader.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/YamlFileLoader.php
new file mode 100644
index 0000000..57fe2a5
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/YamlFileLoader.php
@@ -0,0 +1,129 @@
+<?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\Validator\Mapping\Loader;
+
+use Symfony\Component\Validator\Mapping\ClassMetadata;
+use Symfony\Component\Yaml\Yaml;
+
+class YamlFileLoader extends FileLoader
+{
+    /**
+     * An array of YAML class descriptions
+     *
+     * @var array
+     */
+    protected $classes = null;
+
+    /**
+     * {@inheritDoc}
+     */
+    public function loadClassMetadata(ClassMetadata $metadata)
+    {
+        if (null === $this->classes) {
+            $this->classes = Yaml::parse($this->file);
+
+            // empty file
+            if (null === $this->classes) {
+                return false;
+            }
+
+            // not an array
+            if (!is_array($this->classes)) {
+                throw new \InvalidArgumentException(sprintf('The file "%s" must contain a YAML array.', $this->file));
+            }
+
+            if (isset($this->classes['namespaces'])) {
+                foreach ($this->classes['namespaces'] as $alias => $namespace) {
+                    $this->addNamespaceAlias($alias, $namespace);
+                }
+
+                unset($this->classes['namespaces']);
+            }
+        }
+
+        // TODO validation
+
+        if (isset($this->classes[$metadata->getClassName()])) {
+            $yaml = $this->classes[$metadata->getClassName()];
+
+            if (isset($yaml['group_sequence_provider'])) {
+                $metadata->setGroupSequenceProvider((bool) $yaml['group_sequence_provider']);
+            }
+
+            if (isset($yaml['group_sequence'])) {
+                $metadata->setGroupSequence($yaml['group_sequence']);
+            }
+
+            if (isset($yaml['constraints']) && is_array($yaml['constraints'])) {
+                foreach ($this->parseNodes($yaml['constraints']) as $constraint) {
+                    $metadata->addConstraint($constraint);
+                }
+            }
+
+            if (isset($yaml['properties']) && is_array($yaml['properties'])) {
+                foreach ($yaml['properties'] as $property => $constraints) {
+                    if (null !== $constraints) {
+                        foreach ($this->parseNodes($constraints) as $constraint) {
+                            $metadata->addPropertyConstraint($property, $constraint);
+                        }
+                    }
+                }
+            }
+
+            if (isset($yaml['getters']) && is_array($yaml['getters'])) {
+                foreach ($yaml['getters'] as $getter => $constraints) {
+                    if (null !== $constraints) {
+                        foreach ($this->parseNodes($constraints) as $constraint) {
+                            $metadata->addGetterConstraint($getter, $constraint);
+                        }
+                    }
+                }
+            }
+
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Parses a collection of YAML nodes
+     *
+     * @param array $nodes The YAML nodes
+     *
+     * @return array An array of values or Constraint instances
+     */
+    protected function parseNodes(array $nodes)
+    {
+        $values = array();
+
+        foreach ($nodes as $name => $childNodes) {
+            if (is_numeric($name) && is_array($childNodes) && count($childNodes) == 1) {
+                $options = current($childNodes);
+
+                if (is_array($options)) {
+                    $options = $this->parseNodes($options);
+                }
+
+                $values[] = $this->newConstraint(key($childNodes), $options);
+            } else {
+                if (is_array($childNodes)) {
+                    $childNodes = $this->parseNodes($childNodes);
+                }
+
+                $values[$name] = $childNodes;
+            }
+        }
+
+        return $values;
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/YamlFilesLoader.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/YamlFilesLoader.php
new file mode 100644
index 0000000..bffface
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/YamlFilesLoader.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\Validator\Mapping\Loader;
+
+/**
+ * Loads multiple yaml mapping files
+ *
+ * @author Bulat Shakirzyanov <mallluhuct@gmail.com>
+ *
+ * @see    Symfony\Component\Validator\Mapping\Loader\FilesLoader
+ */
+class YamlFilesLoader extends FilesLoader
+{
+    /**
+     * {@inheritDoc}
+     */
+    public function getFileLoaderInstance($file)
+    {
+        return new YamlFileLoader($file);
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/schema/dic/constraint-mapping/constraint-mapping-1.0.xsd b/core/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/schema/dic/constraint-mapping/constraint-mapping-1.0.xsd
new file mode 100644
index 0000000..1ca840b
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Mapping/Loader/schema/dic/constraint-mapping/constraint-mapping-1.0.xsd
@@ -0,0 +1,160 @@
+<?xml version="1.0" ?>
+
+<xsd:schema xmlns="http://symfony.com/schema/dic/constraint-mapping"
+    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+    targetNamespace="http://symfony.com/schema/dic/constraint-mapping"
+    elementFormDefault="qualified">
+
+  <xsd:annotation>
+    <xsd:documentation><![CDATA[
+      Symfony Validator Constraint Mapping Schema, version 1.0
+      Authors: Bernhard Schussek
+
+      A constraint mapping connects classes, properties and getters with
+      validation constraints.
+    ]]></xsd:documentation>
+  </xsd:annotation>
+  
+  <xsd:element name="constraint-mapping" type="constraint-mapping" />
+  
+  <xsd:complexType name="constraint-mapping">
+    <xsd:annotation>
+      <xsd:documentation><![CDATA[
+        The root element of the constraint mapping definition.
+      ]]></xsd:documentation>
+    </xsd:annotation>
+    <xsd:sequence>
+      <xsd:element name="namespace" type="namespace" minOccurs="0" maxOccurs="unbounded" />
+      <xsd:element name="class" type="class" maxOccurs="unbounded" />
+    </xsd:sequence>
+  </xsd:complexType>
+  
+  <xsd:complexType name="namespace">
+    <xsd:annotation>
+      <xsd:documentation><![CDATA[
+        Contains the abbreviation for a namespace.
+      ]]></xsd:documentation>
+    </xsd:annotation>
+    <xsd:simpleContent>
+      <xsd:extension base="xsd:string">
+        <xsd:attribute name="prefix" type="xsd:string" use="required" />
+      </xsd:extension>
+    </xsd:simpleContent>
+  </xsd:complexType>
+  
+  <xsd:complexType name="class">
+    <xsd:annotation>
+      <xsd:documentation><![CDATA[
+        Contains constraints for a single class.
+        
+        Nested elements may be class constraints, property and/or getter 
+        definitions.
+      ]]></xsd:documentation>
+    </xsd:annotation>
+    <xsd:choice minOccurs="0" maxOccurs="unbounded">
+      <xsd:element name="group-sequence-provider" type="group-sequence-provider" minOccurs="0" maxOccurs="1" />
+      <xsd:element name="group-sequence" type="group-sequence" minOccurs="0" maxOccurs="1" />
+      <xsd:element name="constraint" type="constraint" minOccurs="0" maxOccurs="unbounded" />
+      <xsd:element name="property" type="property" minOccurs="0" maxOccurs="unbounded" />
+      <xsd:element name="getter" type="getter" minOccurs="0" maxOccurs="unbounded" />
+    </xsd:choice>
+    <xsd:attribute name="name" type="xsd:string" use="required" />
+  </xsd:complexType>
+
+  <xsd:complexType name="group-sequence">
+    <xsd:annotation>
+      <xsd:documentation><![CDATA[
+        Contains the group sequence of a class. Each group should be written
+        into a "value" tag.
+      ]]></xsd:documentation>
+    </xsd:annotation>
+    <xsd:sequence>
+      <xsd:element name="value" type="value" minOccurs="1" maxOccurs="unbounded" />
+    </xsd:sequence>
+  </xsd:complexType>
+  
+  <xsd:complexType name="group-sequence-provider">
+    <xsd:annotation>
+      <xsd:documentation><![CDATA[
+        Defines the name of the group sequence provider for a class.
+      ]]></xsd:documentation>
+    </xsd:annotation>
+  </xsd:complexType>
+  
+  <xsd:complexType name="property">
+    <xsd:annotation>
+      <xsd:documentation><![CDATA[
+        Contains constraints for a single property. The name of the property
+        should be given in the "name" option.
+      ]]></xsd:documentation>
+    </xsd:annotation>
+    <xsd:sequence>
+      <xsd:element name="constraint" type="constraint" maxOccurs="unbounded" />
+    </xsd:sequence>
+    <xsd:attribute name="name" type="xsd:string" use="required" />
+  </xsd:complexType>
+  
+  <xsd:complexType name="getter">
+    <xsd:annotation>
+      <xsd:documentation><![CDATA[
+        Contains constraints for a getter method. The name of the corresponding
+        property should be given in the "property" option.
+      ]]></xsd:documentation>
+    </xsd:annotation>
+    <xsd:sequence>
+      <xsd:element name="constraint" type="constraint" maxOccurs="unbounded" />
+    </xsd:sequence>
+    <xsd:attribute name="property" type="xsd:string" use="required" />
+  </xsd:complexType>
+  
+  <xsd:complexType name="constraint" mixed="true">
+    <xsd:annotation>
+      <xsd:documentation><![CDATA[
+        Contains a constraint definition. The name of the constraint should be
+        given in the "name" option.
+        
+        May contain a single value, multiple "constraint" elements, 
+        multiple "value" elements or multiple "option" elements.
+      ]]></xsd:documentation>
+    </xsd:annotation>
+    <xsd:choice minOccurs="0">
+      <xsd:element name="constraint" type="constraint" minOccurs="1" maxOccurs="unbounded" />
+      <xsd:element name="option" type="option" minOccurs="1" maxOccurs="unbounded" />
+      <xsd:element name="value" type="value" minOccurs="1" maxOccurs="unbounded" />
+    </xsd:choice>
+    <xsd:attribute name="name" type="xsd:string" use="required" />    
+  </xsd:complexType>
+  
+  <xsd:complexType name="option" mixed="true">
+    <xsd:annotation>
+      <xsd:documentation><![CDATA[
+        Contains a constraint option definition. The name of the option
+        should be given in the "name" option.
+        
+        May contain a single value, multiple "value" elements or multiple
+        "constraint" elements.
+      ]]></xsd:documentation>
+    </xsd:annotation>
+    <xsd:choice minOccurs="0">
+      <xsd:element name="constraint" type="constraint" minOccurs="1" maxOccurs="unbounded" />
+      <xsd:element name="value" type="value" minOccurs="1" maxOccurs="unbounded" />
+    </xsd:choice>
+    <xsd:attribute name="name" type="xsd:string" use="required" />  
+  </xsd:complexType>
+  
+  <xsd:complexType name="value" mixed="true">
+    <xsd:annotation>
+      <xsd:documentation><![CDATA[
+        A value of an element.
+        
+        May contain a single value, multiple "value" elements or multiple
+        "constraint" elements.
+      ]]></xsd:documentation>
+    </xsd:annotation>
+    <xsd:choice minOccurs="0">
+      <xsd:element name="constraint" type="constraint" minOccurs="1" maxOccurs="unbounded" />
+      <xsd:element name="value" type="value" minOccurs="1" maxOccurs="unbounded" />
+    </xsd:choice>
+    <xsd:attribute name="key" type="xsd:string" use="optional" /> 
+  </xsd:complexType>
+</xsd:schema>
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Mapping/MemberMetadata.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Mapping/MemberMetadata.php
new file mode 100644
index 0000000..7db22a8
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Mapping/MemberMetadata.php
@@ -0,0 +1,220 @@
+<?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\Validator\Mapping;
+
+use Symfony\Component\Validator\ValidationVisitorInterface;
+use Symfony\Component\Validator\ClassBasedInterface;
+use Symfony\Component\Validator\PropertyMetadataInterface;
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\Constraints\Valid;
+use Symfony\Component\Validator\Exception\ConstraintDefinitionException;
+
+abstract class MemberMetadata extends ElementMetadata implements PropertyMetadataInterface, ClassBasedInterface
+{
+    public $class;
+    public $name;
+    public $property;
+    public $cascaded = false;
+    public $collectionCascaded = false;
+    public $collectionCascadedDeeply = false;
+    private $reflMember;
+
+    /**
+     * Constructor.
+     *
+     * @param string $class    The name of the class this member is defined on
+     * @param string $name     The name of the member
+     * @param string $property The property the member belongs to
+     */
+    public function __construct($class, $name, $property)
+    {
+        $this->class = $class;
+        $this->name = $name;
+        $this->property = $property;
+    }
+
+    public function accept(ValidationVisitorInterface $visitor, $value, $group, $propertyPath, $propagatedGroup = null)
+    {
+        $visitor->visit($this, $value, $group, $propertyPath);
+
+        if ($this->isCascaded()) {
+            $visitor->validate($value, $propagatedGroup ?: $group, $propertyPath, $this->isCollectionCascaded(), $this->isCollectionCascadedDeeply());
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function addConstraint(Constraint $constraint)
+    {
+        if (!in_array(Constraint::PROPERTY_CONSTRAINT, (array) $constraint->getTargets())) {
+            throw new ConstraintDefinitionException(sprintf(
+                'The constraint %s cannot be put on properties or getters',
+                get_class($constraint)
+            ));
+        }
+
+        if ($constraint instanceof Valid) {
+            $this->cascaded = true;
+            /* @var Valid $constraint */
+            $this->collectionCascaded = $constraint->traverse;
+            $this->collectionCascadedDeeply = $constraint->deep;
+        } else {
+            parent::addConstraint($constraint);
+        }
+
+        return $this;
+    }
+
+    /**
+     * Returns the names of the properties that should be serialized
+     *
+     * @return array
+     */
+    public function __sleep()
+    {
+        return array_merge(parent::__sleep(), array(
+            'class',
+            'name',
+            'property',
+            'cascaded', // TESTME
+        ));
+    }
+
+    /**
+     * Returns the name of the member
+     *
+     * @return string
+     */
+    public function getName()
+    {
+        return $this->name;
+    }
+
+    /**
+     * Returns the class this member is defined on
+     *
+     * @return string
+     */
+    public function getClassName()
+    {
+        return $this->class;
+    }
+
+    /**
+     * Returns the name of the property this member belongs to
+     *
+     * @return string The property name
+     */
+    public function getPropertyName()
+    {
+        return $this->property;
+    }
+
+    /**
+     * Returns whether this member is public
+     *
+     * @return Boolean
+     */
+    public function isPublic()
+    {
+        return $this->getReflectionMember()->isPublic();
+    }
+
+    /**
+     * Returns whether this member is protected
+     *
+     * @return Boolean
+     */
+    public function isProtected()
+    {
+        return $this->getReflectionMember()->isProtected();
+    }
+
+    /**
+     * Returns whether this member is private
+     *
+     * @return Boolean
+     */
+    public function isPrivate()
+    {
+        return $this->getReflectionMember()->isPrivate();
+    }
+
+    /**
+     * Returns whether objects stored in this member should be validated
+     *
+     * @return Boolean
+     */
+    public function isCascaded()
+    {
+        return $this->cascaded;
+    }
+
+    /**
+     * Returns whether arrays or traversable objects stored in this member
+     * should be traversed and validated in each entry
+     *
+     * @return Boolean
+     */
+    public function isCollectionCascaded()
+    {
+        return $this->collectionCascaded;
+    }
+
+    /**
+     * Returns whether arrays or traversable objects stored in this member
+     * should be traversed recursively for inner arrays/traversable objects
+     *
+     * @return Boolean
+     */
+    public function isCollectionCascadedDeeply()
+    {
+        return $this->collectionCascadedDeeply;
+    }
+
+    /**
+     * Returns the value of this property in the given object
+     *
+     * @param object $object The object
+     *
+     * @return mixed The property value
+     *
+     * @deprecated Deprecated since version 2.2, to be removed in 2.3. Use the
+     *             method {@link getPropertyValue} instead.
+     */
+    public function getValue($object)
+    {
+        return $this->getPropertyValue($object);
+    }
+
+    /**
+     * Returns the Reflection instance of the member
+     *
+     * @return object
+     */
+    public function getReflectionMember()
+    {
+        if (!$this->reflMember) {
+            $this->reflMember = $this->newReflectionMember();
+        }
+
+        return $this->reflMember;
+    }
+
+    /**
+     * Creates a new Reflection instance for the member
+     *
+     * @return object
+     */
+    abstract protected function newReflectionMember();
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Mapping/PropertyMetadata.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Mapping/PropertyMetadata.php
new file mode 100644
index 0000000..caa7b6e
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Mapping/PropertyMetadata.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\Validator\Mapping;
+
+use Symfony\Component\Validator\Exception\ValidatorException;
+
+class PropertyMetadata extends MemberMetadata
+{
+    /**
+     * Constructor.
+     *
+     * @param string $class The class this property is defined on
+     * @param string $name  The name of this property
+     */
+    public function __construct($class, $name)
+    {
+        if (!property_exists($class, $name)) {
+            throw new ValidatorException(sprintf('Property %s does not exist in class %s', $name, $class));
+        }
+
+        parent::__construct($class, $name, $name);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getPropertyValue($object)
+    {
+        return $this->getReflectionMember()->getValue($object);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected function newReflectionMember()
+    {
+        $member = new \ReflectionProperty($this->getClassName(), $this->getName());
+        $member->setAccessible(true);
+
+        return $member;
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/MetadataFactoryInterface.php b/core/vendor/symfony/validator/Symfony/Component/Validator/MetadataFactoryInterface.php
new file mode 100644
index 0000000..6dbab06
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/MetadataFactoryInterface.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\Validator;
+
+/**
+ * Returns {@link MetadataInterface} instances for values.
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+interface MetadataFactoryInterface
+{
+    /**
+     * Returns the metadata for the given value.
+     *
+     * @param mixed $value Some value.
+     *
+     * @return MetadataInterface The metadata for the value.
+     *
+     * @throws Exception\NoSuchMetadataException If no metadata exists for the value.
+     */
+    public function getMetadataFor($value);
+
+    /**
+     * Returns whether metadata exists for the given value.
+     *
+     * @param mixed $value Some value.
+     *
+     * @return Boolean Whether metadata exists for the value.
+     */
+    public function hasMetadataFor($value);
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/MetadataInterface.php b/core/vendor/symfony/validator/Symfony/Component/Validator/MetadataInterface.php
new file mode 100644
index 0000000..a5d6504
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/MetadataInterface.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\Validator;
+
+/**
+ * A container for validation metadata.
+ *
+ * The container contains constraints that may belong to different validation
+ * groups. Constraints for a specific group can be fetched by calling
+ * {@link findConstraints}.
+ *
+ * Implement this interface to add validation metadata to your own metadata
+ * layer. Each metadata may have named properties. Each property can be
+ * represented by one or more {@link PropertyMetadataInterface} instances that
+ * are returned by {@link getPropertyMetadata}. Since
+ * <tt>PropertyMetadataInterface</tt> inherits from <tt>MetadataInterface</tt>,
+ * each property may be divided into further properties.
+ *
+ * The {@link accept} method of each metadata implements the Visitor pattern.
+ * The method should forward the call to the visitor's
+ * {@link ValidationVisitorInterface::visit} method and additionally call
+ * <tt>accept()</tt> on all structurally related metadata instances.
+ *
+ * For example, to store constraints for PHP classes and their properties,
+ * create a class <tt>ClassMetadata</tt> (implementing <tt>MetadataInterface</tt>)
+ * and a class <tt>PropertyMetadata</tt> (implementing <tt>PropertyMetadataInterface</tt>).
+ * <tt>ClassMetadata::getPropertyMetadata($property)</tt> returns all
+ * <tt>PropertyMetadata</tt> instances for a property of that class. Its
+ * <tt>accept()</tt>-method simply forwards to <tt>ValidationVisitorInterface::visit()</tt>
+ * and calls <tt>accept()</tt> on all contained <tt>PropertyMetadata</tt>
+ * instances, which themselves call <tt>ValidationVisitorInterface::visit()</tt>
+ * again.
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+interface MetadataInterface
+{
+    /**
+     * Implementation of the Visitor design pattern.
+     *
+     * Calls {@link ValidationVisitorInterface::visit} and then forwards the
+     * <tt>accept()</tt>-call to all property metadata instances.
+     *
+     * @param ValidationVisitorInterface $visitor      The visitor implementing the validation logic.
+     * @param mixed                      $value        The value to validate.
+     * @param string|string[]            $group        The validation group to validate in.
+     * @param string                     $propertyPath The current property path in the validation graph.
+     */
+    public function accept(ValidationVisitorInterface $visitor, $value, $group, $propertyPath);
+
+    /**
+     * Returns all constraints for a given validation group.
+     *
+     * @param string $group The validation group.
+     *
+     * @return Constraint[] A list of constraint instances.
+     */
+    public function findConstraints($group);
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/ObjectInitializerInterface.php b/core/vendor/symfony/validator/Symfony/Component/Validator/ObjectInitializerInterface.php
new file mode 100644
index 0000000..0426bc8
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/ObjectInitializerInterface.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\Validator;
+
+/**
+ * Prepares an object for validation.
+ *
+ * Concrete implementations of this interface are used by {@link ValidationVisitorInterface}
+ * to initialize objects just before validating them.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @api
+ */
+interface ObjectInitializerInterface
+{
+    /**
+     * Initializes an object just before validation.
+     *
+     * @param object $object The object to validate
+     *
+     * @api
+     */
+    public function initialize($object);
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/PropertyMetadataContainerInterface.php b/core/vendor/symfony/validator/Symfony/Component/Validator/PropertyMetadataContainerInterface.php
new file mode 100644
index 0000000..33db49e
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/PropertyMetadataContainerInterface.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\Validator;
+
+/**
+ * A container for {@link PropertyMetadataInterface} instances.
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+interface PropertyMetadataContainerInterface
+{
+    /**
+     * Returns all metadata instances for the given named property.
+     *
+     * If your implementation does not support properties, simply throw an
+     * exception in this method (for example a <tt>BadMethodCallException</tt>).
+     *
+     * @param string $property The property name.
+     *
+     * @return PropertyMetadataInterface[] A list of metadata instances. Empty if
+     *                                     no metadata exists for the property.
+     */
+    public function getPropertyMetadata($property);
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/PropertyMetadataInterface.php b/core/vendor/symfony/validator/Symfony/Component/Validator/PropertyMetadataInterface.php
new file mode 100644
index 0000000..eaac1a7
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/PropertyMetadataInterface.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\Validator;
+
+/**
+ * A container for validation metadata of a property.
+ *
+ * What exactly you define as "property" is up to you. The validator expects
+ * implementations of {@link MetadataInterface} that contain constraints and
+ * optionally a list of named properties that also have constraints (and may
+ * have further sub properties). Such properties are mapped by implementations
+ * of this interface.
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @see MetadataInterface
+ */
+interface PropertyMetadataInterface extends MetadataInterface
+{
+    /**
+     * Returns the name of the property.
+     *
+     * @return string The property name.
+     */
+    public function getPropertyName();
+
+    /**
+     * Extracts the value of the property from the given container.
+     *
+     * @param mixed $containingValue The container to extract the property value from.
+     *
+     * @return mixed The value of the property.
+     */
+    public function getPropertyValue($containingValue);
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/README.md b/core/vendor/symfony/validator/Symfony/Component/Validator/README.md
new file mode 100644
index 0000000..f1b2556
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/README.md
@@ -0,0 +1,120 @@
+Validator Component
+===================
+
+This component is based on the JSR-303 Bean Validation specification and
+enables specifying validation rules for classes using XML, YAML, PHP or
+annotations, which can then be checked against instances of these classes.
+
+Usage
+-----
+
+The component provides "validation constraints", which are simple objects
+containing the rules for the validation. Let's validate a simple string
+as an example:
+
+    use Symfony\Component\Validator\Validation;
+    use Symfony\Component\Validator\Constraints\Length;
+
+    $validator = Validation::createValidator();
+
+    $violations = $validator->validateValue('Bernhard', new Length(array('min' => 10)));
+
+This validation will fail because the given string is shorter than ten
+characters. The precise errors, here called "constraint violations",  are
+returned by the validator. You can analyze these or return them to the user.
+If the violation list is empty, validation succeeded.
+
+Validation of arrays is possible using the `Collection` constraint:
+
+    use Symfony\Component\Validator\Validation;
+    use Symfony\Component\Validator\Constraints as Assert;
+
+    $validator = Validation::createValidator();
+
+    $constraint = new Assert\Collection(array(
+        'name' => new Assert\Collection(array(
+            'first_name' => new Assert\Length(array('min' => 101)),
+            'last_name'  => new Assert\Length(array('min' => 1)),
+        )),
+        'email'    => new Assert\Email(),
+        'simple'   => new Assert\Length(array('min' => 102)),
+        'gender'   => new Assert\Choice(array(3, 4)),
+        'file'     => new Assert\File(),
+        'password' => new Assert\Length(array('min' => 60)),
+    ));
+
+    $violations = $validator->validateValue($input, $constraint);
+
+Again, the validator returns the list of violations.
+
+Validation of objects is possible using "constraint mapping". With such
+a mapping you can put constraints onto properties and objects of classes.
+Whenever an object of this class is validated, its properties and
+method results are matched against the constraints.
+
+    use Symfony\Component\Validator\Validation;
+    use Symfony\Component\Validator\Constraints as Assert;
+
+    class User
+    {
+        /**
+         * @Assert\Length(min = 3)
+         * @Assert\NotBlank
+         */
+        private $name;
+
+        /**
+         * @Assert\Email
+         * @Assert\NotBlank
+         */
+        private $email;
+
+        public function __construct($name, $email)
+        {
+            $this->name = $name;
+            $this->email = $email;
+        }
+
+        /**
+         * @Assert\True(message = "The user should have a Google Mail account")
+         */
+        public function isGmailUser()
+        {
+            return false !== strpos($this->email, '@gmail.com');
+        }
+    }
+
+    $validator = Validation::createValidatorBuilder()
+        ->enableAnnotationMapping()
+        ->getValidator();
+
+    $user = new User('John Doe', 'john@example.com');
+
+    $violations = $validator->validate($user);
+
+This example uses the annotation support of Doctrine Common to
+map constraints to properties and methods. You can also map constraints
+using XML, YAML or plain PHP, if you dislike annotations or don't want
+to include Doctrine. Check the documentation for more information about
+these drivers.
+
+Resources
+---------
+
+Silex integration:
+
+https://github.com/fabpot/Silex/blob/master/src/Silex/Provider/ValidatorServiceProvider.php
+
+Documentation:
+
+http://symfony.com/doc/2.0/book/validation.html
+
+JSR-303 Specification:
+
+http://jcp.org/en/jsr/detail?id=303
+
+You can run the unit tests with the following command:
+
+    $ cd path/to/Symfony/Component/Validator/
+    $ composer.phar install --dev
+    $ phpunit
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/ConstraintTest.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/ConstraintTest.php
new file mode 100644
index 0000000..007bb1e
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/ConstraintTest.php
@@ -0,0 +1,131 @@
+<?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\Validator\Tests;
+
+use Symfony\Component\Validator\Tests\Fixtures\ClassConstraint;
+use Symfony\Component\Validator\Tests\Fixtures\ConstraintA;
+use Symfony\Component\Validator\Tests\Fixtures\ConstraintB;
+use Symfony\Component\Validator\Tests\Fixtures\ConstraintC;
+
+class ConstraintTest extends \PHPUnit_Framework_TestCase
+{
+    public function testSetProperties()
+    {
+        $constraint = new ConstraintA(array(
+            'property1' => 'foo',
+            'property2' => 'bar',
+        ));
+
+        $this->assertEquals('foo', $constraint->property1);
+        $this->assertEquals('bar', $constraint->property2);
+    }
+
+    public function testSetNotExistingPropertyThrowsException()
+    {
+        $this->setExpectedException('Symfony\Component\Validator\Exception\InvalidOptionsException');
+
+        new ConstraintA(array(
+            'foo' => 'bar',
+        ));
+    }
+
+    public function testMagicPropertiesAreNotAllowed()
+    {
+        $constraint = new ConstraintA();
+
+        $this->setExpectedException('Symfony\Component\Validator\Exception\InvalidOptionsException');
+
+        $constraint->foo = 'bar';
+    }
+
+    public function testInvalidAndRequiredOptionsPassed()
+    {
+        $this->setExpectedException('Symfony\Component\Validator\Exception\InvalidOptionsException');
+
+        new ConstraintC(array(
+            'option1' => 'default',
+            'foo' => 'bar'
+        ));
+    }
+
+    public function testSetDefaultProperty()
+    {
+        $constraint = new ConstraintA('foo');
+
+        $this->assertEquals('foo', $constraint->property2);
+    }
+
+    public function testSetDefaultPropertyDoctrineStyle()
+    {
+        $constraint = new ConstraintA(array('value' => 'foo'));
+
+        $this->assertEquals('foo', $constraint->property2);
+    }
+
+    public function testSetUndefinedDefaultProperty()
+    {
+        $this->setExpectedException('Symfony\Component\Validator\Exception\ConstraintDefinitionException');
+
+        new ConstraintB('foo');
+    }
+
+    public function testRequiredOptionsMustBeDefined()
+    {
+        $this->setExpectedException('Symfony\Component\Validator\Exception\MissingOptionsException');
+
+        new ConstraintC();
+    }
+
+    public function testRequiredOptionsPassed()
+    {
+        new ConstraintC(array('option1' => 'default'));
+    }
+
+    public function testGroupsAreConvertedToArray()
+    {
+        $constraint = new ConstraintA(array('groups' => 'Foo'));
+
+        $this->assertEquals(array('Foo'), $constraint->groups);
+    }
+
+    public function testAddDefaultGroupAddsGroup()
+    {
+        $constraint = new ConstraintA(array('groups' => 'Default'));
+        $constraint->addImplicitGroupName('Foo');
+        $this->assertEquals(array('Default', 'Foo'), $constraint->groups);
+    }
+
+    public function testAllowsSettingZeroRequiredPropertyValue()
+    {
+        $constraint = new ConstraintA(0);
+        $this->assertEquals(0, $constraint->property2);
+    }
+
+    public function testCanCreateConstraintWithNoDefaultOptionAndEmptyArray()
+    {
+        new ConstraintB(array());
+    }
+
+    public function testGetTargetsCanBeString()
+    {
+        $constraint = new ClassConstraint;
+
+        $this->assertEquals('class', $constraint->getTargets());
+    }
+
+    public function testGetTargetsCanBeArray()
+    {
+        $constraint = new ConstraintA;
+
+        $this->assertEquals(array('property', 'class'), $constraint->getTargets());
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/ConstraintValidatorTest.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/ConstraintValidatorTest.php
new file mode 100644
index 0000000..b9af1e9
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/ConstraintValidatorTest.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\Validator\Tests;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\ConstraintValidator;
+
+class ConstraintValidatorTest_Validator extends ConstraintValidator
+{
+    private $message;
+    private $params;
+
+    public function __construct($message, array $params = array())
+    {
+        $this->message = $message;
+        $this->params = $params;
+    }
+
+    public function validate($value, Constraint $constraint)
+    {
+        $this->setMessage($this->message, $this->params);
+    }
+}
+
+class ConstraintValidatorTest extends \PHPUnit_Framework_TestCase
+{
+    public function testSetMessage()
+    {
+        $context = $this->getMock('Symfony\Component\Validator\ExecutionContext', array(), array(), '', false);
+        $constraint = $this->getMock('Symfony\Component\Validator\Constraint', array(), array(), '', false);
+        $validator = new ConstraintValidatorTest_Validator('error message', array('foo' => 'bar'));
+        $validator->initialize($context);
+
+        $context->expects($this->once())
+            ->method('addViolation')
+            ->with('error message', array('foo' => 'bar'));
+
+        $validator->validate('bam', $constraint);
+    }
+
+    /**
+     * @expectedException Symfony\Component\Validator\Exception\ValidatorException
+     */
+    public function testSetMessageFailsIfNoContextSet()
+    {
+        $constraint = $this->getMock('Symfony\Component\Validator\Constraint', array(), array(), '', false);
+        $validator = new ConstraintValidatorTest_Validator('error message', array('foo' => 'bar'));
+
+        $validator->validate('bam', $constraint);
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/ConstraintViolationListTest.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/ConstraintViolationListTest.php
new file mode 100644
index 0000000..f0d3e22
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/ConstraintViolationListTest.php
@@ -0,0 +1,134 @@
+<?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\Validator\Tests;
+
+use Symfony\Component\Validator\ConstraintViolation;
+use Symfony\Component\Validator\ConstraintViolationList;
+
+class ConstraintViolationListTest extends \PHPUnit_Framework_TestCase
+{
+    protected $list;
+
+    protected function setUp()
+    {
+        $this->list = new ConstraintViolationList();
+    }
+
+    protected function tearDown()
+    {
+        $this->list = null;
+    }
+
+    public function testInit()
+    {
+        $this->assertCount(0, $this->list);
+    }
+
+    public function testInitWithViolations()
+    {
+        $violation = $this->getViolation('Error');
+        $this->list = new ConstraintViolationList(array($violation));
+
+        $this->assertCount(1, $this->list);
+        $this->assertSame($violation, $this->list[0]);
+    }
+
+    public function testAdd()
+    {
+        $violation = $this->getViolation('Error');
+        $this->list->add($violation);
+
+        $this->assertCount(1, $this->list);
+        $this->assertSame($violation, $this->list[0]);
+    }
+
+    public function testAddAll()
+    {
+        $violations = array(
+            10 => $this->getViolation('Error 1'),
+            20 => $this->getViolation('Error 2'),
+            30 => $this->getViolation('Error 3'),
+        );
+        $otherList = new ConstraintViolationList($violations);
+        $this->list->addAll($otherList);
+
+        $this->assertCount(3, $this->list);
+
+        $this->assertSame($violations[10], $this->list[0]);
+        $this->assertSame($violations[20], $this->list[1]);
+        $this->assertSame($violations[30], $this->list[2]);
+    }
+
+    public function testIterator()
+    {
+        $violations = array(
+            10 => $this->getViolation('Error 1'),
+            20 => $this->getViolation('Error 2'),
+            30 => $this->getViolation('Error 3'),
+        );
+
+        $this->list = new ConstraintViolationList($violations);
+
+        // indices are reset upon adding -> array_values()
+        $this->assertSame(array_values($violations), iterator_to_array($this->list));
+    }
+
+    public function testArrayAccess()
+    {
+        $violation = $this->getViolation('Error');
+        $this->list[] = $violation;
+
+        $this->assertSame($violation, $this->list[0]);
+        $this->assertTrue(isset($this->list[0]));
+
+        unset($this->list[0]);
+
+        $this->assertFalse(isset($this->list[0]));
+
+        $this->list[10] = $violation;
+
+        $this->assertSame($violation, $this->list[10]);
+        $this->assertTrue(isset($this->list[10]));
+    }
+
+    public function testToString()
+    {
+        $this->list = new ConstraintViolationList(array(
+            $this->getViolation('Error 1', 'Root'),
+            $this->getViolation('Error 2', 'Root', 'foo.bar'),
+            $this->getViolation('Error 3', 'Root', '[baz]'),
+            $this->getViolation('Error 4', '', 'foo.bar'),
+            $this->getViolation('Error 5', '', '[baz]'),
+        ));
+
+        $expected = <<<EOF
+Root:
+    Error 1
+Root.foo.bar:
+    Error 2
+Root[baz]:
+    Error 3
+foo.bar:
+    Error 4
+[baz]:
+    Error 5
+
+EOF;
+
+        $this->assertEquals($expected, (string) $this->list);
+    }
+
+    protected function getViolation($message, $root = null, $propertyPath = null)
+    {
+        return new ConstraintViolation($message, array(), $root, $propertyPath, null);
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/ConstraintViolationTest.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/ConstraintViolationTest.php
new file mode 100644
index 0000000..f4b3652
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/ConstraintViolationTest.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\Validator\Tests;
+
+use Symfony\Component\Validator\ConstraintViolation;
+
+class ConstraintViolationTest extends \PHPUnit_Framework_TestCase
+{
+    public function testToStringHandlesArrays()
+    {
+        $violation = new ConstraintViolation(
+            '{{ value }}',
+            array('{{ value }}' => array(1, 2, 3)),
+            'Root',
+            'property.path',
+            null
+        );
+
+        $expected = <<<EOF
+Root.property.path:
+    Array
+EOF;
+
+        $this->assertSame($expected, (string) $violation);
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/AllTest.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/AllTest.php
new file mode 100644
index 0000000..85b1283
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/AllTest.php
@@ -0,0 +1,41 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Allator\Tests\Constraints;
+
+use Symfony\Component\Validator\Constraints\All;
+use Symfony\Component\Validator\Constraints\Valid;
+
+/**
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+class AllTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @expectedException Symfony\Component\Validator\Exception\ConstraintDefinitionException
+     */
+    public function testRejectNonConstraints()
+    {
+        new All(array(
+            'foo',
+        ));
+    }
+
+    /**
+     * @expectedException Symfony\Component\Validator\Exception\ConstraintDefinitionException
+     */
+    public function testRejectValidConstraint()
+    {
+        new All(array(
+            new Valid(),
+        ));
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/AllValidatorTest.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/AllValidatorTest.php
new file mode 100644
index 0000000..f038128
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/AllValidatorTest.php
@@ -0,0 +1,121 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\ExecutionContext;
+use Symfony\Component\Validator\Constraints\Min;
+use Symfony\Component\Validator\Constraints\Max;
+use Symfony\Component\Validator\Constraints\All;
+use Symfony\Component\Validator\Constraints\AllValidator;
+
+class AllValidatorTest extends \PHPUnit_Framework_TestCase
+{
+    protected $walker;
+    protected $context;
+    protected $validator;
+
+    protected function setUp()
+    {
+        $this->walker = $this->getMock('Symfony\Component\Validator\GraphWalker', array(), array(), '', false);
+        $this->context = $this->getMock('Symfony\Component\Validator\ExecutionContext', array(), array(), '', false);
+        $this->validator = new AllValidator();
+        $this->validator->initialize($this->context);
+
+        $this->context->expects($this->any())
+            ->method('getGraphWalker')
+            ->will($this->returnValue($this->walker));
+        $this->context->expects($this->any())
+            ->method('getGroup')
+            ->will($this->returnValue('MyGroup'));
+        $this->context->expects($this->any())
+            ->method('getPropertyPath')
+            ->will($this->returnValue('foo.bar'));
+    }
+
+    protected function tearDown()
+    {
+        $this->validator = null;
+        $this->walker = null;
+        $this->context = null;
+    }
+
+    public function testNullIsValid()
+    {
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $this->validator->validate(null, new All(new Min(4)));
+    }
+
+    /**
+     * @expectedException Symfony\Component\Validator\Exception\UnexpectedTypeException
+     */
+    public function testThrowsExceptionIfNotTraversable()
+    {
+        $this->validator->validate('foo.barbar', new All(new Min(4)));
+    }
+
+    /**
+     * @dataProvider getValidArguments
+     */
+    public function testWalkSingleConstraint($array)
+    {
+        $constraint = new Min(4);
+
+        $i = 0;
+
+        foreach ($array as $key => $value) {
+            $this->walker->expects($this->at($i++))
+                ->method('walkConstraint')
+                ->with($constraint, $value, 'MyGroup', 'foo.bar['.$key.']');
+        }
+
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $this->validator->validate($array, new All($constraint));
+    }
+
+    /**
+     * @dataProvider getValidArguments
+     */
+    public function testWalkMultipleConstraints($array)
+    {
+        $constraint1 = new Min(4);
+        $constraint2 = new Max(6);
+
+        $constraints = array($constraint1, $constraint2);
+        $i = 0;
+
+        foreach ($array as $key => $value) {
+            $this->walker->expects($this->at($i++))
+                ->method('walkConstraint')
+                ->with($constraint1, $value, 'MyGroup', 'foo.bar['.$key.']');
+            $this->walker->expects($this->at($i++))
+                ->method('walkConstraint')
+                ->with($constraint2, $value, 'MyGroup', 'foo.bar['.$key.']');
+        }
+
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $this->validator->validate($array, new All($constraints));
+    }
+
+    public function getValidArguments()
+    {
+        return array(
+            array(array(5, 6, 7)),
+            array(new \ArrayObject(array(5, 6, 7))),
+        );
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/BlankValidatorTest.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/BlankValidatorTest.php
new file mode 100644
index 0000000..0fbe5e6
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/BlankValidatorTest.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\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Constraints\Blank;
+use Symfony\Component\Validator\Constraints\BlankValidator;
+
+class BlankValidatorTest extends \PHPUnit_Framework_TestCase
+{
+    protected $context;
+    protected $validator;
+
+    protected function setUp()
+    {
+        $this->context = $this->getMock('Symfony\Component\Validator\ExecutionContext', array(), array(), '', false);
+        $this->validator = new BlankValidator();
+        $this->validator->initialize($this->context);
+    }
+
+    protected function tearDown()
+    {
+        $this->context = null;
+        $this->validator = null;
+    }
+
+    public function testNullIsValid()
+    {
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $this->validator->validate(null, new Blank());
+    }
+
+    public function testBlankIsValid()
+    {
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $this->validator->validate('', new Blank());
+    }
+
+    /**
+     * @dataProvider getInvalidValues
+     */
+    public function testInvalidValues($value)
+    {
+        $constraint = new Blank(array(
+            'message' => 'myMessage'
+        ));
+
+        $this->context->expects($this->once())
+            ->method('addViolation')
+            ->with('myMessage', array(
+                '{{ value }}' => $value,
+            ));
+
+        $this->validator->validate($value, $constraint);
+    }
+
+    public function getInvalidValues()
+    {
+        return array(
+            array('foobar'),
+            array(0),
+            array(false),
+            array(1234),
+        );
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CallbackValidatorTest.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CallbackValidatorTest.php
new file mode 100644
index 0000000..bd56e15
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CallbackValidatorTest.php
@@ -0,0 +1,156 @@
+<?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\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\ExecutionContext;
+use Symfony\Component\Validator\Constraints\Callback;
+use Symfony\Component\Validator\Constraints\CallbackValidator;
+
+class CallbackValidatorTest_Class
+{
+    public static function validateStatic($object, ExecutionContext $context)
+    {
+        $context->addViolation('Static message', array('{{ value }}' => 'foobar'), 'invalidValue');
+
+        return false;
+    }
+}
+
+class CallbackValidatorTest_Object
+{
+    public function validateOne(ExecutionContext $context)
+    {
+        $context->addViolation('My message', array('{{ value }}' => 'foobar'), 'invalidValue');
+
+        return false;
+    }
+
+    public function validateTwo(ExecutionContext $context)
+    {
+        $context->addViolation('Other message', array('{{ value }}' => 'baz'), 'otherInvalidValue');
+
+        return false;
+    }
+}
+
+class CallbackValidatorTest extends \PHPUnit_Framework_TestCase
+{
+    protected $context;
+    protected $validator;
+
+    protected function setUp()
+    {
+        $this->context = $this->getMock('Symfony\Component\Validator\ExecutionContext', array(), array(), '', false);
+        $this->validator = new CallbackValidator();
+        $this->validator->initialize($this->context);
+    }
+
+    protected function tearDown()
+    {
+        $this->context = null;
+        $this->validator = null;
+    }
+
+    public function testNullIsValid()
+    {
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $this->validator->validate(null, new Callback(array('foo')));
+    }
+
+    public function testCallbackSingleMethod()
+    {
+        $object = new CallbackValidatorTest_Object();
+        $constraint = new Callback(array('validateOne'));
+
+        $this->context->expects($this->once())
+            ->method('addViolation')
+            ->with('My message', array(
+                '{{ value }}' => 'foobar',
+            ));
+
+        $this->validator->validate($object, $constraint);
+    }
+
+    public function testCallbackSingleStaticMethod()
+    {
+        $object = new CallbackValidatorTest_Object();
+
+        $this->context->expects($this->once())
+            ->method('addViolation')
+            ->with('Static message', array(
+                '{{ value }}' => 'foobar',
+            ));
+
+        $this->validator->validate($object, new Callback(array(
+            array(__CLASS__.'_Class', 'validateStatic')
+        )));
+    }
+
+    public function testCallbackMultipleMethods()
+    {
+        $object = new CallbackValidatorTest_Object();
+
+        $this->context->expects($this->at(0))
+            ->method('addViolation')
+            ->with('My message', array(
+                '{{ value }}' => 'foobar',
+            ));
+        $this->context->expects($this->at(1))
+            ->method('addViolation')
+            ->with('Other message', array(
+                '{{ value }}' => 'baz',
+            ));
+
+        $this->validator->validate($object, new Callback(array(
+            'validateOne', 'validateTwo'
+        )));
+    }
+
+    /**
+     * @expectedException Symfony\Component\Validator\Exception\UnexpectedTypeException
+     */
+    public function testExpectCallbackArray()
+    {
+        $object = new CallbackValidatorTest_Object();
+
+        $this->validator->validate($object, new Callback('foobar'));
+    }
+
+    /**
+     * @expectedException Symfony\Component\Validator\Exception\ConstraintDefinitionException
+     */
+    public function testExpectValidMethods()
+    {
+        $object = new CallbackValidatorTest_Object();
+
+        $this->validator->validate($object, new Callback(array('foobar')));
+    }
+
+    /**
+     * @expectedException Symfony\Component\Validator\Exception\ConstraintDefinitionException
+     */
+    public function testExpectValidCallbacks()
+    {
+        $object = new CallbackValidatorTest_Object();
+
+        $this->validator->validate($object, new Callback(array(array('foo', 'bar'))));
+    }
+
+    public function testConstraintGetTargets()
+    {
+        $constraint = new Callback(array('foo'));
+
+        $this->assertEquals('class', $constraint->getTargets());
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CardSchemeValidatorTest.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CardSchemeValidatorTest.php
new file mode 100644
index 0000000..3fa3092
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CardSchemeValidatorTest.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\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Constraints\CardScheme;
+use Symfony\Component\Validator\Constraints\CardSchemeValidator;
+
+class CardSchemeValidatorTest extends \PHPUnit_Framework_TestCase
+{
+    protected $context;
+    protected $validator;
+
+    protected function setUp()
+    {
+        $this->context = $this->getMock('Symfony\Component\Validator\ExecutionContext', array(), array(), '', false);
+        $this->validator = new CardSchemeValidator();
+        $this->validator->initialize($this->context);
+    }
+
+    protected function tearDown()
+    {
+        $this->context = null;
+        $this->validator = null;
+    }
+
+    public function testNullIsValid()
+    {
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $this->validator->validate(null, new CardScheme(array('schemes' => array())));
+    }
+
+    public function testEmptyStringIsValid()
+    {
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $this->validator->validate('', new CardScheme(array('schemes' => array())));
+    }
+
+    /**
+     * @dataProvider getValidNumbers
+     */
+    public function testValidNumbers($scheme, $number)
+    {
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $this->validator->validate($number, new CardScheme(array('schemes' => array($scheme))));
+    }
+
+    public function getValidNumbers()
+    {
+        return array(
+            array('VISA', '42424242424242424242'),
+            array('AMEX', '378282246310005'),
+            array('AMEX', '371449635398431'),
+            array('AMEX', '378734493671000'),
+            array('DINERS', '30569309025904'),
+            array('DISCOVER', '6011111111111117'),
+            array('DISCOVER', '6011000990139424'),
+            array('JCB', '3530111333300000'),
+            array('JCB', '3566002020360505'),
+            array('MASTERCARD', '5555555555554444'),
+            array('MASTERCARD', '5105105105105100'),
+            array('VISA', '4111111111111111'),
+            array('VISA', '4012888888881881'),
+            array('VISA', '4222222222222'),
+        );
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/ChoiceValidatorTest.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/ChoiceValidatorTest.php
new file mode 100644
index 0000000..34221ff
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/ChoiceValidatorTest.php
@@ -0,0 +1,296 @@
+<?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\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\ExecutionContext;
+use Symfony\Component\Validator\Constraints\Choice;
+use Symfony\Component\Validator\Constraints\ChoiceValidator;
+
+function choice_callback()
+{
+    return array('foo', 'bar');
+}
+
+class ChoiceValidatorTest extends \PHPUnit_Framework_TestCase
+{
+    protected $context;
+    protected $validator;
+
+    public static function staticCallback()
+    {
+        return array('foo', 'bar');
+    }
+
+    protected function setUp()
+    {
+        $this->context = $this->getMock('Symfony\Component\Validator\ExecutionContext', array(), array(), '', false);
+        $this->validator = new ChoiceValidator();
+        $this->validator->initialize($this->context);
+
+        $this->context->expects($this->any())
+            ->method('getCurrentClass')
+            ->will($this->returnValue(__CLASS__));
+    }
+
+    protected function tearDown()
+    {
+        $this->context = null;
+        $this->validator = null;
+    }
+
+    /**
+     * @expectedException Symfony\Component\Validator\Exception\UnexpectedTypeException
+     */
+    public function testExpectArrayIfMultipleIsTrue()
+    {
+        $constraint = new Choice(array(
+            'choices' => array('foo', 'bar'),
+            'multiple' => true,
+        ));
+
+        $this->validator->validate('asdf', $constraint);
+    }
+
+    public function testNullIsValid()
+    {
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $this->validator->validate(null, new Choice(array('choices' => array('foo', 'bar'))));
+    }
+
+    /**
+     * @expectedException Symfony\Component\Validator\Exception\ConstraintDefinitionException
+     */
+    public function testChoicesOrCallbackExpected()
+    {
+        $this->validator->validate('foobar', new Choice());
+    }
+
+    /**
+     * @expectedException Symfony\Component\Validator\Exception\ConstraintDefinitionException
+     */
+    public function testValidCallbackExpected()
+    {
+        $this->validator->validate('foobar', new Choice(array('callback' => 'abcd')));
+    }
+
+    public function testValidChoiceArray()
+    {
+        $constraint = new Choice(array('choices' => array('foo', 'bar')));
+
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $this->validator->validate('bar', $constraint);
+    }
+
+    public function testValidChoiceCallbackFunction()
+    {
+        $constraint = new Choice(array('callback' => __NAMESPACE__.'\choice_callback'));
+
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $this->validator->validate('bar', $constraint);
+    }
+
+    public function testValidChoiceCallbackClosure()
+    {
+        $constraint = new Choice(array('callback' => function() {
+            return array('foo', 'bar');
+        }));
+
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $this->validator->validate('bar', $constraint);
+    }
+
+    public function testValidChoiceCallbackStaticMethod()
+    {
+        $constraint = new Choice(array('callback' => array(__CLASS__, 'staticCallback')));
+
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $this->validator->validate('bar', $constraint);
+    }
+
+    public function testValidChoiceCallbackContextMethod()
+    {
+        $constraint = new Choice(array('callback' => 'staticCallback'));
+
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $this->validator->validate('bar', $constraint);
+    }
+
+    public function testMultipleChoices()
+    {
+        $constraint = new Choice(array(
+            'choices' => array('foo', 'bar', 'baz'),
+            'multiple' => true,
+        ));
+
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $this->validator->validate(array('baz', 'bar'), $constraint);
+    }
+
+    public function testInvalidChoice()
+    {
+        $constraint = new Choice(array(
+            'choices' => array('foo', 'bar'),
+            'message' => 'myMessage',
+        ));
+
+        $this->context->expects($this->once())
+            ->method('addViolation')
+            ->with('myMessage', array(
+                '{{ value }}' => 'baz',
+            ), null, null);
+
+        $this->validator->validate('baz', $constraint);
+    }
+
+    public function testInvalidChoiceMultiple()
+    {
+        $constraint = new Choice(array(
+            'choices' => array('foo', 'bar'),
+            'multipleMessage' => 'myMessage',
+            'multiple' => true,
+        ));
+
+        $this->context->expects($this->once())
+            ->method('addViolation')
+            ->with('myMessage', array(
+                '{{ value }}' => 'baz',
+            ));
+
+        $this->validator->validate(array('foo', 'baz'), $constraint);
+    }
+
+    public function testTooFewChoices()
+    {
+        $constraint = new Choice(array(
+            'choices' => array('foo', 'bar', 'moo', 'maa'),
+            'multiple' => true,
+            'min' => 2,
+            'minMessage' => 'myMessage',
+        ));
+
+        $this->context->expects($this->once())
+            ->method('addViolation')
+            ->with('myMessage', array(
+                '{{ limit }}' => 2,
+            ), null, 2);
+
+        $this->validator->validate(array('foo'), $constraint);
+    }
+
+    public function testTooManyChoices()
+    {
+        $constraint = new Choice(array(
+            'choices' => array('foo', 'bar', 'moo', 'maa'),
+            'multiple' => true,
+            'max' => 2,
+            'maxMessage' => 'myMessage',
+        ));
+
+        $this->context->expects($this->once())
+            ->method('addViolation')
+            ->with('myMessage', array(
+                '{{ limit }}' => 2,
+            ), null, 2);
+
+        $this->validator->validate(array('foo', 'bar', 'moo'), $constraint);
+    }
+
+    public function testNonStrict()
+    {
+        $constraint = new Choice(array(
+            'choices' => array(1, 2),
+            'strict' => false,
+        ));
+
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $this->validator->validate('2', $constraint);
+        $this->validator->validate(2, $constraint);
+    }
+
+    public function testStrictAllowsExactValue()
+    {
+        $constraint = new Choice(array(
+            'choices' => array(1, 2),
+            'strict' => true,
+        ));
+
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $this->validator->validate(2, $constraint);
+    }
+
+    public function testStrictDisallowsDifferentType()
+    {
+        $constraint = new Choice(array(
+            'choices' => array(1, 2),
+            'strict' => true,
+            'message' => 'myMessage'
+        ));
+
+        $this->context->expects($this->once())
+            ->method('addViolation')
+            ->with('myMessage', array(
+                '{{ value }}' => '2',
+            ));
+
+        $this->validator->validate('2', $constraint);
+    }
+
+    public function testNonStrictWithMultipleChoices()
+    {
+        $constraint = new Choice(array(
+            'choices' => array(1, 2, 3),
+            'multiple' => true,
+            'strict' => false
+        ));
+
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $this->validator->validate(array('2', 3), $constraint);
+    }
+
+    public function testStrictWithMultipleChoices()
+    {
+        $constraint = new Choice(array(
+            'choices' => array(1, 2, 3),
+            'multiple' => true,
+            'strict' => true,
+            'multipleMessage' => 'myMessage',
+        ));
+
+        $this->context->expects($this->once())
+            ->method('addViolation')
+            ->with('myMessage', array(
+                '{{ value }}' => '3',
+            ));
+
+        $this->validator->validate(array(2, '3'), $constraint);
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CollectionTest.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CollectionTest.php
new file mode 100644
index 0000000..184d254
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CollectionTest.php
@@ -0,0 +1,73 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Collectionator\Tests\Constraints;
+
+use Symfony\Component\Validator\Constraints\Collection;
+use Symfony\Component\Validator\Constraints\Collection\Required;
+use Symfony\Component\Validator\Constraints\Collection\Optional;
+use Symfony\Component\Validator\Constraints\Valid;
+
+/**
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+class CollectionTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @expectedException Symfony\Component\Validator\Exception\ConstraintDefinitionException
+     */
+    public function testRejectInvalidFieldsOption()
+    {
+        new Collection(array(
+            'fields' => 'foo',
+        ));
+    }
+
+    /**
+     * @expectedException Symfony\Component\Validator\Exception\ConstraintDefinitionException
+     */
+    public function testRejectNonConstraints()
+    {
+        new Collection(array(
+            'foo' => 'bar',
+        ));
+    }
+
+    /**
+     * @expectedException Symfony\Component\Validator\Exception\ConstraintDefinitionException
+     */
+    public function testRejectValidConstraint()
+    {
+        new Collection(array(
+            'foo' => new Valid(),
+        ));
+    }
+
+    /**
+     * @expectedException Symfony\Component\Validator\Exception\ConstraintDefinitionException
+     */
+    public function testRejectValidConstraintWithinOptional()
+    {
+        new Collection(array(
+            'foo' => new Optional(new Valid()),
+        ));
+    }
+
+    /**
+     * @expectedException Symfony\Component\Validator\Exception\ConstraintDefinitionException
+     */
+    public function testRejectValidConstraintWithinRequired()
+    {
+        new Collection(array(
+            'foo' => new Required(new Valid()),
+        ));
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CollectionValidatorArrayObjectTest.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CollectionValidatorArrayObjectTest.php
new file mode 100644
index 0000000..a3c4b33
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CollectionValidatorArrayObjectTest.php
@@ -0,0 +1,20 @@
+<?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\Validator\Tests\Constraints;
+
+class CollectionValidatorArrayObjectTest extends CollectionValidatorTest
+{
+    public function prepareTestData(array $contents)
+    {
+        return new \ArrayObject($contents);
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CollectionValidatorArrayTest.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CollectionValidatorArrayTest.php
new file mode 100644
index 0000000..7517d0c
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CollectionValidatorArrayTest.php
@@ -0,0 +1,20 @@
+<?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\Validator\Tests\Constraints;
+
+class CollectionValidatorArrayTest extends CollectionValidatorTest
+{
+    public function prepareTestData(array $contents)
+    {
+        return $contents;
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CollectionValidatorCustomArrayObjectTest.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CollectionValidatorCustomArrayObjectTest.php
new file mode 100644
index 0000000..ebad849
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CollectionValidatorCustomArrayObjectTest.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\Validator\Tests\Constraints;
+
+/**
+ * This class is a hand written simplified version of PHP native `ArrayObject`
+ * class, to show that it behaves differently than the PHP native implementation.
+ */
+class CustomArrayObject implements \ArrayAccess, \IteratorAggregate, \Countable, \Serializable
+{
+    private $array;
+
+    public function __construct(array $array = null)
+    {
+        $this->array = $array ?: array();
+    }
+
+    public function offsetExists($offset)
+    {
+        return array_key_exists($offset, $this->array);
+    }
+
+    public function offsetGet($offset)
+    {
+        return $this->array[$offset];
+    }
+
+    public function offsetSet($offset, $value)
+    {
+        if (null === $offset) {
+            $this->array[] = $value;
+        } else {
+            $this->array[$offset] = $value;
+        }
+    }
+
+    public function offsetUnset($offset)
+    {
+        unset($this->array[$offset]);
+    }
+
+    public function getIterator()
+    {
+        return new \ArrayIterator($this->array);
+    }
+
+    public function count()
+    {
+        return count($this->array);
+    }
+
+    public function serialize()
+    {
+        return serialize($this->array);
+    }
+
+    public function unserialize($serialized)
+    {
+        $this->array = (array) unserialize((string) $serialized);
+    }
+}
+
+class CollectionValidatorCustomArrayObjectTest extends CollectionValidatorTest
+{
+    public function prepareTestData(array $contents)
+    {
+        return new CustomArrayObject($contents);
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CollectionValidatorTest.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CollectionValidatorTest.php
new file mode 100644
index 0000000..ef1c7c9
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CollectionValidatorTest.php
@@ -0,0 +1,419 @@
+<?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\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\ExecutionContext;
+use Symfony\Component\Validator\Constraints\Min;
+use Symfony\Component\Validator\Constraints\NotNull;
+use Symfony\Component\Validator\Constraints\Collection\Required;
+use Symfony\Component\Validator\Constraints\Collection\Optional;
+use Symfony\Component\Validator\Constraints\Collection;
+use Symfony\Component\Validator\Constraints\CollectionValidator;
+
+abstract class CollectionValidatorTest extends \PHPUnit_Framework_TestCase
+{
+    protected $walker;
+    protected $context;
+    protected $validator;
+
+    protected function setUp()
+    {
+        $this->walker = $this->getMock('Symfony\Component\Validator\GraphWalker', array(), array(), '', false);
+        $this->context = $this->getMock('Symfony\Component\Validator\ExecutionContext', array(), array(), '', false);
+        $this->validator = new CollectionValidator();
+        $this->validator->initialize($this->context);
+
+        $this->context->expects($this->any())
+            ->method('getGraphWalker')
+            ->will($this->returnValue($this->walker));
+        $this->context->expects($this->any())
+            ->method('getGroup')
+            ->will($this->returnValue('MyGroup'));
+        $this->context->expects($this->any())
+            ->method('getPropertyPath')
+            ->will($this->returnValue('foo.bar'));
+    }
+
+    protected function tearDown()
+    {
+        $this->walker = null;
+        $this->context = null;
+        $this->validator = null;
+    }
+
+    abstract protected function prepareTestData(array $contents);
+
+    public function testNullIsValid()
+    {
+        $this->context->expects($this->never())
+            ->method('addViolationAtSubPath');
+
+        $this->validator->validate(null, new Collection(array('fields' => array(
+            'foo' => new Min(4),
+        ))));
+    }
+
+    public function testFieldsAsDefaultOption()
+    {
+        $data = $this->prepareTestData(array('foo' => 'foobar'));
+
+        $this->context->expects($this->never())
+            ->method('addViolationAtSubPath');
+
+        $this->validator->validate($data, new Collection(array(
+            'foo' => new Min(4),
+        )));
+    }
+
+    /**
+     * @expectedException Symfony\Component\Validator\Exception\UnexpectedTypeException
+     */
+    public function testThrowsExceptionIfNotTraversable()
+    {
+        $this->validator->validate('foobar', new Collection(array('fields' => array(
+            'foo' => new Min(4),
+        ))));
+    }
+
+    public function testWalkSingleConstraint()
+    {
+        $constraint = new Min(4);
+
+        $array = array(
+            'foo' => 3,
+            'bar' => 5,
+        );
+        $i = 0;
+
+        foreach ($array as $key => $value) {
+            $this->walker->expects($this->at($i++))
+                ->method('walkConstraint')
+                ->with($constraint, $value, 'MyGroup', 'foo.bar['.$key.']');
+        }
+
+        $data = $this->prepareTestData($array);
+
+        $this->context->expects($this->never())
+            ->method('addViolationAtSubPath');
+
+        $this->validator->validate($data, new Collection(array(
+            'fields' => array(
+                'foo' => $constraint,
+                'bar' => $constraint,
+            ),
+        )));
+    }
+
+    public function testWalkMultipleConstraints()
+    {
+        $constraints = array(
+            new Min(4),
+            new NotNull(),
+        );
+
+        $array = array(
+            'foo' => 3,
+            'bar' => 5,
+        );
+        $i = 0;
+
+        foreach ($array as $key => $value) {
+            foreach ($constraints as $constraint) {
+                $this->walker->expects($this->at($i++))
+                    ->method('walkConstraint')
+                    ->with($constraint, $value, 'MyGroup', 'foo.bar['.$key.']');
+            }
+        }
+
+        $data = $this->prepareTestData($array);
+
+        $this->context->expects($this->never())
+            ->method('addViolationAtSubPath');
+
+        $this->validator->validate($data, new Collection(array(
+            'fields' => array(
+                'foo' => $constraints,
+                'bar' => $constraints,
+            )
+        )));
+    }
+
+    public function testExtraFieldsDisallowed()
+    {
+        $data = $this->prepareTestData(array(
+            'foo' => 5,
+            'baz' => 6,
+        ));
+
+        $this->context->expects($this->once())
+            ->method('addViolationAtSubPath')
+            ->with('[baz]', 'myMessage', array(
+                '{{ field }}' => 'baz'
+            ));
+
+        $this->validator->validate($data, new Collection(array(
+            'fields' => array(
+                'foo' => new Min(4),
+            ),
+            'extraFieldsMessage' => 'myMessage',
+        )));
+    }
+
+    // bug fix
+    public function testNullNotConsideredExtraField()
+    {
+        $data = $this->prepareTestData(array(
+            'foo' => null,
+        ));
+
+        $constraint = new Collection(array(
+            'fields' => array(
+                'foo' => new Min(4),
+            ),
+        ));
+
+        $this->context->expects($this->never())
+            ->method('addViolationAtSubPath');
+
+        $this->validator->validate($data, $constraint);
+    }
+
+    public function testExtraFieldsAllowed()
+    {
+        $data = $this->prepareTestData(array(
+            'foo' => 5,
+            'bar' => 6,
+        ));
+
+        $constraint = new Collection(array(
+            'fields' => array(
+                'foo' => new Min(4),
+            ),
+            'allowExtraFields' => true,
+        ));
+
+        $this->context->expects($this->never())
+            ->method('addViolationAtSubPath');
+
+        $this->validator->validate($data, $constraint);
+    }
+
+    public function testMissingFieldsDisallowed()
+    {
+        $data = $this->prepareTestData(array());
+
+        $constraint = new Collection(array(
+            'fields' => array(
+                'foo' => new Min(4),
+            ),
+            'missingFieldsMessage' => 'myMessage',
+        ));
+
+        $this->context->expects($this->once())
+            ->method('addViolationAtSubPath')
+            ->with('[foo]', 'myMessage', array(
+                '{{ field }}' => 'foo',
+            ));
+
+        $this->validator->validate($data, $constraint);
+    }
+
+    public function testMissingFieldsAllowed()
+    {
+        $data = $this->prepareTestData(array());
+
+        $constraint = new Collection(array(
+            'fields' => array(
+                'foo' => new Min(4),
+            ),
+            'allowMissingFields' => true,
+        ));
+
+        $this->context->expects($this->never())
+            ->method('addViolationAtSubPath');
+
+        $this->validator->validate($data, $constraint);
+    }
+
+    public function testOptionalFieldPresent()
+    {
+        $data = $this->prepareTestData(array(
+            'foo' => null,
+        ));
+
+        $this->context->expects($this->never())
+            ->method('addViolationAtSubPath');
+
+        $this->validator->validate($data, new Collection(array(
+            'foo' => new Optional(),
+        )));
+    }
+
+    public function testOptionalFieldNotPresent()
+    {
+        $data = $this->prepareTestData(array());
+
+        $this->context->expects($this->never())
+            ->method('addViolationAtSubPath');
+
+        $this->validator->validate($data, new Collection(array(
+            'foo' => new Optional(),
+        )));
+    }
+
+    public function testOptionalFieldSingleConstraint()
+    {
+        $array = array(
+            'foo' => 5,
+        );
+
+        $constraint = new Min(4);
+
+        $this->walker->expects($this->once())
+            ->method('walkConstraint')
+            ->with($constraint, $array['foo'], 'MyGroup', 'foo.bar[foo]');
+
+        $this->context->expects($this->never())
+            ->method('addViolationAtSubPath');
+
+        $data = $this->prepareTestData($array);
+
+        $this->validator->validate($data, new Collection(array(
+            'foo' => new Optional($constraint),
+        )));
+    }
+
+    public function testOptionalFieldMultipleConstraints()
+    {
+        $array = array(
+            'foo' => 5,
+        );
+
+        $constraints = array(
+            new NotNull(),
+            new Min(4),
+        );
+
+        foreach ($constraints as $i => $constraint) {
+            $this->walker->expects($this->at($i))
+                ->method('walkConstraint')
+                ->with($constraint, $array['foo'], 'MyGroup', 'foo.bar[foo]');
+        }
+
+        $this->context->expects($this->never())
+            ->method('addViolationAtSubPath');
+
+        $data = $this->prepareTestData($array);
+
+        $this->validator->validate($data, new Collection(array(
+            'foo' => new Optional($constraints),
+        )));
+    }
+
+    public function testRequiredFieldPresent()
+    {
+        $data = $this->prepareTestData(array(
+            'foo' => null,
+        ));
+
+        $this->context->expects($this->never())
+            ->method('addViolationAtSubPath');
+
+        $this->validator->validate($data, new Collection(array(
+            'foo' => new Required(),
+        )));
+    }
+
+    public function testRequiredFieldNotPresent()
+    {
+        $data = $this->prepareTestData(array());
+
+        $this->context->expects($this->once())
+            ->method('addViolationAtSubPath')
+            ->with('[foo]', 'myMessage', array(
+                '{{ field }}' => 'foo',
+            ));
+
+        $this->validator->validate($data, new Collection(array(
+            'fields' => array(
+                 'foo' => new Required(),
+             ),
+            'missingFieldsMessage' => 'myMessage',
+        )));
+    }
+
+    public function testRequiredFieldSingleConstraint()
+    {
+        $array = array(
+            'foo' => 5,
+        );
+
+        $constraint = new Min(4);
+
+        $this->walker->expects($this->once())
+            ->method('walkConstraint')
+            ->with($constraint, $array['foo'], 'MyGroup', 'foo.bar[foo]');
+
+        $this->context->expects($this->never())
+            ->method('addViolationAtSubPath');
+
+        $data = $this->prepareTestData($array);
+
+        $this->validator->validate($data, new Collection(array(
+            'foo' => new Required($constraint),
+        )));
+    }
+
+    public function testRequiredFieldMultipleConstraints()
+    {
+        $array = array(
+            'foo' => 5,
+        );
+
+        $constraints = array(
+            new NotNull(),
+            new Min(4),
+        );
+
+        foreach ($constraints as $i => $constraint) {
+            $this->walker->expects($this->at($i))
+                ->method('walkConstraint')
+                ->with($constraint, $array['foo'], 'MyGroup', 'foo.bar[foo]');
+        }
+
+        $this->context->expects($this->never())
+            ->method('addViolationAtSubPath');
+
+        $data = $this->prepareTestData($array);
+
+        $this->validator->validate($array, new Collection(array(
+            'foo' => new Required($constraints),
+        )));
+    }
+
+    public function testObjectShouldBeLeftUnchanged()
+    {
+        $value = new \ArrayObject(array(
+            'foo' => 3
+        ));
+
+        $this->validator->validate($value, new Collection(array(
+            'fields' => array(
+                'foo' => new Min(2),
+            )
+        )));
+
+        $this->assertEquals(array(
+            'foo' => 3
+        ), (array) $value);
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CountValidatorArrayTest.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CountValidatorArrayTest.php
new file mode 100644
index 0000000..5f562e7
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CountValidatorArrayTest.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\Validator\Tests\Constraints;
+
+/**
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+class CountValidatorArrayTest extends CountValidatorTest
+{
+    protected function createCollection(array $content)
+    {
+        return $content;
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CountValidatorCountableTest.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CountValidatorCountableTest.php
new file mode 100644
index 0000000..ec4d8de
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CountValidatorCountableTest.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\Validator\Tests\Constraints;
+
+class CountValidatorCountableTest_Countable implements \Countable
+{
+    private $content;
+
+    public function __construct(array $content)
+    {
+        $this->content = $content;
+    }
+
+    public function count()
+    {
+        return count($this->content);
+    }
+}
+
+/**
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+class CountValidatorCountableTest extends CountValidatorTest
+{
+    protected function createCollection(array $content)
+    {
+        return new CountValidatorCountableTest_Countable($content);
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CountValidatorTest.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CountValidatorTest.php
new file mode 100644
index 0000000..c7d29c6
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CountValidatorTest.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\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Constraints\Count;
+use Symfony\Component\Validator\Constraints\CountValidator;
+
+/**
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+abstract class CountValidatorTest extends \PHPUnit_Framework_TestCase
+{
+    protected $context;
+    protected $validator;
+
+    protected function setUp()
+    {
+        $this->context = $this->getMock('Symfony\Component\Validator\ExecutionContext', array(), array(), '', false);
+        $this->validator = new CountValidator();
+        $this->validator->initialize($this->context);
+    }
+
+    protected function tearDown()
+    {
+        $this->context = null;
+        $this->validator = null;
+    }
+
+    abstract protected function createCollection(array $content);
+
+    public function testNullIsValid()
+    {
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $this->validator->validate(null, new Count(6));
+    }
+
+    /**
+     * @expectedException Symfony\Component\Validator\Exception\UnexpectedTypeException
+     */
+    public function testExpectsCountableType()
+    {
+        $this->validator->validate(new \stdClass(), new Count(5));
+    }
+
+    public function getThreeOrLessElements()
+    {
+        return array(
+            array($this->createCollection(array(1))),
+            array($this->createCollection(array(1, 2))),
+            array($this->createCollection(array(1, 2, 3))),
+            array($this->createCollection(array('a' => 1, 'b' => 2, 'c' => 3))),
+        );
+    }
+
+    public function getFourElements()
+    {
+        return array(
+            array($this->createCollection(array(1, 2, 3, 4))),
+            array($this->createCollection(array('a' => 1, 'b' => 2, 'c' => 3, 'd' => 4))),
+        );
+    }
+
+    public function getNotFourElements()
+    {
+        return array_merge(
+            $this->getThreeOrLessElements(),
+            $this->getFiveOrMoreElements()
+        );
+    }
+
+    public function getFiveOrMoreElements()
+    {
+        return array(
+            array($this->createCollection(array(1, 2, 3, 4, 5))),
+            array($this->createCollection(array(1, 2, 3, 4, 5, 6))),
+            array($this->createCollection(array('a' => 1, 'b' => 2, 'c' => 3, 'd' => 4, 'e' => 5))),
+        );
+    }
+
+    /**
+     * @dataProvider getThreeOrLessElements
+     */
+    public function testValidValuesMax($value)
+    {
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $constraint = new Count(array('max' => 3));
+        $this->validator->validate($value, $constraint);
+    }
+
+    /**
+     * @dataProvider getFiveOrMoreElements
+     */
+    public function testValidValuesMin($value)
+    {
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $constraint = new Count(array('min' => 5));
+        $this->validator->validate($value, $constraint);
+    }
+
+    /**
+     * @dataProvider getFourElements
+     */
+    public function testValidValuesExact($value)
+    {
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $constraint = new Count(4);
+        $this->validator->validate($value, $constraint);
+    }
+
+    /**
+     * @dataProvider getFiveOrMoreElements
+     */
+    public function testInvalidValuesMax($value)
+    {
+        $constraint = new Count(array(
+            'max' => 4,
+            'maxMessage' => 'myMessage'
+        ));
+
+        $this->context->expects($this->once())
+            ->method('addViolation')
+            ->with('myMessage', $this->identicalTo(array(
+                '{{ count }}' => count($value),
+                '{{ limit }}' => 4,
+            )), $value, 4);
+
+        $this->validator->validate($value, $constraint);
+    }
+
+    /**
+     * @dataProvider getThreeOrLessElements
+     */
+    public function testInvalidValuesMin($value)
+    {
+        $constraint = new Count(array(
+            'min' => 4,
+            'minMessage' => 'myMessage'
+        ));
+
+        $this->context->expects($this->once())
+            ->method('addViolation')
+            ->with('myMessage', $this->identicalTo(array(
+                '{{ count }}' => count($value),
+                '{{ limit }}' => 4,
+            )), $value, 4);
+
+        $this->validator->validate($value, $constraint);
+    }
+
+    /**
+     * @dataProvider getNotFourElements
+     */
+    public function testInvalidValuesExact($value)
+    {
+        $constraint = new Count(array(
+            'min' => 4,
+            'max' => 4,
+            'exactMessage' => 'myMessage'
+        ));
+
+        $this->context->expects($this->once())
+            ->method('addViolation')
+            ->with('myMessage', $this->identicalTo(array(
+            '{{ count }}' => count($value),
+            '{{ limit }}' => 4,
+        )), $value, 4);
+
+        $this->validator->validate($value, $constraint);
+    }
+
+    public function testDefaultOption()
+    {
+        $constraint = new Count(5);
+
+        $this->assertEquals(5, $constraint->min);
+        $this->assertEquals(5, $constraint->max);
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CountryValidatorTest.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CountryValidatorTest.php
new file mode 100644
index 0000000..744f124
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/CountryValidatorTest.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\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Constraints\Country;
+use Symfony\Component\Validator\Constraints\CountryValidator;
+
+class CountryValidatorTest extends LocalizedTestCase
+{
+    protected $context;
+    protected $validator;
+
+    protected function setUp()
+    {
+        parent::setUp();
+
+        $this->context = $this->getMock('Symfony\Component\Validator\ExecutionContext', array(), array(), '', false);
+        $this->validator = new CountryValidator();
+        $this->validator->initialize($this->context);
+    }
+
+    protected function tearDown()
+    {
+        $this->context = null;
+        $this->validator = null;
+    }
+
+    public function testNullIsValid()
+    {
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $this->validator->validate(null, new Country());
+    }
+
+    public function testEmptyStringIsValid()
+    {
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $this->validator->validate('', new Country());
+    }
+
+    /**
+     * @expectedException Symfony\Component\Validator\Exception\UnexpectedTypeException
+     */
+    public function testExpectsStringCompatibleType()
+    {
+        $this->validator->validate(new \stdClass(), new Country());
+    }
+
+    /**
+     * @dataProvider getValidCountries
+     */
+    public function testValidCountries($country)
+    {
+        if (!class_exists('Symfony\Component\Locale\Locale')) {
+            $this->markTestSkipped('The "Locale" component is not available');
+        }
+
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $this->validator->validate($country, new Country());
+    }
+
+    public function getValidCountries()
+    {
+        return array(
+            array('GB'),
+            array('AT'),
+            array('MY'),
+        );
+    }
+
+    /**
+     * @dataProvider getInvalidCountries
+     */
+    public function testInvalidCountries($country)
+    {
+        if (!class_exists('Symfony\Component\Locale\Locale')) {
+            $this->markTestSkipped('The "Locale" component is not available');
+        }
+
+        $constraint = new Country(array(
+            'message' => 'myMessage'
+        ));
+
+        $this->context->expects($this->once())
+            ->method('addViolation')
+            ->with('myMessage', array(
+                '{{ value }}' => $country,
+            ));
+
+        $this->validator->validate($country, $constraint);
+    }
+
+    public function getInvalidCountries()
+    {
+        return array(
+            array('foobar'),
+            array('EN'),
+        );
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/DateTimeValidatorTest.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/DateTimeValidatorTest.php
new file mode 100644
index 0000000..3263d68
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/DateTimeValidatorTest.php
@@ -0,0 +1,120 @@
+<?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\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Constraints\DateTime;
+use Symfony\Component\Validator\Constraints\DateTimeValidator;
+
+class DateTimeValidatorTest extends \PHPUnit_Framework_TestCase
+{
+    protected $context;
+    protected $validator;
+
+    protected function setUp()
+    {
+        $this->context = $this->getMock('Symfony\Component\Validator\ExecutionContext', array(), array(), '', false);
+        $this->validator = new DateTimeValidator();
+        $this->validator->initialize($this->context);
+    }
+
+    protected function tearDown()
+    {
+        $this->context = null;
+        $this->validator = null;
+    }
+
+    public function testNullIsValid()
+    {
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $this->validator->validate(null, new DateTime());
+    }
+
+    public function testEmptyStringIsValid()
+    {
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $this->validator->validate('', new DateTime());
+    }
+
+    public function testDateTimeClassIsValid()
+    {
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $this->validator->validate(new \DateTime(), new DateTime());
+    }
+
+    /**
+     * @expectedException Symfony\Component\Validator\Exception\UnexpectedTypeException
+     */
+    public function testExpectsStringCompatibleType()
+    {
+        $this->validator->validate(new \stdClass(), new DateTime());
+    }
+
+    /**
+     * @dataProvider getValidDateTimes
+     */
+    public function testValidDateTimes($dateTime)
+    {
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $this->validator->validate($dateTime, new DateTime());
+    }
+
+    public function getValidDateTimes()
+    {
+        return array(
+            array('2010-01-01 01:02:03'),
+            array('1955-12-12 00:00:00'),
+            array('2030-05-31 23:59:59'),
+        );
+    }
+
+    /**
+     * @dataProvider getInvalidDateTimes
+     */
+    public function testInvalidDateTimes($dateTime)
+    {
+        $constraint = new DateTime(array(
+            'message' => 'myMessage'
+        ));
+
+        $this->context->expects($this->once())
+            ->method('addViolation')
+            ->with('myMessage', array(
+                '{{ value }}' => $dateTime,
+            ));
+
+        $this->validator->validate($dateTime, $constraint);
+    }
+
+    public function getInvalidDateTimes()
+    {
+        return array(
+            array('foobar'),
+            array('2010-01-01'),
+            array('00:00:00'),
+            array('2010-01-01 00:00'),
+            array('2010-13-01 00:00:00'),
+            array('2010-04-32 00:00:00'),
+            array('2010-02-29 00:00:00'),
+            array('2010-01-01 24:00:00'),
+            array('2010-01-01 00:60:00'),
+            array('2010-01-01 00:00:60'),
+        );
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/DateValidatorTest.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/DateValidatorTest.php
new file mode 100644
index 0000000..007232c
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/DateValidatorTest.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\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Constraints\Date;
+use Symfony\Component\Validator\Constraints\DateValidator;
+
+class DateValidatorTest extends \PHPUnit_Framework_TestCase
+{
+    protected $context;
+    protected $validator;
+
+    protected function setUp()
+    {
+        $this->context = $this->getMock('Symfony\Component\Validator\ExecutionContext', array(), array(), '', false);
+        $this->validator = new DateValidator();
+        $this->validator->initialize($this->context);
+    }
+
+    protected function tearDown()
+    {
+        $this->context = null;
+        $this->validator = null;
+    }
+
+    public function testNullIsValid()
+    {
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $this->validator->validate(null, new Date());
+    }
+
+    public function testEmptyStringIsValid()
+    {
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $this->validator->validate('', new Date());
+    }
+
+    public function testDateTimeClassIsValid()
+    {
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $this->validator->validate(new \DateTime(), new Date());
+    }
+
+    /**
+     * @expectedException Symfony\Component\Validator\Exception\UnexpectedTypeException
+     */
+    public function testExpectsStringCompatibleType()
+    {
+        $this->validator->validate(new \stdClass(), new Date());
+    }
+
+    /**
+     * @dataProvider getValidDates
+     */
+    public function testValidDates($date)
+    {
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $this->validator->validate($date, new Date());
+    }
+
+    public function getValidDates()
+    {
+        return array(
+            array('2010-01-01'),
+            array('1955-12-12'),
+            array('2030-05-31'),
+        );
+    }
+
+    /**
+     * @dataProvider getInvalidDates
+     */
+    public function testInvalidDates($date)
+    {
+        $constraint = new Date(array(
+            'message' => 'myMessage'
+        ));
+
+        $this->context->expects($this->once())
+            ->method('addViolation')
+            ->with('myMessage', array(
+                '{{ value }}' => $date,
+            ));
+
+        $this->validator->validate($date, $constraint);
+    }
+
+    public function getInvalidDates()
+    {
+        return array(
+            array('foobar'),
+            array('foobar 2010-13-01'),
+            array('2010-13-01 foobar'),
+            array('2010-13-01'),
+            array('2010-04-32'),
+            array('2010-02-29'),
+        );
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/EmailValidatorTest.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/EmailValidatorTest.php
new file mode 100644
index 0000000..f95c089
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/EmailValidatorTest.php
@@ -0,0 +1,106 @@
+<?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\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Constraints\Email;
+use Symfony\Component\Validator\Constraints\EmailValidator;
+
+class EmailValidatorTest extends \PHPUnit_Framework_TestCase
+{
+    protected $context;
+    protected $validator;
+
+    protected function setUp()
+    {
+        $this->context = $this->getMock('Symfony\Component\Validator\ExecutionContext', array(), array(), '', false);
+        $this->validator = new EmailValidator();
+        $this->validator->initialize($this->context);
+    }
+
+    protected function tearDown()
+    {
+        $this->context = null;
+        $this->validator = null;
+    }
+
+    public function testNullIsValid()
+    {
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $this->validator->validate(null, new Email());
+    }
+
+    public function testEmptyStringIsValid()
+    {
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $this->validator->validate('', new Email());
+    }
+
+    /**
+     * @expectedException Symfony\Component\Validator\Exception\UnexpectedTypeException
+     */
+    public function testExpectsStringCompatibleType()
+    {
+        $this->validator->validate(new \stdClass(), new Email());
+    }
+
+    /**
+     * @dataProvider getValidEmails
+     */
+    public function testValidEmails($email)
+    {
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $this->validator->validate($email, new Email());
+    }
+
+    public function getValidEmails()
+    {
+        return array(
+            array('fabien@symfony.com'),
+            array('example@example.co.uk'),
+            array('fabien_potencier@example.fr'),
+        );
+    }
+
+    /**
+     * @dataProvider getInvalidEmails
+     */
+    public function testInvalidEmails($email)
+    {
+        $constraint = new Email(array(
+            'message' => 'myMessage'
+        ));
+
+        $this->context->expects($this->once())
+            ->method('addViolation')
+            ->with('myMessage', array(
+                '{{ value }}' => $email,
+            ));
+
+        $this->validator->validate($email, $constraint);
+    }
+
+    public function getInvalidEmails()
+    {
+        return array(
+            array('example'),
+            array('example@'),
+            array('example@localhost'),
+            array('example@example.com@example.com'),
+        );
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/FalseValidatorTest.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/FalseValidatorTest.php
new file mode 100644
index 0000000..1bc16c2
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/FalseValidatorTest.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\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Constraints\False;
+use Symfony\Component\Validator\Constraints\FalseValidator;
+
+class FalseValidatorTest extends \PHPUnit_Framework_TestCase
+{
+    protected $context;
+    protected $validator;
+
+    protected function setUp()
+    {
+        $this->context = $this->getMock('Symfony\Component\Validator\ExecutionContext', array(), array(), '', false);
+        $this->validator = new FalseValidator();
+        $this->validator->initialize($this->context);
+    }
+
+    protected function tearDown()
+    {
+        $this->context = null;
+        $this->validator = null;
+    }
+
+    public function testNullIsValid()
+    {
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $this->validator->validate(null, new False());
+    }
+
+    public function testFalseIsValid()
+    {
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $this->validator->validate(false, new False());
+    }
+
+    public function testTrueIsInvalid()
+    {
+        $constraint = new False(array(
+            'message' => 'myMessage'
+        ));
+
+        $this->context->expects($this->once())
+            ->method('addViolation')
+            ->with('myMessage', array());
+
+        $this->validator->validate(true, $constraint);
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/FileValidatorObjectTest.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/FileValidatorObjectTest.php
new file mode 100644
index 0000000..f35f93b
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/FileValidatorObjectTest.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\Validator\Tests\Constraints;
+
+use Symfony\Component\HttpFoundation\File\File;
+
+class FileValidatorObjectTest extends FileValidatorTest
+{
+    protected function getFile($filename)
+    {
+        return new File($filename);
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/FileValidatorPathTest.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/FileValidatorPathTest.php
new file mode 100644
index 0000000..c4b93cd
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/FileValidatorPathTest.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\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Constraints\File;
+
+class FileValidatorPathTest extends FileValidatorTest
+{
+    protected function getFile($filename)
+    {
+        return $filename;
+    }
+
+    public function testFileNotFound()
+    {
+        $constraint = new File(array(
+            'notFoundMessage' => 'myMessage',
+        ));
+
+        $this->context->expects($this->once())
+            ->method('addViolation')
+            ->with('myMessage', array(
+                '{{ file }}' => 'foobar',
+            ));
+
+        $this->validator->validate('foobar', $constraint);
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/FileValidatorTest.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/FileValidatorTest.php
new file mode 100644
index 0000000..67a38f1
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/FileValidatorTest.php
@@ -0,0 +1,329 @@
+<?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\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Constraints\File;
+use Symfony\Component\Validator\Constraints\FileValidator;
+use Symfony\Component\HttpFoundation\File\UploadedFile;
+
+abstract class FileValidatorTest extends \PHPUnit_Framework_TestCase
+{
+    protected $context;
+    protected $validator;
+    protected $path;
+    protected $file;
+
+    protected function setUp()
+    {
+        if (!class_exists('Symfony\Component\HttpFoundation\File\UploadedFile')) {
+            $this->markTestSkipped('The "HttpFoundation" component is not available');
+        }
+
+        $this->context = $this->getMock('Symfony\Component\Validator\ExecutionContext', array(), array(), '', false);
+        $this->validator = new FileValidator();
+        $this->validator->initialize($this->context);
+        $this->path = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'FileValidatorTest';
+        $this->file = fopen($this->path, 'w');
+    }
+
+    protected function tearDown()
+    {
+        fclose($this->file);
+
+        $this->context = null;
+        $this->validator = null;
+        $this->path = null;
+        $this->file = null;
+    }
+
+    public function testNullIsValid()
+    {
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $this->validator->validate(null, new File());
+    }
+
+    public function testEmptyStringIsValid()
+    {
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $this->validator->validate('', new File());
+    }
+
+    /**
+     * @expectedException Symfony\Component\Validator\Exception\UnexpectedTypeException
+     */
+    public function testExpectsStringCompatibleTypeOrFile()
+    {
+        $this->validator->validate(new \stdClass(), new File());
+    }
+
+    public function testValidFile()
+    {
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $this->validator->validate($this->path, new File());
+    }
+
+    public function testValidUploadedfile()
+    {
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $file = new UploadedFile($this->path, 'originalName');
+        $this->validator->validate($file, new File());
+    }
+
+    public function testTooLargeBytes()
+    {
+        fwrite($this->file, str_repeat('0', 11));
+
+        $constraint = new File(array(
+            'maxSize'           => 10,
+            'maxSizeMessage'    => 'myMessage',
+        ));
+
+        $this->context->expects($this->once())
+            ->method('addViolation')
+            ->with('myMessage', array(
+                '{{ limit }}'   => '10',
+                '{{ size }}'    => '11',
+                '{{ suffix }}'  => 'bytes',
+                '{{ file }}'    => $this->path,
+            ));
+
+        $this->validator->validate($this->getFile($this->path), $constraint);
+    }
+
+    public function testTooLargeKiloBytes()
+    {
+        fwrite($this->file, str_repeat('0', 1400));
+
+        $constraint = new File(array(
+            'maxSize'           => '1k',
+            'maxSizeMessage'    => 'myMessage',
+        ));
+
+        $this->context->expects($this->once())
+            ->method('addViolation')
+            ->with('myMessage', array(
+                '{{ limit }}'   => '1',
+                '{{ size }}'    => '1.4',
+                '{{ suffix }}'  => 'kB',
+                '{{ file }}'    => $this->path,
+            ));
+
+        $this->validator->validate($this->getFile($this->path), $constraint);
+    }
+
+    public function testTooLargeMegaBytes()
+    {
+        fwrite($this->file, str_repeat('0', 1400000));
+
+        $constraint = new File(array(
+            'maxSize'           => '1M',
+            'maxSizeMessage'    => 'myMessage',
+        ));
+
+        $this->context->expects($this->once())
+            ->method('addViolation')
+            ->with('myMessage', array(
+                '{{ limit }}'   => '1',
+                '{{ size }}'    => '1.4',
+                '{{ suffix }}'  => 'MB',
+                '{{ file }}'    => $this->path,
+            ));
+
+        $this->validator->validate($this->getFile($this->path), $constraint);
+    }
+
+    /**
+     * @expectedException Symfony\Component\Validator\Exception\ConstraintDefinitionException
+     */
+    public function testInvalidMaxSize()
+    {
+        $constraint = new File(array(
+            'maxSize' => '1abc',
+        ));
+
+        $this->validator->validate($this->path, $constraint);
+    }
+
+    public function testValidMimeType()
+    {
+        $file = $this
+            ->getMockBuilder('Symfony\Component\HttpFoundation\File\File')
+            ->disableOriginalConstructor()
+            ->getMock()
+        ;
+        $file
+            ->expects($this->once())
+            ->method('getPathname')
+            ->will($this->returnValue($this->path))
+        ;
+        $file
+            ->expects($this->once())
+            ->method('getMimeType')
+            ->will($this->returnValue('image/jpg'))
+        ;
+
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $constraint = new File(array(
+            'mimeTypes' => array('image/png', 'image/jpg'),
+        ));
+
+        $this->validator->validate($file, $constraint);
+    }
+
+    public function testValidWildcardMimeType()
+    {
+        $file = $this
+            ->getMockBuilder('Symfony\Component\HttpFoundation\File\File')
+            ->disableOriginalConstructor()
+            ->getMock()
+        ;
+        $file
+            ->expects($this->once())
+            ->method('getPathname')
+            ->will($this->returnValue($this->path))
+        ;
+        $file
+            ->expects($this->once())
+            ->method('getMimeType')
+            ->will($this->returnValue('image/jpg'))
+        ;
+
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $constraint = new File(array(
+            'mimeTypes' => array('image/*'),
+        ));
+
+        $this->validator->validate($file, $constraint);
+    }
+
+    public function testInvalidMimeType()
+    {
+        $file = $this
+            ->getMockBuilder('Symfony\Component\HttpFoundation\File\File')
+            ->disableOriginalConstructor()
+            ->getMock()
+        ;
+        $file
+            ->expects($this->once())
+            ->method('getPathname')
+            ->will($this->returnValue($this->path))
+        ;
+        $file
+            ->expects($this->once())
+            ->method('getMimeType')
+            ->will($this->returnValue('application/pdf'))
+        ;
+
+        $constraint = new File(array(
+            'mimeTypes' => array('image/png', 'image/jpg'),
+            'mimeTypesMessage' => 'myMessage',
+        ));
+
+        $this->context->expects($this->once())
+            ->method('addViolation')
+            ->with('myMessage', array(
+                '{{ type }}'    => '"application/pdf"',
+                '{{ types }}'   => '"image/png", "image/jpg"',
+                '{{ file }}'    => $this->path,
+            ));
+
+        $this->validator->validate($file, $constraint);
+    }
+
+    public function testInvalidWildcardMimeType()
+    {
+        $file = $this
+            ->getMockBuilder('Symfony\Component\HttpFoundation\File\File')
+            ->disableOriginalConstructor()
+            ->getMock()
+        ;
+        $file
+            ->expects($this->once())
+            ->method('getPathname')
+            ->will($this->returnValue($this->path))
+        ;
+        $file
+            ->expects($this->once())
+            ->method('getMimeType')
+            ->will($this->returnValue('application/pdf'))
+        ;
+
+        $constraint = new File(array(
+            'mimeTypes' => array('image/*', 'image/jpg'),
+            'mimeTypesMessage' => 'myMessage',
+        ));
+
+        $this->context->expects($this->once())
+            ->method('addViolation')
+            ->with('myMessage', array(
+                '{{ type }}'    => '"application/pdf"',
+                '{{ types }}'   => '"image/*", "image/jpg"',
+                '{{ file }}'    => $this->path,
+            ));
+
+        $this->validator->validate($file, $constraint);
+    }
+
+    /**
+     * @dataProvider uploadedFileErrorProvider
+     */
+    public function testUploadedFileError($error, $message, array $params = array())
+    {
+        $file = new UploadedFile('/path/to/file', 'originalName', 'mime', 0, $error);
+
+        $constraint = new File(array(
+            $message => 'myMessage',
+        ));
+
+        $this->context->expects($this->once())
+            ->method('addViolation')
+            ->with('myMessage', $params);
+
+        $this->validator->validate($file, $constraint);
+
+    }
+
+    public function uploadedFileErrorProvider()
+    {
+        $tests = array(
+            array(UPLOAD_ERR_FORM_SIZE, 'uploadFormSizeErrorMessage'),
+            array(UPLOAD_ERR_PARTIAL, 'uploadPartialErrorMessage'),
+            array(UPLOAD_ERR_NO_FILE, 'uploadNoFileErrorMessage'),
+            array(UPLOAD_ERR_NO_TMP_DIR, 'uploadNoTmpDirErrorMessage'),
+            array(UPLOAD_ERR_CANT_WRITE, 'uploadCantWriteErrorMessage'),
+            array(UPLOAD_ERR_EXTENSION, 'uploadExtensionErrorMessage'),
+        );
+
+        if (class_exists('Symfony\Component\HttpFoundation\File\UploadedFile')) {
+            $tests[] = array(UPLOAD_ERR_INI_SIZE, 'uploadIniSizeErrorMessage', array(
+                '{{ limit }}' => UploadedFile::getMaxFilesize(),
+                '{{ suffix }}' => 'bytes',
+            ));
+        }
+
+        return $tests;
+    }
+
+    abstract protected function getFile($filename);
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/Fixtures/test.gif b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/Fixtures/test.gif
new file mode 100644
index 0000000..6b44fc7
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/Fixtures/test.gif
@@ -0,0 +1 @@
+GIF89a  ÷  ÿÿÿ                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             ,         ;
\ No newline at end of file
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/ImageValidatorTest.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/ImageValidatorTest.php
new file mode 100644
index 0000000..8854501
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/ImageValidatorTest.php
@@ -0,0 +1,226 @@
+<?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\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Constraints\Image;
+use Symfony\Component\Validator\Constraints\ImageValidator;
+
+class ImageValidatorTest extends \PHPUnit_Framework_TestCase
+{
+    protected $context;
+    protected $validator;
+    protected $path;
+    protected $image;
+
+    protected function setUp()
+    {
+        $this->context = $this->getMock('Symfony\Component\Validator\ExecutionContext', array(), array(), '', false);
+        $this->validator = new ImageValidator();
+        $this->validator->initialize($this->context);
+        $this->image = __DIR__.'/Fixtures/test.gif';
+    }
+
+    public function testNullIsValid()
+    {
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $this->validator->validate(null, new Image());
+    }
+
+    public function testEmptyStringIsValid()
+    {
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $this->validator->validate('', new Image());
+    }
+
+    public function testValidImage()
+    {
+        if (!class_exists('Symfony\Component\HttpFoundation\File\File')) {
+            $this->markTestSkipped('The "HttpFoundation" component is not available');
+        }
+
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $this->validator->validate($this->image, new Image());
+    }
+
+    public function testValidSize()
+    {
+        if (!class_exists('Symfony\Component\HttpFoundation\File\File')) {
+            $this->markTestSkipped('The "HttpFoundation" component is not available');
+        }
+
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $constraint = new Image(array(
+            'minWidth' => 1,
+            'maxWidth' => 2,
+            'minHeight' => 1,
+            'maxHeight' => 2,
+        ));
+
+        $this->validator->validate($this->image, $constraint);
+    }
+
+    public function testWidthTooSmall()
+    {
+        if (!class_exists('Symfony\Component\HttpFoundation\File\File')) {
+            $this->markTestSkipped('The "HttpFoundation" component is not available');
+        }
+
+        $constraint = new Image(array(
+            'minWidth' => 3,
+            'minWidthMessage' => 'myMessage',
+        ));
+
+        $this->context->expects($this->once())
+            ->method('addViolation')
+            ->with('myMessage', array(
+                '{{ width }}' => '2',
+                '{{ min_width }}' => '3',
+            ));
+
+        $this->validator->validate($this->image, $constraint);
+    }
+
+    public function testWidthTooBig()
+    {
+        if (!class_exists('Symfony\Component\HttpFoundation\File\File')) {
+            $this->markTestSkipped('The "HttpFoundation" component is not available');
+        }
+
+        $constraint = new Image(array(
+            'maxWidth' => 1,
+            'maxWidthMessage' => 'myMessage',
+        ));
+
+        $this->context->expects($this->once())
+            ->method('addViolation')
+            ->with('myMessage', array(
+                '{{ width }}' => '2',
+                '{{ max_width }}' => '1',
+            ));
+
+        $this->validator->validate($this->image, $constraint);
+    }
+
+    public function testHeightTooSmall()
+    {
+        if (!class_exists('Symfony\Component\HttpFoundation\File\File')) {
+            $this->markTestSkipped('The "HttpFoundation" component is not available');
+        }
+
+        $constraint = new Image(array(
+            'minHeight' => 3,
+            'minHeightMessage' => 'myMessage',
+        ));
+
+        $this->context->expects($this->once())
+            ->method('addViolation')
+            ->with('myMessage', array(
+                '{{ height }}' => '2',
+                '{{ min_height }}' => '3',
+            ));
+
+        $this->validator->validate($this->image, $constraint);
+    }
+
+    public function testHeightTooBig()
+    {
+        if (!class_exists('Symfony\Component\HttpFoundation\File\File')) {
+            $this->markTestSkipped('The "HttpFoundation" component is not available');
+        }
+
+        $constraint = new Image(array(
+            'maxHeight' => 1,
+            'maxHeightMessage' => 'myMessage',
+        ));
+
+        $this->context->expects($this->once())
+            ->method('addViolation')
+            ->with('myMessage', array(
+                '{{ height }}' => '2',
+                '{{ max_height }}' => '1',
+            ));
+
+        $this->validator->validate($this->image, $constraint);
+    }
+
+    /**
+     * @expectedException \Symfony\Component\Validator\Exception\ConstraintDefinitionException
+     */
+    public function testInvalidMinWidth()
+    {
+        if (!class_exists('Symfony\Component\HttpFoundation\File\File')) {
+            $this->markTestSkipped('The "HttpFoundation" component is not available');
+        }
+
+        $constraint = new Image(array(
+            'minWidth' => '1abc',
+        ));
+
+        $this->validator->validate($this->image, $constraint);
+    }
+
+    /**
+     * @expectedException \Symfony\Component\Validator\Exception\ConstraintDefinitionException
+     */
+    public function testInvalidMaxWidth()
+    {
+        if (!class_exists('Symfony\Component\HttpFoundation\File\File')) {
+            $this->markTestSkipped('The "HttpFoundation" component is not available');
+        }
+
+        $constraint = new Image(array(
+            'maxWidth' => '1abc',
+        ));
+
+        $this->validator->validate($this->image, $constraint);
+    }
+
+    /**
+     * @expectedException \Symfony\Component\Validator\Exception\ConstraintDefinitionException
+     */
+    public function testInvalidMinHeight()
+    {
+        if (!class_exists('Symfony\Component\HttpFoundation\File\File')) {
+            $this->markTestSkipped('The "HttpFoundation" component is not available');
+        }
+
+        $constraint = new Image(array(
+            'minHeight' => '1abc',
+        ));
+
+        $this->validator->validate($this->image, $constraint);
+    }
+
+    /**
+     * @expectedException \Symfony\Component\Validator\Exception\ConstraintDefinitionException
+     */
+    public function testInvalidMaxHeight()
+    {
+        if (!class_exists('Symfony\Component\HttpFoundation\File\File')) {
+            $this->markTestSkipped('The "HttpFoundation" component is not available');
+        }
+
+        $constraint = new Image(array(
+            'maxHeight' => '1abc',
+        ));
+
+        $this->validator->validate($this->image, $constraint);
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/IpValidatorTest.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/IpValidatorTest.php
new file mode 100644
index 0000000..7429318
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/IpValidatorTest.php
@@ -0,0 +1,478 @@
+<?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\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Constraints\Ip;
+use Symfony\Component\Validator\Constraints\IpValidator;
+
+class IpValidatorTest extends \PHPUnit_Framework_TestCase
+{
+    protected $context;
+    protected $validator;
+
+    protected function setUp()
+    {
+        $this->context = $this->getMock('Symfony\Component\Validator\ExecutionContext', array(), array(), '', false);
+        $this->validator = new IpValidator();
+        $this->validator->initialize($this->context);
+    }
+
+    protected function tearDown()
+    {
+        $this->context = null;
+        $this->validator = null;
+    }
+
+    public function testNullIsValid()
+    {
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $this->validator->validate(null, new Ip());
+    }
+
+    public function testEmptyStringIsValid()
+    {
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $this->validator->validate('', new Ip());
+    }
+
+    /**
+     * @expectedException Symfony\Component\Validator\Exception\UnexpectedTypeException
+     */
+    public function testExpectsStringCompatibleType()
+    {
+        $this->validator->validate(new \stdClass(), new Ip());
+    }
+
+    /**
+     * @expectedException Symfony\Component\Validator\Exception\ConstraintDefinitionException
+     */
+    public function testInvalidValidatorVersion()
+    {
+        $ip = new Ip(array(
+            'version' => 666,
+        ));
+    }
+
+    /**
+     * @dataProvider getValidIpsV4
+     */
+    public function testValidIpsV4($ip)
+    {
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $this->validator->validate($ip, new Ip(array(
+            'version' => Ip::V4,
+        )));
+    }
+
+    public function getValidIpsV4()
+    {
+        return array(
+            array('0.0.0.0'),
+            array('10.0.0.0'),
+            array('123.45.67.178'),
+            array('172.16.0.0'),
+            array('192.168.1.0'),
+            array('224.0.0.1'),
+            array('255.255.255.255'),
+            array('127.0.0.0'),
+        );
+    }
+
+    /**
+     * @dataProvider getValidIpsV6
+     */
+    public function testValidIpsV6($ip)
+    {
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $this->validator->validate($ip, new Ip(array(
+            'version' => Ip::V6,
+        )));
+    }
+
+    public function getValidIpsV6()
+    {
+        return array(
+            array('2001:0db8:85a3:0000:0000:8a2e:0370:7334'),
+            array('2001:0DB8:85A3:0000:0000:8A2E:0370:7334'),
+            array('2001:0Db8:85a3:0000:0000:8A2e:0370:7334'),
+            array('fdfe:dcba:9876:ffff:fdc6:c46b:bb8f:7d4c'),
+            array('fdc6:c46b:bb8f:7d4c:fdc6:c46b:bb8f:7d4c'),
+            array('fdc6:c46b:bb8f:7d4c:0000:8a2e:0370:7334'),
+            array('fe80:0000:0000:0000:0202:b3ff:fe1e:8329'),
+            array('fe80:0:0:0:202:b3ff:fe1e:8329'),
+            array('fe80::202:b3ff:fe1e:8329'),
+            array('0:0:0:0:0:0:0:0'),
+            array('::'),
+            array('0::'),
+            array('::0'),
+            array('0::0'),
+            // IPv4 mapped to IPv6
+            array('2001:0db8:85a3:0000:0000:8a2e:0.0.0.0'),
+            array('::0.0.0.0'),
+            array('::255.255.255.255'),
+            array('::123.45.67.178'),
+        );
+    }
+
+    /**
+     * @dataProvider getValidIpsAll
+     */
+    public function testValidIpsAll($ip)
+    {
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $this->validator->validate($ip, new Ip(array(
+            'version' => Ip::ALL,
+        )));
+    }
+
+    public function getValidIpsAll()
+    {
+        return array_merge($this->getValidIpsV4(), $this->getValidIpsV6());
+    }
+
+    /**
+     * @dataProvider getInvalidIpsV4
+     */
+    public function testInvalidIpsV4($ip)
+    {
+        $constraint = new Ip(array(
+            'version' => Ip::V4,
+            'message' => 'myMessage',
+        ));
+
+        $this->context->expects($this->once())
+            ->method('addViolation')
+            ->with('myMessage', array(
+                '{{ value }}' => $ip,
+            ));
+
+        $this->validator->validate($ip, $constraint);
+    }
+
+    public function getInvalidIpsV4()
+    {
+        return array(
+            array('0'),
+            array('0.0'),
+            array('0.0.0'),
+            array('256.0.0.0'),
+            array('0.256.0.0'),
+            array('0.0.256.0'),
+            array('0.0.0.256'),
+            array('-1.0.0.0'),
+            array('foobar'),
+        );
+    }
+
+    /**
+     * @dataProvider getInvalidPrivateIpsV4
+     */
+    public function testInvalidPrivateIpsV4($ip)
+    {
+        $constraint = new Ip(array(
+            'version' => Ip::V4_NO_PRIV,
+            'message' => 'myMessage',
+        ));
+
+        $this->context->expects($this->once())
+            ->method('addViolation')
+            ->with('myMessage', array(
+                '{{ value }}' => $ip,
+            ));
+
+        $this->validator->validate($ip, $constraint);
+    }
+
+    public function getInvalidPrivateIpsV4()
+    {
+        return array(
+            array('10.0.0.0'),
+            array('172.16.0.0'),
+            array('192.168.1.0'),
+        );
+    }
+
+    /**
+     * @dataProvider getInvalidReservedIpsV4
+     */
+    public function testInvalidReservedIpsV4($ip)
+    {
+        $constraint = new Ip(array(
+            'version' => Ip::V4_NO_RES,
+            'message' => 'myMessage',
+        ));
+
+        $this->context->expects($this->once())
+            ->method('addViolation')
+            ->with('myMessage', array(
+                '{{ value }}' => $ip,
+            ));
+
+        $this->validator->validate($ip, $constraint);
+    }
+
+    public function getInvalidReservedIpsV4()
+    {
+        return array(
+            array('0.0.0.0'),
+            array('224.0.0.1'),
+            array('255.255.255.255'),
+        );
+    }
+
+    /**
+     * @dataProvider getInvalidPublicIpsV4
+     */
+    public function testInvalidPublicIpsV4($ip)
+    {
+        $constraint = new Ip(array(
+            'version' => Ip::V4_ONLY_PUBLIC,
+            'message' => 'myMessage',
+        ));
+
+        $this->context->expects($this->once())
+            ->method('addViolation')
+            ->with('myMessage', array(
+                '{{ value }}' => $ip,
+            ));
+
+        $this->validator->validate($ip, $constraint);
+    }
+
+    public function getInvalidPublicIpsV4()
+    {
+        return array_merge($this->getInvalidPrivateIpsV4(), $this->getInvalidReservedIpsV4());
+    }
+
+    /**
+     * @dataProvider getInvalidIpsV6
+     */
+    public function testInvalidIpsV6($ip)
+    {
+        $constraint = new Ip(array(
+            'version' => Ip::V6,
+            'message' => 'myMessage',
+        ));
+
+        $this->context->expects($this->once())
+            ->method('addViolation')
+            ->with('myMessage', array(
+                '{{ value }}' => $ip,
+            ));
+
+        $this->validator->validate($ip, $constraint);
+    }
+
+    public function getInvalidIpsV6()
+    {
+        return array(
+            array('z001:0db8:85a3:0000:0000:8a2e:0370:7334'),
+            array('fe80'),
+            array('fe80:8329'),
+            array('fe80:::202:b3ff:fe1e:8329'),
+            array('fe80::202:b3ff::fe1e:8329'),
+            // IPv4 mapped to IPv6
+            array('2001:0db8:85a3:0000:0000:8a2e:0370:0.0.0.0'),
+            array('::0.0'),
+            array('::0.0.0'),
+            array('::256.0.0.0'),
+            array('::0.256.0.0'),
+            array('::0.0.256.0'),
+            array('::0.0.0.256'),
+        );
+    }
+
+    /**
+     * @dataProvider getInvalidPrivateIpsV6
+     */
+    public function testInvalidPrivateIpsV6($ip)
+    {
+        $constraint = new Ip(array(
+            'version' => Ip::V6_NO_PRIV,
+            'message' => 'myMessage',
+        ));
+
+        $this->context->expects($this->once())
+            ->method('addViolation')
+            ->with('myMessage', array(
+                '{{ value }}' => $ip,
+            ));
+
+        $this->validator->validate($ip, $constraint);
+    }
+
+    public function getInvalidPrivateIpsV6()
+    {
+        return array(
+            array('fdfe:dcba:9876:ffff:fdc6:c46b:bb8f:7d4c'),
+            array('fdc6:c46b:bb8f:7d4c:fdc6:c46b:bb8f:7d4c'),
+            array('fdc6:c46b:bb8f:7d4c:0000:8a2e:0370:7334'),
+        );
+    }
+
+    /**
+     * @dataProvider getInvalidReservedIpsV6
+     */
+    public function testInvalidReservedIpsV6($ip)
+    {
+        $constraint = new Ip(array(
+            'version' => Ip::V6_NO_RES,
+            'message' => 'myMessage',
+        ));
+
+        $this->context->expects($this->once())
+            ->method('addViolation')
+            ->with('myMessage', array(
+                '{{ value }}' => $ip,
+            ));
+
+        $this->validator->validate($ip, $constraint);
+    }
+
+    public function getInvalidReservedIpsV6()
+    {
+        // Quoting after official filter documentation:
+        // "FILTER_FLAG_NO_RES_RANGE = This flag does not apply to IPv6 addresses."
+        // Full description: http://php.net/manual/en/filter.filters.flags.php
+        return $this->getInvalidIpsV6();
+    }
+
+    /**
+     * @dataProvider getInvalidPublicIpsV6
+     */
+    public function testInvalidPublicIpsV6($ip)
+    {
+        $constraint = new Ip(array(
+            'version' => Ip::V6_ONLY_PUBLIC,
+            'message' => 'myMessage',
+        ));
+
+        $this->context->expects($this->once())
+            ->method('addViolation')
+            ->with('myMessage', array(
+                '{{ value }}' => $ip,
+            ));
+
+        $this->validator->validate($ip, $constraint);
+    }
+
+    public function getInvalidPublicIpsV6()
+    {
+        return array_merge($this->getInvalidPrivateIpsV6(), $this->getInvalidReservedIpsV6());
+    }
+
+    /**
+     * @dataProvider getInvalidIpsAll
+     */
+    public function testInvalidIpsAll($ip)
+    {
+        $constraint = new Ip(array(
+            'version' => Ip::ALL,
+            'message' => 'myMessage',
+        ));
+
+        $this->context->expects($this->once())
+            ->method('addViolation')
+            ->with('myMessage', array(
+                '{{ value }}' => $ip,
+            ));
+
+        $this->validator->validate($ip, $constraint);
+    }
+
+    public function getInvalidIpsAll()
+    {
+        return array_merge($this->getInvalidIpsV4(), $this->getInvalidIpsV6());
+    }
+
+    /**
+     * @dataProvider getInvalidPrivateIpsAll
+     */
+    public function testInvalidPrivateIpsAll($ip)
+    {
+        $constraint = new Ip(array(
+            'version' => Ip::ALL_NO_PRIV,
+            'message' => 'myMessage',
+        ));
+
+        $this->context->expects($this->once())
+            ->method('addViolation')
+            ->with('myMessage', array(
+                '{{ value }}' => $ip,
+            ));
+
+        $this->validator->validate($ip, $constraint);
+    }
+
+    public function getInvalidPrivateIpsAll()
+    {
+        return array_merge($this->getInvalidPrivateIpsV4(), $this->getInvalidPrivateIpsV6());
+    }
+
+    /**
+     * @dataProvider getInvalidReservedIpsAll
+     */
+    public function testInvalidReservedIpsAll($ip)
+    {
+        $constraint = new Ip(array(
+            'version' => Ip::ALL_NO_RES,
+            'message' => 'myMessage',
+        ));
+
+        $this->context->expects($this->once())
+            ->method('addViolation')
+            ->with('myMessage', array(
+                '{{ value }}' => $ip,
+            ));
+
+        $this->validator->validate($ip, $constraint);
+    }
+
+    public function getInvalidReservedIpsAll()
+    {
+        return array_merge($this->getInvalidReservedIpsV4(), $this->getInvalidReservedIpsV6());
+    }
+
+    /**
+     * @dataProvider getInvalidPublicIpsAll
+     */
+    public function testInvalidPublicIpsAll($ip)
+    {
+        $constraint = new Ip(array(
+            'version' => Ip::ALL_ONLY_PUBLIC,
+            'message' => 'myMessage',
+        ));
+
+        $this->context->expects($this->once())
+            ->method('addViolation')
+            ->with('myMessage', array(
+                '{{ value }}' => $ip,
+            ));
+
+        $this->validator->validate($ip, $constraint);
+    }
+
+    public function getInvalidPublicIpsAll()
+    {
+        return array_merge($this->getInvalidPublicIpsV4(), $this->getInvalidPublicIpsV6());
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LanguageValidatorTest.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LanguageValidatorTest.php
new file mode 100644
index 0000000..4f06afa
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LanguageValidatorTest.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\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Constraints\Language;
+use Symfony\Component\Validator\Constraints\LanguageValidator;
+
+class LanguageValidatorTest extends LocalizedTestCase
+{
+    protected $context;
+    protected $validator;
+
+    protected function setUp()
+    {
+        parent::setUp();
+
+        $this->context = $this->getMock('Symfony\Component\Validator\ExecutionContext', array(), array(), '', false);
+        $this->validator = new LanguageValidator();
+        $this->validator->initialize($this->context);
+    }
+
+    protected function tearDown()
+    {
+        $this->context = null;
+        $this->validator = null;
+    }
+
+    public function testNullIsValid()
+    {
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $this->validator->validate(null, new Language());
+    }
+
+    public function testEmptyStringIsValid()
+    {
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $this->validator->validate('', new Language());
+    }
+
+    /**
+     * @expectedException Symfony\Component\Validator\Exception\UnexpectedTypeException
+     */
+    public function testExpectsStringCompatibleType()
+    {
+        $this->validator->validate(new \stdClass(), new Language());
+    }
+
+    /**
+     * @dataProvider getValidLanguages
+     */
+    public function testValidLanguages($language)
+    {
+        if (!class_exists('Symfony\Component\Locale\Locale')) {
+            $this->markTestSkipped('The "Locale" component is not available');
+        }
+
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $this->validator->validate($language, new Language());
+    }
+
+    public function getValidLanguages()
+    {
+        return array(
+            array('en'),
+            array('en_US'),
+            array('my'),
+        );
+    }
+
+    /**
+     * @dataProvider getInvalidLanguages
+     */
+    public function testInvalidLanguages($language)
+    {
+        if (!class_exists('Symfony\Component\Locale\Locale')) {
+            $this->markTestSkipped('The "Locale" component is not available');
+        }
+
+        $constraint = new Language(array(
+            'message' => 'myMessage'
+        ));
+
+        $this->context->expects($this->once())
+            ->method('addViolation')
+            ->with('myMessage', array(
+                '{{ value }}' => $language,
+            ));
+
+        $this->validator->validate($language, $constraint);
+    }
+
+    public function getInvalidLanguages()
+    {
+        return array(
+            array('EN'),
+            array('foobar'),
+        );
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LengthValidatorTest.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LengthValidatorTest.php
new file mode 100644
index 0000000..5a343b4
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LengthValidatorTest.php
@@ -0,0 +1,233 @@
+<?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\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Constraints\Length;
+use Symfony\Component\Validator\Constraints\LengthValidator;
+
+class LengthValidatorTest extends \PHPUnit_Framework_TestCase
+{
+    protected $context;
+    protected $validator;
+
+    protected function setUp()
+    {
+        $this->context = $this->getMock('Symfony\Component\Validator\ExecutionContext', array(), array(), '', false);
+        $this->validator = new LengthValidator();
+        $this->validator->initialize($this->context);
+    }
+
+    protected function tearDown()
+    {
+        $this->context = null;
+        $this->validator = null;
+    }
+
+    public function testNullIsValid()
+    {
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $this->validator->validate(null, new Length(6));
+    }
+
+    public function testEmptyStringIsValid()
+    {
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $this->validator->validate('', new Length(6));
+    }
+
+    /**
+     * @expectedException Symfony\Component\Validator\Exception\UnexpectedTypeException
+     */
+    public function testExpectsStringCompatibleType()
+    {
+        $this->validator->validate(new \stdClass(), new Length(5));
+    }
+
+    public function getThreeOrLessCharacters()
+    {
+        return array(
+            array(12),
+            array('12'),
+            array('Ã¼Ã¼', true),
+            array('Ã©Ã©', true),
+            array(123),
+            array('123'),
+            array('Ã¼Ã¼Ã¼', true),
+            array('Ã©Ã©Ã©', true),
+        );
+    }
+
+    public function getFourCharacters()
+    {
+        return array(
+            array(1234),
+            array('1234'),
+            array('Ã¼Ã¼Ã¼Ã¼', true),
+            array('Ã©Ã©Ã©Ã©', true),
+        );
+    }
+
+    public function getNotFourCharacters()
+    {
+        return array_merge(
+            $this->getThreeOrLessCharacters(),
+            $this->getFiveOrMoreCharacters()
+        );
+    }
+
+    public function getFiveOrMoreCharacters()
+    {
+        return array(
+            array(12345),
+            array('12345'),
+            array('Ã¼Ã¼Ã¼Ã¼Ã¼', true),
+            array('Ã©Ã©Ã©Ã©Ã©', true),
+            array(123456),
+            array('123456'),
+            array('Ã¼Ã¼Ã¼Ã¼Ã¼Ã¼', true),
+            array('Ã©Ã©Ã©Ã©Ã©Ã©', true),
+        );
+    }
+
+    /**
+     * @dataProvider getFiveOrMoreCharacters
+     */
+    public function testValidValuesMin($value, $mbOnly = false)
+    {
+        if ($mbOnly && !function_exists('mb_strlen')) {
+            $this->markTestSkipped('mb_strlen does not exist');
+        }
+
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $constraint = new Length(array('min' => 5));
+        $this->validator->validate($value, $constraint);
+    }
+
+    /**
+     * @dataProvider getThreeOrLessCharacters
+     */
+    public function testValidValuesMax($value, $mbOnly = false)
+    {
+        if ($mbOnly && !function_exists('mb_strlen')) {
+            $this->markTestSkipped('mb_strlen does not exist');
+        }
+
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $constraint = new Length(array('max' => 3));
+        $this->validator->validate($value, $constraint);
+    }
+
+    /**
+     * @dataProvider getFourCharacters
+     */
+    public function testValidValuesExact($value, $mbOnly = false)
+    {
+        if ($mbOnly && !function_exists('mb_strlen')) {
+            $this->markTestSkipped('mb_strlen does not exist');
+        }
+
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $constraint = new Length(4);
+        $this->validator->validate($value, $constraint);
+    }
+
+    /**
+     * @dataProvider getThreeOrLessCharacters
+     */
+    public function testInvalidValuesMin($value, $mbOnly = false)
+    {
+        if ($mbOnly && !function_exists('mb_strlen')) {
+            $this->markTestSkipped('mb_strlen does not exist');
+        }
+
+        $constraint = new Length(array(
+            'min' => 4,
+            'minMessage' => 'myMessage'
+        ));
+
+        $this->context->expects($this->once())
+            ->method('addViolation')
+            ->with('myMessage', $this->identicalTo(array(
+                '{{ value }}' => (string) $value,
+                '{{ limit }}' => 4,
+            )), $this->identicalTo($value), 4);
+
+        $this->validator->validate($value, $constraint);
+    }
+
+    /**
+     * @dataProvider getFiveOrMoreCharacters
+     */
+    public function testInvalidValuesMax($value, $mbOnly = false)
+    {
+        if ($mbOnly && !function_exists('mb_strlen')) {
+            $this->markTestSkipped('mb_strlen does not exist');
+        }
+
+        $constraint = new Length(array(
+            'max' => 4,
+            'maxMessage' => 'myMessage'
+        ));
+
+        $this->context->expects($this->once())
+            ->method('addViolation')
+            ->with('myMessage', $this->identicalTo(array(
+                '{{ value }}' => (string) $value,
+                '{{ limit }}' => 4,
+            )), $this->identicalTo($value), 4);
+
+        $this->validator->validate($value, $constraint);
+    }
+
+    /**
+     * @dataProvider getNotFourCharacters
+     */
+    public function testInvalidValuesExact($value, $mbOnly = false)
+    {
+        if ($mbOnly && !function_exists('mb_strlen')) {
+            $this->markTestSkipped('mb_strlen does not exist');
+        }
+
+        $constraint = new Length(array(
+            'min' => 4,
+            'max' => 4,
+            'exactMessage' => 'myMessage'
+        ));
+
+        $this->context->expects($this->once())
+            ->method('addViolation')
+            ->with('myMessage', $this->identicalTo(array(
+                '{{ value }}' => (string) $value,
+                '{{ limit }}' => 4,
+            )), $this->identicalTo($value), 4);
+
+        $this->validator->validate($value, $constraint);
+    }
+
+    public function testConstraintGetDefaultOption()
+    {
+        $constraint = new Length(5);
+
+        $this->assertEquals(5, $constraint->min);
+        $this->assertEquals(5, $constraint->max);
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LocaleValidatorTest.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LocaleValidatorTest.php
new file mode 100644
index 0000000..01e4b76
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LocaleValidatorTest.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\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Constraints\Locale;
+use Symfony\Component\Validator\Constraints\LocaleValidator;
+
+class LocaleValidatorTest extends LocalizedTestCase
+{
+    protected $context;
+    protected $validator;
+
+    protected function setUp()
+    {
+        parent::setUp();
+
+        $this->context = $this->getMock('Symfony\Component\Validator\ExecutionContext', array(), array(), '', false);
+        $this->validator = new LocaleValidator();
+        $this->validator->initialize($this->context);
+    }
+
+    protected function tearDown()
+    {
+        $this->context = null;
+        $this->validator = null;
+    }
+
+    public function testNullIsValid()
+    {
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $this->validator->validate(null, new Locale());
+    }
+
+    public function testEmptyStringIsValid()
+    {
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $this->validator->validate('', new Locale());
+    }
+
+    /**
+     * @expectedException Symfony\Component\Validator\Exception\UnexpectedTypeException
+     */
+    public function testExpectsStringCompatibleType()
+    {
+        $this->validator->validate(new \stdClass(), new Locale());
+    }
+
+    /**
+     * @dataProvider getValidLocales
+     */
+    public function testValidLocales($locale)
+    {
+        if (!class_exists('Symfony\Component\Locale\Locale')) {
+            $this->markTestSkipped('The "Locale" component is not available');
+        }
+
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $this->validator->validate($locale, new Locale());
+    }
+
+    public function getValidLocales()
+    {
+        return array(
+            array('en'),
+            array('en_US'),
+            array('pt'),
+            array('pt_PT'),
+            array('zh_Hans'),
+        );
+    }
+
+    /**
+     * @dataProvider getInvalidLocales
+     */
+    public function testInvalidLocales($locale)
+    {
+        if (!class_exists('Symfony\Component\Locale\Locale')) {
+            $this->markTestSkipped('The "Locale" component is not available');
+        }
+
+        $constraint = new Locale(array(
+            'message' => 'myMessage'
+        ));
+
+        $this->context->expects($this->once())
+            ->method('addViolation')
+            ->with('myMessage', array(
+                '{{ value }}' => $locale,
+            ));
+
+        $this->validator->validate($locale, $constraint);
+    }
+
+    public function getInvalidLocales()
+    {
+        return array(
+            array('EN'),
+            array('foobar'),
+        );
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LocalizedTestCase.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LocalizedTestCase.php
new file mode 100644
index 0000000..a71c089
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/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\Validator\Tests\Constraints;
+
+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/validator/Symfony/Component/Validator/Tests/Constraints/LuhnValidatorTest.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LuhnValidatorTest.php
new file mode 100644
index 0000000..3c05778
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/LuhnValidatorTest.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\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Constraints\Luhn;
+use Symfony\Component\Validator\Constraints\LuhnValidator;
+
+class LuhnValidatorTest extends \PHPUnit_Framework_TestCase
+{
+    protected $context;
+    protected $validator;
+
+    protected function setUp()
+    {
+        $this->context = $this->getMock('Symfony\Component\Validator\ExecutionContext', array(), array(), '', false);
+        $this->validator = new LuhnValidator();
+        $this->validator->initialize($this->context);
+    }
+
+    protected function tearDown()
+    {
+        $this->context = null;
+        $this->validator = null;
+    }
+
+    public function testNullIsValid()
+    {
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $this->validator->validate(null, new Luhn());
+    }
+
+    public function testEmptyStringIsValid()
+    {
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $this->validator->validate('', new Luhn());
+    }
+
+    /**
+     * @dataProvider getValidNumbers
+     */
+    public function testValidNumbers($number)
+    {
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $this->validator->validate($number, new Luhn());
+    }
+
+    public function getValidNumbers()
+    {
+        return array(
+            array('42424242424242424242'),
+            array('378282246310005'),
+            array('371449635398431'),
+            array('378734493671000'),
+            array('5610591081018250'),
+            array('30569309025904'),
+            array('38520000023237'),
+            array('6011111111111117'),
+            array('6011000990139424'),
+            array('3530111333300000'),
+            array('3566002020360505'),
+            array('5555555555554444'),
+            array('5105105105105100'),
+            array('4111111111111111'),
+            array('4012888888881881'),
+            array('4222222222222'),
+            array('5019717010103742'),
+            array('6331101999990016'),
+        );
+    }
+
+    /**
+     * @dataProvider getInvalidNumbers
+     */
+    public function testInvalidNumbers($number)
+    {
+        $constraint = new Luhn();
+
+        $this->context->expects($this->once())
+            ->method('addViolation')
+            ->with($constraint->message);
+
+        $this->validator->validate($number, $constraint);
+    }
+
+    public function getInvalidNumbers()
+    {
+        return array(
+            array('1234567812345678'),
+            array('4222222222222222'),
+        );
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/MaxLengthValidatorTest.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/MaxLengthValidatorTest.php
new file mode 100644
index 0000000..4db9103
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/MaxLengthValidatorTest.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\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Constraints\MaxLength;
+use Symfony\Component\Validator\Constraints\MaxLengthValidator;
+
+class MaxLengthValidatorTest extends \PHPUnit_Framework_TestCase
+{
+    protected $context;
+    protected $validator;
+
+    protected function setUp()
+    {
+        $this->context = $this->getMock('Symfony\Component\Validator\ExecutionContext', array(), array(), '', false);
+        $this->validator = new MaxLengthValidator();
+        $this->validator->initialize($this->context);
+    }
+
+    protected function tearDown()
+    {
+        $this->context = null;
+        $this->validator = null;
+    }
+
+    public function testNullIsValid()
+    {
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $this->validator->validate(null, new MaxLength(array('limit' => 5)));
+    }
+
+    public function testEmptyStringIsValid()
+    {
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $this->validator->validate('', new MaxLength(array('limit' => 5)));
+    }
+
+    /**
+     * @expectedException Symfony\Component\Validator\Exception\UnexpectedTypeException
+     */
+    public function testExpectsStringCompatibleType()
+    {
+        $this->validator->validate(new \stdClass(), new MaxLength(array('limit' => 5)));
+    }
+
+    /**
+     * @dataProvider getValidValues
+     */
+    public function testValidValues($value, $mbOnly = false)
+    {
+        if ($mbOnly && !function_exists('mb_strlen')) {
+            $this->markTestSkipped('mb_strlen does not exist');
+        }
+
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $constraint = new MaxLength(array('limit' => 5));
+        $this->validator->validate($value, $constraint);
+    }
+
+    public function getValidValues()
+    {
+        return array(
+            array(12345),
+            array('12345'),
+            array('Ã¼Ã¼Ã¼Ã¼Ã¼', true),
+            array('Ã©Ã©Ã©Ã©Ã©', true),
+        );
+    }
+
+    /**
+     * @dataProvider getInvalidValues
+     */
+    public function testInvalidValues($value, $mbOnly = false)
+    {
+        if ($mbOnly && !function_exists('mb_strlen')) {
+            $this->markTestSkipped('mb_strlen does not exist');
+        }
+
+        $constraint = new MaxLength(array(
+            'limit' => 5,
+            'message' => 'myMessage'
+        ));
+
+        $this->context->expects($this->once())
+            ->method('addViolation')
+            ->with('myMessage', $this->identicalTo(array(
+                '{{ value }}' => (string) $value,
+                '{{ limit }}' => 5,
+            )), $this->identicalTo($value), 5);
+
+        $this->validator->validate($value, $constraint);
+    }
+
+    public function getInvalidValues()
+    {
+        return array(
+            array(123456),
+            array('123456'),
+            array('Ã¼Ã¼Ã¼Ã¼Ã¼Ã¼', true),
+            array('Ã©Ã©Ã©Ã©Ã©Ã©', true),
+        );
+    }
+
+    public function testConstraintGetDefaultOption()
+    {
+        $constraint = new MaxLength(array(
+            'limit' => 5,
+        ));
+
+        $this->assertEquals('limit', $constraint->getDefaultOption());
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/MaxValidatorTest.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/MaxValidatorTest.php
new file mode 100644
index 0000000..3ee95ee
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/MaxValidatorTest.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\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Constraints\Max;
+use Symfony\Component\Validator\Constraints\MaxValidator;
+
+class MaxValidatorTest extends \PHPUnit_Framework_TestCase
+{
+    protected $context;
+    protected $validator;
+
+    protected function setUp()
+    {
+        $this->context = $this->getMock('Symfony\Component\Validator\ExecutionContext', array(), array(), '', false);
+        $this->validator = new MaxValidator();
+        $this->validator->initialize($this->context);
+    }
+
+    protected function tearDown()
+    {
+        $this->context = null;
+        $this->validator = null;
+    }
+
+    public function testNullIsValid()
+    {
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $this->validator->validate(null, new Max(array('limit' => 10)));
+    }
+
+    public function testEmptyStringIsValid()
+    {
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $this->validator->validate('', new Max(array('limit' => 10)));
+    }
+
+    /**
+     * @dataProvider getValidValues
+     */
+    public function testValidValues($value)
+    {
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $constraint = new Max(array('limit' => 10));
+        $this->validator->validate($value, $constraint);
+    }
+
+    public function getValidValues()
+    {
+        return array(
+            array(9.999999),
+            array(10),
+            array(10.0),
+            array('10'),
+        );
+    }
+
+    /**
+     * @dataProvider getInvalidValues
+     */
+    public function testInvalidValues($value)
+    {
+        $constraint = new Max(array(
+            'limit' => 10,
+            'message' => 'myMessage',
+            'invalidMessage' => 'myMessage'
+        ));
+
+        $this->context->expects($this->once())
+            ->method('addViolation')
+            ->with('myMessage', array(
+                '{{ value }}' => $value,
+                '{{ limit }}' => 10,
+            ));
+
+        $this->validator->validate($value, $constraint);
+    }
+
+    public function getInvalidValues()
+    {
+        return array(
+            array(10.00001),
+            array('10.00001'),
+            array(new \stdClass()),
+        );
+    }
+
+    public function testConstraintGetDefaultOption()
+    {
+        $constraint = new Max(array(
+            'limit' => 10,
+        ));
+
+        $this->assertEquals('limit', $constraint->getDefaultOption());
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/MinLengthValidatorTest.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/MinLengthValidatorTest.php
new file mode 100644
index 0000000..08d0a81
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/MinLengthValidatorTest.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\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Constraints\MinLength;
+use Symfony\Component\Validator\Constraints\MinLengthValidator;
+
+class MinLengthValidatorTest extends \PHPUnit_Framework_TestCase
+{
+    protected $context;
+    protected $validator;
+
+    protected function setUp()
+    {
+        $this->context = $this->getMock('Symfony\Component\Validator\ExecutionContext', array(), array(), '', false);
+        $this->validator = new MinLengthValidator();
+        $this->validator->initialize($this->context);
+    }
+
+    protected function tearDown()
+    {
+        $this->context = null;
+        $this->validator = null;
+    }
+
+    public function testNullIsValid()
+    {
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $this->validator->validate(null, new MinLength(array('limit' => 6)));
+    }
+
+    public function testEmptyStringIsValid()
+    {
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $this->validator->validate('', new MinLength(array('limit' => 6)));
+    }
+
+    /**
+     * @expectedException Symfony\Component\Validator\Exception\UnexpectedTypeException
+     */
+    public function testExpectsStringCompatibleType()
+    {
+        $this->validator->validate(new \stdClass(), new MinLength(array('limit' => 5)));
+    }
+
+    /**
+     * @dataProvider getValidValues
+     */
+    public function testValidValues($value, $mbOnly = false)
+    {
+        if ($mbOnly && !function_exists('mb_strlen')) {
+            $this->markTestSkipped('mb_strlen does not exist');
+        }
+
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $constraint = new MinLength(array('limit' => 6));
+        $this->validator->validate($value, $constraint);
+    }
+
+    public function getValidValues()
+    {
+        return array(
+            array(123456),
+            array('123456'),
+            array('Ã¼Ã¼Ã¼Ã¼Ã¼Ã¼', true),
+            array('Ã©Ã©Ã©Ã©Ã©Ã©', true),
+        );
+    }
+
+    /**
+     * @dataProvider getInvalidValues
+     */
+    public function testInvalidValues($value, $mbOnly = false)
+    {
+        if ($mbOnly && !function_exists('mb_strlen')) {
+            $this->markTestSkipped('mb_strlen does not exist');
+        }
+
+        $constraint = new MinLength(array(
+            'limit' => 5,
+            'message' => 'myMessage'
+        ));
+
+        $this->context->expects($this->once())
+            ->method('addViolation')
+            ->with('myMessage', $this->identicalTo(array(
+                '{{ value }}' => (string) $value,
+                '{{ limit }}' => 5,
+            )), $this->identicalTo($value), 5);
+
+        $this->validator->validate($value, $constraint);
+    }
+
+    public function getInvalidValues()
+    {
+        return array(
+            array(1234),
+            array('1234'),
+            array('Ã¼Ã¼Ã¼Ã¼', true),
+            array('Ã©Ã©Ã©Ã©', true),
+        );
+    }
+
+    public function testConstraintGetDefaultOption()
+    {
+        $constraint = new MinLength(array(
+            'limit' => 5,
+        ));
+
+        $this->assertEquals('limit', $constraint->getDefaultOption());
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/MinValidatorTest.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/MinValidatorTest.php
new file mode 100644
index 0000000..f760190
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/MinValidatorTest.php
@@ -0,0 +1,105 @@
+<?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\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Constraints\Min;
+use Symfony\Component\Validator\Constraints\MinValidator;
+
+class MinValidatorTest extends \PHPUnit_Framework_TestCase
+{
+    protected $context;
+    protected $validator;
+
+    protected function setUp()
+    {
+        $this->context = $this->getMock('Symfony\Component\Validator\ExecutionContext', array(), array(), '', false);
+        $this->validator = new MinValidator();
+        $this->validator->initialize($this->context);
+    }
+
+    public function testNullIsValid()
+    {
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $this->validator->validate(null, new Min(array('limit' => 10)));
+    }
+
+    public function testEmptyStringIsValid()
+    {
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $this->validator->validate('', new Min(array('limit' => 10)));
+    }
+
+    /**
+     * @dataProvider getValidValues
+     */
+    public function testValidValues($value)
+    {
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $constraint = new Min(array('limit' => 10));
+        $this->validator->validate($value, $constraint);
+    }
+
+    public function getValidValues()
+    {
+        return array(
+            array(10.00001),
+            array('10.00001'),
+            array(10),
+            array(10.0),
+        );
+    }
+
+    /**
+     * @dataProvider getInvalidValues
+     */
+    public function testInvalidValues($value)
+    {
+        $constraint = new Min(array(
+            'limit' => 10,
+            'message' => 'myMessage',
+            'invalidMessage' => 'myMessage'
+        ));
+
+        $this->context->expects($this->once())
+            ->method('addViolation')
+            ->with('myMessage', array(
+                '{{ value }}' => $value,
+                '{{ limit }}' => 10,
+            ));
+
+        $this->validator->validate($value, $constraint);
+    }
+
+    public function getInvalidValues()
+    {
+        return array(
+            array(9.999999),
+            array('9.999999'),
+            array(new \stdClass()),
+        );
+    }
+
+    public function testConstraintGetDefaultOption()
+    {
+        $constraint = new Min(array(
+            'limit' => 10,
+        ));
+
+        $this->assertEquals('limit', $constraint->getDefaultOption());
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/NotBlankValidatorTest.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/NotBlankValidatorTest.php
new file mode 100644
index 0000000..85db95d
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/NotBlankValidatorTest.php
@@ -0,0 +1,108 @@
+<?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\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Constraints\NotBlank;
+use Symfony\Component\Validator\Constraints\NotBlankValidator;
+
+class NotBlankValidatorTest extends \PHPUnit_Framework_TestCase
+{
+    protected $context;
+    protected $validator;
+
+    protected function setUp()
+    {
+        $this->context = $this->getMock('Symfony\Component\Validator\ExecutionContext', array(), array(), '', false);
+        $this->validator = new NotBlankValidator();
+        $this->validator->initialize($this->context);
+    }
+
+    protected function tearDown()
+    {
+        $this->context = null;
+        $this->validator = null;
+    }
+
+    /**
+     * @dataProvider getValidValues
+     */
+    public function testValidValues($date)
+    {
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $this->validator->validate($date, new NotBlank());
+    }
+
+    public function getValidValues()
+    {
+        return array(
+            array('foobar'),
+            array(0),
+            array(0.0),
+            array('0'),
+            array(1234),
+        );
+    }
+
+    public function testNullIsInvalid()
+    {
+        $constraint = new NotBlank(array(
+            'message' => 'myMessage'
+        ));
+
+        $this->context->expects($this->once())
+            ->method('addViolation')
+            ->with('myMessage');
+
+        $this->validator->validate(null, $constraint);
+    }
+
+    public function testBlankIsInvalid()
+    {
+        $constraint = new NotBlank(array(
+            'message' => 'myMessage'
+        ));
+
+        $this->context->expects($this->once())
+            ->method('addViolation')
+            ->with('myMessage');
+
+        $this->validator->validate('', $constraint);
+    }
+
+    public function testFalseIsInvalid()
+    {
+        $constraint = new NotBlank(array(
+            'message' => 'myMessage'
+        ));
+
+        $this->context->expects($this->once())
+            ->method('addViolation')
+            ->with('myMessage');
+
+        $this->validator->validate(false, $constraint);
+    }
+
+    public function testEmptyArrayIsInvalid()
+    {
+        $constraint = new NotBlank(array(
+            'message' => 'myMessage'
+        ));
+
+        $this->context->expects($this->once())
+            ->method('addViolation')
+            ->with('myMessage');
+
+        $this->validator->validate(array(), $constraint);
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/NotNullValidatorTest.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/NotNullValidatorTest.php
new file mode 100644
index 0000000..96f74a1
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/NotNullValidatorTest.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\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Constraints\NotNull;
+use Symfony\Component\Validator\Constraints\NotNullValidator;
+
+class NotNullValidatorTest extends \PHPUnit_Framework_TestCase
+{
+    protected $context;
+    protected $validator;
+
+    protected function setUp()
+    {
+        $this->context = $this->getMock('Symfony\Component\Validator\ExecutionContext', array(), array(), '', false);
+        $this->validator = new NotNullValidator();
+        $this->validator->initialize($this->context);
+    }
+
+    protected function tearDown()
+    {
+        $this->context = null;
+        $this->validator = null;
+    }
+
+    /**
+     * @dataProvider getValidValues
+     */
+    public function testValidValues($value)
+    {
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $this->validator->validate($value, new NotNull());
+    }
+
+    public function getValidValues()
+    {
+        return array(
+            array(0),
+            array(false),
+            array(true),
+            array(''),
+        );
+    }
+
+    public function testNullIsInvalid()
+    {
+        $constraint = new NotNull(array(
+            'message' => 'myMessage'
+        ));
+
+        $this->context->expects($this->once())
+            ->method('addViolation')
+            ->with('myMessage', array(
+            ));
+
+        $this->validator->validate(null, $constraint);
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/NullValidatorTest.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/NullValidatorTest.php
new file mode 100644
index 0000000..4466aa1
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/NullValidatorTest.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\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Constraints\Null;
+use Symfony\Component\Validator\Constraints\NullValidator;
+
+class NullValidatorTest extends \PHPUnit_Framework_TestCase
+{
+    protected $context;
+    protected $validator;
+
+    protected function setUp()
+    {
+        $this->context = $this->getMock('Symfony\Component\Validator\ExecutionContext', array(), array(), '', false);
+        $this->validator = new NullValidator();
+        $this->validator->initialize($this->context);
+    }
+
+    protected function tearDown()
+    {
+        $this->context = null;
+        $this->validator = null;
+    }
+
+    public function testNullIsValid()
+    {
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $this->validator->validate(null, new Null());
+    }
+
+    /**
+     * @dataProvider getInvalidValues
+     */
+    public function testInvalidValues($value)
+    {
+        $constraint = new Null(array(
+            'message' => 'myMessage'
+        ));
+
+        $this->context->expects($this->once())
+            ->method('addViolation')
+            ->with('myMessage', array(
+                '{{ value }}' => $value,
+            ));
+
+        $this->validator->validate($value, $constraint);
+    }
+
+    public function getInvalidValues()
+    {
+        return array(
+            array(0),
+            array(false),
+            array(true),
+            array(''),
+        );
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/RangeValidatorTest.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/RangeValidatorTest.php
new file mode 100644
index 0000000..c44b0ea
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/RangeValidatorTest.php
@@ -0,0 +1,237 @@
+<?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\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Constraints\Range;
+use Symfony\Component\Validator\Constraints\RangeValidator;
+
+class RangeValidatorTest extends \PHPUnit_Framework_TestCase
+{
+    protected $context;
+    protected $validator;
+
+    protected function setUp()
+    {
+        $this->context = $this->getMock('Symfony\Component\Validator\ExecutionContext', array(), array(), '', false);
+        $this->validator = new RangeValidator();
+        $this->validator->initialize($this->context);
+    }
+
+    public function testNullIsValid()
+    {
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $this->validator->validate(null, new Range(array('min' => 10, 'max' => 20)));
+    }
+
+    public function getTenToTwenty()
+    {
+        return array(
+            array(10.00001),
+            array(19.99999),
+            array('10.00001'),
+            array('19.99999'),
+            array(10),
+            array(20),
+            array(10.0),
+            array(20.0),
+        );
+    }
+
+    public function getLessThanTen()
+    {
+        return array(
+            array(9.99999),
+            array('9.99999'),
+            array(5),
+            array(1.0),
+        );
+    }
+
+    public function getMoreThanTwenty()
+    {
+        return array(
+            array(20.000001),
+            array('20.000001'),
+            array(21),
+            array(30.0),
+        );
+    }
+
+    /**
+     * @dataProvider getTenToTwenty
+     */
+    public function testValidValuesMin($value)
+    {
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $constraint = new Range(array('min' => 10));
+        $this->validator->validate($value, $constraint);
+    }
+
+    /**
+     * @dataProvider getTenToTwenty
+     */
+    public function testValidValuesMax($value)
+    {
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $constraint = new Range(array('max' => 20));
+        $this->validator->validate($value, $constraint);
+    }
+
+    /**
+     * @dataProvider getTenToTwenty
+     */
+    public function testValidValuesMinMax($value)
+    {
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $constraint = new Range(array('min' => 10, 'max' => 20));
+        $this->validator->validate($value, $constraint);
+    }
+
+    /**
+     * @dataProvider getLessThanTen
+     */
+    public function testInvalidValuesMin($value)
+    {
+        $constraint = new Range(array(
+            'min' => 10,
+            'minMessage' => 'myMessage',
+        ));
+
+        $this->context->expects($this->once())
+            ->method('addViolation')
+            ->with('myMessage', $this->identicalTo(array(
+                '{{ value }}' => $value,
+                '{{ limit }}' => 10,
+        )));
+
+        $this->validator->validate($value, $constraint);
+    }
+
+    /**
+     * @dataProvider getMoreThanTwenty
+     */
+    public function testInvalidValuesMax($value)
+    {
+        $constraint = new Range(array(
+            'max' => 20,
+            'maxMessage' => 'myMessage',
+        ));
+
+        $this->context->expects($this->once())
+            ->method('addViolation')
+            ->with('myMessage', $this->identicalTo(array(
+                '{{ value }}' => $value,
+                '{{ limit }}' => 20,
+            )));
+
+        $this->validator->validate($value, $constraint);
+    }
+
+    /**
+     * @dataProvider getMoreThanTwenty
+     */
+    public function testInvalidValuesCombinedMax($value)
+    {
+        $constraint = new Range(array(
+            'min' => 10,
+            'max' => 20,
+            'minMessage' => 'myMinMessage',
+            'maxMessage' => 'myMaxMessage',
+        ));
+
+        $this->context->expects($this->once())
+            ->method('addViolation')
+            ->with('myMaxMessage', $this->identicalTo(array(
+                '{{ value }}' => $value,
+                '{{ limit }}' => 20,
+            )));
+
+        $this->validator->validate($value, $constraint);
+    }
+
+    /**
+     * @dataProvider getLessThanTen
+     */
+    public function testInvalidValuesCombinedMin($value)
+    {
+        $constraint = new Range(array(
+            'min' => 10,
+            'max' => 20,
+            'minMessage' => 'myMinMessage',
+            'maxMessage' => 'myMaxMessage',
+        ));
+
+        $this->context->expects($this->once())
+            ->method('addViolation')
+            ->with('myMinMessage', $this->identicalTo(array(
+            '{{ value }}' => $value,
+            '{{ limit }}' => 10,
+        )));
+
+        $this->validator->validate($value, $constraint);
+    }
+
+    public function getInvalidValues()
+    {
+        return array(
+            array(9.999999),
+            array(20.000001),
+            array('9.999999'),
+            array('20.000001'),
+            array(new \stdClass()),
+        );
+    }
+
+    public function testMinMessageIsSet()
+    {
+        $constraint = new Range(array(
+            'min' => 10,
+            'max' => 20,
+            'minMessage' => 'myMessage',
+        ));
+
+        $this->context->expects($this->once())
+            ->method('addViolation')
+            ->with('myMessage', array(
+                '{{ value }}' => 9,
+                '{{ limit }}' => 10,
+            ));
+
+        $this->validator->validate(9, $constraint);
+    }
+
+    public function testMaxMessageIsSet()
+    {
+        $constraint = new Range(array(
+            'min' => 10,
+            'max' => 20,
+            'maxMessage' => 'myMessage',
+        ));
+
+        $this->context->expects($this->once())
+            ->method('addViolation')
+            ->with('myMessage', array(
+                '{{ value }}' => 21,
+                '{{ limit }}' => 20,
+            ));
+
+        $this->validator->validate(21, $constraint);
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/RegexValidatorTest.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/RegexValidatorTest.php
new file mode 100644
index 0000000..1cc0609
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/RegexValidatorTest.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\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Constraints\Regex;
+use Symfony\Component\Validator\Constraints\RegexValidator;
+
+class RegexValidatorTest extends \PHPUnit_Framework_TestCase
+{
+    protected $context;
+    protected $validator;
+
+    protected function setUp()
+    {
+        $this->context = $this->getMock('Symfony\Component\Validator\ExecutionContext', array(), array(), '', false);
+        $this->validator = new RegexValidator();
+        $this->validator->initialize($this->context);
+    }
+
+    protected function tearDown()
+    {
+        $this->context = null;
+        $this->validator = null;
+    }
+
+    public function testNullIsValid()
+    {
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $this->validator->validate(null, new Regex(array('pattern' => '/^[0-9]+$/')));
+    }
+
+    public function testEmptyStringIsValid()
+    {
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $this->validator->validate('', new Regex(array('pattern' => '/^[0-9]+$/')));
+    }
+
+    /**
+     * @expectedException Symfony\Component\Validator\Exception\UnexpectedTypeException
+     */
+    public function testExpectsStringCompatibleType()
+    {
+        $this->validator->validate(new \stdClass(), new Regex(array('pattern' => '/^[0-9]+$/')));
+    }
+
+    /**
+     * @dataProvider getValidValues
+     */
+    public function testValidValues($value)
+    {
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $constraint = new Regex(array('pattern' => '/^[0-9]+$/'));
+        $this->validator->validate($value, $constraint);
+    }
+
+    public function getValidValues()
+    {
+        return array(
+            array(0),
+            array('0'),
+            array('090909'),
+            array(90909),
+        );
+    }
+
+    /**
+     * @dataProvider getInvalidValues
+     */
+    public function testInvalidValues($value)
+    {
+        $constraint = new Regex(array(
+            'pattern' => '/^[0-9]+$/',
+            'message' => 'myMessage'
+        ));
+
+        $this->context->expects($this->once())
+            ->method('addViolation')
+            ->with('myMessage', array(
+                '{{ value }}' => $value,
+            ));
+
+        $this->validator->validate($value, $constraint);
+    }
+
+    public function getInvalidValues()
+    {
+        return array(
+            array('abcd'),
+            array('090foo'),
+        );
+    }
+
+    public function testConstraintGetDefaultOption()
+    {
+        $constraint = new Regex(array(
+            'pattern' => '/^[0-9]+$/',
+        ));
+
+        $this->assertEquals('pattern', $constraint->getDefaultOption());
+    }
+
+    public function testHtmlPatternEscaping()
+    {
+        $constraint = new Regex(array(
+            'pattern' => '/^[0-9]+\/$/',
+        ));
+
+        $this->assertEquals('[0-9]+/', $constraint->getHtmlPattern());
+
+        $constraint = new Regex(array(
+            'pattern' => '#^[0-9]+\#$#',
+        ));
+
+        $this->assertEquals('[0-9]+#', $constraint->getHtmlPattern());
+    }
+
+    public function testHtmlPattern()
+    {
+        // Specified htmlPattern
+        $constraint = new Regex(array(
+            'pattern' => '/^[a-z]+$/i',
+            'htmlPattern' => '[a-zA-Z]+',
+        ));
+        $this->assertEquals('[a-zA-Z]+', $constraint->getHtmlPattern());
+
+        // Disabled htmlPattern
+        $constraint = new Regex(array(
+            'pattern' => '/^[a-z]+$/i',
+            'htmlPattern' => false,
+        ));
+        $this->assertNull($constraint->getHtmlPattern());
+
+        // Cannot be converted
+        $constraint = new Regex(array(
+            'pattern' => '/^[a-z]+$/i',
+        ));
+        $this->assertNull($constraint->getHtmlPattern());
+
+        // Automatically converted
+        $constraint = new Regex(array(
+            'pattern' => '/^[a-z]+$/',
+        ));
+        $this->assertEquals('[a-z]+', $constraint->getHtmlPattern());
+
+        // Automatically converted, adds .*
+        $constraint = new Regex(array(
+            'pattern' => '/[a-z]+/',
+        ));
+        $this->assertEquals('.*[a-z]+.*', $constraint->getHtmlPattern());
+        
+        // Dropped because of match=false
+        $constraint = new Regex(array(
+            'pattern' => '/[a-z]+/',
+            'match' => false
+        ));
+        $this->assertNull($constraint->getHtmlPattern());
+    }
+
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/TimeValidatorTest.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/TimeValidatorTest.php
new file mode 100644
index 0000000..285ab25
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/TimeValidatorTest.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\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Constraints\Time;
+use Symfony\Component\Validator\Constraints\TimeValidator;
+
+class TimeValidatorTest extends \PHPUnit_Framework_TestCase
+{
+    protected $context;
+    protected $validator;
+
+    protected function setUp()
+    {
+        $this->context = $this->getMock('Symfony\Component\Validator\ExecutionContext', array(), array(), '', false);
+        $this->validator = new TimeValidator();
+        $this->validator->initialize($this->context);
+    }
+
+    protected function tearDown()
+    {
+        $this->context = null;
+        $this->validator = null;
+    }
+
+    public function testNullIsValid()
+    {
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $this->validator->validate(null, new Time());
+    }
+
+    public function testEmptyStringIsValid()
+    {
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $this->validator->validate('', new Time());
+    }
+
+    public function testDateTimeClassIsValid()
+    {
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $this->validator->validate(new \DateTime(), new Time());
+    }
+
+    /**
+     * @expectedException Symfony\Component\Validator\Exception\UnexpectedTypeException
+     */
+    public function testExpectsStringCompatibleType()
+    {
+        $this->validator->validate(new \stdClass(), new Time());
+    }
+
+    /**
+     * @dataProvider getValidTimes
+     */
+    public function testValidTimes($time)
+    {
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $this->validator->validate($time, new Time());
+    }
+
+    public function getValidTimes()
+    {
+        return array(
+            array('01:02:03'),
+            array('00:00:00'),
+            array('23:59:59'),
+        );
+    }
+
+    /**
+     * @dataProvider getInvalidTimes
+     */
+    public function testInvalidTimes($time)
+    {
+        $constraint = new Time(array(
+            'message' => 'myMessage'
+        ));
+
+        $this->context->expects($this->once())
+            ->method('addViolation')
+            ->with('myMessage', array(
+                '{{ value }}' => $time,
+            ));
+
+        $this->validator->validate($time, $constraint);
+    }
+
+    public function getInvalidTimes()
+    {
+        return array(
+            array('foobar'),
+            array('foobar 12:34:56'),
+            array('12:34:56 foobar'),
+            array('00:00'),
+            array('24:00:00'),
+            array('00:60:00'),
+            array('00:00:60'),
+        );
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/TrueValidatorTest.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/TrueValidatorTest.php
new file mode 100644
index 0000000..2590179
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/TrueValidatorTest.php
@@ -0,0 +1,64 @@
+<?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\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Constraints\True;
+use Symfony\Component\Validator\Constraints\TrueValidator;
+
+class TrueValidatorTest extends \PHPUnit_Framework_TestCase
+{
+    protected $context;
+    protected $validator;
+
+    protected function setUp()
+    {
+        $this->context = $this->getMock('Symfony\Component\Validator\ExecutionContext', array(), array(), '', false);
+        $this->validator = new TrueValidator();
+        $this->validator->initialize($this->context);
+    }
+
+    protected function tearDown()
+    {
+        $this->context = null;
+        $this->validator = null;
+    }
+
+    public function testNullIsValid()
+    {
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $this->validator->validate(null, new True());
+    }
+
+    public function testTrueIsValid()
+    {
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $this->validator->validate(true, new True());
+    }
+
+    public function testFalseIsInvalid()
+    {
+        $constraint = new True(array(
+            'message' => 'myMessage'
+        ));
+
+        $this->context->expects($this->once())
+            ->method('addViolation')
+            ->with('myMessage', array(
+            ));
+
+        $this->validator->validate(false, $constraint);
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/TypeValidatorTest.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/TypeValidatorTest.php
new file mode 100644
index 0000000..e5e6d0b
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/TypeValidatorTest.php
@@ -0,0 +1,183 @@
+<?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\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Constraints\Type;
+use Symfony\Component\Validator\Constraints\TypeValidator;
+
+class TypeValidatorTest extends \PHPUnit_Framework_TestCase
+{
+    protected static $file;
+
+    protected $context;
+    protected $validator;
+
+    protected function setUp()
+    {
+        $this->context = $this->getMock('Symfony\Component\Validator\ExecutionContext', array(), array(), '', false);
+        $this->validator = new TypeValidator();
+        $this->validator->initialize($this->context);
+    }
+
+    protected function tearDown()
+    {
+        $this->context = null;
+        $this->validator = null;
+    }
+
+    public function testNullIsValid()
+    {
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $this->validator->validate(null, new Type(array('type' => 'integer')));
+    }
+
+    public function testEmptyIsValidIfString()
+    {
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $this->validator->validate('', new Type(array('type' => 'string')));
+    }
+
+    public function testEmptyIsInvalidIfNoString()
+    {
+        $this->context->expects($this->once())
+            ->method('addViolation');
+
+        $this->validator->validate('', new Type(array('type' => 'integer')));
+    }
+
+    /**
+     * @dataProvider getValidValues
+     */
+    public function testValidValues($value, $type)
+    {
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $constraint = new Type(array('type' => $type));
+
+        $this->validator->validate($value, $constraint);
+    }
+
+    public function getValidValues()
+    {
+        $object = new \stdClass();
+        $file = $this->createFile();
+
+        return array(
+            array(true, 'Boolean'),
+            array(false, 'Boolean'),
+            array(true, 'boolean'),
+            array(false, 'boolean'),
+            array(true, 'bool'),
+            array(false, 'bool'),
+            array(0, 'numeric'),
+            array('0', 'numeric'),
+            array(1.5, 'numeric'),
+            array('1.5', 'numeric'),
+            array(0, 'integer'),
+            array(1.5, 'float'),
+            array('12345', 'string'),
+            array(array(), 'array'),
+            array($object, 'object'),
+            array($object, 'stdClass'),
+            array($file, 'resource'),
+            array('12345', 'digit'),
+            array('12a34', 'alnum'),
+            array('abcde', 'alpha'),
+            array("\n\r\t", 'cntrl'),
+            array('arf12', 'graph'),
+            array('abcde', 'lower'),
+            array('ABCDE', 'upper'),
+            array('arf12', 'print'),
+            array('*&$()', 'punct'),
+            array("\n\r\t", 'space'),
+            array('AB10BC99', 'xdigit'),
+        );
+    }
+
+    /**
+     * @dataProvider getInvalidValues
+     */
+    public function testInvalidValues($value, $type, $valueAsString)
+    {
+        $constraint = new Type(array(
+            'type' => $type,
+            'message' => 'myMessage'
+        ));
+
+        $this->context->expects($this->once())
+            ->method('addViolation')
+            ->with('myMessage', array(
+                '{{ value }}' => $valueAsString,
+                '{{ type }}' => $type,
+            ));
+
+        $this->validator->validate($value, $constraint);
+    }
+
+    public function getInvalidValues()
+    {
+        $object = new \stdClass();
+        $file = $this->createFile();
+
+        return array(
+            array('foobar', 'numeric', 'foobar'),
+            array('foobar', 'boolean', 'foobar'),
+            array('0', 'integer', '0'),
+            array('1.5', 'float', '1.5'),
+            array(12345, 'string', '12345'),
+            array($object, 'boolean', 'stdClass'),
+            array($object, 'numeric', 'stdClass'),
+            array($object, 'integer', 'stdClass'),
+            array($object, 'float', 'stdClass'),
+            array($object, 'string', 'stdClass'),
+            array($object, 'resource', 'stdClass'),
+            array($file, 'boolean', (string) $file),
+            array($file, 'numeric', (string) $file),
+            array($file, 'integer', (string) $file),
+            array($file, 'float', (string) $file),
+            array($file, 'string', (string) $file),
+            array($file, 'object', (string) $file),
+            array('12a34', 'digit', '12a34'),
+            array('1a#23', 'alnum', '1a#23'),
+            array('abcd1', 'alpha', 'abcd1'),
+            array("\nabc", 'cntrl', "\nabc"),
+            array("abc\n", 'graph', "abc\n"),
+            array('abCDE', 'lower', 'abCDE'),
+            array('ABcde', 'upper', 'ABcde'),
+            array("\nabc", 'print', "\nabc"),
+            array('abc&$!', 'punct', 'abc&$!'),
+            array("\nabc", 'space', "\nabc"),
+            array('AR1012', 'xdigit', 'AR1012'),
+        );
+    }
+
+    protected function createFile()
+    {
+        if (!self::$file) {
+            self::$file = fopen(__FILE__, 'r');
+        }
+
+        return self::$file;
+    }
+
+    public static function tearDownAfterClass()
+    {
+        if (self::$file) {
+            fclose(self::$file);
+        }
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/UrlValidatorTest.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/UrlValidatorTest.php
new file mode 100644
index 0000000..bace806
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/UrlValidatorTest.php
@@ -0,0 +1,168 @@
+<?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\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Constraints\Url;
+use Symfony\Component\Validator\Constraints\UrlValidator;
+
+class UrlValidatorTest extends \PHPUnit_Framework_TestCase
+{
+    protected $context;
+    protected $validator;
+
+    protected function setUp()
+    {
+        $this->context = $this->getMock('Symfony\Component\Validator\ExecutionContext', array(), array(), '', false);
+        $this->validator = new UrlValidator();
+        $this->validator->initialize($this->context);
+    }
+
+    protected function tearDown()
+    {
+        $this->context = null;
+        $this->validator = null;
+    }
+
+    public function testNullIsValid()
+    {
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $this->validator->validate(null, new Url());
+    }
+
+    public function testEmptyStringIsValid()
+    {
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $this->validator->validate('', new Url());
+    }
+
+    /**
+     * @expectedException Symfony\Component\Validator\Exception\UnexpectedTypeException
+     */
+    public function testExpectsStringCompatibleType()
+    {
+        $this->validator->validate(new \stdClass(), new Url());
+    }
+
+    /**
+     * @dataProvider getValidUrls
+     */
+    public function testValidUrls($url)
+    {
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $this->validator->validate($url, new Url());
+    }
+
+    public function getValidUrls()
+    {
+        return array(
+            array('http://a.pl'),
+            array('http://www.google.com'),
+            array('http://www.google.museum'),
+            array('https://google.com/'),
+            array('https://google.com:80/'),
+            array('http://www.example.coop/'),
+            array('http://www.test-example.com/'),
+            array('http://www.symfony.com/'),
+            array('http://symfony.fake/blog/'),
+            array('http://symfony.com/?'),
+            array('http://symfony.com/search?type=&q=url+validator'),
+            array('http://symfony.com/#'),
+            array('http://symfony.com/#?'),
+            array('http://www.symfony.com/doc/current/book/validation.html#supported-constraints'),
+            array('http://very.long.domain.name.com/'),
+            array('http://127.0.0.1/'),
+            array('http://127.0.0.1:80/'),
+            array('http://[::1]/'),
+            array('http://[::1]:80/'),
+            array('http://[1:2:3::4:5:6:7]/'),
+            array('http://sÃ£opaulo.com/'),
+            array('http://sÃ£opaulo.com.br/'),
+            array('http://Ð¿Ñ€Ð¸Ð¼ÐµÑ€.Ð¸ÑÐ¿Ñ‹Ñ‚Ð°Ð½Ð¸Ðµ/'),
+            array('http://Ù…Ø«Ø§Ù„.Ø¥Ø®ØªØ¨Ø§Ø±/'),
+            array('http://ä¾‹å­.æµ‹è¯•/'),
+            array('http://ä¾‹å­.æ¸¬è©¦/'),
+            array('http://ä¾‹ãˆ.ãƒ†ã‚¹ãƒˆ/'),
+            array('http://Ù…Ø«Ø§Ù„.Ø¢Ø²Ù…Ø§ÛŒØ´ÛŒ/'),
+            array('http://ì‹¤ë¡€.í…ŒìŠ¤íŠ¸/'),
+            array('http://Ø§Ù„Ø¹Ø±Ø¨ÙŠØ©.idn.icann.org/'),
+            array('http://â˜Ž.com/'),
+        );
+    }
+
+    /**
+     * @dataProvider getInvalidUrls
+     */
+    public function testInvalidUrls($url)
+    {
+        $constraint = new Url(array(
+            'message' => 'myMessage'
+        ));
+
+        $this->context->expects($this->once())
+            ->method('addViolation')
+            ->with('myMessage', array(
+                '{{ value }}' => $url,
+            ));
+
+        $this->validator->validate($url, $constraint);
+    }
+
+    public function getInvalidUrls()
+    {
+        return array(
+            array('google.com'),
+            array('://google.com'),
+            array('http ://google.com'),
+            array('http:/google.com'),
+            array('http://goog_le.com'),
+            array('http://google.com::aa'),
+            array('http://google.com:aa'),
+            array('http://symfony.com?'),
+            array('http://symfony.com#'),
+            array('ftp://google.fr'),
+            array('faked://google.fr'),
+            array('http://127.0.0.1:aa/'),
+            array('ftp://[::1]/'),
+            array('http://[::1'),
+        );
+    }
+
+    /**
+     * @dataProvider getValidCustomUrls
+     */
+    public function testCustomProtocolIsValid($url)
+    {
+        $this->context->expects($this->never())
+            ->method('addViolation');
+
+        $constraint = new Url(array(
+            'protocols' => array('ftp', 'file', 'git')
+        ));
+
+        $this->validator->validate($url, $constraint);
+    }
+
+    public function getValidCustomUrls()
+    {
+        return array(
+            array('ftp://google.com'),
+            array('file://127.0.0.1'),
+            array('git://[::1]/'),
+        );
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/ValidTest.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/ValidTest.php
new file mode 100644
index 0000000..0957700
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Constraints/ValidTest.php
@@ -0,0 +1,28 @@
+<?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\Validator\Tests\Constraints;
+
+use Symfony\Component\Validator\Constraints\Valid;
+
+/**
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+class ValidTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @expectedException Symfony\Component\Validator\Exception\ConstraintDefinitionException
+     */
+    public function testRejectGroupsOption()
+    {
+        new Valid(array('groups' => 'foo'));
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/ExecutionContextTest.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/ExecutionContextTest.php
new file mode 100644
index 0000000..40b5996
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/ExecutionContextTest.php
@@ -0,0 +1,305 @@
+<?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\Validator\Tests;
+
+use Symfony\Component\Validator\Mapping\PropertyMetadata;
+use Symfony\Component\Validator\Mapping\ClassMetadata;
+use Symfony\Component\Validator\ConstraintViolation;
+use Symfony\Component\Validator\ConstraintViolationList;
+use Symfony\Component\Validator\ExecutionContext;
+
+class ExecutionContextTest extends \PHPUnit_Framework_TestCase
+{
+    private $visitor;
+    private $violations;
+    private $metadata;
+    private $metadataFactory;
+    private $globalContext;
+
+    /**
+     * @var ExecutionContext
+     */
+    private $context;
+
+    protected function setUp()
+    {
+        $this->visitor = $this->getMockBuilder('Symfony\Component\Validator\ValidationVisitor')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->violations = new ConstraintViolationList();
+        $this->metadata = $this->getMock('Symfony\Component\Validator\MetadataInterface');
+        $this->metadataFactory = $this->getMock('Symfony\Component\Validator\MetadataFactoryInterface');
+        $this->globalContext = $this->getMock('Symfony\Component\Validator\GlobalExecutionContextInterface');
+        $this->globalContext->expects($this->any())
+            ->method('getRoot')
+            ->will($this->returnValue('Root'));
+        $this->globalContext->expects($this->any())
+            ->method('getViolations')
+            ->will($this->returnValue($this->violations));
+        $this->globalContext->expects($this->any())
+            ->method('getVisitor')
+            ->will($this->returnValue($this->visitor));
+        $this->globalContext->expects($this->any())
+            ->method('getMetadataFactory')
+            ->will($this->returnValue($this->metadataFactory));
+        $this->context = new ExecutionContext($this->globalContext, $this->metadata, 'currentValue', 'Group', 'foo.bar');
+    }
+
+    protected function tearDown()
+    {
+        $this->globalContext = null;
+        $this->context = null;
+    }
+
+    public function testInit()
+    {
+        $this->assertCount(0, $this->context->getViolations());
+        $this->assertSame('Root', $this->context->getRoot());
+        $this->assertSame('foo.bar', $this->context->getPropertyPath());
+        $this->assertSame('Group', $this->context->getGroup());
+
+        $this->visitor->expects($this->once())
+            ->method('getGraphWalker')
+            ->will($this->returnValue('GRAPHWALKER'));
+
+        // BC
+        $this->assertNull($this->context->getCurrentClass());
+        $this->assertNull($this->context->getCurrentProperty());
+        $this->assertSame('GRAPHWALKER', $this->context->getGraphWalker());
+        $this->assertSame($this->metadataFactory, $this->context->getMetadataFactory());
+    }
+
+    public function testInitWithClassMetadata()
+    {
+        // BC
+        $this->metadata = new ClassMetadata(__NAMESPACE__ . '\ExecutionContextTest_TestClass');
+        $this->context = new ExecutionContext($this->globalContext, $this->metadata, 'currentValue', 'Group', 'foo.bar');
+
+        $this->assertSame(__NAMESPACE__ . '\ExecutionContextTest_TestClass', $this->context->getCurrentClass());
+        $this->assertNull($this->context->getCurrentProperty());
+    }
+
+    public function testInitWithPropertyMetadata()
+    {
+        // BC
+        $this->metadata = new PropertyMetadata(__NAMESPACE__ . '\ExecutionContextTest_TestClass', 'myProperty');
+        $this->context = new ExecutionContext($this->globalContext, $this->metadata, 'currentValue', 'Group', 'foo.bar');
+
+        $this->assertSame(__NAMESPACE__ . '\ExecutionContextTest_TestClass', $this->context->getCurrentClass());
+        $this->assertSame('myProperty', $this->context->getCurrentProperty());
+    }
+
+    public function testClone()
+    {
+        $clone = clone $this->context;
+
+        // Cloning the context keeps the reference to the original violation
+        // list. This way we can efficiently duplicate context instances during
+        // the validation run and only modify the properties that need to be
+        // changed.
+        $this->assertSame($this->context->getViolations(), $clone->getViolations());
+    }
+
+    public function testAddViolation()
+    {
+        $this->context->addViolation('Error', array('foo' => 'bar'), 'invalid');
+
+        $this->assertEquals(new ConstraintViolationList(array(
+            new ConstraintViolation(
+                'Error',
+                array('foo' => 'bar'),
+                'Root',
+                'foo.bar',
+                'invalid'
+            ),
+        )), $this->context->getViolations());
+    }
+
+    public function testAddViolationUsesPreconfiguredValueIfNotPassed()
+    {
+        $this->context->addViolation('Error');
+
+        $this->assertEquals(new ConstraintViolationList(array(
+            new ConstraintViolation(
+                'Error',
+                array(),
+                'Root',
+                'foo.bar',
+                'currentValue'
+            ),
+        )), $this->context->getViolations());
+    }
+
+    public function testAddViolationUsesPassedNullValue()
+    {
+        // passed null value should override preconfigured value "invalid"
+        $this->context->addViolation('Error', array('foo' => 'bar'), null);
+        $this->context->addViolation('Error', array('foo' => 'bar'), null, 1);
+
+        $this->assertEquals(new ConstraintViolationList(array(
+            new ConstraintViolation(
+                'Error',
+                array('foo' => 'bar'),
+                'Root',
+                'foo.bar',
+                null
+            ),
+            new ConstraintViolation(
+                'Error',
+                array('foo' => 'bar'),
+                'Root',
+                'foo.bar',
+                null,
+                1
+            ),
+        )), $this->context->getViolations());
+    }
+
+    public function testAddViolationAtPath()
+    {
+        // override preconfigured property path
+        $this->context->addViolationAtPath('bar.baz', 'Error', array('foo' => 'bar'), 'invalid');
+
+        $this->assertEquals(new ConstraintViolationList(array(
+            new ConstraintViolation(
+                'Error',
+                array('foo' => 'bar'),
+                'Root',
+                'bar.baz',
+                'invalid'
+            ),
+        )), $this->context->getViolations());
+    }
+
+    public function testAddViolationAtPathUsesPreconfiguredValueIfNotPassed()
+    {
+        $this->context->addViolationAtPath('bar.baz', 'Error');
+
+        $this->assertEquals(new ConstraintViolationList(array(
+            new ConstraintViolation(
+                'Error',
+                array(),
+                'Root',
+                'bar.baz',
+                'currentValue'
+            ),
+        )), $this->context->getViolations());
+    }
+
+    public function testAddViolationAtPathUsesPassedNullValue()
+    {
+        // passed null value should override preconfigured value "invalid"
+        $this->context->addViolationAtPath('bar.baz', 'Error', array('foo' => 'bar'), null);
+        $this->context->addViolationAtPath('bar.baz', 'Error', array('foo' => 'bar'), null, 1);
+
+        $this->assertEquals(new ConstraintViolationList(array(
+            new ConstraintViolation(
+                'Error',
+                array('foo' => 'bar'),
+                'Root',
+                'bar.baz',
+                null
+            ),
+            new ConstraintViolation(
+                'Error',
+                array('foo' => 'bar'),
+                'Root',
+                'bar.baz',
+                null,
+                1
+            ),
+        )), $this->context->getViolations());
+    }
+
+    public function testAddViolationAt()
+    {
+        // override preconfigured property path
+        $this->context->addViolationAt('bam.baz', 'Error', array('foo' => 'bar'), 'invalid');
+
+        $this->assertEquals(new ConstraintViolationList(array(
+            new ConstraintViolation(
+                'Error',
+                array('foo' => 'bar'),
+                'Root',
+                'foo.bar.bam.baz',
+                'invalid'
+            ),
+        )), $this->context->getViolations());
+    }
+
+    public function testAddViolationAtUsesPreconfiguredValueIfNotPassed()
+    {
+        $this->context->addViolationAt('bam.baz', 'Error');
+
+        $this->assertEquals(new ConstraintViolationList(array(
+            new ConstraintViolation(
+                'Error',
+                array(),
+                'Root',
+                'foo.bar.bam.baz',
+                'currentValue'
+            ),
+        )), $this->context->getViolations());
+    }
+
+    public function testAddViolationAtUsesPassedNullValue()
+    {
+        // passed null value should override preconfigured value "invalid"
+        $this->context->addViolationAt('bam.baz', 'Error', array('foo' => 'bar'), null);
+        $this->context->addViolationAt('bam.baz', 'Error', array('foo' => 'bar'), null, 1);
+
+        $this->assertEquals(new ConstraintViolationList(array(
+            new ConstraintViolation(
+                'Error',
+                array('foo' => 'bar'),
+                'Root',
+                'foo.bar.bam.baz',
+                null
+            ),
+            new ConstraintViolation(
+                'Error',
+                array('foo' => 'bar'),
+                'Root',
+                'foo.bar.bam.baz',
+                null,
+                1
+            ),
+        )), $this->context->getViolations());
+    }
+
+    public function testGetPropertyPath()
+    {
+        $this->assertEquals('foo.bar', $this->context->getPropertyPath());
+    }
+
+    public function testGetPropertyPathWithIndexPath()
+    {
+        $this->assertEquals('foo.bar[bam]', $this->context->getPropertyPath('[bam]'));
+    }
+
+    public function testGetPropertyPathWithEmptyPath()
+    {
+        $this->assertEquals('foo.bar', $this->context->getPropertyPath(''));
+    }
+
+    public function testGetPropertyPathWithEmptyCurrentPropertyPath()
+    {
+        $this->context = new ExecutionContext($this->globalContext, $this->metadata, 'currentValue', 'Group', '');
+
+        $this->assertEquals('bam.baz', $this->context->getPropertyPath('bam.baz'));
+    }
+}
+
+class ExecutionContextTest_TestClass
+{
+    public $myProperty;
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/ClassConstraint.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/ClassConstraint.php
new file mode 100644
index 0000000..a4dc777
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/ClassConstraint.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\Validator\Tests\Fixtures;
+
+use Symfony\Component\Validator\Constraint;
+
+class ClassConstraint extends Constraint
+{
+    public function getTargets()
+    {
+        return self::CLASS_CONSTRAINT;
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/ConstraintA.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/ConstraintA.php
new file mode 100644
index 0000000..8a196dc
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/ConstraintA.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\Validator\Tests\Fixtures;
+
+use Symfony\Component\Validator\Constraint;
+
+/** @Annotation */
+class ConstraintA extends Constraint
+{
+    public $property1;
+    public $property2;
+
+    public function getDefaultOption()
+    {
+        return 'property2';
+    }
+
+    public function getTargets()
+    {
+        return array(self::PROPERTY_CONSTRAINT, self::CLASS_CONSTRAINT);
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/ConstraintAValidator.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/ConstraintAValidator.php
new file mode 100644
index 0000000..787c78c
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/ConstraintAValidator.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\Validator\Tests\Fixtures;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\ConstraintValidator;
+use Symfony\Component\Validator\ExecutionContextInterface;
+
+class ConstraintAValidator extends ConstraintValidator
+{
+    public static $passedContext;
+
+    public function initialize(ExecutionContextInterface $context)
+    {
+        parent::initialize($context);
+
+        self::$passedContext = $context;
+    }
+
+    public function validate($value, Constraint $constraint)
+    {
+        if ('VALID' != $value) {
+            $this->context->addViolation('message', array('param' => 'value'));
+
+            return;
+        }
+
+        return;
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/ConstraintB.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/ConstraintB.php
new file mode 100644
index 0000000..6258923
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/ConstraintB.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\Validator\Tests\Fixtures;
+
+use Symfony\Component\Validator\Constraint;
+
+/** @Annotation */
+class ConstraintB extends Constraint
+{
+    public function getTargets()
+    {
+        return array(self::PROPERTY_CONSTRAINT, self::CLASS_CONSTRAINT);
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/ConstraintC.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/ConstraintC.php
new file mode 100644
index 0000000..b0418b8
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/ConstraintC.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\Validator\Tests\Fixtures;
+
+use Symfony\Component\Validator\Constraint;
+
+/** @Annotation */
+class ConstraintC extends Constraint
+{
+    public $option1;
+
+    public function getRequiredOptions()
+    {
+        return array('option1');
+    }
+
+    public function getTargets()
+    {
+        return array(self::PROPERTY_CONSTRAINT, self::CLASS_CONSTRAINT);
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/Entity.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/Entity.php
new file mode 100644
index 0000000..15f73c5
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/Entity.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\Validator\Tests\Fixtures;
+
+use Symfony\Component\Validator\Constraints as Assert;
+
+/**
+ * @Symfony\Component\Validator\Tests\Fixtures\ConstraintA
+ * @Assert\GroupSequence({"Foo", "Entity"})
+ */
+class Entity extends EntityParent implements EntityInterface
+{
+    /**
+     * @Assert\NotNull
+     * @Assert\Min(3)
+     * @Assert\All({@Assert\NotNull, @Assert\Min(3)}),
+     * @Assert\All(constraints={@Assert\NotNull, @Assert\Min(3)})
+     * @Assert\Collection(fields={
+     *   "foo" = {@Assert\NotNull, @Assert\Min(3)},
+     *   "bar" = @Assert\Min(5)
+     * })
+     * @Assert\Choice(choices={"A", "B"}, message="Must be one of %choices%")
+     */
+    protected $firstName;
+    protected $lastName;
+    public $reference;
+
+    private $internal;
+
+    public function __construct($internal = null)
+    {
+        $this->internal = $internal;
+    }
+
+    public function getInternal()
+    {
+        return $this->internal . ' from getter';
+    }
+
+    /**
+     * @Assert\NotNull
+     */
+    public function getLastName()
+    {
+        return $this->lastName;
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/EntityInterface.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/EntityInterface.php
new file mode 100644
index 0000000..2901f26
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/EntityInterface.php
@@ -0,0 +1,16 @@
+<?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\Validator\Tests\Fixtures;
+
+interface EntityInterface
+{
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/EntityParent.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/EntityParent.php
new file mode 100644
index 0000000..d12d943
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/EntityParent.php
@@ -0,0 +1,25 @@
+<?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\Validator\Tests\Fixtures;
+
+use Symfony\Component\Validator\Constraints\NotNull;
+
+class EntityParent
+{
+    protected $firstName;
+    private $internal;
+
+    /**
+     * @NotNull
+     */
+    protected $other;
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/FailingConstraint.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/FailingConstraint.php
new file mode 100644
index 0000000..03019fc
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/FailingConstraint.php
@@ -0,0 +1,24 @@
+<?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\Validator\Tests\Fixtures;
+
+use Symfony\Component\Validator\Constraint;
+
+class FailingConstraint extends Constraint
+{
+    public $message = 'Failed';
+
+    public function getTargets()
+    {
+        return array(self::PROPERTY_CONSTRAINT, self::CLASS_CONSTRAINT);
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/FailingConstraintValidator.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/FailingConstraintValidator.php
new file mode 100644
index 0000000..854e80f
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/FailingConstraintValidator.php
@@ -0,0 +1,25 @@
+<?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\Validator\Tests\Fixtures;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\ConstraintValidator;
+
+class FailingConstraintValidator extends ConstraintValidator
+{
+    public function validate($value, Constraint $constraint)
+    {
+        $this->context->addViolation($constraint->message, array());
+
+        return;
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/FakeMetadataFactory.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/FakeMetadataFactory.php
new file mode 100644
index 0000000..1276ca5
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/FakeMetadataFactory.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\Validator\Tests\Fixtures;
+
+use Symfony\Component\Validator\MetadataFactoryInterface;
+use Symfony\Component\Validator\Exception\NoSuchMetadataException;
+use Symfony\Component\Validator\Mapping\ClassMetadata;
+
+class FakeMetadataFactory implements MetadataFactoryInterface
+{
+    protected $metadatas = array();
+
+    public function getMetadataFor($class)
+    {
+        if (is_object($class)) {
+            $class = get_class($class);
+        }
+
+        if (!is_string($class)) {
+            throw new NoSuchMetadataException('No metadata for type ' . gettype($class));
+        }
+
+        if (!isset($this->metadatas[$class])) {
+            throw new NoSuchMetadataException('No metadata for "' . $class . '"');
+        }
+
+        return $this->metadatas[$class];
+    }
+
+    public function hasMetadataFor($class)
+    {
+        if (is_object($class)) {
+            $class = get_class($class);
+        }
+
+        if (!is_string($class)) {
+            return false;
+        }
+
+        return isset($this->metadatas[$class]);
+    }
+
+    public function addMetadata(ClassMetadata $metadata)
+    {
+        $this->metadatas[$metadata->getClassName()] = $metadata;
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/FilesLoader.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/FilesLoader.php
new file mode 100644
index 0000000..59d8ee8
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/FilesLoader.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\Validator\Tests\Fixtures;
+
+use Symfony\Component\Validator\Mapping\Loader\FilesLoader as BaseFilesLoader;
+use Symfony\Component\Validator\Mapping\Loader\LoaderInterface;
+
+abstract class FilesLoader extends BaseFilesLoader
+{
+    protected $timesCalled = 0;
+    protected $loader;
+
+    public function __construct(array $paths, LoaderInterface $loader)
+    {
+        $this->loader = $loader;
+        parent::__construct($paths);
+    }
+
+    protected function getFileLoaderInstance($file)
+    {
+        $this->timesCalled++;
+
+        return $this->loader;
+    }
+
+    public function getTimesCalled()
+    {
+        return $this->timesCalled;
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/GroupSequenceProviderEntity.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/GroupSequenceProviderEntity.php
new file mode 100644
index 0000000..ef37111
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/GroupSequenceProviderEntity.php
@@ -0,0 +1,36 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Fixtures;
+
+use Symfony\Component\Validator\Constraints as Assert;
+use Symfony\Component\Validator\GroupSequenceProviderInterface;
+
+/**
+ * @Assert\GroupSequenceProvider
+ */
+class GroupSequenceProviderEntity implements GroupSequenceProviderInterface
+{
+    public $firstName;
+    public $lastName;
+
+    protected $groups = array();
+
+    public function setGroups($groups)
+    {
+        $this->groups = $groups;
+    }
+
+    public function getGroupSequence()
+    {
+        return $this->groups;
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/InvalidConstraint.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/InvalidConstraint.php
new file mode 100644
index 0000000..d8df639
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/InvalidConstraint.php
@@ -0,0 +1,16 @@
+<?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\Validator\Tests\Fixtures;
+
+use Symfony\Component\Validator\Constraint;
+
+class InvalidConstraint extends Constraint {}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/InvalidConstraintValidator.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/InvalidConstraintValidator.php
new file mode 100644
index 0000000..f6ebb3b
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/InvalidConstraintValidator.php
@@ -0,0 +1,14 @@
+<?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\Validator\Tests\Fixtures;
+
+class InvalidConstraintValidator {}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/PropertyConstraint.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/PropertyConstraint.php
new file mode 100644
index 0000000..fadb535
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/PropertyConstraint.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\Validator\Tests\Fixtures;
+
+use Symfony\Component\Validator\Constraint;
+
+class PropertyConstraint extends Constraint
+{
+    public function getTargets()
+    {
+        return self::PROPERTY_CONSTRAINT;
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/Reference.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/Reference.php
new file mode 100644
index 0000000..f8ea173
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Fixtures/Reference.php
@@ -0,0 +1,16 @@
+<?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\Validator\Tests\Fixtures;
+
+class Reference
+{
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/GraphWalkerTest.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/GraphWalkerTest.php
new file mode 100644
index 0000000..83a67db
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/GraphWalkerTest.php
@@ -0,0 +1,570 @@
+<?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\Validator\Tests;
+
+use Symfony\Component\Validator\Tests\Fixtures\ConstraintAValidator;
+use Symfony\Component\Validator\ValidationVisitor;
+use Symfony\Component\Validator\Tests\Fixtures\Entity;
+use Symfony\Component\Validator\Tests\Fixtures\Reference;
+use Symfony\Component\Validator\Tests\Fixtures\FakeMetadataFactory;
+use Symfony\Component\Validator\Tests\Fixtures\ConstraintA;
+use Symfony\Component\Validator\Tests\Fixtures\FailingConstraint;
+use Symfony\Component\Validator\GraphWalker;
+use Symfony\Component\Validator\ConstraintViolation;
+use Symfony\Component\Validator\ConstraintViolationList;
+use Symfony\Component\Validator\ConstraintValidatorFactory;
+use Symfony\Component\Validator\Mapping\ClassMetadata;
+use Symfony\Component\Validator\Constraints\Valid;
+use Symfony\Component\Validator\Constraints\Collection;
+
+class GraphWalkerTest extends \PHPUnit_Framework_TestCase
+{
+    const CLASSNAME = 'Symfony\Component\Validator\Tests\Fixtures\Entity';
+
+    /**
+     * @var ValidationVisitor
+     */
+    private $visitor;
+
+    /**
+     * @var FakeMetadataFactory
+     */
+    protected $metadataFactory;
+
+    /**
+     * @var GraphWalker
+     */
+    protected $walker;
+
+    /**
+     * @var ClassMetadata
+     */
+    protected $metadata;
+
+    protected function setUp()
+    {
+        $this->metadataFactory = new FakeMetadataFactory();
+        $this->visitor = new ValidationVisitor('Root', $this->metadataFactory, new ConstraintValidatorFactory());
+        $this->walker = $this->visitor->getGraphWalker();
+        $this->metadata = new ClassMetadata(self::CLASSNAME);
+        $this->metadataFactory->addMetadata($this->metadata);
+    }
+
+    protected function tearDown()
+    {
+        $this->metadataFactory = null;
+        $this->visitor = null;
+        $this->walker = null;
+        $this->metadata = null;
+    }
+
+    public function testWalkObjectPassesCorrectClassAndProperty()
+    {
+        $this->metadata->addConstraint(new ConstraintA());
+
+        $entity = new Entity();
+        $this->walker->walkObject($this->metadata, $entity, 'Default', '');
+
+        $context = ConstraintAValidator::$passedContext;
+
+        $this->assertEquals('Symfony\Component\Validator\Tests\Fixtures\Entity', $context->getCurrentClass());
+        $this->assertNull($context->getCurrentProperty());
+    }
+
+    public function testWalkObjectValidatesConstraints()
+    {
+        $this->metadata->addConstraint(new ConstraintA());
+
+        $this->walker->walkObject($this->metadata, new Entity(), 'Default', '');
+
+        $this->assertCount(1, $this->walker->getViolations());
+    }
+
+    public function testWalkObjectTwiceValidatesConstraintsOnce()
+    {
+        $this->metadata->addConstraint(new ConstraintA());
+
+        $entity = new Entity();
+
+        $this->walker->walkObject($this->metadata, $entity, 'Default', '');
+        $this->walker->walkObject($this->metadata, $entity, 'Default', '');
+
+        $this->assertCount(1, $this->walker->getViolations());
+    }
+
+    public function testWalkObjectOnceInVisitorAndOnceInWalkerValidatesConstraintsOnce()
+    {
+        $this->metadata->addConstraint(new ConstraintA());
+
+        $entity = new Entity();
+
+        $this->visitor->validate($entity, 'Default', '');
+        $this->walker->walkObject($this->metadata, $entity, 'Default', '');
+
+        $this->assertCount(1, $this->walker->getViolations());
+    }
+
+    public function testWalkDifferentObjectsValidatesTwice()
+    {
+        $this->metadata->addConstraint(new ConstraintA());
+
+        $this->walker->walkObject($this->metadata, new Entity(), 'Default', '');
+        $this->walker->walkObject($this->metadata, new Entity(), 'Default', '');
+
+        $this->assertCount(2, $this->walker->getViolations());
+    }
+
+    public function testWalkObjectTwiceInDifferentGroupsValidatesTwice()
+    {
+        $this->metadata->addConstraint(new ConstraintA());
+        $this->metadata->addConstraint(new ConstraintA(array('groups' => 'Custom')));
+
+        $entity = new Entity();
+
+        $this->walker->walkObject($this->metadata, $entity, 'Default', '');
+        $this->walker->walkObject($this->metadata, $entity, 'Custom', '');
+
+        $this->assertCount(2, $this->walker->getViolations());
+    }
+
+    public function testWalkObjectValidatesPropertyConstraints()
+    {
+        $this->metadata->addPropertyConstraint('firstName', new ConstraintA());
+
+        $this->walker->walkObject($this->metadata, new Entity(), 'Default', '');
+
+        $this->assertCount(1, $this->walker->getViolations());
+    }
+
+    public function testWalkObjectValidatesGetterConstraints()
+    {
+        $this->metadata->addGetterConstraint('lastName', new ConstraintA());
+
+        $this->walker->walkObject($this->metadata, new Entity(), 'Default', '');
+
+        $this->assertCount(1, $this->walker->getViolations());
+    }
+
+    public function testWalkObjectInDefaultGroupTraversesGroupSequence()
+    {
+        $entity = new Entity();
+
+        $this->metadata->addPropertyConstraint('firstName', new FailingConstraint(array(
+            'groups' => 'First',
+        )));
+        $this->metadata->addGetterConstraint('lastName', new FailingConstraint(array(
+            'groups' => 'Default',
+        )));
+        $this->metadata->setGroupSequence(array('First', $this->metadata->getDefaultGroup()));
+
+        $this->walker->walkObject($this->metadata, $entity, 'Default', '');
+
+        // After validation of group "First" failed, no more group was
+        // validated
+        $violations = new ConstraintViolationList();
+        $violations->add(new ConstraintViolation(
+            'Failed',
+            array(),
+            'Root',
+            'firstName',
+            ''
+        ));
+
+        $this->assertEquals($violations, $this->walker->getViolations());
+    }
+
+    public function testWalkObjectInGroupSequencePropagatesDefaultGroup()
+    {
+        $entity = new Entity();
+        $entity->reference = new Reference();
+
+        $this->metadata->addPropertyConstraint('reference', new Valid());
+        $this->metadata->setGroupSequence(array($this->metadata->getDefaultGroup()));
+
+        $referenceMetadata = new ClassMetadata(get_class($entity->reference));
+        $referenceMetadata->addConstraint(new FailingConstraint(array(
+            // this constraint is only evaluated if group "Default" is
+            // propagated to the reference
+            'groups' => 'Default',
+        )));
+        $this->metadataFactory->addMetadata($referenceMetadata);
+
+        $this->walker->walkObject($this->metadata, $entity, 'Default', '');
+
+        // The validation of the reference's FailingConstraint in group
+        // "Default" was launched
+        $violations = new ConstraintViolationList();
+        $violations->add(new ConstraintViolation(
+            'Failed',
+            array(),
+            'Root',
+            'reference',
+            $entity->reference
+        ));
+
+        $this->assertEquals($violations, $this->walker->getViolations());
+    }
+
+    public function testWalkObjectInOtherGroupTraversesNoGroupSequence()
+    {
+        $entity = new Entity();
+
+        $this->metadata->addPropertyConstraint('firstName', new FailingConstraint(array(
+            'groups' => 'First',
+        )));
+        $this->metadata->addGetterConstraint('lastName', new FailingConstraint(array(
+            'groups' => $this->metadata->getDefaultGroup(),
+        )));
+        $this->metadata->setGroupSequence(array('First', $this->metadata->getDefaultGroup()));
+
+        $this->walker->walkObject($this->metadata, $entity, $this->metadata->getDefaultGroup(), '');
+
+        // Only group "Second" was validated
+        $violations = new ConstraintViolationList();
+        $violations->add(new ConstraintViolation(
+            'Failed',
+            array(),
+            'Root',
+            'lastName',
+            ''
+        ));
+
+        $this->assertEquals($violations, $this->walker->getViolations());
+    }
+
+    public function testWalkPropertyPassesCorrectClassAndProperty()
+    {
+        $this->metadata->addPropertyConstraint('firstName', new ConstraintA());
+
+        $this->walker->walkPropertyValue($this->metadata, 'firstName', 'value', 'Default', '');
+
+        $context = ConstraintAValidator::$passedContext;
+
+        $this->assertEquals('Symfony\Component\Validator\Tests\Fixtures\Entity', $context->getCurrentClass());
+        $this->assertEquals('firstName', $context->getCurrentProperty());
+    }
+
+    public function testWalkPropertyValueValidatesConstraints()
+    {
+        $this->metadata->addPropertyConstraint('firstName', new ConstraintA());
+
+        $this->walker->walkPropertyValue($this->metadata, 'firstName', 'value', 'Default', '');
+
+        $this->assertCount(1, $this->walker->getViolations());
+    }
+
+    public function testWalkCascadedPropertyValidatesReferences()
+    {
+        $entity = new Entity();
+        $entityMetadata = new ClassMetadata(get_class($entity));
+        $this->metadataFactory->addMetadata($entityMetadata);
+
+        // add a constraint for the entity that always fails
+        $entityMetadata->addConstraint(new FailingConstraint());
+
+        // validate entity when validating the property "reference"
+        $this->metadata->addPropertyConstraint('reference', new Valid());
+
+        // invoke validation on an object
+        $this->walker->walkPropertyValue(
+            $this->metadata,
+            'reference',
+            $entity,  // object!
+            'Default',
+            'path'
+        );
+
+        $violations = new ConstraintViolationList();
+        $violations->add(new ConstraintViolation(
+            'Failed',
+            array(),
+            'Root',
+            'path',
+            $entity
+        ));
+
+        $this->assertEquals($violations, $this->walker->getViolations());
+    }
+
+    public function testWalkCascadedPropertyValidatesArraysByDefault()
+    {
+        $entity = new Entity();
+        $entityMetadata = new ClassMetadata(get_class($entity));
+        $this->metadataFactory->addMetadata($entityMetadata);
+
+        // add a constraint for the entity that always fails
+        $entityMetadata->addConstraint(new FailingConstraint());
+
+        // validate array when validating the property "reference"
+        $this->metadata->addPropertyConstraint('reference', new Valid());
+
+        $this->walker->walkPropertyValue(
+            $this->metadata,
+            'reference',
+            array('key' => $entity), // array!
+            'Default',
+            'path'
+        );
+
+        $violations = new ConstraintViolationList();
+        $violations->add(new ConstraintViolation(
+            'Failed',
+            array(),
+            'Root',
+            'path[key]',
+            $entity
+        ));
+
+        $this->assertEquals($violations, $this->walker->getViolations());
+    }
+
+    public function testWalkCascadedPropertyValidatesTraversableByDefault()
+    {
+        $entity = new Entity();
+        $entityMetadata = new ClassMetadata(get_class($entity));
+        $this->metadataFactory->addMetadata($entityMetadata);
+        $this->metadataFactory->addMetadata(new ClassMetadata('ArrayIterator'));
+
+        // add a constraint for the entity that always fails
+        $entityMetadata->addConstraint(new FailingConstraint());
+
+        // validate array when validating the property "reference"
+        $this->metadata->addPropertyConstraint('reference', new Valid());
+
+        $this->walker->walkPropertyValue(
+            $this->metadata,
+            'reference',
+            new \ArrayIterator(array('key' => $entity)),
+            'Default',
+            'path'
+        );
+
+        $violations = new ConstraintViolationList();
+        $violations->add(new ConstraintViolation(
+            'Failed',
+            array(),
+            'Root',
+            'path[key]',
+            $entity
+        ));
+
+        $this->assertEquals($violations, $this->walker->getViolations());
+    }
+
+    public function testWalkCascadedPropertyDoesNotValidateTraversableIfDisabled()
+    {
+        $entity = new Entity();
+        $entityMetadata = new ClassMetadata(get_class($entity));
+        $this->metadataFactory->addMetadata($entityMetadata);
+        $this->metadataFactory->addMetadata(new ClassMetadata('ArrayIterator'));
+
+        // add a constraint for the entity that always fails
+        $entityMetadata->addConstraint(new FailingConstraint());
+
+        // validate array when validating the property "reference"
+        $this->metadata->addPropertyConstraint('reference', new Valid(array(
+            'traverse' => false,
+        )));
+
+        $this->walker->walkPropertyValue(
+            $this->metadata,
+            'reference',
+            new \ArrayIterator(array('key' => $entity)),
+            'Default',
+            'path'
+        );
+
+        $violations = new ConstraintViolationList();
+
+        $this->assertEquals($violations, $this->walker->getViolations());
+    }
+
+    public function testWalkCascadedPropertyDoesNotRecurseByDefault()
+    {
+        $entity = new Entity();
+        $entityMetadata = new ClassMetadata(get_class($entity));
+        $this->metadataFactory->addMetadata($entityMetadata);
+        $this->metadataFactory->addMetadata(new ClassMetadata('ArrayIterator'));
+
+        // add a constraint for the entity that always fails
+        $entityMetadata->addConstraint(new FailingConstraint());
+
+        // validate iterator when validating the property "reference"
+        $this->metadata->addPropertyConstraint('reference', new Valid());
+
+        $this->walker->walkPropertyValue(
+            $this->metadata,
+            'reference',
+            new \ArrayIterator(array(
+                // The inner iterator should not be traversed by default
+                'key' => new \ArrayIterator(array(
+                    'nested' => $entity,
+                )),
+            )),
+            'Default',
+            'path'
+        );
+
+        $violations = new ConstraintViolationList();
+
+        $this->assertEquals($violations, $this->walker->getViolations());
+    }
+
+    public function testWalkCascadedPropertyRecursesIfDeepIsSet()
+    {
+        $entity = new Entity();
+        $entityMetadata = new ClassMetadata(get_class($entity));
+        $this->metadataFactory->addMetadata($entityMetadata);
+        $this->metadataFactory->addMetadata(new ClassMetadata('ArrayIterator'));
+
+        // add a constraint for the entity that always fails
+        $entityMetadata->addConstraint(new FailingConstraint());
+
+        // validate iterator when validating the property "reference"
+        $this->metadata->addPropertyConstraint('reference', new Valid(array(
+            'deep' => true,
+        )));
+
+        $this->walker->walkPropertyValue(
+            $this->metadata,
+            'reference',
+            new \ArrayIterator(array(
+                // The inner iterator should now be traversed
+                'key' => new \ArrayIterator(array(
+                    'nested' => $entity,
+                )),
+            )),
+            'Default',
+            'path'
+        );
+
+        $violations = new ConstraintViolationList();
+        $violations->add(new ConstraintViolation(
+            'Failed',
+            array(),
+            'Root',
+            'path[key][nested]',
+            $entity
+        ));
+
+        $this->assertEquals($violations, $this->walker->getViolations());
+    }
+
+    public function testWalkCascadedPropertyDoesNotValidateNestedScalarValues()
+    {
+        // validate array when validating the property "reference"
+        $this->metadata->addPropertyConstraint('reference', new Valid());
+
+        $this->walker->walkPropertyValue(
+            $this->metadata,
+            'reference',
+            array('scalar', 'values'),
+            'Default',
+            'path'
+        );
+
+        $violations = new ConstraintViolationList();
+
+        $this->assertEquals($violations, $this->walker->getViolations());
+    }
+
+    public function testWalkCascadedPropertyDoesNotValidateNullValues()
+    {
+        $this->metadata->addPropertyConstraint('reference', new Valid());
+
+        $this->walker->walkPropertyValue(
+            $this->metadata,
+            'reference',
+            null,
+            'Default',
+            ''
+        );
+
+        $this->assertCount(0, $this->walker->getViolations());
+    }
+
+    public function testWalkCascadedPropertyRequiresObjectOrArray()
+    {
+        $this->metadata->addPropertyConstraint('reference', new Valid());
+
+        $this->setExpectedException('Symfony\Component\Validator\Exception\NoSuchMetadataException');
+
+        $this->walker->walkPropertyValue(
+            $this->metadata,
+            'reference',
+            'no object',
+            'Default',
+            ''
+        );
+    }
+
+    public function testWalkConstraintBuildsAViolationIfFailed()
+    {
+        $constraint = new ConstraintA();
+
+        $this->walker->walkConstraint($constraint, 'foobar', 'Default', 'firstName.path');
+
+        $violations = new ConstraintViolationList();
+        $violations->add(new ConstraintViolation(
+            'message',
+            array('param' => 'value'),
+            'Root',
+            'firstName.path',
+            'foobar'
+        ));
+
+        $this->assertEquals($violations, $this->walker->getViolations());
+    }
+
+    public function testWalkConstraintBuildsNoViolationIfSuccessful()
+    {
+        $constraint = new ConstraintA();
+
+        $this->walker->walkConstraint($constraint, 'VALID', 'Default', 'firstName.path');
+
+        $this->assertCount(0, $this->walker->getViolations());
+    }
+
+    public function testWalkObjectUsesCorrectPropertyPathInViolationsWhenUsingCollections()
+    {
+        $constraint = new Collection(array(
+            'foo' => new ConstraintA(),
+            'bar' => new ConstraintA(),
+        ));
+
+        $this->walker->walkConstraint($constraint, array('foo' => 'VALID'), 'Default', 'collection');
+        $violations = $this->walker->getViolations();
+        $this->assertEquals('collection[bar]', $violations[0]->getPropertyPath());
+    }
+
+    public function testWalkObjectUsesCorrectPropertyPathInViolationsWhenUsingNestedCollections()
+    {
+        $constraint = new Collection(array(
+            'foo' => new Collection(array(
+                'foo' => new ConstraintA(),
+                'bar' => new ConstraintA(),
+            )),
+        ));
+
+        $this->walker->walkConstraint($constraint, array('foo' => array('foo' => 'VALID')), 'Default', 'collection');
+        $violations = $this->walker->getViolations();
+        $this->assertEquals('collection[foo][bar]', $violations[0]->getPropertyPath());
+    }
+
+    protected function getProperty($property)
+    {
+        $p = new \ReflectionProperty($this->walker, $property);
+        $p->setAccessible(true);
+
+        return $p->getValue($this->walker);
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Cache/ApcCacheTest.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Cache/ApcCacheTest.php
new file mode 100644
index 0000000..4c7fe79
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Cache/ApcCacheTest.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\Validator\Tests\Mapping\Cache;
+
+use Symfony\Component\Validator\Mapping\Cache\ApcCache;
+
+class ApcCacheTest extends \PHPUnit_Framework_TestCase
+{
+    protected function setUp()
+    {
+        if (!extension_loaded('apc') || !ini_get('apc.enable_cli')) {
+            $this->markTestSkipped('APC is not loaded.');
+        }
+    }
+
+    public function testWrite()
+    {
+        $meta = $this->getMockBuilder('Symfony\\Component\\Validator\\Mapping\\ClassMetadata')
+            ->disableOriginalConstructor()
+            ->setMethods(array('getClassName'))
+            ->getMock();
+
+        $meta->expects($this->once())
+            ->method('getClassName')
+            ->will($this->returnValue('bar'));
+
+        $cache = new ApcCache('foo');
+        $cache->write($meta);
+
+        $this->assertInstanceOf('Symfony\\Component\\Validator\\Mapping\\ClassMetadata', apc_fetch('foobar'), '->write() stores metadata in APC');
+    }
+
+    public function testHas()
+    {
+        $meta = $this->getMockBuilder('Symfony\\Component\\Validator\\Mapping\\ClassMetadata')
+            ->disableOriginalConstructor()
+            ->setMethods(array('getClassName'))
+            ->getMock();
+
+        $meta->expects($this->once())
+            ->method('getClassName')
+            ->will($this->returnValue('bar'));
+
+        apc_delete('foobar');
+
+        $cache = new ApcCache('foo');
+        $this->assertFalse($cache->has('bar'), '->has() returns false when there is no entry');
+
+        $cache->write($meta);
+        $this->assertTrue($cache->has('bar'), '->has() returns true when the is an entry');
+    }
+
+    public function testRead()
+    {
+        $meta = $this->getMockBuilder('Symfony\\Component\\Validator\\Mapping\\ClassMetadata')
+            ->disableOriginalConstructor()
+            ->setMethods(array('getClassName'))
+            ->getMock();
+
+        $meta->expects($this->once())
+            ->method('getClassName')
+            ->will($this->returnValue('bar'));
+
+        $cache = new ApcCache('foo');
+        $cache->write($meta);
+
+        $this->assertInstanceOf('Symfony\\Component\\Validator\\Mapping\\ClassMetadata', $cache->read('bar'), '->read() returns metadata');
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/ClassMetadataFactoryTest.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/ClassMetadataFactoryTest.php
new file mode 100644
index 0000000..7ee36b4
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/ClassMetadataFactoryTest.php
@@ -0,0 +1,119 @@
+<?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\Validator\Tests\Mapping;
+
+use Symfony\Component\Validator\Tests\Fixtures\Entity;
+use Symfony\Component\Validator\Tests\Fixtures\ConstraintA;
+use Symfony\Component\Validator\Mapping\ClassMetadataFactory;
+use Symfony\Component\Validator\Mapping\ClassMetadata;
+use Symfony\Component\Validator\Mapping\Loader\LoaderInterface;
+
+class ClassMetadataFactoryTest extends \PHPUnit_Framework_TestCase
+{
+    const CLASSNAME = 'Symfony\Component\Validator\Tests\Fixtures\Entity';
+    const PARENTCLASS = 'Symfony\Component\Validator\Tests\Fixtures\EntityParent';
+
+    public function testLoadClassMetadata()
+    {
+        $factory = new ClassMetadataFactory(new TestLoader());
+        $metadata = $factory->getClassMetadata(self::PARENTCLASS);
+
+        $constraints = array(
+            new ConstraintA(array('groups' => array('Default', 'EntityParent'))),
+        );
+
+        $this->assertEquals($constraints, $metadata->getConstraints());
+    }
+
+    public function testMergeParentConstraints()
+    {
+        $factory = new ClassMetadataFactory(new TestLoader());
+        $metadata = $factory->getClassMetadata(self::CLASSNAME);
+
+        $constraints = array(
+            new ConstraintA(array('groups' => array(
+                'Default',
+                'EntityParent',
+                'Entity',
+            ))),
+            new ConstraintA(array('groups' => array(
+                'Default',
+                'EntityInterface',
+                'Entity',
+            ))),
+            new ConstraintA(array('groups' => array(
+                'Default',
+                'Entity',
+            ))),
+        );
+
+        $this->assertEquals($constraints, $metadata->getConstraints());
+    }
+
+    public function testWriteMetadataToCache()
+    {
+        $cache = $this->getMock('Symfony\Component\Validator\Mapping\Cache\CacheInterface');
+        $factory = new ClassMetadataFactory(new TestLoader(), $cache);
+
+        $tester = $this;
+        $constraints = array(
+            new ConstraintA(array('groups' => array('Default', 'EntityParent'))),
+        );
+
+        $cache->expects($this->never())
+              ->method('has');
+        $cache->expects($this->once())
+              ->method('read')
+              ->with($this->equalTo(self::PARENTCLASS))
+              ->will($this->returnValue(false));
+        $cache->expects($this->once())
+              ->method('write')
+              ->will($this->returnCallback(function($metadata) use ($tester, $constraints) {
+                  $tester->assertEquals($constraints, $metadata->getConstraints());
+              }));
+
+        $metadata = $factory->getClassMetadata(self::PARENTCLASS);
+
+        $this->assertEquals(self::PARENTCLASS, $metadata->getClassName());
+        $this->assertEquals($constraints, $metadata->getConstraints());
+    }
+
+    public function testReadMetadataFromCache()
+    {
+        $loader = $this->getMock('Symfony\Component\Validator\Mapping\Loader\LoaderInterface');
+        $cache = $this->getMock('Symfony\Component\Validator\Mapping\Cache\CacheInterface');
+        $factory = new ClassMetadataFactory($loader, $cache);
+
+        $tester = $this;
+        $metadata = new ClassMetadata(self::PARENTCLASS);
+        $metadata->addConstraint(new ConstraintA());
+
+        $loader->expects($this->never())
+               ->method('loadClassMetadata');
+
+        $cache->expects($this->never())
+              ->method('has');
+        $cache->expects($this->once())
+              ->method('read')
+              ->will($this->returnValue($metadata));
+
+        $this->assertEquals($metadata,$factory->getClassMetadata(self::PARENTCLASS));
+    }
+}
+
+class TestLoader implements LoaderInterface
+{
+    public function loadClassMetadata(ClassMetadata $metadata)
+    {
+        $metadata->addConstraint(new ConstraintA());
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/ClassMetadataTest.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/ClassMetadataTest.php
new file mode 100644
index 0000000..a7a0c1e
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/ClassMetadataTest.php
@@ -0,0 +1,225 @@
+<?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\Validator\Tests\Mapping;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\Constraints\Valid;
+use Symfony\Component\Validator\Mapping\ClassMetadata;
+use Symfony\Component\Validator\Exception\GroupDefinitionException;
+use Symfony\Component\Validator\Tests\Fixtures\Entity;
+use Symfony\Component\Validator\Tests\Fixtures\ConstraintA;
+use Symfony\Component\Validator\Tests\Fixtures\ConstraintB;
+use Symfony\Component\Validator\Tests\Fixtures\PropertyConstraint;
+
+class ClassMetadataTest extends \PHPUnit_Framework_TestCase
+{
+    const CLASSNAME = 'Symfony\Component\Validator\Tests\Fixtures\Entity';
+    const PARENTCLASS = 'Symfony\Component\Validator\Tests\Fixtures\EntityParent';
+    const PROVIDERCLASS = 'Symfony\Component\Validator\Tests\Fixtures\GroupSequenceProviderEntity';
+
+    protected $metadata;
+
+    protected function setUp()
+    {
+        $this->metadata = new ClassMetadata(self::CLASSNAME);
+    }
+
+    protected function tearDown()
+    {
+        $this->metadata = null;
+    }
+
+    public function testAddConstraintDoesNotAcceptValid()
+    {
+        $this->setExpectedException('Symfony\Component\Validator\Exception\ConstraintDefinitionException');
+
+        $this->metadata->addConstraint(new Valid());
+    }
+
+    public function testAddConstraintRequiresClassConstraints()
+    {
+        $this->setExpectedException('Symfony\Component\Validator\Exception\ConstraintDefinitionException');
+
+        $this->metadata->addConstraint(new PropertyConstraint());
+    }
+
+    public function testAddPropertyConstraints()
+    {
+        $this->metadata->addPropertyConstraint('firstName', new ConstraintA());
+        $this->metadata->addPropertyConstraint('lastName', new ConstraintB());
+
+        $this->assertEquals(array('firstName', 'lastName'), $this->metadata->getConstrainedProperties());
+    }
+
+    public function testMergeConstraintsMergesClassConstraints()
+    {
+        $parent = new ClassMetadata(self::PARENTCLASS);
+        $parent->addConstraint(new ConstraintA());
+
+        $this->metadata->mergeConstraints($parent);
+        $this->metadata->addConstraint(new ConstraintA());
+
+        $constraints = array(
+            new ConstraintA(array('groups' => array(
+                'Default',
+                'EntityParent',
+                'Entity',
+            ))),
+            new ConstraintA(array('groups' => array(
+                'Default',
+                'Entity',
+            ))),
+        );
+
+        $this->assertEquals($constraints, $this->metadata->getConstraints());
+    }
+
+    public function testMergeConstraintsMergesMemberConstraints()
+    {
+        $parent = new ClassMetadata(self::PARENTCLASS);
+        $parent->addPropertyConstraint('firstName', new ConstraintA());
+
+        $this->metadata->mergeConstraints($parent);
+        $this->metadata->addPropertyConstraint('firstName', new ConstraintA());
+
+        $constraints = array(
+            new ConstraintA(array('groups' => array(
+                'Default',
+                'EntityParent',
+                'Entity',
+            ))),
+            new ConstraintA(array('groups' => array(
+                'Default',
+                'Entity',
+            ))),
+        );
+
+        $members = $this->metadata->getMemberMetadatas('firstName');
+
+        $this->assertCount(1, $members);
+        $this->assertEquals(self::PARENTCLASS, $members[0]->getClassName());
+        $this->assertEquals($constraints, $members[0]->getConstraints());
+    }
+
+    public function testMemberMetadatas()
+    {
+        $this->metadata->addPropertyConstraint('firstName', new ConstraintA());
+
+        $this->assertTrue($this->metadata->hasMemberMetadatas('firstName'));
+        $this->assertFalse($this->metadata->hasMemberMetadatas('non_existant_field'));
+    }
+
+    public function testMergeConstraintsKeepsPrivateMembersSeparate()
+    {
+        $parent = new ClassMetadata(self::PARENTCLASS);
+        $parent->addPropertyConstraint('internal', new ConstraintA());
+
+        $this->metadata->mergeConstraints($parent);
+        $this->metadata->addPropertyConstraint('internal', new ConstraintA());
+
+        $parentConstraints = array(
+            new ConstraintA(array('groups' => array(
+                'Default',
+                'EntityParent',
+                'Entity',
+            ))),
+        );
+        $constraints = array(
+            new ConstraintA(array('groups' => array(
+                'Default',
+                'Entity',
+            ))),
+        );
+
+        $members = $this->metadata->getMemberMetadatas('internal');
+
+        $this->assertCount(2, $members);
+        $this->assertEquals(self::PARENTCLASS, $members[0]->getClassName());
+        $this->assertEquals($parentConstraints, $members[0]->getConstraints());
+        $this->assertEquals(self::CLASSNAME, $members[1]->getClassName());
+        $this->assertEquals($constraints, $members[1]->getConstraints());
+    }
+
+    public function testGetReflectionClass()
+    {
+        $reflClass = new \ReflectionClass(self::CLASSNAME);
+
+        $this->assertEquals($reflClass, $this->metadata->getReflectionClass());
+    }
+
+    public function testSerialize()
+    {
+        $this->metadata->addConstraint(new ConstraintA(array('property1' => 'A')));
+        $this->metadata->addConstraint(new ConstraintB(array('groups' => 'TestGroup')));
+        $this->metadata->addPropertyConstraint('firstName', new ConstraintA());
+        $this->metadata->addGetterConstraint('lastName', new ConstraintB());
+
+        $metadata = unserialize(serialize($this->metadata));
+
+        $this->assertEquals($this->metadata, $metadata);
+    }
+
+    public function testGroupSequencesWorkIfContainingDefaultGroup()
+    {
+        $this->metadata->setGroupSequence(array('Foo', $this->metadata->getDefaultGroup()));
+    }
+
+    public function testGroupSequencesFailIfNotContainingDefaultGroup()
+    {
+        $this->setExpectedException('Symfony\Component\Validator\Exception\GroupDefinitionException');
+
+        $this->metadata->setGroupSequence(array('Foo', 'Bar'));
+    }
+
+    public function testGroupSequencesFailIfContainingDefault()
+    {
+        $this->setExpectedException('Symfony\Component\Validator\Exception\GroupDefinitionException');
+
+        $this->metadata->setGroupSequence(array('Foo', $this->metadata->getDefaultGroup(), Constraint::DEFAULT_GROUP));
+    }
+
+    /**
+     * @expectedException Symfony\Component\Validator\Exception\GroupDefinitionException
+     */
+    public function testGroupSequenceFailsIfGroupSequenceProviderIsSet()
+    {
+        $metadata = new ClassMetadata(self::PROVIDERCLASS);
+        $metadata->setGroupSequenceProvider(true);
+        $metadata->setGroupSequence(array('GroupSequenceProviderEntity', 'Foo'));
+    }
+
+    /**
+     * @expectedException Symfony\Component\Validator\Exception\GroupDefinitionException
+     */
+    public function testGroupSequenceProviderFailsIfGroupSequenceIsSet()
+    {
+        $metadata = new ClassMetadata(self::PROVIDERCLASS);
+        $metadata->setGroupSequence(array('GroupSequenceProviderEntity', 'Foo'));
+        $metadata->setGroupSequenceProvider(true);
+    }
+
+    /**
+     * @expectedException Symfony\Component\Validator\Exception\GroupDefinitionException
+     */
+    public function testGroupSequenceProviderFailsIfDomainClassIsInvalid()
+    {
+        $metadata = new ClassMetadata('stdClass');
+        $metadata->setGroupSequenceProvider(true);
+    }
+
+    public function testGroupSequenceProvider()
+    {
+        $metadata = new ClassMetadata(self::PROVIDERCLASS);
+        $metadata->setGroupSequenceProvider(true);
+        $this->assertTrue($metadata->isGroupSequenceProvider());
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/ElementMetadataTest.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/ElementMetadataTest.php
new file mode 100644
index 0000000..eb01d11
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/ElementMetadataTest.php
@@ -0,0 +1,73 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Mapping;
+
+use Symfony\Component\Validator\Tests\Fixtures\ConstraintA;
+use Symfony\Component\Validator\Tests\Fixtures\ConstraintB;
+use Symfony\Component\Validator\Mapping\ElementMetadata;
+
+class ElementMetadataTest extends \PHPUnit_Framework_TestCase
+{
+    protected $metadata;
+
+    protected function setUp()
+    {
+        $this->metadata = new TestElementMetadata('Symfony\Component\Validator\Tests\Fixtures\Entity');
+    }
+
+    protected function tearDown()
+    {
+        $this->metadata = null;
+    }
+
+    public function testAddConstraints()
+    {
+        $this->metadata->addConstraint($constraint1 = new ConstraintA());
+        $this->metadata->addConstraint($constraint2 = new ConstraintA());
+
+        $this->assertEquals(array($constraint1, $constraint2), $this->metadata->getConstraints());
+    }
+
+    public function testMultipleConstraintsOfTheSameType()
+    {
+        $constraint1 = new ConstraintA(array('property1' => 'A'));
+        $constraint2 = new ConstraintA(array('property1' => 'B'));
+
+        $this->metadata->addConstraint($constraint1);
+        $this->metadata->addConstraint($constraint2);
+
+        $this->assertEquals(array($constraint1, $constraint2), $this->metadata->getConstraints());
+    }
+
+    public function testFindConstraintsByGroup()
+    {
+        $constraint1 = new ConstraintA(array('groups' => 'TestGroup'));
+        $constraint2 = new ConstraintB();
+
+        $this->metadata->addConstraint($constraint1);
+        $this->metadata->addConstraint($constraint2);
+
+        $this->assertEquals(array($constraint1), $this->metadata->findConstraints('TestGroup'));
+    }
+
+    public function testSerialize()
+    {
+        $this->metadata->addConstraint(new ConstraintA(array('property1' => 'A')));
+        $this->metadata->addConstraint(new ConstraintB(array('groups' => 'TestGroup')));
+
+        $metadata = unserialize(serialize($this->metadata));
+
+        $this->assertEquals($this->metadata, $metadata);
+    }
+}
+
+class TestElementMetadata extends ElementMetadata {}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/GetterMetadataTest.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/GetterMetadataTest.php
new file mode 100644
index 0000000..99303e9
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/GetterMetadataTest.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\Validator\Tests\Mapping;
+
+use Symfony\Component\Validator\Mapping\GetterMetadata;
+use Symfony\Component\Validator\Tests\Fixtures\Entity;
+
+class GetterMetadataTest extends \PHPUnit_Framework_TestCase
+{
+    const CLASSNAME = 'Symfony\Component\Validator\Tests\Fixtures\Entity';
+
+    public function testInvalidPropertyName()
+    {
+        $this->setExpectedException('Symfony\Component\Validator\Exception\ValidatorException');
+
+        new GetterMetadata(self::CLASSNAME, 'foobar');
+    }
+
+    public function testGetValueFromPublicGetter()
+    {
+        // private getters don't work yet because ReflectionMethod::setAccessible()
+        // does not exists yet in a stable PHP release
+
+        $entity = new Entity('foobar');
+        $metadata = new GetterMetadata(self::CLASSNAME, 'internal');
+
+        $this->assertEquals('foobar from getter', $metadata->getValue($entity));
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/AnnotationLoaderTest.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/AnnotationLoaderTest.php
new file mode 100644
index 0000000..ce444ac
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/AnnotationLoaderTest.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\Validator\Tests\Mapping\Loader;
+
+use Doctrine\Common\Annotations\AnnotationReader;
+use Symfony\Component\Validator\Constraints\All;
+use Symfony\Component\Validator\Constraints\Collection;
+use Symfony\Component\Validator\Constraints\NotNull;
+use Symfony\Component\Validator\Constraints\Min;
+use Symfony\Component\Validator\Constraints\Choice;
+use Symfony\Component\Validator\Mapping\ClassMetadata;
+use Symfony\Component\Validator\Mapping\Loader\AnnotationLoader;
+use Symfony\Component\Validator\Tests\Fixtures\ConstraintA;
+
+class AnnotationLoaderTest extends \PHPUnit_Framework_TestCase
+{
+    protected function setUp()
+    {
+        if (!class_exists('Doctrine\Common\Annotations\AnnotationReader')) {
+            $this->markTestSkipped('The "Doctrine Common" library is not available');
+        }
+    }
+
+    public function testLoadClassMetadataReturnsTrueIfSuccessful()
+    {
+        $reader = new AnnotationReader();
+        $loader = new AnnotationLoader($reader);
+        $metadata = new ClassMetadata('Symfony\Component\Validator\Tests\Fixtures\Entity');
+
+        $this->assertTrue($loader->loadClassMetadata($metadata));
+    }
+
+    public function testLoadClassMetadataReturnsFalseIfNotSuccessful()
+    {
+        $loader = new AnnotationLoader(new AnnotationReader());
+        $metadata = new ClassMetadata('\stdClass');
+
+        $this->assertFalse($loader->loadClassMetadata($metadata));
+    }
+
+    public function testLoadClassMetadata()
+    {
+        $loader = new AnnotationLoader(new AnnotationReader());
+        $metadata = new ClassMetadata('Symfony\Component\Validator\Tests\Fixtures\Entity');
+
+        $loader->loadClassMetadata($metadata);
+
+        $expected = new ClassMetadata('Symfony\Component\Validator\Tests\Fixtures\Entity');
+        $expected->setGroupSequence(array('Foo', 'Entity'));
+        $expected->addConstraint(new ConstraintA());
+        $expected->addPropertyConstraint('firstName', new NotNull());
+        $expected->addPropertyConstraint('firstName', new Min(3));
+        $expected->addPropertyConstraint('firstName', new All(array(new NotNull(), new Min(3))));
+        $expected->addPropertyConstraint('firstName', new All(array('constraints' => array(new NotNull(), new Min(3)))));
+        $expected->addPropertyConstraint('firstName', new Collection(array('fields' => array(
+            'foo' => array(new NotNull(), new Min(3)),
+            'bar' => new Min(5),
+        ))));
+        $expected->addPropertyConstraint('firstName', new Choice(array(
+            'message' => 'Must be one of %choices%',
+            'choices' => array('A', 'B'),
+        )));
+        $expected->addGetterConstraint('lastName', new NotNull());
+
+        // load reflection class so that the comparison passes
+        $expected->getReflectionClass();
+
+        $this->assertEquals($expected, $metadata);
+    }
+
+    /**
+     * Test MetaData merge with parent annotation.
+     */
+    public function testLoadParentClassMetadata()
+    {
+        $loader = new AnnotationLoader(new AnnotationReader());
+
+        // Load Parent MetaData
+        $parent_metadata = new ClassMetadata('Symfony\Component\Validator\Tests\Fixtures\EntityParent');
+        $loader->loadClassMetadata($parent_metadata);
+
+        $expected_parent = new ClassMetadata('Symfony\Component\Validator\Tests\Fixtures\EntityParent');
+        $expected_parent->addPropertyConstraint('other', new NotNull());
+        $expected_parent->getReflectionClass();
+
+        $this->assertEquals($expected_parent, $parent_metadata);
+    }
+    /**
+     * Test MetaData merge with parent annotation.
+     */
+    public function testLoadClassMetadataAndMerge()
+    {
+        $loader = new AnnotationLoader(new AnnotationReader());
+
+        // Load Parent MetaData
+        $parent_metadata = new ClassMetadata('Symfony\Component\Validator\Tests\Fixtures\EntityParent');
+        $loader->loadClassMetadata($parent_metadata);
+
+        $metadata = new ClassMetadata('Symfony\Component\Validator\Tests\Fixtures\Entity');
+
+        // Merge parent metaData.
+        $metadata->mergeConstraints($parent_metadata);
+
+        $loader->loadClassMetadata($metadata);
+
+        $expected_parent = new ClassMetadata('Symfony\Component\Validator\Tests\Fixtures\EntityParent');
+        $expected_parent->addPropertyConstraint('other', new NotNull());
+        $expected_parent->getReflectionClass();
+
+        $expected = new ClassMetadata('Symfony\Component\Validator\Tests\Fixtures\Entity');
+        $expected->mergeConstraints($expected_parent);
+
+        $expected->setGroupSequence(array('Foo', 'Entity'));
+        $expected->addConstraint(new ConstraintA());
+        $expected->addPropertyConstraint('firstName', new NotNull());
+        $expected->addPropertyConstraint('firstName', new Min(3));
+        $expected->addPropertyConstraint('firstName', new All(array(new NotNull(), new Min(3))));
+        $expected->addPropertyConstraint('firstName', new All(array('constraints' => array(new NotNull(), new Min(3)))));
+        $expected->addPropertyConstraint('firstName', new Collection(array('fields' => array(
+            'foo' => array(new NotNull(), new Min(3)),
+            'bar' => new Min(5),
+        ))));
+        $expected->addPropertyConstraint('firstName', new Choice(array(
+            'message' => 'Must be one of %choices%',
+            'choices' => array('A', 'B'),
+        )));
+        $expected->addGetterConstraint('lastName', new NotNull());
+
+        // load reflection class so that the comparison passes
+        $expected->getReflectionClass();
+
+        $this->assertEquals($expected, $metadata);
+    }
+
+    public function testLoadGroupSequenceProviderAnnotation()
+    {
+        $loader = new AnnotationLoader(new AnnotationReader());
+
+        $metadata = new ClassMetadata('Symfony\Component\Validator\Tests\Fixtures\GroupSequenceProviderEntity');
+        $loader->loadClassMetadata($metadata);
+
+        $expected = new ClassMetadata('Symfony\Component\Validator\Tests\Fixtures\GroupSequenceProviderEntity');
+        $expected->setGroupSequenceProvider(true);
+        $expected->getReflectionClass();
+
+        $this->assertEquals($expected, $metadata);
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/FilesLoaderTest.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/FilesLoaderTest.php
new file mode 100644
index 0000000..301ef0e
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/FilesLoaderTest.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\Validator\Tests\Mapping\Loader;
+
+use Symfony\Component\Validator\Mapping\Loader\LoaderInterface;
+use Symfony\Component\Validator\Mapping\ClassMetadata;
+
+class FilesLoaderTest extends \PHPUnit_Framework_TestCase
+{
+    public function testCallsGetFileLoaderInstanceForeachPath()
+    {
+        $loader = $this->getFilesLoader($this->getFileLoader());
+        $this->assertEquals(4, $loader->getTimesCalled());
+    }
+
+    public function testCallsActualFileLoaderForMetadata()
+    {
+        $fileLoader = $this->getFileLoader();
+        $fileLoader->expects($this->exactly(4))
+            ->method('loadClassMetadata');
+        $loader = $this->getFilesLoader($fileLoader);
+        $loader->loadClassMetadata(new ClassMetadata('Symfony\Component\Validator\Tests\Fixtures\Entity'));
+    }
+
+    public function getFilesLoader(LoaderInterface $loader)
+    {
+        return $this->getMockForAbstractClass('Symfony\Component\Validator\Tests\Fixtures\FilesLoader', array(array(
+            __DIR__ . '/constraint-mapping.xml',
+            __DIR__ . '/constraint-mapping.yaml',
+            __DIR__ . '/constraint-mapping.test',
+            __DIR__ . '/constraint-mapping.txt',
+        ), $loader));
+    }
+
+    public function getFileLoader()
+    {
+        return $this->getMock('Symfony\Component\Validator\Mapping\Loader\LoaderInterface');
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/LoaderChainTest.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/LoaderChainTest.php
new file mode 100644
index 0000000..647a568
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/LoaderChainTest.php
@@ -0,0 +1,84 @@
+<?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\Validator\Tests\Mapping\Loader;
+
+use Symfony\Component\Validator\Mapping\ClassMetadata;
+use Symfony\Component\Validator\Mapping\Loader\LoaderChain;
+
+class LoaderChainTest extends \PHPUnit_Framework_TestCase
+{
+    public function testAllLoadersAreCalled()
+    {
+        $metadata = new ClassMetadata('\stdClass');
+
+        $loader1 = $this->getMock('Symfony\Component\Validator\Mapping\Loader\LoaderInterface');
+        $loader1->expects($this->once())
+                        ->method('loadClassMetadata')
+                        ->with($this->equalTo($metadata));
+
+        $loader2 = $this->getMock('Symfony\Component\Validator\Mapping\Loader\LoaderInterface');
+        $loader2->expects($this->once())
+                        ->method('loadClassMetadata')
+                        ->with($this->equalTo($metadata));
+
+        $chain = new LoaderChain(array(
+            $loader1,
+            $loader2,
+        ));
+
+        $chain->loadClassMetadata($metadata);
+    }
+
+    public function testReturnsTrueIfAnyLoaderReturnedTrue()
+    {
+        $metadata = new ClassMetadata('\stdClass');
+
+        $loader1 = $this->getMock('Symfony\Component\Validator\Mapping\Loader\LoaderInterface');
+        $loader1->expects($this->any())
+                        ->method('loadClassMetadata')
+                        ->will($this->returnValue(true));
+
+        $loader2 = $this->getMock('Symfony\Component\Validator\Mapping\Loader\LoaderInterface');
+        $loader2->expects($this->any())
+                        ->method('loadClassMetadata')
+                        ->will($this->returnValue(false));
+
+        $chain = new LoaderChain(array(
+            $loader1,
+            $loader2,
+        ));
+
+        $this->assertTrue($chain->loadClassMetadata($metadata));
+    }
+
+    public function testReturnsFalseIfNoLoaderReturnedTrue()
+    {
+        $metadata = new ClassMetadata('\stdClass');
+
+        $loader1 = $this->getMock('Symfony\Component\Validator\Mapping\Loader\LoaderInterface');
+        $loader1->expects($this->any())
+                        ->method('loadClassMetadata')
+                        ->will($this->returnValue(false));
+
+        $loader2 = $this->getMock('Symfony\Component\Validator\Mapping\Loader\LoaderInterface');
+        $loader2->expects($this->any())
+                        ->method('loadClassMetadata')
+                        ->will($this->returnValue(false));
+
+        $chain = new LoaderChain(array(
+            $loader1,
+            $loader2,
+        ));
+
+        $this->assertFalse($chain->loadClassMetadata($metadata));
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/StaticMethodLoaderTest.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/StaticMethodLoaderTest.php
new file mode 100644
index 0000000..4fc18c1
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/StaticMethodLoaderTest.php
@@ -0,0 +1,95 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Mapping\Loader;
+
+use Symfony\Component\Validator\Mapping\ClassMetadata;
+use Symfony\Component\Validator\Mapping\Loader\StaticMethodLoader;
+use Symfony\Component\Validator\Tests\Fixtures\ConstraintA;
+
+class StaticMethodLoaderTest extends \PHPUnit_Framework_TestCase
+{
+    public function testLoadClassMetadataReturnsTrueIfSuccessful()
+    {
+        $loader = new StaticMethodLoader('loadMetadata');
+        $metadata = new ClassMetadata(__NAMESPACE__.'\StaticLoaderEntity');
+
+        $this->assertTrue($loader->loadClassMetadata($metadata));
+    }
+
+    public function testLoadClassMetadataReturnsFalseIfNotSuccessful()
+    {
+        $loader = new StaticMethodLoader('loadMetadata');
+        $metadata = new ClassMetadata('\stdClass');
+
+        $this->assertFalse($loader->loadClassMetadata($metadata));
+    }
+
+    public function testLoadClassMetadata()
+    {
+        $loader = new StaticMethodLoader('loadMetadata');
+        $metadata = new ClassMetadata(__NAMESPACE__.'\StaticLoaderEntity');
+
+        $loader->loadClassMetadata($metadata);
+
+        $this->assertEquals(StaticLoaderEntity::$invokedWith, $metadata);
+    }
+
+    public function testLoadClassMetadataDoesNotRepeatLoadWithParentClasses()
+    {
+        $loader = new StaticMethodLoader('loadMetadata');
+        $metadata = new ClassMetadata(__NAMESPACE__.'\StaticLoaderDocument');
+        $loader->loadClassMetadata($metadata);
+        $this->assertSame(0, count($metadata->getConstraints()));
+
+        $loader = new StaticMethodLoader('loadMetadata');
+        $metadata = new ClassMetadata(__NAMESPACE__.'\BaseStaticLoaderDocument');
+        $loader->loadClassMetadata($metadata);
+        $this->assertSame(1, count($metadata->getConstraints()));
+    }
+
+    public function testLoadClassMetadataIgnoresInterfaces()
+    {
+        $loader = new StaticMethodLoader('loadMetadata');
+        $metadata = new ClassMetadata(__NAMESPACE__.'\StaticLoaderInterface');
+
+        $loader->loadClassMetadata($metadata);
+
+        $this->assertSame(0, count($metadata->getConstraints()));
+    }
+}
+
+interface StaticLoaderInterface
+{
+    public static function loadMetadata(ClassMetadata $metadata);
+}
+
+class StaticLoaderEntity
+{
+    public static $invokedWith = null;
+
+    public static function loadMetadata(ClassMetadata $metadata)
+    {
+        self::$invokedWith = $metadata;
+    }
+}
+
+class StaticLoaderDocument extends BaseStaticLoaderDocument
+{
+}
+
+class BaseStaticLoaderDocument
+{
+    public static function loadMetadata(ClassMetadata $metadata)
+    {
+        $metadata->addConstraint(new ConstraintA());
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/XmlFileLoaderTest.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/XmlFileLoaderTest.php
new file mode 100644
index 0000000..428fe6b
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/XmlFileLoaderTest.php
@@ -0,0 +1,95 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests\Mapping\Loader;
+
+use Symfony\Component\Validator\Constraints\All;
+use Symfony\Component\Validator\Constraints\Collection;
+use Symfony\Component\Validator\Constraints\NotNull;
+use Symfony\Component\Validator\Constraints\Min;
+use Symfony\Component\Validator\Constraints\Choice;
+use Symfony\Component\Validator\Mapping\ClassMetadata;
+use Symfony\Component\Validator\Mapping\Loader\XmlFileLoader;
+use Symfony\Component\Validator\Tests\Fixtures\ConstraintA;
+use Symfony\Component\Validator\Tests\Fixtures\ConstraintB;
+
+class XmlFileLoaderTest extends \PHPUnit_Framework_TestCase
+{
+    public function testLoadClassMetadataReturnsTrueIfSuccessful()
+    {
+        $loader = new XmlFileLoader(__DIR__.'/constraint-mapping.xml');
+        $metadata = new ClassMetadata('Symfony\Component\Validator\Tests\Fixtures\Entity');
+
+        $this->assertTrue($loader->loadClassMetadata($metadata));
+    }
+
+    public function testLoadClassMetadataReturnsFalseIfNotSuccessful()
+    {
+        $loader = new XmlFileLoader(__DIR__.'/constraint-mapping.xml');
+        $metadata = new ClassMetadata('\stdClass');
+
+        $this->assertFalse($loader->loadClassMetadata($metadata));
+    }
+
+    public function testLoadClassMetadata()
+    {
+        $loader = new XmlFileLoader(__DIR__.'/constraint-mapping.xml');
+        $metadata = new ClassMetadata('Symfony\Component\Validator\Tests\Fixtures\Entity');
+
+        $loader->loadClassMetadata($metadata);
+
+        $expected = new ClassMetadata('Symfony\Component\Validator\Tests\Fixtures\Entity');
+        $expected->setGroupSequence(array('Foo', 'Entity'));
+        $expected->addConstraint(new ConstraintA());
+        $expected->addConstraint(new ConstraintB());
+        $expected->addPropertyConstraint('firstName', new NotNull());
+        $expected->addPropertyConstraint('firstName', new Min(3));
+        $expected->addPropertyConstraint('firstName', new Choice(array('A', 'B')));
+        $expected->addPropertyConstraint('firstName', new All(array(new NotNull(), new Min(3))));
+        $expected->addPropertyConstraint('firstName', new All(array('constraints' => array(new NotNull(), new Min(3)))));
+        $expected->addPropertyConstraint('firstName', new Collection(array('fields' => array(
+            'foo' => array(new NotNull(), new Min(3)),
+            'bar' => array(new Min(5)),
+        ))));
+        $expected->addPropertyConstraint('firstName', new Choice(array(
+            'message' => 'Must be one of %choices%',
+            'choices' => array('A', 'B'),
+        )));
+        $expected->addGetterConstraint('lastName', new NotNull());
+
+        $this->assertEquals($expected, $metadata);
+    }
+
+    public function testLoadGroupSequenceProvider()
+    {
+        $loader = new XmlFileLoader(__DIR__.'/constraint-mapping.xml');
+        $metadata = new ClassMetadata('Symfony\Component\Validator\Tests\Fixtures\GroupSequenceProviderEntity');
+
+        $loader->loadClassMetadata($metadata);
+
+        $expected = new ClassMetadata('Symfony\Component\Validator\Tests\Fixtures\GroupSequenceProviderEntity');
+        $expected->setGroupSequenceProvider(true);
+
+        $this->assertEquals($expected, $metadata);
+    }
+
+    /**
+     * @expectedException        Symfony\Component\Validator\Exception\MappingException
+     * @expectedExceptionMessage Document types are not allowed.
+     */
+    public function testDocTypeIsNotAllowed()
+    {
+        $loader = new XmlFileLoader(__DIR__.'/withdoctype.xml');
+        $metadata = new ClassMetadata('Symfony\Component\Validator\Tests\Fixtures\Entity');
+
+        $loader->loadClassMetadata($metadata);
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/YamlFileLoaderTest.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/YamlFileLoaderTest.php
new file mode 100644
index 0000000..a175817
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/YamlFileLoaderTest.php
@@ -0,0 +1,108 @@
+<?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\Validator\Tests\Mapping\Loader;
+
+use Symfony\Component\Validator\Constraints\All;
+use Symfony\Component\Validator\Constraints\Collection;
+use Symfony\Component\Validator\Constraints\NotNull;
+use Symfony\Component\Validator\Constraints\Min;
+use Symfony\Component\Validator\Constraints\Choice;
+use Symfony\Component\Validator\Mapping\ClassMetadata;
+use Symfony\Component\Validator\Mapping\Loader\YamlFileLoader;
+use Symfony\Component\Validator\Tests\Fixtures\ConstraintA;
+use Symfony\Component\Validator\Tests\Fixtures\ConstraintB;
+
+class YamlFileLoaderTest extends \PHPUnit_Framework_TestCase
+{
+    protected function setUp()
+    {
+        if (!class_exists('Symfony\Component\Yaml\Yaml')) {
+            $this->markTestSkipped('The "Yaml" component is not available');
+        }
+    }
+
+    public function testLoadClassMetadataReturnsFalseIfEmpty()
+    {
+        $loader = new YamlFileLoader(__DIR__.'/empty-mapping.yml');
+        $metadata = new ClassMetadata('Symfony\Component\Validator\Tests\Fixtures\Entity');
+
+        $this->assertFalse($loader->loadClassMetadata($metadata));
+    }
+
+    /**
+     * @expectedException \InvalidArgumentException
+     */
+    public function testLoadClassMetadataThrowsExceptionIfNotAnArray()
+    {
+        $loader = new YamlFileLoader(__DIR__.'/nonvalid-mapping.yml');
+        $metadata = new ClassMetadata('Symfony\Component\Validator\Tests\Fixtures\Entity');
+        $loader->loadClassMetadata($metadata);
+    }
+
+    public function testLoadClassMetadataReturnsTrueIfSuccessful()
+    {
+        $loader = new YamlFileLoader(__DIR__.'/constraint-mapping.yml');
+        $metadata = new ClassMetadata('Symfony\Component\Validator\Tests\Fixtures\Entity');
+
+        $this->assertTrue($loader->loadClassMetadata($metadata));
+    }
+
+    public function testLoadClassMetadataReturnsFalseIfNotSuccessful()
+    {
+        $loader = new YamlFileLoader(__DIR__.'/constraint-mapping.yml');
+        $metadata = new ClassMetadata('\stdClass');
+
+        $this->assertFalse($loader->loadClassMetadata($metadata));
+    }
+
+    public function testLoadClassMetadata()
+    {
+        $loader = new YamlFileLoader(__DIR__.'/constraint-mapping.yml');
+        $metadata = new ClassMetadata('Symfony\Component\Validator\Tests\Fixtures\Entity');
+
+        $loader->loadClassMetadata($metadata);
+
+        $expected = new ClassMetadata('Symfony\Component\Validator\Tests\Fixtures\Entity');
+        $expected->setGroupSequence(array('Foo', 'Entity'));
+        $expected->addConstraint(new ConstraintA());
+        $expected->addConstraint(new ConstraintB());
+        $expected->addPropertyConstraint('firstName', new NotNull());
+        $expected->addPropertyConstraint('firstName', new Min(3));
+        $expected->addPropertyConstraint('firstName', new Choice(array('A', 'B')));
+        $expected->addPropertyConstraint('firstName', new All(array(new NotNull(), new Min(3))));
+        $expected->addPropertyConstraint('firstName', new All(array('constraints' => array(new NotNull(), new Min(3)))));
+        $expected->addPropertyConstraint('firstName', new Collection(array('fields' => array(
+            'foo' => array(new NotNull(), new Min(3)),
+            'bar' => array(new Min(5)),
+        ))));
+        $expected->addPropertyConstraint('firstName', new Choice(array(
+            'message' => 'Must be one of %choices%',
+            'choices' => array('A', 'B'),
+        )));
+        $expected->addGetterConstraint('lastName', new NotNull());
+
+        $this->assertEquals($expected, $metadata);
+    }
+
+    public function testLoadGroupSequenceProvider()
+    {
+        $loader = new YamlFileLoader(__DIR__.'/constraint-mapping.yml');
+        $metadata = new ClassMetadata('Symfony\Component\Validator\Tests\Fixtures\GroupSequenceProviderEntity');
+
+        $loader->loadClassMetadata($metadata);
+
+        $expected = new ClassMetadata('Symfony\Component\Validator\Tests\Fixtures\GroupSequenceProviderEntity');
+        $expected->setGroupSequenceProvider(true);
+
+        $this->assertEquals($expected, $metadata);
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/constraint-mapping.xml b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/constraint-mapping.xml
new file mode 100644
index 0000000..e815dce
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/constraint-mapping.xml
@@ -0,0 +1,92 @@
+<?xml version="1.0" ?>
+
+<constraint-mapping xmlns="http://symfony.com/schema/dic/constraint-mapping"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://symfony.com/schema/dic/constraint-mapping http://symfony.com/schema/dic/services/constraint-mapping-1.0.xsd">
+
+  <namespace prefix="custom">Symfony\Component\Validator\Tests\Fixtures\</namespace>
+
+  <class name="Symfony\Component\Validator\Tests\Fixtures\Entity">
+
+    <group-sequence>
+       <value>Foo</value>
+       <value>Entity</value>
+    </group-sequence>
+
+    <!-- CLASS CONSTRAINTS -->
+
+    <!-- Custom constraint -->
+    <constraint name="Symfony\Component\Validator\Tests\Fixtures\ConstraintA" />
+
+    <!-- Custom constraint with namespace abbreviation-->
+    <constraint name="custom:ConstraintB" />
+
+    <!-- PROPERTY CONSTRAINTS -->
+
+    <property name="firstName">
+
+      <!-- Constraint without value -->
+      <constraint name="NotNull" />
+
+      <!-- Constraint with single value -->
+      <constraint name="Min">3</constraint>
+
+      <!-- Constraint with multiple values -->
+      <constraint name="Choice">
+        <value>A</value>
+        <value>B</value>
+      </constraint>
+
+      <!-- Constraint with child constraints -->
+      <constraint name="All">
+        <constraint name="NotNull" />
+        <constraint name="Min">3</constraint>
+      </constraint>
+
+      <!-- Option with child constraints -->
+      <constraint name="All">
+        <option name="constraints">
+          <constraint name="NotNull" />
+          <constraint name="Min">3</constraint>
+        </option>
+      </constraint>
+
+      <!-- Value with child constraints -->
+      <constraint name="Collection">
+        <option name="fields">
+          <value key="foo">
+            <constraint name="NotNull" />
+            <constraint name="Min">3</constraint>
+          </value>
+          <value key="bar">
+            <constraint name="Min">5</constraint>
+          </value>
+        </option>
+      </constraint>
+
+      <!-- Constraint with options -->
+      <constraint name="Choice">
+        <!-- Option with single value -->
+        <option name="message">Must be one of %choices%</option>
+        <!-- Option with multiple values -->
+        <option name="choices">
+          <value>A</value>
+          <value>B</value>
+        </option>
+      </constraint>
+    </property>
+
+    <!-- GETTER CONSTRAINTS -->
+
+    <getter property="lastName">
+      <constraint name="NotNull" />
+    </getter>
+  </class>
+
+  <class name="Symfony\Component\Validator\Tests\Fixtures\GroupSequenceProviderEntity">
+
+    <!-- GROUP SEQUENCE PROVIDER -->
+    <group-sequence-provider />
+
+  </class>
+</constraint-mapping>
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/constraint-mapping.yml b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/constraint-mapping.yml
new file mode 100644
index 0000000..b910c88
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/constraint-mapping.yml
@@ -0,0 +1,49 @@
+namespaces:
+  custom: Symfony\Component\Validator\Tests\Fixtures\
+
+Symfony\Component\Validator\Tests\Fixtures\Entity:
+  group_sequence:
+    - Foo
+    - Entity
+
+  constraints:
+    # Custom constraint
+    - Symfony\Component\Validator\Tests\Fixtures\ConstraintA: ~
+    # Custom constraint with namespaces prefix
+    - "custom:ConstraintB": ~
+
+  properties:
+    firstName:
+      # Constraint without value
+      - NotNull: ~
+      # Constraint with single value
+      - Min: 3
+      # Constraint with multiple values
+      - Choice: [A, B]
+      # Constraint with child constraints
+      - All:
+          - NotNull: ~
+          - Min: 3
+      # Option with child constraints
+      - All:
+          constraints:
+            - NotNull: ~
+            - Min: 3
+      # Value with child constraints
+      - Collection:
+          fields:
+            foo:
+              - NotNull: ~
+              - Min: 3
+            bar:
+              - Min: 5
+      # Constraint with options
+      - Choice: { choices: [A, B], message: Must be one of %choices% }
+    dummy:
+
+  getters:
+    lastName:
+      - NotNull: ~
+
+Symfony\Component\Validator\Tests\Fixtures\GroupSequenceProviderEntity:
+  group_sequence_provider: true
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/empty-mapping.yml b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/empty-mapping.yml
new file mode 100644
index 0000000..e69de29
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/nonvalid-mapping.yml b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/nonvalid-mapping.yml
new file mode 100644
index 0000000..257cc56
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/nonvalid-mapping.yml
@@ -0,0 +1 @@
+foo
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/withdoctype.xml b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/withdoctype.xml
new file mode 100644
index 0000000..557cccb
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/Loader/withdoctype.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0"?>
+<!DOCTYPE foo>
+<constraint-mapping xmlns="http://symfony.com/schema/dic/constraint-mapping"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://symfony.com/schema/dic/constraint-mapping http://symfony.com/schema/dic/services/constraint-mapping-1.0.xsd">
+  <class name="Symfony\Tests\Component\Validator\Fixtures\Entity" />
+</constraint-mapping>
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/MemberMetadataTest.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/MemberMetadataTest.php
new file mode 100644
index 0000000..747a36b
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/MemberMetadataTest.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\Validator\Tests\Mapping;
+
+use Symfony\Component\Validator\Tests\Fixtures\ConstraintA;
+use Symfony\Component\Validator\Tests\Fixtures\ConstraintB;
+use Symfony\Component\Validator\Tests\Fixtures\ClassConstraint;
+use Symfony\Component\Validator\Constraints\Valid;
+use Symfony\Component\Validator\Mapping\MemberMetadata;
+
+class MemberMetadataTest extends \PHPUnit_Framework_TestCase
+{
+    protected $metadata;
+
+    protected function setUp()
+    {
+        $this->metadata = new TestMemberMetadata(
+            'Symfony\Component\Validator\Tests\Fixtures\Entity',
+            'getLastName',
+            'lastName'
+        );
+    }
+
+    protected function tearDown()
+    {
+        $this->metadata = null;
+    }
+
+    public function testAddValidSetsMemberToCascaded()
+    {
+        $result = $this->metadata->addConstraint(new Valid());
+
+        $this->assertEquals(array(), $this->metadata->getConstraints());
+        $this->assertEquals($result, $this->metadata);
+        $this->assertTrue($this->metadata->isCascaded());
+    }
+
+    public function testAddOtherConstraintDoesNotSetMemberToCascaded()
+    {
+        $result = $this->metadata->addConstraint($constraint = new ConstraintA());
+
+        $this->assertEquals(array($constraint), $this->metadata->getConstraints());
+        $this->assertEquals($result, $this->metadata);
+        $this->assertFalse($this->metadata->isCascaded());
+    }
+
+    public function testAddConstraintRequiresClassConstraints()
+    {
+        $this->setExpectedException('Symfony\Component\Validator\Exception\ConstraintDefinitionException');
+
+        $this->metadata->addConstraint(new ClassConstraint());
+    }
+
+    public function testSerialize()
+    {
+        $this->metadata->addConstraint(new ConstraintA(array('property1' => 'A')));
+        $this->metadata->addConstraint(new ConstraintB(array('groups' => 'TestGroup')));
+
+        $metadata = unserialize(serialize($this->metadata));
+
+        $this->assertEquals($this->metadata, $metadata);
+    }
+}
+
+class TestMemberMetadata extends MemberMetadata
+{
+    public function getPropertyValue($object)
+    {
+    }
+
+    protected function newReflectionMember()
+    {
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/PropertyMetadataTest.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/PropertyMetadataTest.php
new file mode 100644
index 0000000..0dc1bb6
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/Mapping/PropertyMetadataTest.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\Validator\Tests\Mapping;
+
+use Symfony\Component\Validator\Mapping\PropertyMetadata;
+use Symfony\Component\Validator\Tests\Fixtures\Entity;
+
+class PropertyMetadataTest extends \PHPUnit_Framework_TestCase
+{
+    const CLASSNAME = 'Symfony\Component\Validator\Tests\Fixtures\Entity';
+
+    public function testInvalidPropertyName()
+    {
+        $this->setExpectedException('Symfony\Component\Validator\Exception\ValidatorException');
+
+        new PropertyMetadata(self::CLASSNAME, 'foobar');
+    }
+
+    public function testGetValueFromPrivateProperty()
+    {
+        $entity = new Entity('foobar');
+        $metadata = new PropertyMetadata(self::CLASSNAME, 'internal');
+
+        $this->assertEquals('foobar', $metadata->getValue($entity));
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/ValidationVisitorTest.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/ValidationVisitorTest.php
new file mode 100644
index 0000000..ab35b6f
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/ValidationVisitorTest.php
@@ -0,0 +1,508 @@
+<?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\Validator\Tests;
+
+use Symfony\Component\Validator\Tests\Fixtures\FakeMetadataFactory;
+use Symfony\Component\Validator\Constraints\Valid;
+use Symfony\Component\Validator\Tests\Fixtures\Reference;
+use Symfony\Component\Validator\ConstraintViolation;
+use Symfony\Component\Validator\ConstraintViolationList;
+use Symfony\Component\Validator\Tests\Fixtures\FailingConstraint;
+use Symfony\Component\Validator\Tests\Fixtures\ConstraintAValidator;
+use Symfony\Component\Validator\Tests\Fixtures\Entity;
+use Symfony\Component\Validator\Tests\Fixtures\ConstraintA;
+use Symfony\Component\Validator\Mapping\ClassMetadata;
+use Symfony\Component\Validator\ConstraintValidatorFactory;
+use Symfony\Component\Validator\ValidationVisitor;
+
+/**
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+class ValidationVisitorTest extends \PHPUnit_Framework_TestCase
+{
+    const CLASS_NAME = 'Symfony\Component\Validator\Tests\Fixtures\Entity';
+
+    /**
+     * @var ValidationVisitor
+     */
+    private $visitor;
+
+    /**
+     * @var FakeMetadataFactory
+     */
+    private $metadataFactory;
+
+    /**
+     * @var ClassMetadata
+     */
+    private $metadata;
+
+    protected function setUp()
+    {
+        $this->metadataFactory = new FakeMetadataFactory();
+        $this->visitor = new ValidationVisitor('Root', $this->metadataFactory, new ConstraintValidatorFactory());
+        $this->metadata = new ClassMetadata(self::CLASS_NAME);
+        $this->metadataFactory->addMetadata($this->metadata);
+    }
+
+    protected function tearDown()
+    {
+        $this->metadataFactory = null;
+        $this->visitor = null;
+        $this->metadata = null;
+    }
+
+    public function testValidatePassesCorrectClassAndProperty()
+    {
+        $this->metadata->addConstraint(new ConstraintA());
+
+        $entity = new Entity();
+        $this->visitor->validate($entity, 'Default', '');
+
+        $context = ConstraintAValidator::$passedContext;
+
+        $this->assertEquals('Symfony\Component\Validator\Tests\Fixtures\Entity', $context->getClassName());
+        $this->assertNull($context->getPropertyName());
+    }
+
+    public function testValidateConstraints()
+    {
+        $this->metadata->addConstraint(new ConstraintA());
+
+        $this->visitor->validate(new Entity(), 'Default', '');
+
+        $this->assertCount(1, $this->visitor->getViolations());
+    }
+
+    public function testValidateTwiceValidatesConstraintsOnce()
+    {
+        $this->metadata->addConstraint(new ConstraintA());
+
+        $entity = new Entity();
+
+        $this->visitor->validate($entity, 'Default', '');
+        $this->visitor->validate($entity, 'Default', '');
+
+        $this->assertCount(1, $this->visitor->getViolations());
+    }
+
+    public function testValidateDifferentObjectsValidatesTwice()
+    {
+        $this->metadata->addConstraint(new ConstraintA());
+
+        $this->visitor->validate(new Entity(), 'Default', '');
+        $this->visitor->validate(new Entity(), 'Default', '');
+
+        $this->assertCount(2, $this->visitor->getViolations());
+    }
+
+    public function testValidateTwiceInDifferentGroupsValidatesTwice()
+    {
+        $this->metadata->addConstraint(new ConstraintA());
+        $this->metadata->addConstraint(new ConstraintA(array('groups' => 'Custom')));
+
+        $entity = new Entity();
+
+        $this->visitor->validate($entity, 'Default', '');
+        $this->visitor->validate($entity, 'Custom', '');
+
+        $this->assertCount(2, $this->visitor->getViolations());
+    }
+
+    public function testValidatePropertyConstraints()
+    {
+        $this->metadata->addPropertyConstraint('firstName', new ConstraintA());
+
+        $this->visitor->validate(new Entity(), 'Default', '');
+
+        $this->assertCount(1, $this->visitor->getViolations());
+    }
+
+    public function testValidateGetterConstraints()
+    {
+        $this->metadata->addGetterConstraint('lastName', new ConstraintA());
+
+        $this->visitor->validate(new Entity(), 'Default', '');
+
+        $this->assertCount(1, $this->visitor->getViolations());
+    }
+
+    public function testValidateInDefaultGroupTraversesGroupSequence()
+    {
+        $entity = new Entity();
+
+        $this->metadata->addPropertyConstraint('firstName', new FailingConstraint(array(
+            'groups' => 'First',
+        )));
+        $this->metadata->addGetterConstraint('lastName', new FailingConstraint(array(
+            'groups' => 'Default',
+        )));
+        $this->metadata->setGroupSequence(array('First', $this->metadata->getDefaultGroup()));
+
+        $this->visitor->validate($entity, 'Default', '');
+
+        // After validation of group "First" failed, no more group was
+        // validated
+        $violations = new ConstraintViolationList(array(
+            new ConstraintViolation(
+                'Failed',
+                array(),
+                'Root',
+                'firstName',
+                ''
+            ),
+        ));
+
+        $this->assertEquals($violations, $this->visitor->getViolations());
+    }
+
+    public function testValidateInGroupSequencePropagatesDefaultGroup()
+    {
+        $entity = new Entity();
+        $entity->reference = new Reference();
+
+        $this->metadata->addPropertyConstraint('reference', new Valid());
+        $this->metadata->setGroupSequence(array($this->metadata->getDefaultGroup()));
+
+        $referenceMetadata = new ClassMetadata(get_class($entity->reference));
+        $referenceMetadata->addConstraint(new FailingConstraint(array(
+                // this constraint is only evaluated if group "Default" is
+                // propagated to the reference
+                'groups' => 'Default',
+            )));
+        $this->metadataFactory->addMetadata($referenceMetadata);
+
+        $this->visitor->validate($entity, 'Default', '');
+
+        // The validation of the reference's FailingConstraint in group
+        // "Default" was launched
+        $violations = new ConstraintViolationList(array(
+            new ConstraintViolation(
+                'Failed',
+                array(),
+                'Root',
+                'reference',
+                $entity->reference
+            ),
+        ));
+
+        $this->assertEquals($violations, $this->visitor->getViolations());
+    }
+
+    public function testValidateInOtherGroupTraversesNoGroupSequence()
+    {
+        $entity = new Entity();
+
+        $this->metadata->addPropertyConstraint('firstName', new FailingConstraint(array(
+            'groups' => 'First',
+        )));
+        $this->metadata->addGetterConstraint('lastName', new FailingConstraint(array(
+            'groups' => $this->metadata->getDefaultGroup(),
+        )));
+        $this->metadata->setGroupSequence(array('First', $this->metadata->getDefaultGroup()));
+
+        $this->visitor->validate($entity, $this->metadata->getDefaultGroup(), '');
+
+        // Only group "Second" was validated
+        $violations = new ConstraintViolationList(array(
+            new ConstraintViolation(
+                'Failed',
+                array(),
+                'Root',
+                'lastName',
+                ''
+            ),
+        ));
+
+        $this->assertEquals($violations, $this->visitor->getViolations());
+    }
+
+    public function testValidateCascadedPropertyValidatesReferences()
+    {
+        $entity = new Entity();
+        $entity->reference = new Entity();
+
+        // add a constraint for the entity that always fails
+        $this->metadata->addConstraint(new FailingConstraint());
+
+        // validate entity when validating the property "reference"
+        $this->metadata->addPropertyConstraint('reference', new Valid());
+
+        // invoke validation on an object
+        $this->visitor->validate($entity, 'Default', '');
+
+        $violations = new ConstraintViolationList(array(
+            // generated by the root object
+            new ConstraintViolation(
+                'Failed',
+                array(),
+                'Root',
+                '',
+                $entity
+            ),
+            // generated by the reference
+            new ConstraintViolation(
+                'Failed',
+                array(),
+                'Root',
+                'reference',
+                $entity->reference
+            ),
+        ));
+
+        $this->assertEquals($violations, $this->visitor->getViolations());
+    }
+
+    public function testValidateCascadedPropertyValidatesArraysByDefault()
+    {
+        $entity = new Entity();
+        $entity->reference = array('key' => new Entity());
+
+        // add a constraint for the entity that always fails
+        $this->metadata->addConstraint(new FailingConstraint());
+
+        // validate array when validating the property "reference"
+        $this->metadata->addPropertyConstraint('reference', new Valid());
+
+        $this->visitor->validate($entity, 'Default', '');
+
+        $violations = new ConstraintViolationList(array(
+            // generated by the root object
+            new ConstraintViolation(
+                'Failed',
+                array(),
+                'Root',
+                '',
+                $entity
+            ),
+            // generated by the reference
+            new ConstraintViolation(
+                'Failed',
+                array(),
+                'Root',
+                'reference[key]',
+                $entity->reference['key']
+            ),
+        ));
+
+        $this->assertEquals($violations, $this->visitor->getViolations());
+    }
+
+    public function testValidateCascadedPropertyValidatesTraversableByDefault()
+    {
+        $entity = new Entity();
+        $entity->reference = new \ArrayIterator(array('key' => new Entity()));
+
+        // add a constraint for the entity that always fails
+        $this->metadata->addConstraint(new FailingConstraint());
+
+        // validate array when validating the property "reference"
+        $this->metadata->addPropertyConstraint('reference', new Valid());
+
+        $this->visitor->validate($entity, 'Default', '');
+
+        $violations = new ConstraintViolationList(array(
+            // generated by the root object
+            new ConstraintViolation(
+                'Failed',
+                array(),
+                'Root',
+                '',
+                $entity
+            ),
+            // generated by the reference
+            new ConstraintViolation(
+                'Failed',
+                array(),
+                'Root',
+                'reference[key]',
+                $entity->reference['key']
+            ),
+        ));
+
+        $this->assertEquals($violations, $this->visitor->getViolations());
+    }
+
+    public function testValidateCascadedPropertyDoesNotValidateTraversableIfDisabled()
+    {
+        $entity = new Entity();
+        $entity->reference = new \ArrayIterator(array('key' => new Entity()));
+
+        $this->metadataFactory->addMetadata(new ClassMetadata('ArrayIterator'));
+
+        // add a constraint for the entity that always fails
+        $this->metadata->addConstraint(new FailingConstraint());
+
+        // validate array when validating the property "reference"
+        $this->metadata->addPropertyConstraint('reference', new Valid(array(
+            'traverse' => false,
+        )));
+
+        $this->visitor->validate($entity, 'Default', '');
+
+        $violations = new ConstraintViolationList(array(
+            // generated by the root object
+            new ConstraintViolation(
+                'Failed',
+                array(),
+                'Root',
+                '',
+                $entity
+            ),
+            // nothing generated by the reference!
+        ));
+
+        $this->assertEquals($violations, $this->visitor->getViolations());
+    }
+
+    public function testMetadataMayNotExistIfTraversalIsEnabled()
+    {
+        $entity = new Entity();
+        $entity->reference = new \ArrayIterator();
+
+        $this->metadata->addPropertyConstraint('reference', new Valid(array(
+            'traverse' => true,
+        )));
+
+        $this->visitor->validate($entity, 'Default', '');
+    }
+
+    /**
+     * @expectedException \Symfony\Component\Validator\Exception\NoSuchMetadataException
+     */
+    public function testMetadataMustExistIfTraversalIsDisabled()
+    {
+        $entity = new Entity();
+        $entity->reference = new \ArrayIterator();
+
+        $this->metadata->addPropertyConstraint('reference', new Valid(array(
+            'traverse' => false,
+        )));
+
+        $this->visitor->validate($entity, 'Default', '');
+    }
+
+    public function testValidateCascadedPropertyDoesNotRecurseByDefault()
+    {
+        $entity = new Entity();
+        $entity->reference = new \ArrayIterator(array(
+            // The inner iterator should not be traversed by default
+            'key' => new \ArrayIterator(array(
+                'nested' => new Entity(),
+            )),
+        ));
+
+        $this->metadataFactory->addMetadata(new ClassMetadata('ArrayIterator'));
+
+        // add a constraint for the entity that always fails
+        $this->metadata->addConstraint(new FailingConstraint());
+
+        // validate iterator when validating the property "reference"
+        $this->metadata->addPropertyConstraint('reference', new Valid());
+
+        $this->visitor->validate($entity, 'Default', '');
+
+        $violations = new ConstraintViolationList(array(
+            // generated by the root object
+            new ConstraintViolation(
+                'Failed',
+                array(),
+                'Root',
+                '',
+                $entity
+            ),
+            // nothing generated by the reference!
+        ));
+
+        $this->assertEquals($violations, $this->visitor->getViolations());
+    }
+
+    public function testValidateCascadedPropertyRecursesIfDeepIsSet()
+    {
+        $entity = new Entity();
+        $entity->reference = new \ArrayIterator(array(
+            // The inner iterator should now be traversed
+            'key' => new \ArrayIterator(array(
+                'nested' => new Entity(),
+            )),
+        ));
+
+        // add a constraint for the entity that always fails
+        $this->metadata->addConstraint(new FailingConstraint());
+
+        // validate iterator when validating the property "reference"
+        $this->metadata->addPropertyConstraint('reference', new Valid(array(
+            'deep' => true,
+        )));
+
+        $this->visitor->validate($entity, 'Default', '');
+
+        $violations = new ConstraintViolationList(array(
+            // generated by the root object
+            new ConstraintViolation(
+                'Failed',
+                array(),
+                'Root',
+                '',
+                $entity
+            ),
+            // nothing generated by the reference!
+            new ConstraintViolation(
+                'Failed',
+                array(),
+                'Root',
+                'reference[key][nested]',
+                $entity->reference['key']['nested']
+            ),
+        ));
+
+        $this->assertEquals($violations, $this->visitor->getViolations());
+    }
+
+    public function testValidateCascadedPropertyDoesNotValidateNestedScalarValues()
+    {
+        $entity = new Entity();
+        $entity->reference = array('scalar', 'values');
+
+        // validate array when validating the property "reference"
+        $this->metadata->addPropertyConstraint('reference', new Valid());
+
+        $this->visitor->validate($entity, 'Default', '');
+
+        $this->assertCount(0, $this->visitor->getViolations());
+    }
+
+    public function testValidateCascadedPropertyDoesNotValidateNullValues()
+    {
+        $entity = new Entity();
+        $entity->reference = null;
+
+        $this->metadata->addPropertyConstraint('reference', new Valid());
+
+        $this->visitor->validate($entity, 'Default', '');
+
+        $this->assertCount(0, $this->visitor->getViolations());
+    }
+
+    /**
+     * @expectedException \Symfony\Component\Validator\Exception\NoSuchMetadataException
+     */
+    public function testValidateCascadedPropertyRequiresObjectOrArray()
+    {
+        $entity = new Entity();
+        $entity->reference = 'no object';
+
+        $this->metadata->addPropertyConstraint('reference', new Valid());
+
+        $this->visitor->validate($entity, 'Default', '');
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/ValidatorBuilderTest.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/ValidatorBuilderTest.php
new file mode 100644
index 0000000..d963e4a
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/ValidatorBuilderTest.php
@@ -0,0 +1,110 @@
+<?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\Validator\Tests;
+
+use Symfony\Component\Validator\ValidatorBuilder;
+use Symfony\Component\Validator\ValidatorBuilderInterface;
+
+class ValidatorBuilderTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var ValidatorBuilderInterface
+     */
+    protected $builder;
+
+    protected function setUp()
+    {
+        $this->builder = new ValidatorBuilder();
+    }
+
+    protected function tearDown()
+    {
+        $this->builder = null;
+    }
+
+    public function testAddObjectInitializer()
+    {
+        $this->assertSame($this->builder, $this->builder->addObjectInitializer(
+            $this->getMock('Symfony\Component\Validator\ObjectInitializerInterface')
+        ));
+    }
+
+    public function testAddObjectInitializers()
+    {
+        $this->assertSame($this->builder, $this->builder->addObjectInitializers(array()));
+    }
+
+    public function testAddXmlMapping()
+    {
+        $this->assertSame($this->builder, $this->builder->addXmlMapping('mapping'));
+    }
+
+    public function testAddXmlMappings()
+    {
+        $this->assertSame($this->builder, $this->builder->addXmlMappings(array()));
+    }
+
+    public function testAddYamlMapping()
+    {
+        $this->assertSame($this->builder, $this->builder->addYamlMapping('mapping'));
+    }
+
+    public function testAddYamlMappings()
+    {
+        $this->assertSame($this->builder, $this->builder->addYamlMappings(array()));
+    }
+
+    public function testAddMethodMapping()
+    {
+        $this->assertSame($this->builder, $this->builder->addMethodMapping('mapping'));
+    }
+
+    public function testAddMethodMappings()
+    {
+        $this->assertSame($this->builder, $this->builder->addMethodMappings(array()));
+    }
+
+    public function testEnableAnnotationMapping()
+    {
+        if (!class_exists('Doctrine\Common\Annotations\AnnotationReader')) {
+            $this->markTestSkipped('Annotations is required for this test');
+        }
+
+        $this->assertSame($this->builder, $this->builder->enableAnnotationMapping());
+    }
+
+    public function testDisableAnnotationMapping()
+    {
+        $this->assertSame($this->builder, $this->builder->disableAnnotationMapping());
+    }
+
+    public function testSetMetadataFactory()
+    {
+        $this->assertSame($this->builder, $this->builder->setMetadataFactory(
+            $this->getMock('Symfony\Component\Validator\Mapping\ClassMetadataFactoryInterface'))
+        );
+    }
+
+    public function testSetMetadataCache()
+    {
+        $this->assertSame($this->builder, $this->builder->setMetadataCache($this->getMock(
+            'Symfony\Component\Validator\Mapping\Cache\CacheInterface'))
+        );
+    }
+
+    public function testSetConstraintValidatorFactory()
+    {
+        $this->assertSame($this->builder, $this->builder->setConstraintValidatorFactory(
+            $this->getMock('Symfony\Component\Validator\ConstraintValidatorFactoryInterface'))
+        );
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/ValidatorContextTest.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/ValidatorContextTest.php
new file mode 100644
index 0000000..e10c2da
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/ValidatorContextTest.php
@@ -0,0 +1,62 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Tests;
+
+use Symfony\Component\Validator\Validator;
+use Symfony\Component\Validator\Mapping\ClassMetadataFactoryAdapter;
+use Symfony\Component\Validator\ValidatorContext;
+
+class ValidatorContextTest extends \PHPUnit_Framework_TestCase
+{
+    protected $context;
+
+    protected function setUp()
+    {
+        $this->context = new ValidatorContext();
+    }
+
+    protected function tearDown()
+    {
+        $this->context = null;
+    }
+
+    public function testSetClassMetadataFactory()
+    {
+        $factory = $this->getMock('Symfony\Component\Validator\Mapping\ClassMetadataFactoryInterface');
+        $result = $this->context->setClassMetadataFactory($factory);
+
+        $this->assertSame($this->context, $result);
+        $this->assertSame($factory, $this->context->getClassMetadataFactory());
+    }
+
+    public function testSetConstraintValidatorFactory()
+    {
+        $factory = $this->getMock('Symfony\Component\Validator\ConstraintValidatorFactoryInterface');
+        $result = $this->context->setConstraintValidatorFactory($factory);
+
+        $this->assertSame($this->context, $result);
+        $this->assertSame($factory, $this->context->getConstraintValidatorFactory());
+    }
+
+    public function testGetValidator()
+    {
+        $metadataFactory = $this->getMock('Symfony\Component\Validator\Mapping\ClassMetadataFactoryInterface');
+        $validatorFactory = $this->getMock('Symfony\Component\Validator\ConstraintValidatorFactoryInterface');
+
+        $validator = $this->context
+            ->setClassMetadataFactory($metadataFactory)
+            ->setConstraintValidatorFactory($validatorFactory)
+            ->getValidator();
+
+        $this->assertEquals(new Validator(new ClassMetadataFactoryAdapter($metadataFactory), $validatorFactory), $validator);
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/ValidatorFactoryTest.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/ValidatorFactoryTest.php
new file mode 100644
index 0000000..8ca3758
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/ValidatorFactoryTest.php
@@ -0,0 +1,179 @@
+<?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\Validator\Tests;
+
+use Doctrine\Common\Annotations\AnnotationReader;
+use Symfony\Component\Validator\Mapping\ClassMetadataFactoryAdapter;
+use Symfony\Component\Validator\Validator;
+use Symfony\Component\Validator\ValidatorContext;
+use Symfony\Component\Validator\ValidatorFactory;
+use Symfony\Component\Validator\ConstraintValidatorFactory;
+use Symfony\Component\Validator\Mapping\ClassMetadataFactory;
+use Symfony\Component\Validator\Mapping\Loader\XmlFilesLoader;
+use Symfony\Component\Validator\Mapping\Loader\YamlFilesLoader;
+use Symfony\Component\Validator\Mapping\Loader\AnnotationLoader;
+use Symfony\Component\Validator\Mapping\Loader\StaticMethodLoader;
+use Symfony\Component\Validator\Mapping\Loader\LoaderChain;
+
+class ValidatorFactoryTest extends \PHPUnit_Framework_TestCase
+{
+    protected $defaultContext;
+    protected $factory;
+
+    protected function setUp()
+    {
+        $this->defaultContext = new ValidatorContext();
+        $this->factory = new ValidatorFactory($this->defaultContext);
+    }
+
+    protected function tearDown()
+    {
+        $this->defaultContext = null;
+        $this->factory = null;
+    }
+
+    public function testOverrideClassMetadataFactory()
+    {
+        $factory1 = $this->getMock('Symfony\Component\Validator\Mapping\ClassMetadataFactoryInterface');
+        $factory2 = $this->getMock('Symfony\Component\Validator\Mapping\ClassMetadataFactoryInterface');
+
+        $this->defaultContext->setClassMetadataFactory($factory1);
+
+        $result = $this->factory->setClassMetadataFactory($factory2);
+
+        $this->assertSame($factory1, $this->defaultContext->getClassMetadataFactory());
+        $this->assertSame($factory2, $result->getClassMetadataFactory());
+    }
+
+    public function testOverrideConstraintValidatorFactory()
+    {
+        $factory1 = $this->getMock('Symfony\Component\Validator\ConstraintValidatorFactoryInterface');
+        $factory2 = $this->getMock('Symfony\Component\Validator\ConstraintValidatorFactoryInterface');
+
+        $this->defaultContext->setConstraintValidatorFactory($factory1);
+
+        $result = $this->factory->setConstraintValidatorFactory($factory2);
+
+        $this->assertSame($factory1, $this->defaultContext->getConstraintValidatorFactory());
+        $this->assertSame($factory2, $result->getConstraintValidatorFactory());
+    }
+
+    public function testGetValidator()
+    {
+        $metadataFactory = $this->getMock('Symfony\Component\Validator\Mapping\ClassMetadataFactoryInterface');
+        $validatorFactory = $this->getMock('Symfony\Component\Validator\ConstraintValidatorFactoryInterface');
+
+        $this->defaultContext
+            ->setClassMetadataFactory($metadataFactory)
+            ->setConstraintValidatorFactory($validatorFactory);
+
+        $validator = $this->factory->getValidator();
+
+        $this->assertEquals(new Validator(new ClassMetadataFactoryAdapter($metadataFactory), $validatorFactory), $validator);
+    }
+
+    public function testBuildDefaultFromAnnotationsWithCustomNamespaces()
+    {
+        if (!class_exists('Doctrine\Common\Annotations\AnnotationReader')) {
+            $this->markTestSkipped('Annotations is required for this test');
+        }
+        $factory = ValidatorFactory::buildDefault(array(), true);
+
+        $context = new ValidatorContext();
+        $context
+            ->setClassMetadataFactory(new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader())))
+            ->setConstraintValidatorFactory(new ConstraintValidatorFactory());
+
+        $this->assertEquals(new ValidatorFactory($context), $factory);
+    }
+
+    public function testBuildDefaultFromXml()
+    {
+        $path = __DIR__.'/Mapping/Loader/constraint-mapping.xml';
+        $factory = ValidatorFactory::buildDefault(array($path), false);
+
+        $context = new ValidatorContext();
+        $context
+            ->setClassMetadataFactory(new ClassMetadataFactory(new XmlFilesLoader(array($path))))
+            ->setConstraintValidatorFactory(new ConstraintValidatorFactory());
+
+        $this->assertEquals(new ValidatorFactory($context), $factory);
+    }
+
+    public function testBuildDefaultFromYaml()
+    {
+        $path = __DIR__.'/Mapping/Loader/constraint-mapping.yml';
+        $factory = ValidatorFactory::buildDefault(array($path), false);
+
+        $context = new ValidatorContext();
+        $context
+            ->setClassMetadataFactory(new ClassMetadataFactory(new YamlFilesLoader(array($path))))
+            ->setConstraintValidatorFactory(new ConstraintValidatorFactory());
+
+        $this->assertEquals(new ValidatorFactory($context), $factory);
+    }
+
+    public function testBuildDefaultFromStaticMethod()
+    {
+        $path = __DIR__.'/Mapping/Loader/constraint-mapping.yml';
+        $factory = ValidatorFactory::buildDefault(array(), false, 'loadMetadata');
+
+        $context = new ValidatorContext();
+        $context
+            ->setClassMetadataFactory(new ClassMetadataFactory(new StaticMethodLoader('loadMetadata')))
+            ->setConstraintValidatorFactory(new ConstraintValidatorFactory());
+
+        $this->assertEquals(new ValidatorFactory($context), $factory);
+    }
+
+    public function testBuildDefaultFromMultipleLoaders()
+    {
+        if (!class_exists('Doctrine\Common\Annotations\AnnotationReader')) {
+            $this->markTestSkipped('Annotations is required for this test');
+        }
+        $xmlPath = __DIR__.'/Mapping/Loader/constraint-mapping.xml';
+        $yamlPath = __DIR__.'/Mapping/Loader/constraint-mapping.yml';
+        $factory = ValidatorFactory::buildDefault(array($xmlPath, $yamlPath), true, 'loadMetadata');
+
+        $chain = new LoaderChain(array(
+            new XmlFilesLoader(array($xmlPath)),
+            new YamlFilesLoader(array($yamlPath)),
+            new AnnotationLoader(new AnnotationReader()),
+            new StaticMethodLoader('loadMetadata'),
+        ));
+
+        $context = new ValidatorContext();
+        $context
+            ->setClassMetadataFactory(new ClassMetadataFactory($chain))
+            ->setConstraintValidatorFactory(new ConstraintValidatorFactory());
+
+        $this->assertEquals(new ValidatorFactory($context), $factory);
+    }
+
+    /**
+     * @expectedException Symfony\Component\Validator\Exception\MappingException
+     */
+    public function testBuildDefaultThrowsExceptionIfNoLoaderIsFound()
+    {
+        ValidatorFactory::buildDefault();
+    }
+
+    /**
+     * @expectedException Symfony\Component\Validator\Exception\MappingException
+     */
+    public function testBuildDefaultThrowsExceptionIfUnknownExtension()
+    {
+        ValidatorFactory::buildDefault(array(
+            __DIR__.'/Mapping/Loader/StaticMethodLoaderTest.php'
+        ));
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/ValidatorTest.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/ValidatorTest.php
new file mode 100644
index 0000000..a2fccc6
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Tests/ValidatorTest.php
@@ -0,0 +1,264 @@
+<?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\Validator\Tests;
+
+use Symfony\Component\Validator\Tests\Fixtures\Entity;
+use Symfony\Component\Validator\Tests\Fixtures\GroupSequenceProviderEntity;
+use Symfony\Component\Validator\Tests\Fixtures\FakeMetadataFactory;
+use Symfony\Component\Validator\Tests\Fixtures\FailingConstraint;
+use Symfony\Component\Validator\Validator;
+use Symfony\Component\Validator\ConstraintViolation;
+use Symfony\Component\Validator\ConstraintViolationList;
+use Symfony\Component\Validator\ConstraintValidatorFactory;
+use Symfony\Component\Validator\Constraints\Valid;
+use Symfony\Component\Validator\Mapping\ClassMetadata;
+
+class ValidatorTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var FakeMetadataFactory
+     */
+    private $metadataFactory;
+
+    /**
+     * @var Validator
+     */
+    private $validator;
+
+    protected function setUp()
+    {
+        $this->metadataFactory = new FakeMetadataFactory();
+        $this->validator = new Validator($this->metadataFactory, new ConstraintValidatorFactory());
+    }
+
+    protected function tearDown()
+    {
+        $this->metadataFactory = null;
+        $this->validator = null;
+    }
+
+    public function testValidate_defaultGroup()
+    {
+        $entity = new Entity();
+        $metadata = new ClassMetadata(get_class($entity));
+        $metadata->addPropertyConstraint('firstName', new FailingConstraint());
+        $metadata->addPropertyConstraint('lastName', new FailingConstraint(array(
+            'groups' => 'Custom',
+        )));
+        $this->metadataFactory->addMetadata($metadata);
+
+        // Only the constraint of group "Default" failed
+        $violations = new ConstraintViolationList();
+        $violations->add(new ConstraintViolation(
+            'Failed',
+            array(),
+            $entity,
+            'firstName',
+            ''
+        ));
+
+        $this->assertEquals($violations, $this->validator->validate($entity));
+    }
+
+    public function testValidate_oneGroup()
+    {
+        $entity = new Entity();
+        $metadata = new ClassMetadata(get_class($entity));
+        $metadata->addPropertyConstraint('firstName', new FailingConstraint());
+        $metadata->addPropertyConstraint('lastName', new FailingConstraint(array(
+            'groups' => 'Custom',
+        )));
+        $this->metadataFactory->addMetadata($metadata);
+
+        // Only the constraint of group "Custom" failed
+        $violations = new ConstraintViolationList();
+        $violations->add(new ConstraintViolation(
+            'Failed',
+            array(),
+            $entity,
+            'lastName',
+            ''
+        ));
+
+        $this->assertEquals($violations, $this->validator->validate($entity, 'Custom'));
+    }
+
+    public function testValidate_multipleGroups()
+    {
+        $entity = new Entity();
+        $metadata = new ClassMetadata(get_class($entity));
+        $metadata->addPropertyConstraint('firstName', new FailingConstraint(array(
+            'groups' => 'First',
+        )));
+        $metadata->addPropertyConstraint('lastName', new FailingConstraint(array(
+            'groups' => 'Second',
+        )));
+        $this->metadataFactory->addMetadata($metadata);
+
+        // The constraints of both groups failed
+        $violations = new ConstraintViolationList();
+        $violations->add(new ConstraintViolation(
+            'Failed',
+            array(),
+            $entity,
+            'firstName',
+            ''
+        ));
+        $violations->add(new ConstraintViolation(
+            'Failed',
+            array(),
+            $entity,
+            'lastName',
+            ''
+        ));
+
+        $result = $this->validator->validate($entity, array('First', 'Second'));
+
+        $this->assertEquals($violations, $result);
+    }
+
+    public function testValidate_groupSequenceProvider()
+    {
+        $entity = new GroupSequenceProviderEntity();
+        $metadata = new ClassMetadata(get_class($entity));
+        $metadata->addPropertyConstraint('firstName', new FailingConstraint(array(
+            'groups' => 'First',
+        )));
+        $metadata->addPropertyConstraint('lastName', new FailingConstraint(array(
+            'groups' => 'Second',
+        )));
+        $metadata->setGroupSequenceProvider(true);
+        $this->metadataFactory->addMetadata($metadata);
+
+        $violations = new ConstraintViolationList();
+        $violations->add(new ConstraintViolation(
+            'Failed',
+            array(),
+            $entity,
+            'firstName',
+            ''
+        ));
+
+        $entity->setGroups(array('First'));
+        $result = $this->validator->validate($entity);
+        $this->assertEquals($violations, $result);
+
+        $violations = new ConstraintViolationList();
+        $violations->add(new ConstraintViolation(
+            'Failed',
+            array(),
+            $entity,
+            'lastName',
+            ''
+        ));
+
+        $entity->setGroups(array('Second'));
+        $result = $this->validator->validate($entity);
+        $this->assertEquals($violations, $result);
+
+        $entity->setGroups(array());
+        $result = $this->validator->validate($entity);
+        $this->assertEquals(new ConstraintViolationList(), $result);
+    }
+
+    public function testValidateProperty()
+    {
+        $entity = new Entity();
+        $metadata = new ClassMetadata(get_class($entity));
+        $metadata->addPropertyConstraint('firstName', new FailingConstraint());
+        $this->metadataFactory->addMetadata($metadata);
+
+        $result = $this->validator->validateProperty($entity, 'firstName');
+
+        $this->assertCount(1, $result);
+    }
+
+    public function testValidatePropertyValue()
+    {
+        $entity = new Entity();
+        $metadata = new ClassMetadata(get_class($entity));
+        $metadata->addPropertyConstraint('firstName', new FailingConstraint());
+        $this->metadataFactory->addMetadata($metadata);
+
+        $result = $this->validator->validatePropertyValue(get_class($entity), 'firstName', 'Bernhard');
+
+        $this->assertCount(1, $result);
+    }
+
+    public function testValidateValue()
+    {
+        $violations = new ConstraintViolationList();
+        $violations->add(new ConstraintViolation(
+            'Failed',
+            array(),
+            '',
+            '',
+            'Bernhard'
+        ));
+
+        $this->assertEquals($violations, $this->validator->validateValue('Bernhard', new FailingConstraint()));
+    }
+
+    /**
+     * @expectedException \Symfony\Component\Validator\Exception\ValidatorException
+     */
+    public function testValidateValueRejectsValid()
+    {
+        $entity = new Entity();
+        $metadata = new ClassMetadata(get_class($entity));
+        $this->metadataFactory->addMetadata($metadata);
+
+        $this->validator->validateValue($entity, new Valid());
+    }
+
+    /**
+     * @expectedException \Symfony\Component\Validator\Exception\ValidatorException
+     */
+    public function testValidatePropertyFailsIfPropertiesNotSupported()
+    {
+        // $metadata does not implement PropertyMetadataContainerInterface
+        $metadata = $this->getMock('Symfony\Component\Validator\MetadataInterface');
+        $this->metadataFactory = $this->getMock('Symfony\Component\Validator\MetadataFactoryInterface');
+        $this->metadataFactory->expects($this->any())
+            ->method('getMetadataFor')
+            ->with('VALUE')
+            ->will($this->returnValue($metadata));
+        $this->validator = new Validator($this->metadataFactory, new ConstraintValidatorFactory());
+
+        $this->validator->validateProperty('VALUE', 'someProperty');
+    }
+
+    /**
+     * @expectedException \Symfony\Component\Validator\Exception\ValidatorException
+     */
+    public function testValidatePropertyValueFailsIfPropertiesNotSupported()
+    {
+        // $metadata does not implement PropertyMetadataContainerInterface
+        $metadata = $this->getMock('Symfony\Component\Validator\MetadataInterface');
+        $this->metadataFactory = $this->getMock('Symfony\Component\Validator\MetadataFactoryInterface');
+        $this->metadataFactory->expects($this->any())
+            ->method('getMetadataFor')
+            ->with('VALUE')
+            ->will($this->returnValue($metadata));
+        $this->validator = new Validator($this->metadataFactory, new ConstraintValidatorFactory());
+
+        $this->validator->validatePropertyValue('VALUE', 'someProperty', 'propertyValue');
+    }
+
+    public function testGetMetadataFactory()
+    {
+        $this->assertInstanceOf(
+            'Symfony\Component\Validator\MetadataFactoryInterface',
+            $this->validator->getMetadataFactory()
+        );
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Validation.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Validation.php
new file mode 100644
index 0000000..de77e83
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Validation.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\Validator;
+
+/**
+ * Entry point for the Validator component.
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+final class Validation
+{
+    /**
+     * Creates a new validator.
+     *
+     * If you want to configure the validator, use
+     * {@link createValidatorBuilder()} instead.
+     *
+     * @return ValidatorInterface The new validator.
+     */
+    public static function createValidator()
+    {
+        return self::createValidatorBuilder()->getValidator();
+    }
+
+    /**
+     * Creates a configurable builder for validator objects.
+     *
+     * @return ValidatorBuilderInterface The new builder.
+     */
+    public static function createValidatorBuilder()
+    {
+        return new ValidatorBuilder();
+    }
+
+    /**
+     * This class cannot be instantiated.
+     */
+    private function __construct()
+    {
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/ValidationVisitor.php b/core/vendor/symfony/validator/Symfony/Component/Validator/ValidationVisitor.php
new file mode 100644
index 0000000..c826830
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/ValidationVisitor.php
@@ -0,0 +1,204 @@
+<?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\Validator;
+
+use Symfony\Component\Validator\Exception\NoSuchMetadataException;
+use Symfony\Component\Validator\Exception\UnexpectedTypeException;
+
+/**
+ * Default implementation of {@link ValidationVisitorInterface} and
+ * {@link GlobalExecutionContextInterface}.
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+class ValidationVisitor implements ValidationVisitorInterface, GlobalExecutionContextInterface
+{
+    /**
+     * @var mixed
+     */
+    private $root;
+
+    /**
+     * @var MetadataFactoryInterface
+     */
+    private $metadataFactory;
+
+    /**
+     * @var ConstraintValidatorFactoryInterface
+     */
+    private $validatorFactory;
+
+    /**
+     * @var array
+     */
+    private $objectInitializers;
+
+    /**
+     * @var ConstraintViolationList
+     */
+    private $violations;
+
+    /**
+     * @var array
+     */
+    private $validatedObjects = array();
+
+    /**
+     * @var GraphWalker
+     *
+     * @deprecated Deprecated since version 2.2, to be removed in 2.3.
+     */
+    private $graphWalker;
+
+    /**
+     * Creates a new validation visitor.
+     *
+     * @param mixed                               $root               The value passed to the validator.
+     * @param MetadataFactoryInterface            $metadataFactory    The factory for obtaining metadata instances.
+     * @param ConstraintValidatorFactoryInterface $validatorFactory   The factory for creating constraint validators.
+     * @param ObjectInitializerInterface[]        $objectInitializers The initializers for preparing objects before validation.
+     *
+     * @throws UnexpectedTypeException If any of the object initializers is not an instance of ObjectInitializerInterface
+     */
+    public function __construct($root, MetadataFactoryInterface $metadataFactory, ConstraintValidatorFactoryInterface $validatorFactory, array $objectInitializers = array())
+    {
+        foreach ($objectInitializers as $initializer) {
+            if (!$initializer instanceof ObjectInitializerInterface) {
+                throw new UnexpectedTypeException($initializer, 'Symfony\Component\Validator\ObjectInitializerInterface');
+            }
+        }
+
+        $this->root = $root;
+        $this->metadataFactory = $metadataFactory;
+        $this->validatorFactory = $validatorFactory;
+        $this->objectInitializers = $objectInitializers;
+        $this->violations = new ConstraintViolationList();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function visit(MetadataInterface $metadata, $value, $group, $propertyPath)
+    {
+        $context = new ExecutionContext(
+            $this,
+            $metadata,
+            $value,
+            $group,
+            $propertyPath
+        );
+
+        $context->validateValue($value, $metadata->findConstraints($group));
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function validate($value, $group, $propertyPath, $traverse = false, $deep = false)
+    {
+        if (null === $value) {
+            return;
+        }
+
+        if (is_object($value)) {
+            $hash = spl_object_hash($value);
+
+            // Exit, if the object is already validated for the current group
+            if (isset($this->validatedObjects[$hash][$group])) {
+                return;
+            }
+
+            // Remember validating this object before starting and possibly
+            // traversing the object graph
+            $this->validatedObjects[$hash][$group] = true;
+
+            foreach ($this->objectInitializers as $initializer) {
+                if (!$initializer instanceof ObjectInitializerInterface) {
+                    throw new \LogicException('Validator initializers must implement ObjectInitializerInterface.');
+                }
+                $initializer->initialize($value);
+            }
+        }
+
+        if ($traverse && (is_array($value) || $value instanceof \Traversable)) {
+            foreach ($value as $key => $element) {
+                // Ignore any scalar values in the collection
+                if (is_object($element) || is_array($element)) {
+                    // Only repeat the traversal if $deep is set
+                    $this->validate($element, $group, $propertyPath.'['.$key.']', $deep, $deep);
+                }
+            }
+
+            try {
+                $this->metadataFactory->getMetadataFor($value)->accept($this, $value, $group, $propertyPath);
+            } catch (NoSuchMetadataException $e) {
+                // Metadata doesn't necessarily have to exist for
+                // traversable objects, because we know how to validate
+                // them anyway. Optionally, additional metadata is supported.
+            }
+        } else {
+            $this->metadataFactory->getMetadataFor($value)->accept($this, $value, $group, $propertyPath);
+        }
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getGraphWalker()
+    {
+        if (null === $this->graphWalker) {
+            $this->graphWalker = new GraphWalker($this, $this->metadataFactory, $this->validatedObjects);
+        }
+
+        return $this->graphWalker;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getViolations()
+    {
+        return $this->violations;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getRoot()
+    {
+        return $this->root;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getVisitor()
+    {
+        return $this;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getValidatorFactory()
+    {
+        return $this->validatorFactory;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getMetadataFactory()
+    {
+        return $this->metadataFactory;
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/ValidationVisitorInterface.php b/core/vendor/symfony/validator/Symfony/Component/Validator/ValidationVisitorInterface.php
new file mode 100644
index 0000000..fb1022f
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/ValidationVisitorInterface.php
@@ -0,0 +1,90 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator;
+
+/**
+ * Validates values against constraints defined in {@link MetadataInterface}
+ * instances.
+ *
+ * This interface is an implementation of the Visitor design pattern. A value
+ * is validated by first passing it to the {@link validate} method. That method
+ * will determine the matching {@link MetadataInterface} for validating the
+ * value. It then calls the {@link MetadataInterface::accept} method of that
+ * metadata. <tt>accept()</tt> does two things:
+ *
+ * <ol>
+ * <li>It calls {@link visit} to validate the value against the constraints of
+ * the metadata.</li>
+ * <li>It calls <tt>accept()</tt> on all nested metadata instances with the
+ * corresponding values extracted from the current value. For example, if the
+ * current metadata represents a class and the current value is an object of
+ * that class, the metadata contains nested instances for each property of that
+ * class. It forwards the call to these nested metadata with the values of the
+ * corresponding properties in the original object.</li>
+ * </ol>
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+interface ValidationVisitorInterface
+{
+    /**
+     * Validates a value.
+     *
+     * If the value is an array or a traversable object, you can set the
+     * parameter <tt>$traverse</tt> to <tt>true</tt> in order to run through
+     * the collection and validate each element. If these elements can be
+     * collections again and you want to traverse them recursively, set the
+     * parameter <tt>$deep</tt> to <tt>true</tt> as well.
+     *
+     * If you set <tt>$traversable</tt> to <tt>true</tt>, the visitor will
+     * nevertheless try to find metadata for the collection and validate its
+     * constraints. If no such metadata is found, the visitor ignores that and
+     * only iterates the collection.
+     *
+     * If you don't set <tt>$traversable</tt> to <tt>true</tt> and the visitor
+     * does not find metadata for the given value, it will fail with an
+     * exception.
+     *
+     * @param mixed   $value        The value to validate.
+     * @param string  $group        The validation group to validate.
+     * @param string  $propertyPath The current property path in the validation graph.
+     * @param Boolean $traverse     Whether to traverse the value if it is traversable.
+     * @param Boolean $deep         Whether to traverse nested traversable values recursively.
+     *
+     * @throws Exception\NoSuchMetadataException If no metadata can be found for
+     *                                           the given value.
+     */
+    public function validate($value, $group, $propertyPath, $traverse = false, $deep = false);
+
+    /**
+     * Validates a value against the constraints defined in some metadata.
+     *
+     * This method implements the Visitor design pattern. See also
+     * {@link ValidationVisitorInterface}.
+     *
+     * @param MetadataInterface $metadata     The metadata holding the constraints.
+     * @param mixed             $value        The value to validate.
+     * @param string            $group        The validation group to validate.
+     * @param string            $propertyPath The current property path in the validation graph.
+     */
+    public function visit(MetadataInterface $metadata, $value, $group, $propertyPath);
+
+    /**
+     * Returns a graph walker with an alternative, deprecated API of the
+     * visitor.
+     *
+     * @return GraphWalker The graph walker.
+     *
+     * @deprecated Deprecated since version 2.2, to be removed in 2.3.
+     */
+    public function getGraphWalker();
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/Validator.php b/core/vendor/symfony/validator/Symfony/Component/Validator/Validator.php
new file mode 100644
index 0000000..848dc4e
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/Validator.php
@@ -0,0 +1,191 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator;
+
+use Symfony\Component\Validator\Constraints\Valid;
+use Symfony\Component\Validator\Exception\ValidatorException;
+
+/**
+ * Default implementation of {@link ValidatorInterface}.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+class Validator implements ValidatorInterface
+{
+    /**
+     * @var MetadataFactoryInterface
+     */
+    private $metadataFactory;
+
+    /**
+     * @var ConstraintValidatorFactoryInterface
+     */
+    private $validatorFactory;
+
+    /**
+     * @var array
+     */
+    private $objectInitializers;
+
+    public function __construct(
+        MetadataFactoryInterface $metadataFactory,
+        ConstraintValidatorFactoryInterface $validatorFactory,
+        array $objectInitializers = array()
+    )
+    {
+        $this->metadataFactory = $metadataFactory;
+        $this->validatorFactory = $validatorFactory;
+        $this->objectInitializers = $objectInitializers;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getMetadataFactory()
+    {
+        return $this->metadataFactory;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function getMetadataFor($value)
+    {
+        return $this->metadataFactory->getMetadataFor($value);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function validate($value, $groups = null, $traverse = false, $deep = false)
+    {
+        $visitor = $this->createVisitor($value);
+
+        foreach ($this->resolveGroups($groups) as $group) {
+            $visitor->validate($value, $group, '');
+        }
+
+        return $visitor->getViolations();
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @throws ValidatorException If the metadata for the value does not support properties.
+     */
+    public function validateProperty($containingValue, $property, $groups = null)
+    {
+        $visitor = $this->createVisitor($containingValue);
+        $metadata = $this->metadataFactory->getMetadataFor($containingValue);
+
+        if (!$metadata instanceof PropertyMetadataContainerInterface) {
+            $valueAsString = is_scalar($containingValue)
+                ? '"' . $containingValue . '"'
+                : 'the value of type ' . gettype($containingValue);
+
+            throw new ValidatorException(sprintf('The metadata for ' . $valueAsString . ' does not support properties.'));
+        }
+
+        foreach ($this->resolveGroups($groups) as $group) {
+            foreach ($metadata->getPropertyMetadata($property) as $propMeta) {
+                $propMeta->accept($visitor, $propMeta->getPropertyValue($containingValue), $group, $property);
+            }
+        }
+
+        return $visitor->getViolations();
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @throws ValidatorException If the metadata for the value does not support properties.
+     */
+    public function validatePropertyValue($containingValue, $property, $value, $groups = null)
+    {
+        $visitor = $this->createVisitor($containingValue);
+        $metadata = $this->metadataFactory->getMetadataFor($containingValue);
+
+        if (!$metadata instanceof PropertyMetadataContainerInterface) {
+            $valueAsString = is_scalar($containingValue)
+                ? '"' . $containingValue . '"'
+                : 'the value of type ' . gettype($containingValue);
+
+            throw new ValidatorException(sprintf('The metadata for ' . $valueAsString . ' does not support properties.'));
+        }
+
+        foreach ($this->resolveGroups($groups) as $group) {
+            foreach ($metadata->getPropertyMetadata($property) as $propMeta) {
+                $propMeta->accept($visitor, $value, $group, $property);
+            }
+        }
+
+        return $visitor->getViolations();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public function validateValue($value, $constraints, $groups = null)
+    {
+        $context = new ExecutionContext($this->createVisitor(null));
+
+        $constraints = is_array($constraints) ? $constraints : array($constraints);
+
+        foreach ($constraints as $constraint) {
+            if ($constraint instanceof Valid) {
+                // Why can't the Valid constraint be executed directly?
+                //
+                // It cannot be executed like regular other constraints, because regular
+                // constraints are only executed *if they belong to the validated group*.
+                // The Valid constraint, on the other hand, is always executed and propagates
+                // the group to the cascaded object. The propagated group depends on
+                //
+                //  * Whether a group sequence is currently being executed. Then the default
+                //    group is propagated.
+                //
+                //  * Otherwise the validated group is propagated.
+
+                throw new ValidatorException(
+                    sprintf(
+                        'The constraint %s cannot be validated. Use the method validate() instead.',
+                        get_class($constraint)
+                    )
+                );
+            }
+
+            $context->validateValue($value, $constraint, $groups);
+        }
+
+        return $context->getViolations();
+    }
+
+    /**
+     * @param mixed $root
+     *
+     * @return ValidationVisitor
+     */
+    private function createVisitor($root)
+    {
+        return new ValidationVisitor($root, $this->metadataFactory, $this->validatorFactory, $this->objectInitializers);
+    }
+
+    /**
+     * @param null|string|string[] $groups
+     *
+     * @return string[]
+     */
+    private function resolveGroups($groups)
+    {
+        return $groups ? (array) $groups : array(Constraint::DEFAULT_GROUP);
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/ValidatorBuilder.php b/core/vendor/symfony/validator/Symfony/Component/Validator/ValidatorBuilder.php
new file mode 100644
index 0000000..8f39d4a
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/ValidatorBuilder.php
@@ -0,0 +1,302 @@
+<?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\Validator;
+
+use Symfony\Component\Validator\Mapping\ClassMetadataFactory;
+use Symfony\Component\Validator\Mapping\ClassMetadataFactoryAdapter;
+use Symfony\Component\Validator\Exception\ValidatorException;
+use Symfony\Component\Validator\Mapping\Loader\LoaderChain;
+use Symfony\Component\Validator\Mapping\ClassMetadataFactoryInterface;
+use Symfony\Component\Validator\Mapping\Cache\CacheInterface;
+use Symfony\Component\Validator\Mapping\Loader\StaticMethodLoader;
+use Symfony\Component\Validator\Mapping\Loader\YamlFileLoader;
+use Symfony\Component\Validator\Mapping\Loader\AnnotationLoader;
+use Symfony\Component\Validator\Mapping\Loader\YamlFilesLoader;
+use Symfony\Component\Validator\Mapping\Loader\XmlFileLoader;
+use Symfony\Component\Validator\Mapping\Loader\XmlFilesLoader;
+use Doctrine\Common\Annotations\Reader;
+use Doctrine\Common\Annotations\AnnotationReader;
+use Doctrine\Common\Annotations\CachedReader;
+use Doctrine\Common\Cache\ArrayCache;
+
+/**
+ * The default implementation of {@link ValidatorBuilderInterface}.
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+class ValidatorBuilder implements ValidatorBuilderInterface
+{
+    /**
+     * @var array
+     */
+    private $initializers = array();
+
+    /**
+     * @var array
+     */
+    private $xmlMappings = array();
+
+    /**
+     * @var array
+     */
+    private $yamlMappings = array();
+
+    /**
+     * @var array
+     */
+    private $methodMappings = array();
+
+    /**
+     * @var Reader
+     */
+    private $annotationReader = null;
+
+    /**
+     * @var MetadataFactoryInterface
+     */
+    private $metadataFactory;
+
+    /**
+     * @var ConstraintValidatorFactoryInterface
+     */
+    private $validatorFactory;
+
+    /**
+     * @var CacheInterface
+     */
+    private $metadataCache;
+
+    /**
+     * {@inheritdoc}
+     */
+    public function addObjectInitializer(ObjectInitializerInterface $initializer)
+    {
+        $this->initializers[] = $initializer;
+
+        return $this;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function addObjectInitializers(array $initializers)
+    {
+        $this->initializers = array_merge($this->initializers, $initializers);
+
+        return $this;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function addXmlMapping($path)
+    {
+        if (null !== $this->metadataFactory) {
+            throw new ValidatorException('You cannot add custom mappings after setting a custom metadata factory. Configure your metadata factory instead.');
+        }
+
+        $this->xmlMappings[] = $path;
+
+        return $this;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function addXmlMappings(array $paths)
+    {
+        if (null !== $this->metadataFactory) {
+            throw new ValidatorException('You cannot add custom mappings after setting a custom metadata factory. Configure your metadata factory instead.');
+        }
+
+        $this->xmlMappings = array_merge($this->xmlMappings, $paths);
+
+        return $this;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function addYamlMapping($path)
+    {
+        if (null !== $this->metadataFactory) {
+            throw new ValidatorException('You cannot add custom mappings after setting a custom metadata factory. Configure your metadata factory instead.');
+        }
+
+        $this->yamlMappings[] = $path;
+
+        return $this;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function addYamlMappings(array $paths)
+    {
+        if (null !== $this->metadataFactory) {
+            throw new ValidatorException('You cannot add custom mappings after setting a custom metadata factory. Configure your metadata factory instead.');
+        }
+
+        $this->yamlMappings = array_merge($this->yamlMappings, $paths);
+
+        return $this;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function addMethodMapping($methodName)
+    {
+        if (null !== $this->metadataFactory) {
+            throw new ValidatorException('You cannot add custom mappings after setting a custom metadata factory. Configure your metadata factory instead.');
+        }
+
+        $this->methodMappings[] = $methodName;
+
+        return $this;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function addMethodMappings(array $methodNames)
+    {
+        if (null !== $this->metadataFactory) {
+            throw new ValidatorException('You cannot add custom mappings after setting a custom metadata factory. Configure your metadata factory instead.');
+        }
+
+        $this->methodMappings = array_merge($this->methodMappings, $methodNames);
+
+        return $this;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function enableAnnotationMapping(Reader $annotationReader = null)
+    {
+        if (null !== $this->metadataFactory) {
+            throw new ValidatorException('You cannot enable annotation mapping after setting a custom metadata factory. Configure your metadata factory instead.');
+        }
+
+        if (null === $annotationReader) {
+            if (!class_exists('Doctrine\Common\Annotations\AnnotationReader')) {
+                throw new \RuntimeException('Requested a ValidatorFactory with an AnnotationLoader, but the AnnotationReader was not found. You should add Doctrine Common to your project.');
+            }
+
+            $annotationReader = new CachedReader(new AnnotationReader(), new ArrayCache());
+        }
+
+        $this->annotationReader = $annotationReader;
+
+        return $this;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function disableAnnotationMapping()
+    {
+        $this->annotationReader = null;
+
+        return $this;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function setMetadataFactory($metadataFactory)
+    {
+        if (count($this->xmlMappings) > 0 || count($this->yamlMappings) > 0 || count($this->methodMappings) > 0 || null !== $this->annotationReader) {
+            throw new ValidatorException('You cannot set a custom metadata factory after adding custom mappings. You should do either of both.');
+        }
+
+        if ($metadataFactory instanceof ClassMetadataFactoryInterface
+                && !$metadataFactory instanceof MetadataFactoryInterface) {
+            $metadataFactory = new ClassMetadataFactoryAdapter($metadataFactory);
+        }
+
+        $this->metadataFactory = $metadataFactory;
+
+        return $this;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function setMetadataCache(CacheInterface $cache)
+    {
+        if (null !== $this->metadataFactory) {
+            throw new ValidatorException('You cannot set a custom metadata cache after setting a custom metadata factory. Configure your metadata factory instead.');
+        }
+
+        $this->metadataCache = $cache;
+
+        return $this;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function setConstraintValidatorFactory(ConstraintValidatorFactoryInterface $validatorFactory)
+    {
+        $this->validatorFactory = $validatorFactory;
+
+        return $this;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getValidator()
+    {
+        $metadataFactory = $this->metadataFactory;
+
+        if (!$metadataFactory) {
+            $loaders = array();
+
+            if (count($this->xmlMappings) > 1) {
+                $loaders[] = new XmlFilesLoader($this->xmlMappings);
+            } elseif (1 === count($this->xmlMappings)) {
+                $loaders[] = new XmlFileLoader($this->xmlMappings[0]);
+            }
+
+            if (count($this->yamlMappings) > 1) {
+                $loaders[] = new YamlFilesLoader($this->yamlMappings);
+            } elseif (1 === count($this->yamlMappings)) {
+                $loaders[] = new YamlFileLoader($this->yamlMappings[0]);
+            }
+
+            foreach ($this->methodMappings as $methodName) {
+                $loaders[] = new StaticMethodLoader($methodName);
+            }
+
+            if ($this->annotationReader) {
+                $loaders[] = new AnnotationLoader($this->annotationReader);
+            }
+
+            $loader = null;
+
+            if (count($loaders) > 1) {
+                $loader = new LoaderChain($loaders);
+            } elseif (1 === count($loaders)) {
+                $loader = $loaders[0];
+            }
+
+            $metadataFactory = new ClassMetadataFactory($loader, $this->metadataCache);
+        }
+
+        $validatorFactory = $this->validatorFactory ?: new ConstraintValidatorFactory();
+
+        return new Validator($metadataFactory, $validatorFactory, $this->initializers);
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/ValidatorBuilderInterface.php b/core/vendor/symfony/validator/Symfony/Component/Validator/ValidatorBuilderInterface.php
new file mode 100644
index 0000000..914d4f9
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/ValidatorBuilderInterface.php
@@ -0,0 +1,148 @@
+<?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\Validator;
+
+use Symfony\Component\Validator\Mapping\Cache\CacheInterface;
+use Doctrine\Common\Annotations\Reader;
+
+/**
+ * A configurable builder for ValidatorInterface objects.
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+interface ValidatorBuilderInterface
+{
+    /**
+     * Adds an object initializer to the validator.
+     *
+     * @param ObjectInitializerInterface $initializer The initializer.
+     *
+     * @return ValidatorBuilderInterface The builder object.
+     */
+    public function addObjectInitializer(ObjectInitializerInterface $initializer);
+
+    /**
+     * Adds a list of object initializers to the validator.
+     *
+     * @param array $initializers The initializer.
+     *
+     * @return ValidatorBuilderInterface The builder object.
+     */
+    public function addObjectInitializers(array $initializers);
+
+    /**
+     * Adds an XML constraint mapping file to the validator.
+     *
+     * @param string $path The path to the mapping file.
+     *
+     * @return ValidatorBuilderInterface The builder object.
+     */
+    public function addXmlMapping($path);
+
+    /**
+     * Adds a list of XML constraint mapping files to the validator.
+     *
+     * @param array $paths The paths to the mapping files.
+     *
+     * @return ValidatorBuilderInterface The builder object.
+     */
+    public function addXmlMappings(array $paths);
+
+    /**
+     * Adds a YAML constraint mapping file to the validator.
+     *
+     * @param string $path The path to the mapping file.
+     *
+     * @return ValidatorBuilderInterface The builder object.
+     */
+    public function addYamlMapping($path);
+
+    /**
+     * Adds a list of YAML constraint mappings file to the validator.
+     *
+     * @param array $paths The paths to the mapping files.
+     *
+     * @return ValidatorBuilderInterface The builder object.
+     */
+    public function addYamlMappings(array $paths);
+
+    /**
+     * Enables constraint mapping using the given static method.
+     *
+     * @param string $methodName The name of the method.
+     *
+     * @return ValidatorBuilderInterface The builder object.
+     */
+    public function addMethodMapping($methodName);
+
+    /**
+     * Enables constraint mapping using the given static methods.
+     *
+     * @param array $methodNames The names of the methods.
+     *
+     * @return ValidatorBuilderInterface The builder object.
+     */
+    public function addMethodMappings(array $methodNames);
+
+    /**
+     * Enables annotation based constraint mapping.
+     *
+     * @param Reader $annotationReader The annotation reader to be used.
+     *
+     * @return ValidatorBuilderInterface The builder object.
+     */
+    public function enableAnnotationMapping(Reader $annotationReader = null);
+
+    /**
+     * Disables annotation based constraint mapping.
+     *
+     * @return ValidatorBuilderInterface The builder object.
+     */
+    public function disableAnnotationMapping();
+
+    /**
+     * Sets the class metadata factory used by the validator.
+     *
+     * As of Symfony 2.3, the first parameter of this method will be typed
+     * against {@link MetadataFactoryInterface}.
+     *
+     * @param MetadataFactoryInterface|Mapping\ClassMetadataFactoryInterface $metadataFactory The metadata factory.
+     *
+     * @return ValidatorBuilderInterface The builder object.
+     */
+    public function setMetadataFactory($metadataFactory);
+
+    /**
+     * Sets the cache for caching class metadata.
+     *
+     * @param CacheInterface $cache The cache instance.
+     *
+     * @return ValidatorBuilderInterface The builder object.
+     */
+    public function setMetadataCache(CacheInterface $cache);
+
+    /**
+     * Sets the constraint validator factory used by the validator.
+     *
+     * @param ConstraintValidatorFactoryInterface $validatorFactory The validator factory.
+     *
+     * @return ValidatorBuilderInterface The builder object.
+     */
+    public function setConstraintValidatorFactory(ConstraintValidatorFactoryInterface $validatorFactory);
+
+    /**
+     * Builds and returns a new validator object.
+     *
+     * @return ValidatorInterface The built validator.
+     */
+    public function getValidator();
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/ValidatorContext.php b/core/vendor/symfony/validator/Symfony/Component/Validator/ValidatorContext.php
new file mode 100644
index 0000000..c2f6880
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/ValidatorContext.php
@@ -0,0 +1,113 @@
+<?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\Validator;
+
+use Symfony\Component\Validator\Mapping\ClassMetadataFactoryInterface;
+use Symfony\Component\Validator\Mapping\ClassMetadataFactoryAdapter;
+
+/**
+ * Default implementation of ValidatorContextInterface
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @deprecated Deprecated since version 2.1, to be removed in 2.3. Use
+ *             {@link Validation::createValidatorBuilder()} instead.
+ */
+class ValidatorContext implements ValidatorContextInterface
+{
+    /**
+     * @var MetadataFactoryInterface
+     */
+    private $metadataFactory;
+
+    /**
+     * The class metadata factory used in the new validator
+     * @var ClassMetadataFactoryInterface
+     */
+    protected $classMetadataFactory = null;
+
+    /**
+     * The constraint validator factory used in the new validator
+     * @var ConstraintValidatorFactoryInterface
+     */
+    protected $constraintValidatorFactory = null;
+
+    /**
+     * {@inheritDoc}
+     *
+     * @deprecated Deprecated since version 2.1, to be removed in 2.3. Use
+     *             {@link Validation::createValidatorBuilder()} instead.
+     */
+    public function setClassMetadataFactory(ClassMetadataFactoryInterface $classMetadataFactory)
+    {
+        if ($classMetadataFactory instanceof MetadataFactoryInterface) {
+            $this->metadataFactory = $classMetadataFactory;
+        } else {
+            $this->metadataFactory = new ClassMetadataFactoryAdapter($classMetadataFactory);
+        }
+
+        $this->classMetadataFactory = $classMetadataFactory;
+
+        return $this;
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @deprecated Deprecated since version 2.1, to be removed in 2.3. Use
+     *             {@link Validation::createValidatorBuilder()} instead.
+     */
+    public function setConstraintValidatorFactory(ConstraintValidatorFactoryInterface $constraintValidatorFactory)
+    {
+        $this->constraintValidatorFactory = $constraintValidatorFactory;
+
+        return $this;
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @deprecated Deprecated since version 2.1, to be removed in 2.3. Use
+     *             {@link Validation::createValidator()} instead.
+     */
+    public function getValidator()
+    {
+        return new Validator(
+            $this->metadataFactory,
+            $this->constraintValidatorFactory
+        );
+    }
+
+    /**
+     * Returns the class metadata factory used in the new validator
+     *
+     * @return ClassMetadataFactoryInterface  The factory instance
+     *
+     * @deprecated Deprecated since version 2.1, to be removed in 2.3.
+     */
+    public function getClassMetadataFactory()
+    {
+        return $this->classMetadataFactory;
+    }
+
+    /**
+     * Returns the constraint validator factory used in the new validator
+     *
+     * @return ConstraintValidatorFactoryInterface  The factory instance
+     *
+     * @deprecated Deprecated since version 2.1, to be removed in 2.3.
+     */
+    public function getConstraintValidatorFactory()
+    {
+        return $this->constraintValidatorFactory;
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/ValidatorContextInterface.php b/core/vendor/symfony/validator/Symfony/Component/Validator/ValidatorContextInterface.php
new file mode 100644
index 0000000..73ce6b6
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/ValidatorContextInterface.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\Validator;
+
+use Symfony\Component\Validator\Mapping\ClassMetadataFactoryInterface;
+
+/**
+ * Stores settings for creating a new validator and creates validators
+ *
+ * The methods in this class are chainable, i.e. they return the context
+ * object itself. When you have finished configuring the new validator, call
+ * getValidator() to create the it.
+ *
+ * <code>
+ * $validator = $context
+ *     ->setClassMetadataFactory($customFactory)
+ *     ->getValidator();
+ * </code>
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @deprecated Deprecated since version 2.1, to be removed in 2.3. Use
+ *             {@link Validation::createValidatorBuilder()} instead.
+ */
+interface ValidatorContextInterface
+{
+    /**
+     * Sets the class metadata factory used in the new validator
+     *
+     * @param ClassMetadataFactoryInterface $classMetadataFactory The factory instance
+     *
+     * @deprecated Deprecated since version 2.1, to be removed in 2.3. Use
+     *             {@link Validation::createValidatorBuilder()} instead.
+     */
+    public function setClassMetadataFactory(ClassMetadataFactoryInterface $classMetadataFactory);
+
+    /**
+     * Sets the constraint validator factory used in the new validator
+     *
+     * @param ConstraintValidatorFactoryInterface $constraintValidatorFactory The factory instance
+     *
+     * @deprecated Deprecated since version 2.1, to be removed in 2.3. Use
+     *             {@link Validation::createValidatorBuilder()} instead.
+     */
+    public function setConstraintValidatorFactory(ConstraintValidatorFactoryInterface $constraintValidatorFactory);
+
+    /**
+     * Creates a new validator with the settings stored in this context
+     *
+     * @return ValidatorInterface   The new validator
+     *
+     * @deprecated Deprecated since version 2.1, to be removed in 2.3. Use
+     *             {@link Validation::createValidator()} instead.
+     */
+    public function getValidator();
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/ValidatorFactory.php b/core/vendor/symfony/validator/Symfony/Component/Validator/ValidatorFactory.php
new file mode 100644
index 0000000..5e16b2e
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/ValidatorFactory.php
@@ -0,0 +1,224 @@
+<?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\Validator;
+
+use Doctrine\Common\Annotations\AnnotationReader;
+use Symfony\Component\Validator\Exception\MappingException;
+use Symfony\Component\Validator\Mapping\ClassMetadataFactory;
+use Symfony\Component\Validator\Mapping\ClassMetadataFactoryInterface;
+use Symfony\Component\Validator\Mapping\Loader\XmlFilesLoader;
+use Symfony\Component\Validator\Mapping\Loader\YamlFilesLoader;
+use Symfony\Component\Validator\Mapping\Loader\AnnotationLoader;
+use Symfony\Component\Validator\Mapping\Loader\StaticMethodLoader;
+use Symfony\Component\Validator\Mapping\Loader\LoaderChain;
+
+/**
+ * Creates and configures new validator objects
+ *
+ * Usually you will use the static method buildDefault() to initialize a
+ * factory with default configuration. To this method you can pass various
+ * parameters that configure where the validator mapping is found. If you
+ * don't pass a parameter, the mapping will be read from annotations.
+ *
+ * <code>
+ * // read from annotations only
+ * $factory = ValidatorFactory::buildDefault();
+ *
+ * // read from XML and YAML, suppress annotations
+ * $factory = ValidatorFactory::buildDefault(array(
+ *   '/path/to/mapping.xml',
+ *   '/path/to/other/mapping.yml',
+ * ), false);
+ * </code>
+ *
+ * You then have to call getValidator() to create new validators.
+ *
+ * <code>
+ * $validator = $factory->getValidator();
+ * </code>
+ *
+ * When manually constructing a factory, the default configuration of the
+ * validators can be passed to the constructor as a ValidatorContextInterface
+ * object.
+ *
+ * <code>
+ * $defaultContext = new ValidatorContext();
+ * $defaultContext->setClassMetadataFactory($metadataFactory);
+ * $defaultContext->setConstraintValidatorFactory($validatorFactory);
+ * $factory = new ValidatorFactory($defaultContext);
+ *
+ * $form = $factory->getValidator();
+ * </code>
+ *
+ * You can also override the default configuration by calling any of the
+ * methods in this class. These methods return a ValidatorContextInterface object
+ * on which you can override further settings or call getValidator() to create
+ * a form.
+ *
+ * <code>
+ * $form = $factory
+ *     ->setClassMetadataFactory($customFactory);
+ *     ->getValidator();
+ * </code>
+ *
+ * ValidatorFactory instances should be cached and reused in your application.
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @deprecated Deprecated since version 2.1, to be removed in 2.3. Use
+ *             {@link Validation::createValidatorBuilder()} instead.
+ */
+class ValidatorFactory implements ValidatorContextInterface
+{
+    /**
+     * Holds the context with the default configuration
+     * @var ValidatorContextInterface
+     */
+    protected $defaultContext;
+
+    /**
+     * Builds a validator factory with the default mapping loaders
+     *
+     * @param array $mappingFiles A list of XML or YAML file names
+     *                                      where mapping information can be
+     *                                      found. Can be empty.
+     * @param Boolean $annotations Whether to use annotations for
+     *                                      retrieving mapping information
+     * @param string $staticMethod The name of the static method to
+     *                                      use, if static method loading should
+     *                                      be enabled
+     *
+     * @return ValidatorFactory             The validator factory.
+     *
+     * @throws MappingException             If any of the files in $mappingFiles
+     *                                      has neither the extension ".xml" nor
+     *                                      ".yml" nor ".yaml"
+     * @throws \RuntimeException            If annotations are not supported.
+     *
+     * @deprecated Deprecated since version 2.1, to be removed in 2.3. Use
+     *             {@link Validation::createValidatorBuilder()} instead.
+     */
+    public static function buildDefault(array $mappingFiles = array(), $annotations = false, $staticMethod = null)
+    {
+        $xmlMappingFiles = array();
+        $yamlMappingFiles = array();
+        $loaders = array();
+        $context = new ValidatorContext();
+
+        foreach ($mappingFiles as $file) {
+            $extension = pathinfo($file, PATHINFO_EXTENSION);
+
+            if ($extension === 'xml') {
+                $xmlMappingFiles[] = $file;
+            } elseif ($extension === 'yaml' || $extension === 'yml') {
+                $yamlMappingFiles[] = $file;
+            } else {
+                throw new MappingException('The only supported mapping file formats are XML and YAML');
+            }
+        }
+
+        if (count($xmlMappingFiles) > 0) {
+            $loaders[] = new XmlFilesLoader($xmlMappingFiles);
+        }
+
+        if (count($yamlMappingFiles) > 0) {
+            $loaders[] = new YamlFilesLoader($yamlMappingFiles);
+        }
+
+        if ($annotations) {
+            if (!class_exists('Doctrine\Common\Annotations\AnnotationReader')) {
+                throw new \RuntimeException('Requested a ValidatorFactory with an AnnotationLoader, but the AnnotationReader was not found. You should add Doctrine Common to your project.');
+            }
+
+            $loaders[] = new AnnotationLoader(new AnnotationReader());
+        }
+
+        if ($staticMethod) {
+            $loaders[] = new StaticMethodLoader($staticMethod);
+        }
+
+        if (count($loaders) > 1) {
+            $loader = new LoaderChain($loaders);
+        } elseif (count($loaders) === 1) {
+            $loader = $loaders[0];
+        } else {
+            throw new MappingException('No mapping loader was found for the given parameters');
+        }
+
+        $context->setClassMetadataFactory(new ClassMetadataFactory($loader));
+        $context->setConstraintValidatorFactory(new ConstraintValidatorFactory());
+
+        return new static($context);
+    }
+
+    /**
+     * Sets the given context as default context
+     *
+     * @param ValidatorContextInterface $defaultContext A preconfigured context
+     *
+     * @deprecated Deprecated since version 2.1, to be removed in 2.3. Use
+     *             {@link Validation::createValidatorBuilder()} instead.
+     */
+    public function __construct(ValidatorContextInterface $defaultContext = null)
+    {
+        $this->defaultContext = null === $defaultContext ? new ValidatorContext() : $defaultContext;
+    }
+
+    /**
+     * Overrides the class metadata factory of the default context and returns
+     * the new context
+     *
+     * @param ClassMetadataFactoryInterface $metadataFactory The new factory instance
+     *
+     * @return ValidatorContextInterface                       The preconfigured form context
+     *
+     * @deprecated Deprecated since version 2.1, to be removed in 2.3. Use
+     *             {@link Validation::createValidatorBuilder()} instead.
+     */
+    public function setClassMetadataFactory(ClassMetadataFactoryInterface $metadataFactory)
+    {
+        $context = clone $this->defaultContext;
+
+        return $context->setClassMetadataFactory($metadataFactory);
+    }
+
+    /**
+     * Overrides the constraint validator factory of the default context and
+     * returns the new context
+     *
+     * @param ClassMetadataFactoryInterface $validatorFactory The new factory instance
+     *
+     * @return ValidatorContextInterface                        The preconfigured form context
+     *
+     * @deprecated Deprecated since version 2.1, to be removed in 2.3. Use
+     *             {@link Validation::createValidatorBuilder()} instead.
+     */
+    public function setConstraintValidatorFactory(ConstraintValidatorFactoryInterface $validatorFactory)
+    {
+        $context = clone $this->defaultContext;
+
+        return $context->setConstraintValidatorFactory($validatorFactory);
+    }
+
+    /**
+     * Creates a new validator with the settings stored in the default context
+     *
+     * @return ValidatorInterface  The new validator
+     *
+     * @deprecated Deprecated since version 2.1, to be removed in 2.3. Use
+     *             {@link Validation::createValidator()} instead.
+     */
+    public function getValidator()
+    {
+        return $this->defaultContext->getValidator();
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/ValidatorInterface.php b/core/vendor/symfony/validator/Symfony/Component/Validator/ValidatorInterface.php
new file mode 100644
index 0000000..b56c580
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/ValidatorInterface.php
@@ -0,0 +1,101 @@
+<?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\Validator;
+
+use Symfony\Component\Validator\Constraint;
+
+/**
+ * Validates values and graphs of objects and arrays.
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ *
+ * @api
+ */
+interface ValidatorInterface
+{
+    /**
+     * Validates a value.
+     *
+     * The accepted values depend on the {@link MetadataFactoryInterface}
+     * implementation.
+     *
+     * @param mixed      $value    The value to validate
+     * @param array|null $groups   The validation groups to validate.
+     * @param Boolean    $traverse Whether to traverse the value if it is traversable.
+     * @param Boolean    $deep     Whether to traverse nested traversable values recursively.
+     *
+     * @return ConstraintViolationListInterface A list of constraint violations. If the
+     *                                          list is empty, validation succeeded.
+     *
+     * @api
+     */
+    public function validate($value, $groups = null, $traverse = false, $deep = false);
+
+    /**
+     * Validates a property of a value against its current value.
+     *
+     * The accepted values depend on the {@link MetadataFactoryInterface}
+     * implementation.
+     *
+     * @param mixed      $containingValue The value containing the property.
+     * @param string     $property        The name of the property to validate.
+     * @param array|null $groups          The validation groups to validate.
+     *
+     * @return ConstraintViolationListInterface A list of constraint violations. If the
+     *                                          list is empty, validation succeeded.
+     *
+     * @api
+     */
+    public function validateProperty($containingValue, $property, $groups = null);
+
+    /**
+     * Validate a property of a value against a potential value.
+     *
+     * The accepted values depend on the {@link MetadataFactoryInterface}
+     * implementation.
+     *
+     * @param string     $containingValue The value containing the property.
+     * @param string     $property        The name of the property to validate
+     * @param string     $value           The value to validate against the
+     *                                    constraints of the property.
+     * @param array|null $groups          The validation groups to validate.
+     *
+     * @return ConstraintViolationListInterface A list of constraint violations. If the
+     *                                          list is empty, validation succeeded.
+     *
+     * @api
+     */
+    public function validatePropertyValue($containingValue, $property, $value, $groups = null);
+
+    /**
+     * Validates a value against a constraint or a list of constraints.
+     *
+     * @param mixed                   $value       The value to validate.
+     * @param Constraint|Constraint[] $constraints The constraint(s) to validate against.
+     * @param array|null              $groups      The validation groups to validate.
+     *
+     * @return ConstraintViolationListInterface A list of constraint violations. If the
+     *                                          list is empty, validation succeeded.
+     *
+     * @api
+     */
+    public function validateValue($value, $constraints, $groups = null);
+
+    /**
+     * Returns the factory for metadata instances.
+     *
+     * @return MetadataFactoryInterface The metadata factory.
+     *
+     * @api
+     */
+    public function getMetadataFactory();
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/composer.json b/core/vendor/symfony/validator/Symfony/Component/Validator/composer.json
new file mode 100644
index 0000000..a52d33b
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/composer.json
@@ -0,0 +1,41 @@
+{
+    "name": "symfony/validator",
+    "type": "library",
+    "description": "Symfony Validator 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/http-foundation": "2.2.*",
+        "symfony/locale": "2.2.*",
+        "symfony/yaml": "2.2.*"
+    },
+    "suggest": {
+        "doctrine/common": ">=2.1,<2.4-dev",
+        "symfony/http-foundation": "2.2.*",
+        "symfony/yaml": "2.2.*"
+    },
+    "autoload": {
+        "psr-0": { "Symfony\\Component\\Validator\\": "" }
+    },
+    "target-dir": "Symfony/Component/Validator",
+    "minimum-stability": "dev",
+    "extra": {
+        "branch-alias": {
+            "dev-master": "2.2-dev"
+        }
+    }
+}
diff --git a/core/vendor/symfony/validator/Symfony/Component/Validator/phpunit.xml.dist b/core/vendor/symfony/validator/Symfony/Component/Validator/phpunit.xml.dist
new file mode 100644
index 0000000..c7f1cef
--- /dev/null
+++ b/core/vendor/symfony/validator/Symfony/Component/Validator/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="vendor/autoload.php"
+>
+    <testsuites>
+        <testsuite name="Symfony Validator Component Test Suite">
+            <directory>./Tests/</directory>
+        </testsuite>
+    </testsuites>
+
+    <filter>
+        <whitelist>
+            <directory>./</directory>
+            <exclude>
+                <directory>./vendor</directory>
+                <directory>./Tests</directory>
+            </exclude>
+        </whitelist>
+    </filter>
+</phpunit>
