diff --git a/config/application.config.php b/config/application.config.php
index 843ed8d0715285f7bc641480ac2a52735af0f862..de312e3daf883ad5e2a53c5cdea6f10ed4214204 100644
--- a/config/application.config.php
+++ b/config/application.config.php
@@ -24,8 +24,10 @@ if ($localModules = getenv('VUFIND_LOCAL_MODULES')) {
 
 /** Begin of temporarily necessary adjustments. */
 array_push($modules, ...[
+    'Zend\Filter',
     'Zend\Validator',
     'Zend\Serializer',
+    'Zend\InputFilter',
     'finc\VuFindHttpPsrCompat',
     'finc\SymfonySerializerZendBridge',
     'finc',
diff --git a/module/fid/config/module.config.php b/module/fid/config/module.config.php
index d07e068a9a61af254c60eeb7a5246394270bfbc0..075a68cf034e5af117a91b2e0bd67a270097368d 100644
--- a/module/fid/config/module.config.php
+++ b/module/fid/config/module.config.php
@@ -21,6 +21,11 @@
 
 use fid\Controller\UserController;
 use fid\Controller\UserControllerFactory;
+use fid\FormModel\PasswordChangeModel;
+use fid\FormModel\PasswordResetModel;
+use fid\FormModel\UserCreateModel;
+use fid\FormModel\UserInitModel;
+use fid\FormModel\UserUpdateModel;
 use fid\Helper\RegistrationFormLabel;
 use fid\Helper\TranslatorDelegator;
 use fid\Listener\ErrorListener;
@@ -44,16 +49,23 @@ use Zend\Mvc\Plugin\FlashMessenger\FlashMessenger;
 use Zend\ServiceManager\Factory\InvokableFactory;
 
 return [
-    'controllers'     => [
+    'forms'              => [
+        UserInitModel::class       => require_once 'user-init-form.php',
+        UserCreateModel::class     => require_once 'user-create-form.php',
+        UserUpdateModel::class     => require_once 'user-update-form.php',
+        PasswordResetModel::class  => require_once 'password-reset-form.php',
+        PasswordChangeModel::class => require_once 'password-change-form.php',
+    ],
+    'controllers'        => [
         'factories' => [
             UserController::class => UserControllerFactory::class,
         ]
     ],
-    'listeners'       => [
+    'listeners'          => [
         ErrorListener::class,
         LocaleListener::class,
     ],
-    'view_helpers'    => [
+    'view_helpers'       => [
         'invokables' => [
             'formLabel' => RegistrationFormLabel::class,
         ],
@@ -64,7 +76,7 @@ return [
             'flashmessenger' => FlashMessenger::class,
         ]
     ],
-    'service_manager' => [
+    'service_manager'    => [
         'aliases'    => [
             BaseILSAuthenticator::class => ILSAuthenticator::class,
             'MvcTranslator'             => Translator::class,
@@ -84,7 +96,7 @@ return [
             LocaleListener::class   => InvokableFactory::class,
         ],
     ],
-    'vufind'          => [
+    'vufind'             => [
         'plugin_managers' => [
             'auth'       => [
                 'aliases'   => [
@@ -117,7 +129,7 @@ return [
             ],
         ],
     ],
-    'router'          => [
+    'router'             => [
         'routes' => [
             'fid'                => [
                 'type'          => 'literal',
@@ -133,7 +145,7 @@ return [
                             'route' => '/user',
                         ],
                         'child_routes'  => [
-                            'init'     => [
+                            'init'            => [
                                 'may_terminate' => true,
                                 'type'          => 'literal',
                                 'options'       => [
@@ -144,7 +156,7 @@ return [
                                     ],
                                 ],
                             ],
-                            'create'   => [
+                            'create'          => [
                                 'type'    => 'literal',
                                 'options' => [
                                     'route'    => '/create',
@@ -154,7 +166,7 @@ return [
                                     ],
                                 ],
                             ],
-                            'update'   => [
+                            'update'          => [
                                 'type'    => 'literal',
                                 'options' => [
                                     'route'    => '/update',
@@ -164,7 +176,7 @@ return [
                                     ],
                                 ],
                             ],
-                            'policy'   => [
+                            'policy'          => [
                                 'type'    => 'literal',
                                 'options' => [
                                     'route'    => '/policy',
@@ -174,7 +186,7 @@ return [
                                     ],
                                 ],
                             ],
-                            'terms'    => [
+                            'terms'           => [
                                 'type'    => 'literal',
                                 'options' => [
                                     'route'    => '/terms',
@@ -184,7 +196,7 @@ return [
                                     ],
                                 ],
                             ],
-                            'reset-password' => [
+                            'reset-password'  => [
                                 'type'    => 'literal',
                                 'options' => [
                                     'route'    => '/reset-password',
diff --git a/module/fid/config/password-change-form.php b/module/fid/config/password-change-form.php
new file mode 100644
index 0000000000000000000000000000000000000000..afddec4ca6b3114194584e71539dba6b3bfc456e
--- /dev/null
+++ b/module/fid/config/password-change-form.php
@@ -0,0 +1,124 @@
+<?php
+/**
+ * Copyright (C) 2019 Leipzig University Library
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * @author  Sebastian Kehr <kehr@ub.uni-leipzig.de>
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU GPLv2
+ */
+
+use Zend\Filter\StringTrim;
+use Zend\Form\Element\Password;
+use Zend\Form\Element\Submit;
+use Zend\Hydrator\ClassMethods;
+use Zend\Validator\Identical;
+use Zend\Validator\NotEmpty;
+use Zend\Validator\Regex;
+use Zend\Validator\StringLength;
+
+return [
+    'hydrator'     => ClassMethods::class,
+    'elements'     => [
+        'password'             => [
+            'spec' => [
+                'name'       => 'password',
+                'type'       => Password::class,
+                'options'    => [
+                    'label' => 'label_password',
+                ],
+                'attributes' => [
+                    'required' => 'required',
+                ],
+            ],
+        ],
+        'passwordConfirmation' => [
+            'spec' => [
+                'name'       => 'passwordConfirmation',
+                'type'       => Password::class,
+                'options'    => [
+                    'label' => 'label_password_confirmation',
+                ],
+                'attributes' => [
+                    'required' => 'required',
+                ],
+            ],
+        ],
+        'submit'               => [
+            'spec' => [
+                'name'       => 'submit',
+                'type'       => Submit::class,
+                'attributes' => [
+                    'value' => 'label_submit',
+                ],
+            ],
+        ],
+    ],
+    'input_filter' => [
+        'password'             => [
+            'name'       => 'password',
+            'required'   => true,
+            'filters'    => [
+                StringTrim::class => [
+                    'name' => StringTrim::class,
+                ],
+            ],
+            'validators' => [
+                StringLength::class => [
+                    'name'    => StringLength::class,
+                    'options' => [
+                        'min'      => 8,
+                        'max'      => 255,
+                        'messages' => [
+                            StringLength::TOO_SHORT => 'error_password_length',
+                            StringLength::TOO_LONG  => 'error_password_length',
+                        ],
+                    ],
+                ],
+                Regex::class        => [
+                    'name'    => Regex::class,
+                    'options' => [
+                        'pattern'  => '/(?:.*[0-9].*[^\w].*|.*[^\w].*[0-9].*)/',
+                        'messages' => [
+                            Regex::NOT_MATCH => 'error_password_pattern',
+                        ],
+                    ],
+                ],
+                Identical::class    => [
+                    'name'    => Identical::class,
+                    'options' => [
+                        'strict'   => false,
+                        'token'    => 'passwordConfirmation',
+                        'messages' => [
+                            Identical::NOT_SAME => 'error_password_confirmation',
+                        ],
+                    ],
+                ],
+            ],
+        ],
+        'passwordConfirmation' => [
+            'name'       => 'passwordConfirmation',
+            'required'   => true,
+            'validators' => [
+                NotEmpty::class => [
+                    'name' => NotEmpty::class,
+                ],
+            ],
+        ],
+        'submit'               => [
+            'name'     => 'submit',
+            'required' => true,
+        ],
+    ],
+];
\ No newline at end of file
diff --git a/module/fid/config/password-reset-form.php b/module/fid/config/password-reset-form.php
new file mode 100644
index 0000000000000000000000000000000000000000..e177096ef180c70b3d6330ed516232e9876c55d6
--- /dev/null
+++ b/module/fid/config/password-reset-form.php
@@ -0,0 +1,80 @@
+<?php
+/**
+ * Copyright (C) 2019 Leipzig University Library
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * @author  Sebastian Kehr <kehr@ub.uni-leipzig.de>
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU GPLv2
+ */
+
+use Zend\Filter\StringTrim;
+use Zend\Form\Element\Email;
+use Zend\Form\Element\Submit;
+use Zend\Hydrator\ClassMethods;
+use Zend\Validator\EmailAddress;
+use Zend\Validator\StringLength;
+
+return [
+    'hydrator'     => ClassMethods::class,
+    'elements'     => [
+        'username' => [
+            'spec' => [
+                'name'       => 'username',
+                'type'       => Email::class,
+                'options'    => [
+                    'label' => 'label_username',
+                ],
+                'attributes' => [
+                    'required' => 'required',
+                ],
+            ],
+        ],
+        'submit'   => [
+            'spec' => [
+                'name'       => 'submit',
+                'type'       => Submit::class,
+                'attributes' => [
+                    'value' => 'label_submit',
+                ],
+            ],
+        ],
+    ],
+    'input_filter' => [
+        'username'             => [
+            'name'       => 'username',
+            'required'   => true,
+            'filters'    => [
+                StringTrim::class => [
+                    'name' => StringTrim::class,
+                ],
+            ],
+            'validators' => [
+                StringLength::class => [
+                    'name'    => StringLength::class,
+                    'options' => [
+                        'max' => 255
+                    ],
+                ],
+                EmailAddress::class => [
+                    'name' => EmailAddress::class,
+                ],
+            ],
+        ],
+        'submit'               => [
+            'name'       => 'submit',
+            'required'   => true,
+        ],
+    ],
+];
\ No newline at end of file
diff --git a/module/fid/config/user-create-form.php b/module/fid/config/user-create-form.php
new file mode 100644
index 0000000000000000000000000000000000000000..3c8dada0f73f6a10b1e914e0a0c0b64c8c68bc4e
--- /dev/null
+++ b/module/fid/config/user-create-form.php
@@ -0,0 +1,414 @@
+<?php
+/**
+ * Copyright (C) 2019 Leipzig University Library
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * @author  Sebastian Kehr <kehr@ub.uni-leipzig.de>
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU GPLv2
+ */
+
+use Zend\Filter\Boolean;
+use Zend\Filter\StringTrim;
+use Zend\Filter\ToInt;
+use Zend\Filter\ToNull;
+use Zend\Form\Element\Checkbox;
+use Zend\Form\Element\Number;
+use Zend\Form\Element\Password;
+use Zend\Form\Element\Radio;
+use Zend\Form\Element\Select;
+use Zend\Form\Element\Submit;
+use Zend\Form\Element\Text;
+use Zend\Hydrator\ClassMethods;
+use Zend\Validator\EmailAddress;
+use Zend\Validator\Identical;
+use Zend\Validator\NotEmpty;
+use Zend\Validator\Regex;
+use Zend\Validator\StringLength;
+
+return [
+    'hydrator'     => ClassMethods::class,
+    'elements'     => [
+        'username'             => [
+            'spec' => [
+                'name'       => 'username',
+                'type'       => Text::class,
+                'options'    => [
+                    'label' => 'label_username',
+                ],
+                'attributes' => [
+                    'required' => 'required',
+                ],
+            ],
+        ],
+        'password'             => [
+            'spec' => [
+                'name'       => 'password',
+                'type'       => Password::class,
+                'options'    => [
+                    'label' => 'label_password',
+                ],
+                'attributes' => [
+                    'required' => 'required',
+                ],
+            ],
+        ],
+        'passwordConfirmation' => [
+            'spec' => [
+                'name'       => 'passwordConfirmation',
+                'type'       => Password::class,
+                'options'    => [
+                    'label' => 'label_password_confirmation',
+                ],
+                'attributes' => [
+                    'required' => 'required',
+                ],
+            ],
+        ],
+        'salutation'           => [
+            'spec' => [
+                'name'    => 'salutation',
+                'type'    => Select::class,
+                'options' => [
+                    'label'        => 'label_salutation',
+                    'options'      => [
+                        'mr'  => [
+                            'value' => 'mr',
+                            'label' => 'label_salutation_mr',
+                        ],
+                        'mrs' => [
+                            'value' => 'mrs',
+                            'label' => 'label_salutation_mrs',
+                        ]
+                    ],
+                    'empty_option' => '',
+                ],
+            ],
+        ],
+        'academicTitle'        => [
+            'spec' => [
+                'name'    => 'academicTitle',
+                'type'    => Text::class,
+                'options' => [
+                    'label' => 'label_academic_title',
+                ],
+            ],
+        ],
+        'firstname'            => [
+            'spec' => [
+                'name'       => 'firstname',
+                'type'       => Text::class,
+                'options'    => [
+                    'label' => 'label_firstname',
+                ],
+                'attributes' => [
+                    'required' => 'required',
+                ],
+            ],
+        ],
+        'lastname'             => [
+            'spec' => [
+                'name'       => 'lastname',
+                'type'       => Text::class,
+                'options'    => [
+                    'label' => 'label_lastname',
+                ],
+                'attributes' => [
+                    'required' => 'required',
+                ],
+            ],
+        ],
+        'homeLibrary'          => [
+            'spec' => [
+                'name'       => 'homeLibrary',
+                'type'       => Select::class,
+                'options'    => [
+                    'label'        => 'label_home_library',
+                    'empty_option' => '',
+                ],
+                'attributes' => [
+                    'required' => 'required',
+                ],
+            ],
+        ],
+        'accessLevel'          => [
+            'spec' => [
+                'name'       => 'accessLevel',
+                'type'       => Radio::class,
+                'options'    => [
+                    'label' => 'label_access_level',
+                ],
+                'attributes' => [
+                    'required' => 'required',
+                ],
+            ],
+        ],
+        'yearOfBirth'          => [
+            'spec' => [
+                'name'       => 'yearOfBirth',
+                'type'       => Number::class,
+                'options'    => [
+                    'label' => 'label_year_of_birth',
+                ],
+                'attributes' => [
+                    'min' => 1900,
+                    'max' => 2018,
+                ],
+            ]
+        ],
+        'jobTitle'             => [
+            'spec' => [
+                'name'    => 'jobTitle',
+                'type'    => Text::class,
+                'options' => [
+                    'label' => 'label_job_title',
+                ],
+            ],
+        ],
+        'college'              => [
+            'spec' => [
+                'name'    => 'college',
+                'type'    => Text::class,
+                'options' => [
+                    'label' => 'label_college',
+                ]
+            ],
+        ],
+        'eulaAccepted'         => [
+            'spec' => [
+                'name'       => 'eulaAccepted',
+                'type'       => Checkbox::class,
+                'attributes' => [
+                    'required' => 'required',
+                ],
+            ],
+        ],
+        'submit'               => [
+            'spec' => [
+                'name'       => 'submit',
+                'type'       => Submit::class,
+                'attributes' => [
+                    'value' => 'label_submit',
+                ],
+            ],
+        ],
+    ],
+    'input_filter' => [
+        'username'             => [
+            'name'       => 'username',
+            'required'   => true,
+            'filters'    => [
+                StringTrim::class => [
+                    'name' => StringTrim::class,
+                ],
+            ],
+            'validators' => [
+                StringLength::class => [
+                    'name'    => StringLength::class,
+                    'options' => [
+                        'max' => 255
+                    ],
+                ],
+                EmailAddress::class => [
+                    'name' => EmailAddress::class,
+                ],
+            ],
+        ],
+        'password'             => [
+            'name'       => 'password',
+            'required'   => true,
+            'filters'    => [
+                StringTrim::class => [
+                    'name' => StringTrim::class,
+                ],
+            ],
+            'validators' => [
+                StringLength::class => [
+                    'name'    => StringLength::class,
+                    'options' => [
+                        'min'      => 8,
+                        'max'      => 255,
+                        'messages' => [
+                            StringLength::TOO_SHORT => 'error_password_length',
+                            StringLength::TOO_LONG  => 'error_password_length',
+                        ],
+                    ],
+                ],
+                Regex::class        => [
+                    'name'    => Regex::class,
+                    'options' => [
+                        'pattern'  => '/(?:.*[0-9].*[^\w].*|.*[^\w].*[0-9].*)/',
+                        'messages' => [
+                            Regex::NOT_MATCH => 'error_password_pattern',
+                        ],
+                    ],
+                ],
+                Identical::class    => [
+                    'name'    => Identical::class,
+                    'options' => [
+                        'strict'   => false,
+                        'token'    => 'passwordConfirmation',
+                        'messages' => [
+                            Identical::NOT_SAME => 'error_password_confirmation',
+                        ],
+                    ],
+                ],
+            ],
+        ],
+        'passwordConfirmation' => [
+            'name'       => 'passwordConfirmation',
+            'required'   => true,
+            'validators' => [
+                NotEmpty::class => [
+                    'name' => NotEmpty::class,
+                ],
+            ],
+        ],
+        'salutation'           => [
+            'name'     => 'salutation',
+            'required' => false,
+            'filters'  => [
+                StringTrim::class => [
+                    'name' => StringTrim::class,
+                ],
+            ],
+        ],
+        'academicTitle'        => [
+            'name'     => 'academicTitle',
+            'required' => false,
+            'filters'  => [
+                StringTrim::class => [
+                    'name' => StringTrim::class,
+                ],
+            ],
+        ],
+        'firstname'            => [
+            'name'       => 'firstname',
+            'required'   => true,
+            'filters'    => [
+                StringTrim::class => [
+                    'name' => StringTrim::class,
+                ],
+            ],
+            'validators' => [
+                StringLength::class => [
+                    'name'    => StringLength::class,
+                    'options' => [
+                        'max' => 255
+                    ],
+                ],
+                Regex::class        => [
+                    'name'    => Regex::class,
+                    'options' => [
+                        'pattern' => '/^\D*$/',
+                    ],
+                ],
+            ],
+        ],
+        'lastname'             => [
+            'name'       => 'lastname',
+            'required'   => true,
+            'filters'    => [
+                StringTrim::class => [
+                    'name' => StringTrim::class,
+                ],
+            ],
+            'validators' => [
+                StringLength::class => [
+                    'name'    => StringLength::class,
+                    'options' => [
+                        'max' => 255
+                    ]
+                ],
+                Regex::class        => [
+                    'name'    => Regex::class,
+                    'options' => [
+                        'pattern' => '/^\D*$/',
+                    ],
+                ],
+            ],
+        ],
+        'homeLibrary'          => [
+            'name'     => 'homeLibrary',
+            'required' => true,
+            'filters'  => [
+                StringTrim::class => [
+                    'name' => StringTrim::class,
+                ],
+            ],
+        ],
+        'accessLevel'          => [
+            'name'     => 'accessLevel',
+            'required' => true,
+            'filters'  => [
+                StringTrim::class => [
+                    'name' => StringTrim::class,
+                ],
+            ],
+        ],
+        'yearOfBirth'          => [
+            'name'     => 'yearOfBirth',
+            'required' => false,
+            'filters'  => [
+                ToNull::class => [
+                    'name' => ToNull::class,
+                ],
+                ToInt::class  => [
+                    'name' => ToInt::class,
+                ],
+            ],
+        ],
+        'jobTitle'             => [
+            'name'     => 'jobTitle',
+            'required' => false,
+            'filters'  => [
+                StringTrim::class => [
+                    'name' => StringTrim::class,
+                ],
+            ],
+        ],
+        'college'              => [
+            'name'     => 'college',
+            'required' => false,
+            'filters'  => [
+                StringTrim::class => [
+                    'name' => StringTrim::class,
+                ],
+            ],
+        ],
+        'eulaAccepted'         => [
+            'name'       => 'eulaAccepted',
+            'required'   => true,
+            'filters'    => [
+                Boolean::class => [
+                    'name' => Boolean::class,
+                ],
+            ],
+            'validators' => [
+                NotEmpty::class => [
+                    'name'    => NotEmpty::class,
+                    'options' => [
+                        'messages' => [
+                            NotEmpty::IS_EMPTY => 'error_eula_accepted',
+                        ],
+                    ],
+                ],
+            ],
+        ],
+        'submit'               => [
+            'name'     => 'submit',
+            'required' => true,
+        ],
+    ],
+];
\ No newline at end of file
diff --git a/module/fid/config/user-init-form.php b/module/fid/config/user-init-form.php
new file mode 100644
index 0000000000000000000000000000000000000000..24a7a49a809cc36169ac9363aa6ce2763a62cc62
--- /dev/null
+++ b/module/fid/config/user-init-form.php
@@ -0,0 +1,212 @@
+<?php
+/**
+ * Copyright (C) 2019 Leipzig University Library
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * @author  Sebastian Kehr <kehr@ub.uni-leipzig.de>
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU GPLv2
+ */
+
+use Zend\Filter\Boolean;
+use Zend\Filter\StringTrim;
+use Zend\Form\Element\Checkbox;
+use Zend\Form\Element\Email;
+use Zend\Form\Element\Submit;
+use Zend\Form\Element\Text;
+use Zend\Hydrator\ClassMethods;
+use Zend\Validator\EmailAddress;
+use Zend\Validator\Identical;
+use Zend\Validator\NotEmpty;
+use Zend\Validator\Regex;
+use Zend\Validator\StringLength;
+
+return [
+    'hydrator'     => ClassMethods::class,
+    'elements'     => [
+        'username'             => [
+            'spec' => [
+                'name'       => 'username',
+                'type'       => Email::class,
+                'options'    => [
+                    'label' => 'label_username',
+                ],
+                'attributes' => [
+                    'required' => 'required',
+                ],
+            ],
+        ],
+        'usernameConfirmation' => [
+            'spec' => [
+                'name'       => 'usernameConfirmation',
+                'type'       => Text::class,
+                'options'    => [
+                    'label' => 'label_username_confirmation',
+                ],
+                'attributes' => [
+                    'required' => 'required',
+                ],
+            ],
+        ],
+        'firstname'            => [
+            'spec' => [
+                'name'       => 'firstname',
+                'type'       => Text::class,
+                'options'    => [
+                    'label' => 'label_firstname',
+                ],
+                'attributes' => [
+                    'required' => 'required',
+                ],
+            ],
+        ],
+        'lastname'             => [
+            'spec' => [
+                'name'       => 'lastname',
+                'type'       => Text::class,
+                'options'    => [
+                    'label' => 'label_lastname',
+                ],
+                'attributes' => [
+                    'required' => 'required',
+                ],
+            ],
+        ],
+        'eulaAccepted'         => [
+            'spec' => [
+                'name'       => 'eulaAccepted',
+                'type'       => Checkbox::class,
+                'attributes' => [
+                    'required' => 'required',
+                ],
+            ],
+        ],
+        'submit'               => [
+            'spec' => [
+                'name'       => 'submit',
+                'type'       => Submit::class,
+                'attributes' => [
+                    'value' => 'label_submit',
+                ],
+            ],
+        ],
+    ],
+    'input_filter' => [
+        'username'             => [
+            'name'       => 'username',
+            'required'   => true,
+            'filters'    => [
+                StringTrim::class => [
+                    'name' => StringTrim::class,
+                ],
+            ],
+            'validators' => [
+                StringLength::class => [
+                    'name'    => StringLength::class,
+                    'options' => [
+                        'max' => 255
+                    ],
+                ],
+                EmailAddress::class => [
+                    'name' => EmailAddress::class,
+                ],
+            ],
+        ],
+        'usernameConfirmation' => [
+            'name'       => 'usernameConfirmation',
+            'required'   => true,
+            'validators' => [
+                Identical::class => [
+                    'name'    => Identical::class,
+                    'options' => [
+                        'strict'   => false,
+                        'token'    => 'username',
+                        'messages' => [
+                            Identical::NOT_SAME => 'error_username_confirmation',
+                        ],
+                    ],
+                ],
+            ],
+        ],
+        'firstname'            => [
+            'name'       => 'firstname',
+            'required'   => true,
+            'filters'    => [
+                StringTrim::class => [
+                    'name' => StringTrim::class,
+                ],
+            ],
+            'validators' => [
+                StringLength::class => [
+                    'name'    => StringLength::class,
+                    'options' => [
+                        'max' => 255
+                    ]
+                ],
+                Regex::class        => [
+                    'name'    => Regex::class,
+                    'options' => [
+                        'pattern' => '/^\D*$/',
+                    ],
+                ],
+            ],
+        ],
+        'lastname'             => [
+            'name'       => 'lastname',
+            'required'   => true,
+            'filters'    => [
+                StringTrim::class => [
+                    'name' => StringTrim::class,
+                ],
+            ],
+            'validators' => [
+                StringLength::class => [
+                    'name'    => StringLength::class,
+                    'options' => [
+                        'max' => 255
+                    ]
+                ],
+                Regex::class        => [
+                    'name'    => Regex::class,
+                    'options' => [
+                        'pattern' => '/^\D*$/',
+                    ],
+                ],
+            ],
+        ],
+        'eulaAccepted'         => [
+            'name'       => 'eulaAccepted',
+            'required'   => true,
+            'filters'    => [
+                Boolean::class => [
+                    'name' => Boolean::class,
+                ],
+            ],
+            'validators' => [
+                NotEmpty::class => [
+                    'name'    => NotEmpty::class,
+                    'options' => [
+                        'messages' => [
+                            NotEmpty::IS_EMPTY => 'error_eula_accepted',
+                        ],
+                    ],
+                ],
+            ],
+        ],
+        'submit'               => [
+            'name'       => 'submit',
+            'required'   => true,
+        ],
+    ],
+];
\ No newline at end of file
diff --git a/module/fid/config/user-update-form.php b/module/fid/config/user-update-form.php
new file mode 100644
index 0000000000000000000000000000000000000000..6ce6b77daffa9c7d07559526d87f66f45a2cb675
--- /dev/null
+++ b/module/fid/config/user-update-form.php
@@ -0,0 +1,252 @@
+<?php
+/**
+ * Copyright (C) 2019 Leipzig University Library
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * @author  Sebastian Kehr <kehr@ub.uni-leipzig.de>
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU GPLv2
+ */
+
+use Zend\Filter\StringTrim;
+use Zend\Filter\ToInt;
+use Zend\Filter\ToNull;
+use Zend\Form\Element\Number;
+use Zend\Form\Element\Select;
+use Zend\Form\Element\Submit;
+use Zend\Form\Element\Text;
+use Zend\Hydrator\ClassMethods;
+use Zend\Validator\Regex;
+use Zend\Validator\StringLength;
+
+return [
+    'hydrator'     => ClassMethods::class,
+    'elements'     => [
+        'salutation'    => [
+            'spec' => [
+                'name'    => 'salutation',
+                'type'    => Select::class,
+                'options' => [
+                    'label'        => 'label_salutation',
+                    'options'      => [
+                        'mr'  => [
+                            'value' => 'mr',
+                            'label' => 'label_salutation_mr',
+                        ],
+                        'mrs' => [
+                            'value' => 'mrs',
+                            'label' => 'label_salutation_mrs',
+                        ]
+                    ],
+                    'empty_option' => '',
+                ],
+            ],
+        ],
+        'academicTitle' => [
+            'spec' => [
+                'name'    => 'academicTitle',
+                'type'    => Text::class,
+                'options' => [
+                    'label' => 'label_academic_title',
+                ],
+            ],
+        ],
+        'firstname'     => [
+            'spec' => [
+                'name'       => 'firstname',
+                'type'       => Text::class,
+                'options'    => [
+                    'label' => 'label_firstname',
+                ],
+                'attributes' => [
+                    'required' => 'required',
+                ],
+            ],
+        ],
+        'lastname'      => [
+            'spec' => [
+                'name'       => 'lastname',
+                'type'       => Text::class,
+                'options'    => [
+                    'label' => 'label_lastname',
+                ],
+                'attributes' => [
+                    'required' => 'required',
+                ],
+            ],
+        ],
+        'homeLibrary'   => [
+            'spec' => [
+                'name'       => 'homeLibrary',
+                'type'       => Select::class,
+                'options'    => [
+                    'label'        => 'label_home_library',
+                    'empty_option' => '',
+                ],
+                'attributes' => [
+                    'required' => 'required',
+                ],
+            ],
+        ],
+        'yearOfBirth'   => [
+            'spec' => [
+                'name'       => 'yearOfBirth',
+                'type'       => Number::class,
+                'options'    => [
+                    'label' => 'label_year_of_birth',
+                ],
+                'attributes' => [
+                    'min' => 1900,
+                    'max' => 2018,
+                ],
+            ]
+        ],
+        'jobTitle'      => [
+            'spec' => [
+                'name'    => 'jobTitle',
+                'type'    => Text::class,
+                'options' => [
+                    'label' => 'label_job_title',
+                ],
+            ],
+        ],
+        'college'       => [
+            'spec' => [
+                'name'    => 'college',
+                'type'    => Text::class,
+                'options' => [
+                    'label' => 'label_college',
+                ]
+            ],
+        ],
+        'submit'        => [
+            'spec' => [
+                'name'       => 'submit',
+                'type'       => Submit::class,
+                'attributes' => [
+                    'value' => 'label_submit',
+                ],
+            ],
+        ],
+    ],
+    'input_filter' => [
+        'salutation'    => [
+            'name'     => 'salutation',
+            'required' => false,
+            'filters'  => [
+                StringTrim::class => [
+                    'name' => StringTrim::class,
+                ],
+            ],
+        ],
+        'academicTitle' => [
+            'name'     => 'academicTitle',
+            'required' => false,
+            'filters'  => [
+                StringTrim::class => [
+                    'name' => StringTrim::class,
+                ],
+            ],
+        ],
+        'firstname'     => [
+            'name'       => 'firstname',
+            'required'   => true,
+            'filters'    => [
+                StringTrim::class => [
+                    'name' => StringTrim::class,
+                ],
+            ],
+            'validators' => [
+                StringLength::class => [
+                    'name'    => StringLength::class,
+                    'options' => [
+                        'max' => 255
+                    ],
+                ],
+                Regex::class        => [
+                    'name'    => Regex::class,
+                    'options' => [
+                        'pattern' => '/^\D*$/',
+                    ],
+                ],
+            ],
+        ],
+        'lastname'      => [
+            'name'       => 'lastname',
+            'required'   => true,
+            'filters'    => [
+                StringTrim::class => [
+                    'name' => StringTrim::class,
+                ],
+            ],
+            'validators' => [
+                StringLength::class => [
+                    'name'    => StringLength::class,
+                    'options' => [
+                        'max' => 255
+                    ]
+                ],
+                Regex::class        => [
+                    'name'    => Regex::class,
+                    'options' => [
+                        'pattern' => '/^\D*$/',
+                    ],
+                ],
+            ],
+        ],
+        'homeLibrary'   => [
+            'name'       => 'homeLibrary',
+            'required'   => true,
+            'filters'    => [
+                StringTrim::class => [
+                    'name' => StringTrim::class,
+                ],
+            ],
+        ],
+        'yearOfBirth'   => [
+            'name'     => 'yearOfBirth',
+            'required' => false,
+            'filters'  => [
+                ToNull::class => [
+                    'name' => ToNull::class,
+                ],
+                ToInt::class  => [
+                    'name' => ToInt::class,
+                ],
+            ],
+        ],
+        'jobTitle'      => [
+            'name'     => 'jobTitle',
+            'required' => false,
+            'filters'  => [
+                StringTrim::class => [
+                    'name' => StringTrim::class,
+                ],
+            ],
+        ],
+        'college'       => [
+            'name'     => 'college',
+            'required' => false,
+            'filters'  => [
+                StringTrim::class => [
+                    'name' => StringTrim::class,
+                ],
+            ],
+        ],
+        'submit'               => [
+            'name'       => 'submit',
+            'required'   => true,
+        ],
+    ],
+];
\ No newline at end of file
diff --git a/module/fid/src/Controller/UserController.php b/module/fid/src/Controller/UserController.php
index dff182627d652cc0a5c0216c610b06f19779aedf..10deb2e9c83e9068af4458f9494b7f2c95e9879d 100644
--- a/module/fid/src/Controller/UserController.php
+++ b/module/fid/src/Controller/UserController.php
@@ -32,11 +32,11 @@ use fid\Service\ClientException;
 use fid\Service\DataTransferObject\Library;
 use fid\Service\DataTransferObject\User;
 use Symfony\Component\Serializer\SerializerAwareTrait;
-use Symfony\Component\Serializer\SerializerInterface;
-use VuFind\Auth\Manager as Authenticator;
+use VuFind\Auth\Manager as AuthManager;
 use VuFind\Controller\AbstractBase;
 use VuFind\Exception\Auth as AuthException;
-use Zend\Form\Annotation\AnnotationBuilder;
+use Zend\Form\Element\Radio;
+use Zend\Form\Element\Select;
 use Zend\Form\Form;
 use Zend\Http\PhpEnvironment\Request;
 use Zend\Http\Response;
@@ -49,19 +49,9 @@ class UserController extends AbstractBase
     use SerializerAwareTrait;
 
     /**
-     * @var Authenticator
+     * @var AuthManager
      */
-    protected $authenticator;
-
-    /**
-     * @var SerializerInterface
-     */
-    protected $serializer;
-
-    /**
-     * @var AnnotationBuilder
-     */
-    protected $builder;
+    protected $authManager;
 
     /**
      * @var Client
@@ -77,24 +67,18 @@ class UserController extends AbstractBase
      * RegistrationController constructor.
      *
      * @param ServiceLocatorInterface $serviceLocator
-     * @param SerializerInterface     $serializer
-     * @param Authenticator           $authenticator
-     * @param AnnotationBuilder       $builder
+     * @param AuthManager             $authManager
      * @param Client                  $client
      * @param array                   $config
      */
     public function __construct(
         ServiceLocatorInterface $serviceLocator,
-        SerializerInterface $serializer,
-        Authenticator $authenticator,
-        AnnotationBuilder $builder,
+        AuthManager $authManager,
         Client $client,
         array $config
     ) {
         parent::__construct($serviceLocator);
-        $this->authenticator = $authenticator;
-        $this->serializer = $serializer;
-        $this->builder = $builder;
+        $this->authManager = $authManager;
         $this->client = $client;
         $this->config = $config;
     }
@@ -106,7 +90,7 @@ class UserController extends AbstractBase
     {
         /** @var Request $request */
         $request = $this->getRequest();
-        $form = $this->builder->createForm(UserInitModel::class);
+        $form = $this->serviceLocator->get(UserInitModel::class);
         $forwarded = $this->params()->fromRoute('forwarded', false);
 
         if ($submitted = $this->formWasSubmitted()) {
@@ -150,17 +134,6 @@ class UserController extends AbstractBase
             ]);
         }
 
-        $form = $this->builder->createForm(UserCreateModel::class);
-
-        if ($this->formWasSubmitted()) {
-            $form->setData($request->getPost());
-            if ($form->isValid()) {
-                return $this->create($form);
-            }
-        } else {
-            $form->setData($query);
-        }
-
         try {
             $libraries = array_map(function (Library $libary) {
                 return $libary->getLabel();
@@ -171,9 +144,32 @@ class UserController extends AbstractBase
             return $this->redirect()->toRoute('fid/user/init');
         }
 
-        $view = $this->createViewModel();
+        /** @var Form $form */
+        $form = $this->serviceLocator->get(UserCreateModel::class);
+
+        /** @var Select $homeLibraryElement */
+        $homeLibraryElement = $form->get('homeLibrary');
+        $homeLibraryElement->setValueOptions($libraries);
+
+        /** @var Radio $accessLevelElement */
+        $accessLevelElement = $form->get('accessLevel');
         $accessLevels = $this->config['Security']['access_levels'];
-        $view->setVariables(compact('form', 'accessLevels', 'libraries'));
+        $accessLevelValueOptions = array_map(function ($accessLevel) {
+            return "label_access_level_$accessLevel";
+        }, array_combine($accessLevels, $accessLevels));
+        $accessLevelElement->setValueOptions($accessLevelValueOptions);
+
+        if ($this->formWasSubmitted()) {
+            $form->setData($request->getPost());
+            if ($form->isValid()) {
+                return $this->create($form);
+            }
+        } else {
+            $form->setData($query);
+        }
+
+        $view = $this->createViewModel();
+        $view->setVariables(compact('form'));
         $view->setTemplate('fid/user/create');
 
         return $view;
@@ -183,14 +179,6 @@ class UserController extends AbstractBase
     {
         /** @var Request $request */
         $request = $this->getRequest();
-        $form = $this->builder->createForm(UserUpdateModel::class);
-
-        if ($this->formWasSubmitted()) {
-            $form->setData($request->getPost());
-            if ($form->isValid()) {
-                return $this->update($form);
-            }
-        }
 
         try {
             $user = $this->client->requestUserDetails();
@@ -206,8 +194,22 @@ class UserController extends AbstractBase
             return $this->redirect()->toRoute('myresearch-home');
         }
 
+        /** @var Form $form */
+        $form = $this->serviceLocator->get(UserUpdateModel::class);
+
+        /** @var Select $homeLibraryElement */
+        $homeLibraryElement = $form->get('homeLibrary');
+        $homeLibraryElement->setValueOptions($libraries);
+
+        if ($this->formWasSubmitted()) {
+            $form->setData($request->getPost());
+            if ($form->isValid()) {
+                return $this->update($form);
+            }
+        }
+
         $viewModel = $this->createViewModel();
-        $viewModel->setVariables(compact('form', 'user', 'libraries'));
+        $viewModel->setVariables(compact('form', 'user'));
         $viewModel->setTemplate('fid/user/update');
 
         return $viewModel;
@@ -244,9 +246,10 @@ class UserController extends AbstractBase
      */
     public function resetPasswordAction()
     {
+        /** @var Form $form */
         /** @var Request $request */
         $request = $this->getRequest();
-        $form = $this->builder->createForm(PasswordResetModel::class);
+        $form = $this->serviceLocator->get(PasswordResetModel::class);
         $forwarded = $this->params()->fromRoute('forwarded', false);
 
         if ($submitted = $this->formWasSubmitted()) {
@@ -292,7 +295,7 @@ class UserController extends AbstractBase
             ]);
         }
 
-        $form = $this->builder->createForm(PasswordChangeModel::class);
+        $form = $this->serviceLocator->get(PasswordChangeModel::class);
 
         if ($this->formWasSubmitted()) {
             $form->setData($request->getPost());
@@ -374,7 +377,7 @@ class UserController extends AbstractBase
             $message = $this->translate('fid::user_create_success');
             $messenger->addSuccessMessage($message);
             /** @noinspection PhpParamsInspection */
-            $this->authenticator->create($this->getRequest());
+            $this->authManager->create($this->getRequest());
         } catch (ClientException $exception) {
             $message = $this->translate('fid::user_create_error');
             $messenger->addErrorMessage($message);
@@ -415,7 +418,8 @@ class UserController extends AbstractBase
             $messenger->addSuccessMessage($message);
         } catch (ClientException $exception) {
             if (in_array($exception->getCode(), [403])) {
-                $message = $this->translate('fid::user_update_error_' . $exception->getCode());
+                $message = $this->translate('fid::user_update_error_'
+                    . $exception->getCode());
             } else {
                 $message = $this->translate('fid::user_update_error');
             }
@@ -475,7 +479,7 @@ class UserController extends AbstractBase
             $params->set('username', $username);
             $params->set('password', $password);
             $request->setPost($params);
-            $this->authenticator->create($request);
+            $this->authManager->create($request);
         } catch (ClientException $exception) {
             $message = $this->translate('fid::password_change_error');
             $messenger->addErrorMessage($message);
diff --git a/module/fid/src/Controller/UserControllerFactory.php b/module/fid/src/Controller/UserControllerFactory.php
index 6706b160fb3ee80b7f6e7290a5b9e0be7c9be989..03febcf316f473a955095e7132e21742c2c02a43 100644
--- a/module/fid/src/Controller/UserControllerFactory.php
+++ b/module/fid/src/Controller/UserControllerFactory.php
@@ -24,12 +24,9 @@ namespace fid\Controller;
 
 use fid\Service\Client;
 use Psr\Container\ContainerInterface;
-use Symfony\Component\Serializer\SerializerInterface;
 use VuFind\Auth\Manager as AuthManager;
-use VuFind\Config\PluginManager;
-use Zend\Form\Annotation\AnnotationBuilder;
+use VuFind\Config\PluginManager as ConfigManager;
 use Zend\ServiceManager\ServiceLocatorInterface;
-use Zend\Validator\ValidatorPluginManager;
 
 class UserControllerFactory
 {
@@ -40,24 +37,9 @@ class UserControllerFactory
      */
     public function __invoke(ContainerInterface $container)
     {
-        /** @var ValidatorPluginManager $plugins */
-        $plugins = $container->get(ValidatorPluginManager::class);
-
-        $builder = new AnnotationBuilder();
-        $builder->getFormFactory()->getInputFilterFactory()
-            ->getDefaultValidatorChain()->setPluginManager($plugins);
-
-        /** @var Client $client */
         $client = $container->get(Client::class);
-        /** @var AuthManager $authManager */
         $authManager = $container->get(AuthManager::class);
-
-        /** @var SerializerInterface $serializer */
-        $serializer = $container->get(SerializerInterface::class);
-
-        $config = $container->get(PluginManager::class)->get('fid')->toArray();
-
-        return new UserController($container, $serializer, $authManager,
-            $builder, $client, $config);
+        $config = $container->get(ConfigManager::class)->get('fid')->toArray();
+        return new UserController($container, $authManager, $client, $config);
     }
 }
\ No newline at end of file
diff --git a/module/fid/src/FormModel/PasswordChangeModel.php b/module/fid/src/FormModel/PasswordChangeModel.php
index 20d59851125710c0778c75bfbdb903ff71eaac7c..23fce4b0053ca1956cebe701f73595c6b736127c 100644
--- a/module/fid/src/FormModel/PasswordChangeModel.php
+++ b/module/fid/src/FormModel/PasswordChangeModel.php
@@ -22,60 +22,20 @@
 
 namespace fid\FormModel;
 
-use Zend\Form\Annotation;
-
-/**
- * @Annotation\Name("passwordchange")
- * @Annotation\Hydrator("Zend\Hydrator\ClassMethods")
- */
 class PasswordChangeModel
 {
     /**
      * @var string
-     * @Annotation\Type("Zend\Form\Element\Password")
-     * @Annotation\Required({"required":"true"})
-     * @Annotation\Filter({"name":"StringTrim"})
-     * @Annotation\Validator({
-     *     "name":"StringLength", "options":{
-     *          "min":8, "max":255,
-     *          "messages": {
-     *              "stringLengthTooShort": "error_password_length",
-     *              "stringLengthTooLong": "error_password_length"
-     *          }
-     *     }
-     * })
-     * @Annotation\Validator({
-     *     "name": "Regex", "options": {
-     *          "pattern": "/(?:.*[0-9].*[^\w].*|.*[^\w].*[0-9].*)/",
-     *          "messages": {
-     *              "regexNotMatch": "error_password_pattern"
-     *          }
-     *      }
-     * })
-     * @Annotation\Validator({
-     *     "name": "Identical", "options": {
-     *          "strict": false,
-     *          "token": "passwordConfirmation",
-     *          "messages": {"notSame": "error_password_confirmation"}
-     *     }
-     * })
-     * @Annotation\Options({"label": "label_password"})
      */
     protected $password;
 
     /**
      * @var string
-     * @Annotation\Type("Zend\Form\Element\Password")
-     * @Annotation\Required({"required":"true"})
-     * @Annotation\AllowEmpty()
-     * @Annotation\Options({"label": "label_password_confirmation"})
      */
     protected $passwordConfirmation;
 
     /**
      * @var string
-     * @Annotation\Type("Zend\Form\Element\Submit")
-     * @Annotation\Attributes({"value": "label_submit"})
      */
     protected $submit;
 
diff --git a/module/fid/src/FormModel/PasswordResetModel.php b/module/fid/src/FormModel/PasswordResetModel.php
index 2089e06991f46360e4ccfca033dca187df9198d4..a4da7532638c0d8b732ef36550eff7e60c8aefae 100644
--- a/module/fid/src/FormModel/PasswordResetModel.php
+++ b/module/fid/src/FormModel/PasswordResetModel.php
@@ -22,33 +22,16 @@
 
 namespace fid\FormModel;
 
-use Zend\Form\Annotation;
-
-/**
- * @Annotation\Name("passwordreset")
- * @Annotation\Hydrator("Zend\Hydrator\ClassMethods")
- */
 class PasswordResetModel
 {
     /**
      * @var string
-     * @Annotation\Type("Zend\Form\Element\Email")
-     * @Annotation\Required({"required":"true"})
-     * @Annotation\Filter({"name": "StringTrim"})
-     * @Annotation\Validator({
-     *     "name": "StringLength",
-     *     "options": {"min": 1, "max": 255}
-     * })
-     * @Annotation\Validator({"name": "Zend\Validator\EmailAddress"})
-     * @Annotation\Options({"label": "label_username"})
      */
     protected $username;
 
 
     /**
      * @var string
-     * @Annotation\Type("Zend\Form\Element\Submit")
-     * @Annotation\Attributes({"value": "label_submit"})
      */
     protected $submit;
 
diff --git a/module/fid/src/FormModel/UserCreateModel.php b/module/fid/src/FormModel/UserCreateModel.php
index b70d5b33765d652f6ca58e3d28ff40057ff04127..59821135110b7ea948f9b99e831b54cbb2aac146 100644
--- a/module/fid/src/FormModel/UserCreateModel.php
+++ b/module/fid/src/FormModel/UserCreateModel.php
@@ -22,198 +22,75 @@
 
 namespace fid\FormModel;
 
-use Zend\Form\Annotation;
-
-/**
- * @Annotation\Name("user_create")
- * @Annotation\Hydrator("Zend\Hydrator\ClassMethods")
- */
 class UserCreateModel
 {
     /**
      * @var string
-     * @Annotation\Type("Zend\Form\Element\Text")
-     * @Annotation\Required(true)
-     * @Annotation\Options({"label": "label_username"})
      */
     protected $username;
 
     /**
      * @var string
-     * @Annotation\Type("Zend\Form\Element\Password")
-     * @Annotation\Required(true)
-     * @Annotation\Filter({"name":"StringTrim"})
-     * @Annotation\Validator({
-     *     "name":"StringLength", "options":{
-     *          "min":8, "max":255, "messages": {
-     *              "stringLengthTooShort": "error_password_length",
-     *              "stringLengthTooLong": "error_password_length"
-     *          }
-     *     }
-     * })
-     * @Annotation\Validator({
-     *     "name": "Regex", "options": {
-     *          "pattern": "/(?:.*[0-9].*[^\w].*|.*[^\w].*[0-9].*)/",
-     *          "messages": {
-     *              "regexNotMatch": "error_password_pattern"
-     *          }
-     *      }
-     * })
-     * @Annotation\Validator({
-     *     "name": "Identical", "options": {
-     *          "strict": false,
-     *          "token": "passwordConfirmation",
-     *          "messages": {"notSame": "error_password_confirmation"}
-     *     }
-     * })
-     * @Annotation\Options({"label": "label_password"})
      */
     protected $password;
 
     /**
      * @var string
-     * @Annotation\Type("Zend\Form\Element\Password")
-     * @Annotation\Required(true)
-     * @Annotation\Validator({"name":"NotEmpty"})
-     * @Annotation\Options({"label":"label_password_confirmation"})
      */
     protected $passwordConfirmation;
 
     /**
      * @var string
-     * @Annotation\Type("Zend\Form\Element\Select")
-     * @Annotation\Required(false)
-     * @Annotation\Options({
-     *     "label": "label_salutation",
-     *     "empty_option": "",
-     *     "options":{
-     *          {"value": "mr", "label": "label_salutation_mr"},
-     *          {"value": "mrs", "label": "label_salutation_mrs"}
-     *     }
-     * })
      */
     protected $salutation;
 
     /**
      * @var string
-     * @Annotation\Type("Zend\Form\Element\Text")
-     * @Annotation\Required(false)
-     * @Annotation\Filter({"name":"StringTrim"})
-     * @Annotation\Options({"label": "label_academic_title"})
      */
     protected $academicTitle;
 
     /**
      * @var string
-     * @Annotation\Type("Zend\Form\Element\Text")
-     * @Annotation\Required(true)
-     * @Annotation\Filter({"name":"StringTrim"})
-     * @Annotation\Validator({
-     *     "name": "StringLength",
-     *     "options": {"min": 1, "max": 255}
-     * })
-     * @Annotation\Validator({"name": "Zend\Validator\NotEmpty"})
-     * @Annotation\Validator({
-     *     "name": "Regex",
-     *     "options": {"pattern": "/^\D*$/"}
-     * })
-     * @Annotation\Options({"label": "label_firstname"})
      */
     protected $firstname;
 
     /**
      * @var string
-     * @Annotation\Type("Zend\Form\Element\Text")
-     * @Annotation\Required(true)
-     * @Annotation\Filter({"name": "StringTrim"})
-     * @Annotation\Validator({
-     *     "name": "StringLength",
-     *     "options": {"min":1, "max":255}
-     * })
-     * @Annotation\Validator({"name": "Zend\Validator\NotEmpty"})
-     * @Annotation\Validator({
-     *     "name": "Regex",
-     *     "options": {"pattern":"/^\D*$/"}
-     * })
-     * @Annotation\Options({"label": "label_lastname"})
      */
     protected $lastname;
 
     /**
      * @var string
-     * @Annotation\Type("Zend\Form\Element\Select")
-     * @Annotation\Required(true)
-     * @Annotation\Validator({
-     *     "name": "StringLength",
-     *     "options": {"min":1, "max":255}
-     * })
-     * @Annotation\Options({
-     *     "label": "label_home_library",
-     *     "disable_inarray_validator": true,
-     *     "empty_option": ""
-     * })
      */
     protected $homeLibrary;
 
     /**
      * @var string
-     * @Annotation\Type("Zend\Form\Element\Radio")
-     * @Annotation\Required(true)
-     * @Annotation\Options({
-     *     "label": "label_access_level",
-     *     "disable_inarray_validator": true
-     * })
      */
     protected $accessLevel;
 
     /**
      * @var int|null
-     * @Annotation\Type("Zend\Form\Element\Number")
-     * @Annotation\Required(false)
-     * @Annotation\Attributes({"min": 1900, "max": 2018})
-     * @Annotation\Options({"label": "label_year_of_birth"})
-     * @Annotation\Filter({"name": "ToNull"})
-     * @Annotation\Filter({"name": "ToInt"})
      */
     protected $yearOfBirth;
 
     /**
      * @var string
-     * @Annotation\Type("Zend\Form\Element\Text")
-     * @Annotation\Required(false)
-     * @Annotation\Filter({"name":"StringTrim"})
-     * @Annotation\Options({"label": "label_job_title"})
      */
     protected $jobTitle;
 
     /**
      * @var string
-     * @Annotation\Type("Zend\Form\Element\Text")
-     * @Annotation\Filter({"name":"StringTrim"})
-     * @Annotation\Required(false)
-     * @Annotation\Options({"label": "label_college"})
      */
     protected $college;
 
     /**
      * @var bool
-     * @Annotation\Type("Zend\Form\Element\Checkbox")
-     * @Annotation\Required(true)
-     * @Annotation\Filter({"name": "Boolean"})
-     * @Annotation\Validator({
-     *     "name": "Identical", "options": {
-     *          "token": true,
-     *          "messages": {"notSame": "error_eula_accepted"}
-     *     }
-     * })
      */
     protected $eulaAccepted;
 
     /**
      * @var string
-     * @Annotation\Required(true)
-     * @Annotation\Type("Zend\Form\Element\Submit")
-     * @Annotation\Attributes({"value": "label_submit"})
      */
     protected $submit;
 
diff --git a/module/fid/src/FormModel/UserInitModel.php b/module/fid/src/FormModel/UserInitModel.php
index bce1dcc44b598ebd2e3f2cbdb463c819131de1b1..6d48255e633f5a55cced7f8c63386a1c37ff30d2 100644
--- a/module/fid/src/FormModel/UserInitModel.php
+++ b/module/fid/src/FormModel/UserInitModel.php
@@ -22,99 +22,35 @@
 
 namespace fid\FormModel;
 
-use Zend\Form\Annotation;
-
-/**
- * @Annotation\Name("user_init")
- * @Annotation\Hydrator("Zend\Hydrator\ClassMethods")
- */
 class UserInitModel
 {
     /**
      * @var string
-     * @Annotation\Type("Zend\Form\Element\Email")
-     * @Annotation\Required(true)
-     * @Annotation\Filter({"name": "StringTrim"})
-     * @Annotation\Validator({
-     *     "name": "StringLength",
-     *     "options": {"min": 1, "max": 255}
-     * })
-     * @Annotation\Validator({"name": "Zend\Validator\EmailAddress"})
-     * @Annotation\Options({"label": "label_username"})
      */
     protected $username;
 
     /**
      * @var string
-     * @Annotation\Type("Zend\Form\Element\Text")
-     * @Annotation\Required(true)
-     * @Annotation\Validator({
-     *     "name": "Zend\Validator\Identical",
-     *     "options": {
-     *         "strict": false,
-     *         "token": "username",
-     *         "messages": { "notSame": "error_username_confirmation" }
-     *     }
-     * })
-     * @Annotation\Options({"label": "label_username_confirmation"})
      */
     protected $usernameConfirmation;
 
     /**
      * @var string
-     * @Annotation\Type("Zend\Form\Element\Text")
-     * @Annotation\Required(true)
-     * @Annotation\Filter({"name":"StringTrim"})
-     * @Annotation\Validator({
-     *     "name": "StringLength",
-     *     "options": {"min": 1, "max": 255}
-     * })
-     * @Annotation\Validator({"name": "Zend\Validator\NotEmpty"})
-     * @Annotation\Validator({
-     *     "name": "Regex",
-     *     "options": {"pattern": "/^\D*$/"}
-     * })
-     * @Annotation\Options({"label": "label_firstname"})
      */
     protected $firstname;
 
     /**
      * @var string
-     * @Annotation\Type("Zend\Form\Element\Text")
-     * @Annotation\Required(true)
-     * @Annotation\Filter({"name": "StringTrim"})
-     * @Annotation\Validator({
-     *     "name": "StringLength",
-     *     "options": {"min":1, "max":255}
-     * })
-     * @Annotation\Validator({"name": "Zend\Validator\NotEmpty"})
-     * @Annotation\Validator({
-     *     "name": "Regex",
-     *     "options": {"pattern":"/^\D*$/"}
-     * })
-     * @Annotation\Options({"label": "label_lastname"})
      */
     protected $lastname;
 
     /**
      * @var bool
-     * @Annotation\Type("Zend\Form\Element\Checkbox")
-     * @Annotation\Required(true)
-     * @Annotation\Validator({"name":"NotEmpty"})
-     * @Annotation\Filter({"name": "Boolean"})
-     * @Annotation\Validator({
-     *     "name": "Identical", "options": {
-     *          "token": true,
-     *          "messages": {"notSame": "error_eula_accepted"}
-     *     }
-     * })
      */
     protected $eulaAccepted;
 
     /**
      * @var string
-     * @Annotation\Type("Zend\Form\Element\Submit")
-     * @Annotation\Attributes({"value": "label_submit"})
      */
     protected $submit;
 
diff --git a/module/fid/src/FormModel/UserUpdateModel.php b/module/fid/src/FormModel/UserUpdateModel.php
index 28de1a1ef8af0a8ccd5469271517cfec6645b05a..e6bda2be41d7a7a684bd70f41a6db0e76dd9f0dd 100644
--- a/module/fid/src/FormModel/UserUpdateModel.php
+++ b/module/fid/src/FormModel/UserUpdateModel.php
@@ -22,123 +22,50 @@
 
 namespace fid\FormModel;
 
-use Zend\Form\Annotation;
-
-/**
- * @Annotation\Name("user_update")
- * @Annotation\Hydrator("Zend\Hydrator\ClassMethods")
- */
 class UserUpdateModel
 {
     /**
      * @var string
-     * @Annotation\Type("Zend\Form\Element\Select")
-     * @Annotation\Required(false)
-     * @Annotation\Options({
-     *     "label": "label_salutation",
-     *     "empty_option": "",
-     *     "options":{
-     *          {"value": "mr", "label": "label_salutation_mr"},
-     *          {"value": "mrs", "label": "label_salutation_mrs"}
-     *     }
-     * })
      */
     protected $salutation;
 
     /**
      * @var string
-     * @Annotation\Type("Zend\Form\Element\Text")
-     * @Annotation\Required(false)
-     * @Annotation\Filter({"name":"StringTrim"})
-     * @Annotation\Options({"label": "label_academic_title"})
      */
     protected $academicTitle;
 
     /**
      * @var string
-     * @Annotation\Type("Zend\Form\Element\Text")
-     * @Annotation\Required(true)
-     * @Annotation\Filter({"name":"StringTrim"})
-     * @Annotation\Validator({
-     *     "name": "StringLength",
-     *     "options": {"min": 1, "max": 255}
-     * })
-     * @Annotation\Validator({"name": "Zend\Validator\NotEmpty"})
-     * @Annotation\Validator({
-     *     "name": "Regex",
-     *     "options": {"pattern": "/^\D*$/"}
-     * })
-     * @Annotation\Options({"label": "label_firstname"})
      */
     protected $firstname;
 
     /**
      * @var string
-     * @Annotation\Type("Zend\Form\Element\Text")
-     * @Annotation\Required(true)
-     * @Annotation\Filter({"name": "StringTrim"})
-     * @Annotation\Validator({
-     *     "name": "StringLength",
-     *     "options": {"min":1, "max":255}
-     * })
-     * @Annotation\Validator({"name": "Zend\Validator\NotEmpty"})
-     * @Annotation\Validator({
-     *     "name": "Regex",
-     *     "options": {"pattern":"/^\D*$/"}
-     * })
-     * @Annotation\Options({"label": "label_lastname"})
      */
     protected $lastname;
 
     /**
      * @var string
-     * @Annotation\Type("Zend\Form\Element\Select")
-     * @Annotation\Required(true)
-     * @Annotation\Validator({
-     *     "name": "StringLength",
-     *     "options": {"min":1, "max":255}
-     * })
-     * @Annotation\Options({
-     *     "label": "label_home_library",
-     *     "disable_inarray_validator": true,
-     *     "empty_option": ""
-     * })
      */
     protected $homeLibrary;
 
     /**
      * @var int|null
-     * @Annotation\Type("Zend\Form\Element\Number")
-     * @Annotation\Required(false)
-     * @Annotation\Attributes({"min": 1900, "max": 2018})
-     * @Annotation\Options({"label": "label_year_of_birth"})
-     * @Annotation\Filter({"name": "ToNull"})
-     * @Annotation\Filter({"name": "ToInt"})
      */
     protected $yearOfBirth;
 
     /**
      * @var string
-     * @Annotation\Type("Zend\Form\Element\Text")
-     * @Annotation\Required(false)
-     * @Annotation\Filter({"name":"StringTrim"})
-     * @Annotation\Options({"label": "label_job_title"})
      */
     protected $jobTitle;
 
     /**
      * @var string
-     * @Annotation\Type("Zend\Form\Element\Text")
-     * @Annotation\Filter({"name":"StringTrim"})
-     * @Annotation\Required(false)
-     * @Annotation\Options({"label": "label_college"})
      */
     protected $college;
 
     /**
      * @var string|null
-     * @Annotation\Type("Zend\Form\Element\Submit")
-     * @Annotation\Attributes({"value": "label_submit"})
      */
     protected $submit;
 
diff --git a/themes/fid/templates/fid/user/create.phtml b/themes/fid/templates/fid/user/create.phtml
index 35a227f3e846323370b0ecb4cc04cdae60720eaf..7b6f4e7596ae9eec3a886192a4ed2c5e168279e9 100644
--- a/themes/fid/templates/fid/user/create.phtml
+++ b/themes/fid/templates/fid/user/create.phtml
@@ -66,9 +66,9 @@ $this->headTitle($this->translate("fid::user_create_form_title"));
 
 <?= $this->flashmessages() ?>
 <?= $this->form()->openTag($form) ?>
-<h2><?= $this->translate("fid::user_create_form_title") ?></h2>
+    <h2><?= $this->translate("fid::user_create_form_title") ?></h2>
     <div class="subito-pg">
-        * <?=$this->transEsc("This field is required")?>
+        * <?= $this->transEsc("This field is required") ?>
     </div>
 <? /* username */ ?>
 <?php
@@ -77,16 +77,16 @@ $elemUsername = $form->get('username');
 $elemUsername->setLabelAttributes(['class' => 'col-md-4']);
 $elemUsername->setAttributes(['class' => 'form-control', 'disabled' => 1]);
 ?>
-<div class="form-group">
-    <?= $this->formLabel($elemUsername) ?>
-    <?= $this->formElement($elemUsername) ?>
-    <?= $this->formElementErrors($elemUsername) ?>
-    <?php
-    $elemUsername->removeAttribute('disabled');
-    $elemUsername->setAttribute('type', 'hidden');
-    echo $this->formElement($elemUsername);
-    ?>
-</div>
+    <div class="form-group">
+        <?= $this->formLabel($elemUsername) ?>
+        <?= $this->formElement($elemUsername) ?>
+        <?= $this->formElementErrors($elemUsername) ?>
+        <?php
+        $elemUsername->removeAttribute('disabled');
+        $elemUsername->setAttribute('type', 'hidden');
+        echo $this->formElement($elemUsername);
+        ?>
+    </div>
 
 <? /* password */ ?>
 <?php
@@ -95,11 +95,11 @@ $elemPassword = $form->get('password');
 $elemPassword->setLabelAttributes(['class' => 'col-md-4']);
 $elemPassword->setAttributes(['class' => 'form-control']);
 ?>
-<div class="form-group">
-    <?= $this->formLabel($elemPassword) ?>
-    <?= $this->formElement($elemPassword) ?>
-    <?= $this->formElementErrors($elemPassword) ?>
-</div>
+    <div class="form-group">
+        <?= $this->formLabel($elemPassword) ?>
+        <?= $this->formElement($elemPassword) ?>
+        <?= $this->formElementErrors($elemPassword) ?>
+    </div>
 
 <? /* password confirmation */ ?>
 <?php
@@ -108,11 +108,11 @@ $elemPasswordConfirmation = $form->get('passwordConfirmation');
 $elemPasswordConfirmation->setLabelAttributes(['class' => 'col-md-4']);
 $elemPasswordConfirmation->setAttributes(['class' => 'form-control']);
 ?>
-<div class="form-group">
-    <?= $this->formLabel($elemPasswordConfirmation) ?>
-    <?= $this->formElement($elemPasswordConfirmation) ?>
-    <?= $this->formElementErrors($elemPasswordConfirmation) ?>
-</div>
+    <div class="form-group">
+        <?= $this->formLabel($elemPasswordConfirmation) ?>
+        <?= $this->formElement($elemPasswordConfirmation) ?>
+        <?= $this->formElementErrors($elemPasswordConfirmation) ?>
+    </div>
 
 <? /* home library */ ?>
 <?php
@@ -120,13 +120,12 @@ $elemPasswordConfirmation->setAttributes(['class' => 'form-control']);
 $elemHomeLibrary = $form->get('homeLibrary');
 $elemHomeLibrary->setLabelAttributes(['class' => 'col-md-4']);
 $elemHomeLibrary->setAttributes(['class' => 'form-control']);
-$elemHomeLibrary->setValueOptions($this->libraries);
 ?>
-<div class="form-group">
-    <?= $this->formLabel($elemHomeLibrary) ?>
-    <?= $this->formSelect($elemHomeLibrary) ?>
-    <?= $this->formElementErrors($elemHomeLibrary) ?>
-</div>
+    <div class="form-group">
+        <?= $this->formLabel($elemHomeLibrary) ?>
+        <?= $this->formSelect($elemHomeLibrary) ?>
+        <?= $this->formElementErrors($elemHomeLibrary) ?>
+    </div>
 
 <? /* salutation */ ?>
 <?php
@@ -135,10 +134,10 @@ $elemSalutation = $form->get('salutation');
 $elemSalutation->setLabelAttributes(['class' => 'col-md-4']);
 $elemSalutation->setAttributes(['class' => 'form-control']);
 ?>
-<div class="form-group">
-    <?= $this->formLabel($elemSalutation) ?>
-    <?= $this->formSelect($elemSalutation) ?>
-</div>
+    <div class="form-group">
+        <?= $this->formLabel($elemSalutation) ?>
+        <?= $this->formSelect($elemSalutation) ?>
+    </div>
 
 <? /* academic title */ ?>
 <?php
@@ -147,10 +146,10 @@ $elemAcademicTitle = $form->get('academicTitle');
 $elemAcademicTitle->setLabelAttributes(['class' => 'col-md-4']);
 $elemAcademicTitle->setAttributes(['class' => 'form-control']);
 ?>
-<div class="form-group">
-    <?= $this->formLabel($elemAcademicTitle) ?>
-    <?= $this->formElement($elemAcademicTitle) ?>
-</div>
+    <div class="form-group">
+        <?= $this->formLabel($elemAcademicTitle) ?>
+        <?= $this->formElement($elemAcademicTitle) ?>
+    </div>
 
 <? /* firstname */ ?>
 <?php
@@ -159,11 +158,11 @@ $elemFirstname = $form->get('firstname');
 $elemFirstname->setLabelAttributes(['class' => 'col-md-4']);
 $elemFirstname->setAttributes(['class' => 'form-control']);
 ?>
-<div class="form-group">
-    <?= $this->formLabel($elemFirstname) ?>
-    <?= $this->formElement($elemFirstname) ?>
-    <?= $this->formElementErrors($elemFirstname) ?>
-</div>
+    <div class="form-group">
+        <?= $this->formLabel($elemFirstname) ?>
+        <?= $this->formElement($elemFirstname) ?>
+        <?= $this->formElementErrors($elemFirstname) ?>
+    </div>
 
 <? /* lastname */ ?>
 <?php
@@ -172,11 +171,11 @@ $elemLastname = $form->get('lastname');
 $elemLastname->setLabelAttributes(['class' => 'col-md-4']);
 $elemLastname->setAttributes(['class' => 'form-control']);
 ?>
-<div class="form-group">
-    <?= $this->formLabel($elemLastname) ?>
-    <?= $this->formElement($elemLastname) ?>
-    <?= $this->formElementErrors($elemLastname) ?>
-</div>
+    <div class="form-group">
+        <?= $this->formLabel($elemLastname) ?>
+        <?= $this->formElement($elemLastname) ?>
+        <?= $this->formElementErrors($elemLastname) ?>
+    </div>
 
 <? /* year of birth */ ?>
 <?php
@@ -185,11 +184,11 @@ $elemYearOfBirth = $form->get('yearOfBirth');
 $elemYearOfBirth->setLabelAttributes(['class' => 'col-md-4']);
 $elemYearOfBirth->setAttributes(['class' => 'form-control']);
 ?>
-<div class="form-group">
-    <?= $this->formLabel($elemYearOfBirth) ?>
-    <?= $this->formElement($elemYearOfBirth) ?>
-    <?= $this->formElementErrors($elemYearOfBirth) ?>
-</div>
+    <div class="form-group">
+        <?= $this->formLabel($elemYearOfBirth) ?>
+        <?= $this->formElement($elemYearOfBirth) ?>
+        <?= $this->formElementErrors($elemYearOfBirth) ?>
+    </div>
 
 <? /* college */ ?>
 <?php
@@ -198,11 +197,11 @@ $elemCollege = $form->get('college');
 $elemCollege->setLabelAttributes(['class' => 'col-md-4']);
 $elemCollege->setAttributes(['class' => 'form-control']);
 ?>
-<div class="form-group">
-    <?= $this->formLabel($elemCollege) ?>
-    <?= $this->formElement($elemCollege) ?>
-    <?= $this->formElementErrors($elemCollege) ?>
-</div>
+    <div class="form-group">
+        <?= $this->formLabel($elemCollege) ?>
+        <?= $this->formElement($elemCollege) ?>
+        <?= $this->formElementErrors($elemCollege) ?>
+    </div>
 
 <? /* job title */ ?>
 <?php
@@ -211,55 +210,51 @@ $elemJobTitle = $form->get('jobTitle');
 $elemJobTitle->setLabelAttributes(['class' => 'col-md-4']);
 $elemJobTitle->setAttributes(['class' => 'form-control']);
 ?>
-<div class="form-group">
-    <?= $this->formLabel($elemJobTitle) ?>
-    <?= $this->formElement($elemJobTitle) ?>
-    <?= $this->formElementErrors($elemJobTitle) ?>
-</div>
+    <div class="form-group">
+        <?= $this->formLabel($elemJobTitle) ?>
+        <?= $this->formElement($elemJobTitle) ?>
+        <?= $this->formElementErrors($elemJobTitle) ?>
+    </div>
 
 <? /* role (user group)  */ ?>
 <?php
 /** @var Element\Radio $accessLevel */
 $accessLevel = $form->get('accessLevel');
-$accessLevelValueOptions = array_map(function ($accessLevel) {
-    return "label_access_level_$accessLevel";
-}, array_combine($this->accessLevels, $this->accessLevels));
-$accessLevel->setValueOptions($accessLevelValueOptions);
 ?>
-<div class="form-group">
-    <div class="col-md-4">
-        <?= $this->formLabel($accessLevel) ?>
-    </div>
-    <div class="col-md-8">
-        <?= $this->formRadio($accessLevel) ?>
+    <div class="form-group">
+        <div class="col-md-4">
+            <?= $this->formLabel($accessLevel) ?>
+        </div>
+        <div class="col-md-8">
+            <?= $this->formRadio($accessLevel) ?>
+        </div>
+        <?= $this->formElementErrors($accessLevel) ?>
     </div>
-    <?= $this->formElementErrors($accessLevel) ?>
-</div>
 
 <? /* eula privacy policy */ ?>
 <?php
 /** @var Checkbox $elemEulaAccepted */
 $elemEulaAccepted = $form->get('eulaAccepted');
-$elemEulaAccepted->setAttribute('id', $elemEulaAccepted->getAttribute('name') ?? 'eulaAccepted');
+$elemEulaAccepted->setAttribute('id', 'eulaAccepted');
 ?>
-<div class="form-group eula">
-    <div>
-        <?= $this->formElement($elemEulaAccepted) ?>
-        <?= $this->formLabel()->openTag($elemEulaAccepted) ?>
-        <?= $this->translate("fid::policy_text") ?>
-        <?php $url = $this->url('fid/user/policy') ?>
-        <a data-lightbox href="<?= $url ?>">
-            <?= $this->translate("fid::policy") ?>
-        </a>
-        <?= $this->translate("fid::terms_text") ?>
-        <?php $url = $this->url('fid/user/terms') ?>
-        <a data-lightbox href="<?= $url ?>">
-            <?= $this->translate("fid::terms") ?>
-        </a>.
-        <?= $this->formLabel()->closeTag($elemEulaAccepted) ?>
+    <div class="form-group eula">
+        <div>
+            <?= $this->formElement($elemEulaAccepted) ?>
+            <?= $this->formLabel()->openTag($elemEulaAccepted) ?>
+            <?= $this->translate("fid::policy_text") ?>
+            <?php $url = $this->url('fid/user/policy') ?>
+            <a data-lightbox href="<?= $url ?>">
+                <?= $this->translate("fid::policy") ?>
+            </a>
+            <?= $this->translate("fid::terms_text") ?>
+            <?php $url = $this->url('fid/user/terms') ?>
+            <a data-lightbox href="<?= $url ?>">
+                <?= $this->translate("fid::terms") ?>
+            </a>.
+            <?= $this->formLabel()->closeTag($elemEulaAccepted) ?>
+        </div>
+        <?= $this->formElementErrors($elemEulaAccepted) ?>
     </div>
-    <?= $this->formElementErrors($elemEulaAccepted) ?>
-</div>
 
 <? /* submit button */ ?>
 <?php
@@ -267,10 +262,10 @@ $elemEulaAccepted->setAttribute('id', $elemEulaAccepted->getAttribute('name') ??
 $elemSubmit = $form->get('submit');
 $elemSubmit->setAttributes(['class' => 'btn btn-primary']);
 ?>
-<div class="form-group">
-    <div class="">
-        <?= $this->formSubmit($elemSubmit) ?>
+    <div class="form-group">
+        <div class="">
+            <?= $this->formSubmit($elemSubmit) ?>
+        </div>
     </div>
-</div>
 
 <?= $this->form()->closeTag($form) ?>
\ No newline at end of file
diff --git a/themes/fid/templates/fid/user/update.phtml b/themes/fid/templates/fid/user/update.phtml
index 1ac47e76d9dc849de69f5b9c57b97194d7bca803..ac924b015c77c17de416611a18a966994f53cf0f 100644
--- a/themes/fid/templates/fid/user/update.phtml
+++ b/themes/fid/templates/fid/user/update.phtml
@@ -66,10 +66,10 @@ $this->headTitle($this->translate('Profile Form'));
 $this->headTitle($this->translate("fid::user_update_form_title"));
 ?>
 
-<h2><?= $this->translate("fid::user_update_form_title") ?></h2>
+    <h2><?= $this->translate("fid::user_update_form_title") ?></h2>
 <?= $this->flashmessages() ?>
 <?= $this->form()->openTag($form) ?>
-<br/>
+    <br/>
 
 <? /* home library */ ?>
 <?php
@@ -77,14 +77,13 @@ $this->headTitle($this->translate("fid::user_update_form_title"));
 $elemHomeLibrary = $form->get('homeLibrary');
 $elemHomeLibrary->setLabelAttributes(['class' => 'inline col-md-4 col-sm-10']);
 $elemHomeLibrary->setAttributes(['class' => 'inline col-sm-6']);
-$elemHomeLibrary->setValueOptions($this->libraries);
 $elemHomeLibrary->setValue($user->getHomeLibrary());
 ?>
-<div class="form-group">
-    <?= $this->formLabel($elemHomeLibrary) ?>
-    <?= $this->formSelect($elemHomeLibrary) ?>
-    <?= $this->formElementErrors($elemHomeLibrary) ?>
-</div>
+    <div class="form-group">
+        <?= $this->formLabel($elemHomeLibrary) ?>
+        <?= $this->formSelect($elemHomeLibrary) ?>
+        <?= $this->formElementErrors($elemHomeLibrary) ?>
+    </div>
 
 <? /* salutation */ ?>
 <?php
@@ -94,11 +93,11 @@ $elemSalutation->setLabelAttributes(['class' => 'inline col-md-4 col-sm-10']);
 $elemSalutation->setAttributes(['class' => 'inline col-sm-2']);
 $elemSalutation->setValue($user->getSalutation());
 ?>
-<div class="form-group">
-    <?= $this->formLabel($elemSalutation) ?>
-    <?= $this->formSelect($elemSalutation) ?>
+    <div class="form-group">
+        <?= $this->formLabel($elemSalutation) ?>
+        <?= $this->formSelect($elemSalutation) ?>
 
-</div>
+    </div>
 
 <? /* academic title */ ?>
 <?php
@@ -108,10 +107,10 @@ $elemAcademicTitle->setLabelAttributes(['class' => 'inline col-md-4 col-sm-10'])
 $elemAcademicTitle->setAttributes(['class' => 'form-control']);
 $elemAcademicTitle->setValue($user->getAcademicTitle());
 ?>
-<div class="form-group">
-    <?= $this->formLabel($elemAcademicTitle) ?>
-    <?= $this->formElement($elemAcademicTitle) ?>
-</div>
+    <div class="form-group">
+        <?= $this->formLabel($elemAcademicTitle) ?>
+        <?= $this->formElement($elemAcademicTitle) ?>
+    </div>
 
 <? /* firstname */ ?>
 <?php
@@ -121,11 +120,11 @@ $elemFirstname->setLabelAttributes(['class' => 'inline col-md-4 col-sm-10']);
 $elemFirstname->setAttributes(['class' => 'form-control']);
 $elemFirstname->setValue($user->getFirstname());
 ?>
-<div class="form-group">
-    <?= $this->formLabel($elemFirstname) ?>
-    <?= $this->formElement($elemFirstname) ?>
-    <?= $this->formElementErrors($elemFirstname) ?>
-</div>
+    <div class="form-group">
+        <?= $this->formLabel($elemFirstname) ?>
+        <?= $this->formElement($elemFirstname) ?>
+        <?= $this->formElementErrors($elemFirstname) ?>
+    </div>
 
 <? /* lastname */ ?>
 <?php
@@ -135,11 +134,11 @@ $elemLastname->setLabelAttributes(['class' => 'inline col-md-4 col-sm-10']);
 $elemLastname->setAttributes(['class' => 'form-control']);
 $elemLastname->setValue($user->getLastname());
 ?>
-<div class="form-group">
-    <?= $this->formLabel($elemLastname) ?>
-    <?= $this->formElement($elemLastname) ?>
-    <?= $this->formElementErrors($elemLastname) ?>
-</div>
+    <div class="form-group">
+        <?= $this->formLabel($elemLastname) ?>
+        <?= $this->formElement($elemLastname) ?>
+        <?= $this->formElementErrors($elemLastname) ?>
+    </div>
 
 <? /* year of birth */ ?>
 <?php
@@ -149,11 +148,11 @@ $elemYearOfBirth->setLabelAttributes(['class' => 'inline col-md-4 col-sm-10']);
 $elemYearOfBirth->setAttributes(['class' => 'form-control']);
 $elemYearOfBirth->setValue($user->getYearOfBirth());
 ?>
-<div class="form-group">
-    <?= $this->formLabel($elemYearOfBirth) ?>
-    <?= $this->formElement($elemYearOfBirth) ?>
-    <?= $this->formElementErrors($elemYearOfBirth) ?>
-</div>
+    <div class="form-group">
+        <?= $this->formLabel($elemYearOfBirth) ?>
+        <?= $this->formElement($elemYearOfBirth) ?>
+        <?= $this->formElementErrors($elemYearOfBirth) ?>
+    </div>
 
 <? /* college */ ?>
 <?php
@@ -163,11 +162,11 @@ $elemCollege->setLabelAttributes(['class' => 'inline col-md-4 col-sm-10']);
 $elemCollege->setAttributes(['class' => 'form-control']);
 $elemCollege->setValue($user->getCollege());
 ?>
-<div class="form-group">
-    <?= $this->formLabel($elemCollege) ?>
-    <?= $this->formElement($elemCollege) ?>
-    <?= $this->formElementErrors($elemCollege) ?>
-</div>
+    <div class="form-group">
+        <?= $this->formLabel($elemCollege) ?>
+        <?= $this->formElement($elemCollege) ?>
+        <?= $this->formElementErrors($elemCollege) ?>
+    </div>
 
 <? /* job title */ ?>
 <?php
@@ -177,11 +176,11 @@ $elemJobTitle->setLabelAttributes(['class' => 'inline col-md-4 col-sm-10']);
 $elemJobTitle->setAttributes(['class' => 'form-control']);
 $elemJobTitle->setValue($user->getJobTitle());
 ?>
-<div class="form-group">
-    <?= $this->formLabel($elemJobTitle) ?>
-    <?= $this->formElement($elemJobTitle) ?>
-    <?= $this->formElementErrors($elemJobTitle) ?>
-</div>
+    <div class="form-group">
+        <?= $this->formLabel($elemJobTitle) ?>
+        <?= $this->formElement($elemJobTitle) ?>
+        <?= $this->formElementErrors($elemJobTitle) ?>
+    </div>
 
 <? /* submit button */ ?>
 <?php
@@ -189,11 +188,14 @@ $elemJobTitle->setValue($user->getJobTitle());
 $elemSubmit = $form->get('submit');
 $elemSubmit->setAttributes(['class' => 'btn btn-primary']);
 ?>
-<div class="form-group">
-  <div class="col-lg-11 col-md-9 col-sm-11 col-xs-12">
-    <?= $this->formSubmit($elemSubmit) ?>
-    <a href="<?=$this->url('myresearch-profile')?>" class="btn btn-primary"><?=$this->transEsc('Cancel')?></a>
-  </div>
-</div>
+    <div class="form-group">
+        <div class="col-lg-11 col-md-9 col-sm-11 col-xs-12">
+            <?= $this->formSubmit($elemSubmit) ?>
+            <a href="<?= $this->url('myresearch-profile') ?>"
+               class="btn btn-primary">
+                <?= $this->transEsc('Cancel') ?>
+            </a>
+        </div>
+    </div>
 
 <?= $this->form()->closeTag($form) ?>
\ No newline at end of file