diff --git a/composer.json b/composer.json
index 32d2eaa8ff3fc9957bdcc5b20ee76046aaa5ab73..1c02bdae2228ecd3bf64592af8317b0195261280 100644
--- a/composer.json
+++ b/composer.json
@@ -11,6 +11,7 @@
         "symfony/flex": "^1.3.1",
         "symfony/form": "5.0.*",
         "symfony/framework-bundle": "5.0.*",
+        "symfony/validator": "5.0.*",
         "symfony/yaml": "5.0.*"
     },
     "require-dev": {
diff --git a/composer.lock b/composer.lock
index 7b0ad7766b3c1c81762662b478d7fbbefe431ddd..2a338a486565cb07704b3a57cb269245c82d2a49 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
         "This file is @generated automatically"
     ],
-    "content-hash": "91ff357897f2296188db5dd0fce8893b",
+    "content-hash": "18678eee5ad956a975c1e6ae6eb2a1dd",
     "packages": [
         {
             "name": "doctrine/annotations",
@@ -2114,6 +2114,156 @@
             ],
             "time": "2019-11-18T17:27:11+00:00"
         },
+        {
+            "name": "symfony/translation-contracts",
+            "version": "v2.0.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/translation-contracts.git",
+                "reference": "8cc682ac458d75557203b2f2f14b0b92e1c744ed"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/8cc682ac458d75557203b2f2f14b0b92e1c744ed",
+                "reference": "8cc682ac458d75557203b2f2f14b0b92e1c744ed",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^7.2.5"
+            },
+            "suggest": {
+                "symfony/translation-implementation": ""
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "2.0-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Symfony\\Contracts\\Translation\\": ""
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Nicolas Grekas",
+                    "email": "p@tchwork.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Generic abstractions related to translation",
+            "homepage": "https://symfony.com",
+            "keywords": [
+                "abstractions",
+                "contracts",
+                "decoupling",
+                "interfaces",
+                "interoperability",
+                "standards"
+            ],
+            "time": "2019-11-18T17:27:11+00:00"
+        },
+        {
+            "name": "symfony/validator",
+            "version": "v5.0.7",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/validator.git",
+                "reference": "fc459a3d66bda9c0f8231a4d44dddd6daf23db92"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/validator/zipball/fc459a3d66bda9c0f8231a4d44dddd6daf23db92",
+                "reference": "fc459a3d66bda9c0f8231a4d44dddd6daf23db92",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^7.2.5",
+                "symfony/polyfill-ctype": "~1.8",
+                "symfony/polyfill-mbstring": "~1.0",
+                "symfony/translation-contracts": "^1.1|^2"
+            },
+            "conflict": {
+                "doctrine/lexer": "<1.0.2",
+                "phpunit/phpunit": "<5.4.3",
+                "symfony/dependency-injection": "<4.4",
+                "symfony/http-kernel": "<4.4",
+                "symfony/intl": "<4.4",
+                "symfony/translation": "<4.4",
+                "symfony/yaml": "<4.4"
+            },
+            "require-dev": {
+                "doctrine/annotations": "~1.7",
+                "doctrine/cache": "~1.0",
+                "egulias/email-validator": "^2.1.10",
+                "symfony/cache": "^4.4|^5.0",
+                "symfony/config": "^4.4|^5.0",
+                "symfony/dependency-injection": "^4.4|^5.0",
+                "symfony/expression-language": "^4.4|^5.0",
+                "symfony/http-client": "^4.4|^5.0",
+                "symfony/http-foundation": "^4.4|^5.0",
+                "symfony/http-kernel": "^4.4|^5.0",
+                "symfony/intl": "^4.4|^5.0",
+                "symfony/mime": "^4.4|^5.0",
+                "symfony/property-access": "^4.4|^5.0",
+                "symfony/property-info": "^4.4|^5.0",
+                "symfony/translation": "^4.4|^5.0",
+                "symfony/yaml": "^4.4|^5.0"
+            },
+            "suggest": {
+                "doctrine/annotations": "For using the annotation mapping. You will also need doctrine/cache.",
+                "doctrine/cache": "For using the default cached annotation reader.",
+                "egulias/email-validator": "Strict (RFC compliant) email validation",
+                "psr/cache-implementation": "For using the mapping cache.",
+                "symfony/config": "",
+                "symfony/expression-language": "For using the Expression validator",
+                "symfony/http-foundation": "",
+                "symfony/intl": "",
+                "symfony/property-access": "For accessing properties within comparison constraints",
+                "symfony/property-info": "To automatically add NotNull and Type constraints",
+                "symfony/translation": "For translating validation errors.",
+                "symfony/yaml": ""
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "5.0-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Symfony\\Component\\Validator\\": ""
+                },
+                "exclude-from-classmap": [
+                    "/Tests/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Fabien Potencier",
+                    "email": "fabien@symfony.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Symfony Validator Component",
+            "homepage": "https://symfony.com",
+            "time": "2020-03-30T11:42:42+00:00"
+        },
         {
             "name": "symfony/var-dumper",
             "version": "v5.0.5",
diff --git a/config/packages/test/validator.yaml b/config/packages/test/validator.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..1e5ab7880bf02b6c8982877393c846b9b3ca400d
--- /dev/null
+++ b/config/packages/test/validator.yaml
@@ -0,0 +1,3 @@
+framework:
+    validation:
+        not_compromised_password: false
diff --git a/config/packages/validator.yaml b/config/packages/validator.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..350786a13d9cc5f54e945984c0590cf37792ffcc
--- /dev/null
+++ b/config/packages/validator.yaml
@@ -0,0 +1,8 @@
+framework:
+    validation:
+        email_validation_mode: html5
+
+        # Enables validator auto-mapping support.
+        # For instance, basic validation constraints will be inferred from Doctrine's metadata.
+        #auto_mapping:
+        #    App\Entity\: []
diff --git a/src/Controller/TestHeahdudeController.php b/src/Controller/TestHeahdudeController.php
new file mode 100644
index 0000000000000000000000000000000000000000..7d375fce30c3f24ac42b3792743e00caf738444f
--- /dev/null
+++ b/src/Controller/TestHeahdudeController.php
@@ -0,0 +1,83 @@
+<?php
+declare(strict_types=1);
+
+namespace App\Controller;
+
+
+use App\Exception\InvalidColorException;
+use App\Form\ColorType;
+use App\Model\ColorVo;
+use App\Model\ParentModel;
+use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
+use Symfony\Component\Form\DataMapperInterface;
+use Symfony\Component\Form\Exception\TransformationFailedException;
+use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
+use Symfony\Component\Form\Extension\Core\Type\FormType;
+use Symfony\Component\Form\Extension\Core\Type\TextType;
+use Symfony\Component\Form\FormFactoryInterface;
+use Symfony\Component\Routing\Annotation\Route;
+use Symfony\Component\Validator\Constraints\Callback;
+use Symfony\Component\Validator\Constraints\IsTrue;
+use Symfony\Component\Validator\Constraints\Type;
+
+class TestHeahdudeController extends AbstractController
+{
+    /**
+     * @Route("/test-heahdude", name="test_heah_form")
+     */
+    public function index(FormFactoryInterface $formFactory)
+    {
+        $form = $formFactory->createNamedBuilder('', FormType::class, null, [
+            'data_class' => ParentModel::class,
+            'empty_data' => null, //function () { return new ParentModel('', new ColorVo('foo')); }
+            ])
+            ->setDataMapper(new class implements DataMapperInterface {
+                public function mapDataToForms($viewData, iterable $forms)
+                {
+                    if ($viewData === null) {
+                        return;
+                    }
+                    $forms = iterator_to_array($forms);
+                    $forms['color']->setData($viewData->getColor());
+                    $forms['content']->setData($viewData->getContent());
+                }
+
+                public function mapFormsToData(iterable $forms, &$viewData)
+                {
+                    $forms = iterator_to_array($forms);
+                    try {
+                        $viewData = new ParentModel($forms['content']->getData(), new ColorVo($forms['color']->getData()));
+                    } catch (InvalidColorException $error) {
+                        // What to do here ?!
+
+                        // This does not work
+                        // $forms['colorCondition']->setData(false);
+                        // Even if it would, the error path is wrong!
+                    }
+                }
+            })
+            ->add('color', ColorType::class, [
+                'constraints' => [
+                    new Type(['type' => 'string']),
+                    new Callback(['callback' => ColorVo::class . '::validateColor'])
+                ]
+            ])
+            ->add('content', TextType::class)
+            ->add('colorCondition', CheckboxType::class, [
+                'label' => 'Accept color',
+                'required' => false,
+                'mapped' => false,
+                'empty_data' => true,
+                'constraints' => new IsTrue(['message' => 'Wrong color input'])
+            ])
+            ->getForm();
+        $form->submit(['color' => 10, 'content' => 'foobar']);
+
+        dump($form->getErrors(true, true));
+
+        return $this->json([
+            'message' => 'Welcome to your new controller!',
+            'path' => 'src/Controller/TestVoFormController.php',
+        ]);
+    }
+}
diff --git a/src/Controller/TestVoFormController.php b/src/Controller/TestVoFormController.php
index 2d7e9c71285d9fc2f782060bdc51d447d7977f84..63f3f07b53f5076c9c873dce676ef4d8647d32ad 100644
--- a/src/Controller/TestVoFormController.php
+++ b/src/Controller/TestVoFormController.php
@@ -1,4 +1,5 @@
 <?php
+declare(strict_types=1);
 
 namespace App\Controller;
 
diff --git a/src/Exception/InvalidColorException.php b/src/Exception/InvalidColorException.php
new file mode 100644
index 0000000000000000000000000000000000000000..7c275a6036bd7b40ca8672599f31127d9b12721d
--- /dev/null
+++ b/src/Exception/InvalidColorException.php
@@ -0,0 +1,9 @@
+<?php
+
+namespace App\Exception;
+
+
+class InvalidColorException extends \InvalidArgumentException
+{
+
+}
diff --git a/src/Form/ColorType.php b/src/Form/ColorType.php
index aaea4c82a29bc128118798b39efcee55c19139f6..489f9edfe33b1e6272f15534ae8161d81c3e2d6e 100644
--- a/src/Form/ColorType.php
+++ b/src/Form/ColorType.php
@@ -1,8 +1,10 @@
 <?php
+declare(strict_types=1);
 
 namespace App\Form;
 
 
+use App\Exception\InvalidColorException;
 use App\Model\ColorVo;
 use Symfony\Component\Form\AbstractType;
 use Symfony\Component\Form\DataMapperInterface;
@@ -12,6 +14,7 @@ use Symfony\Component\Form\Exception\TransformationFailedException;
 use Symfony\Component\Form\FormBuilderInterface;
 use Symfony\Component\Form\FormInterface;
 use Symfony\Component\OptionsResolver\OptionsResolver;
+use Symfony\Component\Validator\Context\ExecutionContextInterface;
 
 class ColorType extends AbstractType implements DataTransformerInterface
 {
@@ -57,4 +60,24 @@ class ColorType extends AbstractType implements DataTransformerInterface
     {
         $viewData = new ColorVo($forms->getData());
     }
+
+    public static function assertColorIsValid(string $color): void
+    {
+        if (preg_match('#^\#[0-9]{6}$#', $color) === 1) {
+            return;
+        }
+
+        throw new InvalidColorException('Invalid color');
+    }
+
+    public static function validateColor($color, ExecutionContextInterface $context, $payload)
+    {
+        try {
+            self::assertColorIsValid($color);
+        } catch (InvalidColorException $e) {
+            $context->buildViolation('Impossible color bruuuu')
+                ->addViolation()
+            ;
+        }
+    }
 }
diff --git a/src/Model/ColorVo.php b/src/Model/ColorVo.php
index 832d3ce513f463a3dd13cabc9acde0a5315e79f2..b6da30789f8120a6bb51ac92d666a6e2b92fd27e 100644
--- a/src/Model/ColorVo.php
+++ b/src/Model/ColorVo.php
@@ -1,4 +1,5 @@
 <?php
+declare(strict_types=1);
 
 namespace App\Model;
 
diff --git a/src/Model/ParentModel.php b/src/Model/ParentModel.php
index 1c548126954e0e15b2952f75d91fa70c777ef6ca..bc7fb11c799ae770f8493cf1c868d93776610f7c 100644
--- a/src/Model/ParentModel.php
+++ b/src/Model/ParentModel.php
@@ -1,4 +1,5 @@
 <?php
+declare(strict_types=1);
 
 namespace App\Model;
 
diff --git a/symfony.lock b/symfony.lock
index ee44accf92fe73059b0b693c53ff19c4564110a3..415a1dae4e5c303a85b9163e39742770e74144ff 100644
--- a/symfony.lock
+++ b/symfony.lock
@@ -172,6 +172,22 @@
     "symfony/service-contracts": {
         "version": "v2.0.1"
     },
+    "symfony/translation-contracts": {
+        "version": "v2.0.1"
+    },
+    "symfony/validator": {
+        "version": "4.3",
+        "recipe": {
+            "repo": "github.com/symfony/recipes",
+            "branch": "master",
+            "version": "4.3",
+            "ref": "d902da3e4952f18d3bf05aab29512eb61cabd869"
+        },
+        "files": [
+            "config/packages/test/validator.yaml",
+            "config/packages/validator.yaml"
+        ]
+    },
     "symfony/var-dumper": {
         "version": "v5.0.5"
     },