+       /**
+        * Confirm account from mail link
+        *
+        * @param Request $request The request
+        * @param UserPasswordEncoderInterface $encoder The password encoder
+        * @param SluggerUtil $slugger The slugger
+        * @param MailerInterface $mailer The mailer
+        * @param string $mail The shorted mail address
+        * @param string $extra The serialized then shorted extra array
+        * @param string $hash The hashed password
+        * @return Response The response
+        */
+       public function confirm(Request $request, UserPasswordEncoderInterface $encoder, SluggerUtil $slugger, MailerInterface $mailer, $mail, $extra, $hash) {
+               //Get doctrine
+               $doctrine = $this->getDoctrine();
+
+               //With invalid hash
+               if ($hash != $slugger->hash($mail.$extra)) {
+                       //Throw bad request
+                       throw new BadRequestHttpException($this->translator->trans('Invalid %field% field: %value%', ['%field%' => 'hash', '%value%' => $hash]));
+               }
+
+               //Get mail
+               $mail = $slugger->unshort($smail = $mail);
+
+               //Without valid mail
+               if (filter_var($mail, FILTER_VALIDATE_EMAIL) === false) {
+                       //Throw bad request
+                       throw new BadRequestHttpException($this->translator->trans('Invalid %field% field: %value%', ['%field%' => 'mail', '%value%' => $mail]));
+               }
+
+               //With existing subscriber
+               if ($doctrine->getRepository($this->config['class']['user'])->findOneByMail($mail)) {
+                       //Add error message mail already exists
+                       $this->addFlash('error', $this->translator->trans('Account %mail% already exists', ['%mail%' => $mail]));
+
+                       //Redirect to user view
+                       return $this->redirectToRoute($this->config['route']['edit']['name'], ['mail' => $smail]+$this->config['route']['edit']['context']);
+               }
+
+               //Get extra
+               $extra = $slugger->unserialize($sextra = $extra);
+
+               //Without valid extra
+               if (!is_array($extra)) {
+                       //Throw bad request
+                       throw new BadRequestHttpException($this->translator->trans('Invalid %field% field: %value%', ['%field%' => 'extra', '%value%' => $sextra]));
+               }
+
+               //Extract names and pseudonym from mail
+               $names = explode(' ', $pseudonym = ucwords(trim(preg_replace('/[^a-zA-Z]+/', ' ', current(explode('@', $mail))))));
+
+               //Get manager
+               $manager = $doctrine->getManager();
+
+               //Init reflection
+               $reflection = new \ReflectionClass($this->config['class']['user']);
+
+               //Create new user
+               $user = $reflection->newInstance();
+
+               //Set mail
+               $user->setMail($mail);
+
+               //Set default value
+               $default = [
+                       'civility(title)' => $this->config['default']['civility'],
+                       'pseudonym' => $pseudonym,
+                       'forename' => $names[0]??$pseudonym,
+                       'surname' => $names[1]??$pseudonym,
+                       'password' => $encoder->encodePassword($user, $mail),
+                       'active' => true
+               ];
+
+               //Iterate on each default value
+               //TODO: store add/set action between [] ???
+               foreach($extra+$default as $key => $value) {
+                       //Set member
+                       $member = $key;
+
+                       //With title entity
+                       if (substr($key, -strlen('(title)')) === '(title)') {
+                               //Remove field info
+                               $member = substr($member, 0, -strlen('(title)'));
+
+                               //Get object as value
+                               $value = $doctrine->getRepository($this->config['class'][$member])->findOneByTitle($value);
+                       //With id entity
+                       } elseif (substr($key, -strlen('(id)')) === '(id)') {
+                               //Remove field info
+                               $member = substr($member, 0, -strlen('(id)'));
+
+                               //Get object as value
+                               $value = $doctrine->getRepository($this->config['class'][$key])->findOneById($value);
+                       }
+
+                       //Set value
+                       $user->{'set'.ucfirst($member)}($value);
+
+                       //Unset extra value
+                       unset($extra[$key]);
+               }
+
+               //Iterate on default group
+               foreach($this->config['default']['group'] as $i => $groupTitle) {
+                       //Fetch group
+                       if (($group = $doctrine->getRepository($this->config['class']['group'])->findOneByTitle($groupTitle))) {
+                               //Set default group
+                               //XXX: see vendor/symfony/security-core/Role/Role.php
+                               $user->addGroup($group);
+                       //Group not found
+                       } else {
+                               //Throw exception
+                               //XXX: consider missing group as fatal
+                               throw new \Exception(sprintf('Group from rapsys_user.default.group[%d] not found by title: %s', $i, $groupTitle));
+                       }
+               }
+
+               $user->setCreated(new \DateTime('now'));
+               $user->setUpdated(new \DateTime('now'));
+
+               //Persist user
+               $manager->persist($user);
+
+               //Try saving in database
+               try {
+                       //Send to database
+                       $manager->flush();
+
+                       //Add error message mail already exists
+                       $this->addFlash('notice', $this->translator->trans('Your account has been created'));
+               //Catch double subscription
+               } catch (\Doctrine\DBAL\Exception\UniqueConstraintViolationException $e) {
+                       //Add error message mail already exists
+                       $this->addFlash('error', $this->translator->trans('Account %mail% already exists', ['%mail%' => $mail]));
+               }
+
+               //Redirect to user view
+               return $this->redirectToRoute($this->config['route']['edit']['name'], ['mail' => $smail]+$this->config['route']['edit']['context']);
+       }
+
+       /**
+        * Edit account by shorted mail
+        *
+        * @param Request $request The request
+        * @param SluggerUtil $slugger The slugger
+        * @param string $mail The shorted mail address
+        * @return Response The response
+        */
+       public function edit(Request $request, SluggerUtil $slugger, $mail) {
+               //Get doctrine
+               $doctrine = $this->getDoctrine();
+
+               //Get mail
+               $mail = $slugger->unshort($smail = $mail);
+
+               //With existing subscriber
+               if (empty($user = $doctrine->getRepository($this->config['class']['user'])->findOneByMail($mail))) {
+                       var_dump($mail);
+                       //Throw not found
+                       //XXX: prevent slugger reverse engineering by not displaying decoded mail
+                       throw $this->createNotFoundException($this->translator->trans('Unable to find account %mail%', ['%mail%' => $smail]));
+               }
+
+               //Get user token
+               $token = new UsernamePasswordToken($user, null, 'none', $user->getRoles());
+
+               //Check if guest
+               $isGuest = $this->get('rapsys_user.access_decision_manager')->decide($token, ['ROLE_GUEST']);
+
+               //Prevent access when not admin, user is not guest and not currently logged user
+               if (!$this->isGranted('ROLE_ADMIN') && empty($isGuest) && $user != $this->getUser()) {
+                       //Throw access denied
+                       //XXX: prevent slugger reverse engineering by not displaying decoded mail
+                       throw $this->createAccessDeniedException($this->translator->trans('Unable to access user: %mail%', ['%mail%' => $smail]));
+               }
+
+               //Create the RegisterType form and give the proper parameters
+               $form = $this->createForm($this->config['register']['view']['form'], $user, [
+                       //Set action to register route name and context
+                       'action' => $this->generateUrl($this->config['route']['edit']['name'], ['mail' => $smail]+$this->config['route']['edit']['context']),
+                       //Set civility class
+                       'civility_class' => $this->config['class']['civility'],
+                       //Set civility default
+                       'civility_default' => $doctrine->getRepository($this->config['class']['civility'])->findOneByTitle($this->config['default']['civility']),
+                       //Disable mail
+                       'mail' => $this->isGranted('ROLE_ADMIN'),
+                       //Disable password
+                       //XXX: prefer a reset on login to force user unspam action
+                       'password' => false,
+                       //Set method
+                       'method' => 'POST'
+               ]);
+
+               if ($request->isMethod('POST')) {
+                       //Refill the fields in case the form is not valid.
+                       $form->handleRequest($request);
+
+                       if ($form->isValid()) {
+                               //Set data
+                               $data = $form->getData();
+
+                               //Get manager
+                               $manager = $doctrine->getManager();
+
+                               //Queue snippet save
+                               $manager->persist($data);
+
+                               //Flush to get the ids
+                               $manager->flush();
+
+                               //Add notice
+                               $this->addFlash('notice', $this->translator->trans('Account %mail% updated', ['%mail%' => $mail]));
+
+                               //Redirect to user view
+                               //TODO: extract referer ??? or useless ???
+                               return $this->redirectToRoute($this->config['route']['edit']['name'], ['mail' => $smail]+$this->config['route']['edit']['context']);
+
+                               //Redirect to cleanup the form
+                               return $this->redirectToRoute('rapsys_air', ['user' => $data->getId()]);
+                       }
+               } else {
+                       //Add notice
+                       $this->addFlash('notice', $this->translator->trans('To change your password login with your mail %mail% and any password then follow the procedure', ['%mail%' => $mail]));
+               }
+
+               //Render view
+               return $this->render(
+                       //Template
+                       $this->config['edit']['view']['name'],
+                       //Context
+                       ['form' => $form->createView(), 'sent' => $request->query->get('sent', 0)]+$this->config['edit']['view']['context']
+               );
+       }
+